Skip to content
Snippets Groups Projects
Commit dc053d5b authored by W. Spencer Smith's avatar W. Spencer Smith
Browse files

A3 Part 2 Solution

parent 56e94a2e
No related branches found
No related tags found
No related merge requests found
Showing
with 13749 additions and 0 deletions
SRC_DIRS := src
C_SRCS := $(foreach srcdir,$(SRC_DIRS),$(wildcard $(srcdir)/*.c))
CXX_SRCS := $(foreach srcdir,$(SRC_DIRS),$(wildcard $(srcdir)/*.cpp))
C_OBJS := ${C_SRCS:.c=.o}
CXX_OBJS := ${CXX_SRCS:.cpp=.o}
OBJS := $(C_OBJS) $(CXX_OBJS)
INCLUDE_DIRS := include
LIBRARY_DIRS :=
LIBRARIES :=
prog_NAME := experiment
prog_DIR := bin
prog_FULL := $(prog_DIR)/$(prog_NAME)
prog_SRC_DIRS := experiment
prog_C_SRCS := $(foreach srcdir,$(prog_SRC_DIRS),$(wildcard $(srcdir)/*.c))
prog_CXX_SRCS := $(foreach srcdir,$(prog_SRC_DIRS),$(wildcard $(srcdir)/*.cpp))
prog_C_OBJS := ${prog_C_SRCS:.c=.o}
prog_CXX_OBJS := ${prog_CXX_SRCS:.cpp=.o}
prog_OBJS := $(prog_C_OBJS) $(prog_CXX_OBJS)
prog_INCLUDE_DIRS :=
prog_LIBRARY_DIRS :=
prog_LIBRARIES :=
test_NAME := test
test_DIR := bin
test_FULL := $(test_DIR)/$(test_NAME)
test_SRC_DIRS := test
test_C_SRCS := $(foreach srcdir,$(test_SRC_DIRS),$(wildcard $(srcdir)/*.c))
test_CXX_SRCS := $(foreach srcdir,$(test_SRC_DIRS),$(wildcard $(srcdir)/*.cpp))
test_C_OBJS := ${test_C_SRCS:.c=.o}
test_CXX_OBJS := ${test_CXX_SRCS:.cpp=.o}
test_OBJS := $(test_C_OBJS) $(test_CXX_OBJS)
test_INCLUDE_DIRS := catch
test_LIBRARY_DIRS :=
test_LIBRARIES :=
all_OBJS := $(OBJS) $(prog_OBJS) $(test_OBJS)
DEP := $(all_OBJS:%.o=%.d)
CXXFLAGS += -std=c++11
CXXFLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir))
LDFLAGS += $(foreach librarydir,$(LIBRARY_DIRS),-L$(librarydir))
LDFLAGS += $(foreach library,$(LIBRARIES),-l$(library))
.PHONY: test experiment clean
test: CXXFLAGS += $(foreach includedir,$(test_INCLUDE_DIRS),-I$(includedir))
test: LDFLAGS += $(foreach librarydir,$(test_LIBRARY_DIRS),-L$(librarydir))
test: LDFLAGS += $(foreach library,$(test_LIBRARIES),-l$(library))
experiment: CXXFLAGS += $(foreach includedir,$(prog_INCLUDE_DIRS),-I$(includedir))
experiment: LDFLAGS += $(foreach librarydir,$(prog_LIBRARY_DIRS),-L$(librarydir))
experiment: LDFLAGS += $(foreach library,$(prog_LIBRARIES),-l$(library))
test: $(test_FULL)
./$(test_FULL)
experiment: $(prog_FULL)
./$(prog_FULL)
$(test_FULL): $(test_OBJS) $(OBJS)
$(LINK.cc) $^ -o $@
$(prog_FULL): $(prog_OBJS) $(OBJS)
$(LINK.cc) $^ -o $@
-include $(DEP)
%.o: %.cpp
$(CXX) $(CXXFLAGS) -MMD -c $< -o $@
clean:
@- $(RM) $(prog_FULL)
@- $(RM) $(prog_OBJS)
@- $(RM) $(test_FULL)
@- $(RM) $(test_OBJS)
@- $(RM) $(OBJS)
@- $(RM) $(DEP)
This diff is collapsed.
/*
* use this file for experimenting with your code,
* testing things that don't work, debugging, etc.
*
* you can compile and run this via 'make experiment'
*
* this file will not be graded
*/
#include "PointADT.h"
#include "LineADT.h"
#include "PathADT.h"
#include "DEM.h"
#include "LanduseMap.h"
#include "MapTypes.h"
#include "Seq2D.h"
#include "Exceptions.h"
#include <iostream>
#include <vector>
using namespace std;
int main()
{
cout << "'make experiment' will run this main" << endl;
// when you are finished your implementation, uncomment the code
// below and make sure 'make experiment' compiles and runs.
// This will ensure that your interface has the correct syntax and will be
// compatible with our unit tests that we will run for grading.
/*
{
LanduseT l = Recreational;
l = Transport;
l = Agricultural;
l = Residential;
l = Commercial;
}
{
CompassT o = N;
o = S;
o = E;
o = W;
}
{
RotateT r = CW;
r = CCW;
}
{
PointT p(0, 0);
int a = p.x();
a = p.y();
PointT p2 = p.translate(0, 0);
}
{
LineT l(PointT(0, 0), N, 1);
PointT s = l.strt();
s = l.end();
CompassT o = l.orient();
unsigned int a = l.len();
LineT l2 = l.flip();
l2 = l.rotate(CW);
l2 = l.translate(0, 0);
}
{
PathT pth(PointT(0, 0), N, 1);
pth.append(W, 1);
PointT p = pth.strt();
p = pth.end();
LineT l = pth.line(0);
unsigned int a = pth.size();
a = pth.len();
PathT pth2 = pth.translate(0, 0);
}
{
vector<vector<int>> v = {
{0, 0, 0}
, {0, 0, 0}
, {0, 0, 0}
};
DEMT d(v, 1.0);
d.set(PointT(0, 0), 0);
int a = d.get(PointT(0, 0));
unsigned int b = d.getNumRow();
b = d.getNumCol();
double c = d.getScale();
b = d.count(0);
b = d.count(LineT(PointT(0, 0), N, 1), 0);
b = d.count(PathT(PointT(0, 0), N, 1), 0);
c = d.length(PathT(PointT(0, 0), N, 1));
bool e = d.connected(PointT(0, 0), PointT(0, 0));
}
{
vector<vector<LanduseT>> v = {
{Transport, Transport, Transport}
, {Transport, Transport, Transport}
, {Transport, Transport, Transport}
};
LanduseMapT lum(v, 1.0);
lum.set(PointT(0, 0), Transport);
int a = lum.get(PointT(0, 0));
unsigned int b = lum.getNumRow();
b = lum.getNumCol();
double c = lum.getScale();
b = lum.count(Transport);
b = lum.count(LineT(PointT(0, 0), N, 1), Transport);
b = lum.count(PathT(PointT(0, 0), N, 1), Transport);
c = lum.length(PathT(PointT(0, 0), N, 1));
bool e = lum.connected(PointT(0, 0), PointT(0, 0));
}
*/
return 0;
}
\ No newline at end of file
#ifndef DEM_H
#define DEM_H
#include "Seq2D.h"
typedef Seq2D<int> DEMT;
#endif
\ No newline at end of file
#ifndef EXCEPTIONS_H
#define EXCEPTIONS_H
#include <exception>
class invalid_argument : public std::exception {
const char * what () const throw () {
return "invalid argument";
}
};
class outside_bounds : public std::exception {
const char * what () const throw () {
return "outside bounds";
}
};
#endif
\ No newline at end of file
#ifndef LANDUSEMAP_H
#define LANDUSEMAP_H
#include "Seq2D.h"
#include "MapTypes.h"
typedef Seq2D<LanduseT> LanduseMapT;
#endif
\ No newline at end of file
#ifndef LINEADT_H
#define LINEADT_H
#include "PointADT.h"
#include "MapTypes.h"
class LineT
{
private:
PointT s;
CompassT o;
nat L;
public:
LineT(PointT s, CompassT o, nat l);
PointT strt() const;
PointT end() const;
CompassT orient() const;
nat len() const;
LineT flip() const;
LineT rotate(RotateT r) const;
LineT translate(int dx, int dy) const;
};
#endif
\ No newline at end of file
#ifndef MAPTYPES_H
#define MAPTYPES_H
enum CompassT {N, S, E, W};
enum LanduseT {Recreational, Transport, Agricultural, Residential, Commercial};
enum RotateT {CW, CCW};
typedef unsigned int nat;
#endif
\ No newline at end of file
#ifndef PATHADT_H
#define PATHADT_H
#include "PointADT.h"
#include "LineADT.h"
#include "MapTypes.h"
#include <vector>
using std::vector;
class PathT
{
private:
vector<LineT> s;
void translatePriv(int dx, int dy);
vector<PointT> pointsInLine(LineT ln) const;
PointT adjPt(CompassT o) const;
bool intersects(LineT a, LineT b) const;
public:
PathT(PointT st, CompassT o, nat l);
void append(CompassT o, nat l);
PointT strt() const;
PointT end() const;
LineT line(nat i) const;
nat size() const;
nat len() const;
PathT translate(int dx, int dy) const;
};
#endif
#ifndef POINTADT_H
#define POINTADT_H
#include <functional>
class PointT
{
private:
int xc;
int yc;
public:
PointT(int x, int y);
int x() const;
int y() const;
PointT translate(int dx, int dy) const;
};
// overloading comparison operators for convenience
inline bool operator==(const PointT& lhs, const PointT& rhs)
{
return lhs.x() == rhs.x() && lhs.y() == rhs.y();
}
inline bool operator!=(const PointT& lhs, const PointT& rhs)
{
return !operator==(lhs, rhs);
}
namespace std
{
template <>
struct hash<PointT>
{
size_t operator()(const PointT& p) const
{
return p.x() ^ p.y();
}
};
}
#endif
\ No newline at end of file
#ifndef SEQ2D_H
#define SEQ2D_H
#include "PointADT.h"
#include "LineADT.h"
#include "PathADT.h"
#include "MapTypes.h"
#include <vector>
using std::vector;
template <class T>
class Seq2D
{
private:
vector<vector<T>> s;
double scale;
nat nRow;
nat nCol;
bool validRow(nat i) const;
bool validCol(nat j) const;
bool validPoint(PointT p) const;
bool validLine(LineT l) const;
bool validPath(PathT pth) const;
vector<PointT> pointsInLine(LineT l) const;
vector<PointT> pointsInPath(PathT pth) const;
public:
Seq2D(vector<vector<T>> s, double scale);
void set(PointT p, T v);
T get(PointT p) const;
nat getNumRow() const;
nat getNumCol() const;
double getScale() const;
nat count(T t) const;
nat count(LineT l, T t) const;
nat count(PathT pth, T t) const;
double length(PathT pth) const;
bool connected(PointT p1, PointT p2) const;
};
#endif
#include "LineADT.h"
#include "PointADT.h"
#include "MapTypes.h"
#include "Exceptions.h"
LineT::LineT(PointT s, CompassT o, nat l) : s(s)
{
if(l == 0)
throw invalid_argument();
this->o = o;
this->L = l;
}
PointT LineT::strt() const
{
return s; // returning s makes a copy
}
PointT LineT::end() const
{
nat d = L - 1;
switch(o) {
case N:
return PointT(s.x(), s.y() + d);
case S:
return PointT(s.x(), s.y() - d);
case E:
return PointT(s.x() + d, s.y());
case W:
return PointT(s.x() - d, s.y());
}
}
CompassT LineT::orient() const
{
return o;
}
nat LineT::len() const
{
return L;
}
LineT LineT::flip() const
{
switch(o) {
case N:
return LineT(s, S, L);
case S:
return LineT(s, N, L);
case E:
return LineT(s, W, L);
case W:
return LineT(s, E, L);
}
}
LineT LineT::rotate(RotateT r) const
{
switch(o) {
case N:
return (r == CW) ? LineT(s, E, L) : LineT(s, W, L);
case S:
return (r == CW) ? LineT(s, W, L) : LineT(s, E, L);
case E:
return (r == CW) ? LineT(s, S, L) : LineT(s, N, L);
case W:
return (r == CW) ? LineT(s, N, L) : LineT(s, S, L);
}
}
LineT LineT::translate(int dx, int dy) const
{
return LineT(s.translate(dx, dy), o, L);
}
#include "PathADT.h"
#include "PointADT.h"
#include "LineADT.h"
#include "MapTypes.h"
#include "Exceptions.h"
#include <vector>
using std::vector;
PathT::PathT(PointT st, CompassT o, nat l)
{
s.push_back(LineT(st, o, l));
}
void PathT::append(CompassT o, nat l)
{
LineT newLn(adjPt(o), o, l);
for(auto ln : s)
if(intersects(newLn, ln))
throw invalid_argument();
s.push_back(newLn);
}
PointT PathT::strt() const
{
return s.front().strt();
}
PointT PathT::end() const
{
return s.back().end();
}
LineT PathT::line(nat i) const
{
return s[i];
}
nat PathT::size() const
{
return s.size();
}
nat PathT::len() const
{
nat sum = 0;
for(auto ln : s)
sum += ln.len();
return sum;
}
PathT PathT::translate(int dx, int dy) const
{
PathT newPath = *this;
newPath.translatePriv(dx, dy);
return newPath;
}
// private methods
void PathT::translatePriv(int dx, int dy)
{
for(vector<LineT>::iterator it = s.begin(); it != s.end(); ++it)
*it = (*it).translate(dx, dy);
}
vector<PointT> PathT::pointsInLine(LineT ln) const
{
vector<PointT> pts;
int xFactor = 0;
int yFactor = 0;
switch(ln.orient()){
case N:
yFactor = 1;
break;
case S:
yFactor = -1;
break;
case E:
xFactor = 1;
break;
case W:
xFactor = -1;
break;
}
for(nat i = 0; i < ln.len(); ++i)
pts.push_back(ln.strt().translate(i*xFactor, i*yFactor));
return pts;
}
PointT PathT::adjPt(CompassT o) const
{
switch(o){
case N:
return end().translate(0, 1);
case S:
return end().translate(0, -1);
case E:
return end().translate(1, 0);
case W:
return end().translate(-1, 0);
}
}
bool PathT::intersects(LineT a, LineT b) const
{
vector<PointT> ptsA = pointsInLine(a);
vector<PointT> ptsB = pointsInLine(b);
for(auto pA : ptsA)
for(auto pB : ptsB)
if(pA == pB) return true;
return false;
}
#include "PointADT.h"
PointT::PointT(int x, int y)
{
this->xc = x;
this->yc = y;
}
int PointT::x() const
{
return this->xc;
}
int PointT::y() const
{
return this->yc;
}
PointT PointT::translate(int dx, int dy) const
{
return PointT(this->xc + dx, this->yc + dy);
}
\ No newline at end of file
#include "Seq2D.h"
#include "PointADT.h"
#include "LineADT.h"
#include "PathADT.h"
#include "MapTypes.h"
#include "Exceptions.h"
#include <vector>
#include <queue>
#include <unordered_set>
using std::vector;
using std::queue;
using std::unordered_set;
template <class T>
Seq2D<T>::Seq2D(vector<vector<T>> s, double scale)
{
if(scale <= 0) throw invalid_argument();
if(s.empty()) throw invalid_argument();
if(s[0].empty()) throw invalid_argument();
for(auto row : s)
if( row.size() != s[0].size() )
throw invalid_argument();
this->s = s;
this->scale = scale;
this->nRow = s.size();
this->nCol = s[0].size();
}
template <class T>
void Seq2D<T>::set(PointT p, T v)
{
if(!(validPoint(p)))
throw outside_bounds();
s[p.y()][p.x()] = v;
}
template <class T>
T Seq2D<T>::get(PointT p) const
{
if(!(validPoint(p)))
throw outside_bounds();
return s[p.y()][p.x()];
}
template <class T>
nat Seq2D<T>::getNumRow() const
{
return nRow;
}
template <class T>
nat Seq2D<T>::getNumCol() const
{
return nCol;
}
template <class T>
double Seq2D<T>::getScale() const
{
return scale;
}
template <class T>
nat Seq2D<T>::count(T t) const
{
nat cnt = 0;
for(auto row : s)
for(auto element : row)
if(element == t)
++cnt;
return cnt;
}
template <class T>
nat Seq2D<T>::count(LineT l, T t) const
{
if(!validLine(l))
throw invalid_argument();
nat cnt = 0;
for(auto pt : pointsInLine(l))
if(get(pt) == t)
++cnt;
return cnt;
}
template <class T>
nat Seq2D<T>::count(PathT pth, T t) const
{
if(!validPath(pth))
throw invalid_argument();
nat cnt = 0;
for(auto pt : pointsInPath(pth))
if(get(pt) == t)
++cnt;
return cnt;
}
template <class T>
double Seq2D<T>::length(PathT pth) const
{
if(!validPath(pth))
throw invalid_argument();
return pth.len() * scale;
}
template <class T>
bool Seq2D<T>::connected(PointT p1, PointT p2) const
{
if(!validPoint(p1) || !validPoint(p2))
throw invalid_argument();
T t = get(p1);
if(get(p2) != t)
return false;
// use BFS
queue<PointT> q;
unordered_set<PointT> marked;
q.push(p1);
marked.insert(p1);
while(!q.empty()){
PointT p = q.front();
q.pop();
// get adjacent points
unordered_set<PointT> adj =
{ p.translate(0,1),
p.translate(0,-1),
p.translate(1,0),
p.translate(-1,0) };
for(auto pAdj : adj){
if(pAdj == p2) return true;
if(validPoint(pAdj) && marked.find(pAdj) == marked.end())
if(get(pAdj) == t){
q.push(pAdj);
marked.insert(pAdj);
}
}
}
return false;
}
// private methods
template <class T>
bool Seq2D<T>::validRow(nat i) const
{
return i <= (nRow - 1);
}
template <class T>
bool Seq2D<T>::validCol(nat j) const
{
return j <= (nCol - 1);
}
template <class T>
bool Seq2D<T>::validPoint(PointT p) const
{
return validRow(p.x()) && validCol(p.y());
}
template <class T>
bool Seq2D<T>::validLine(LineT l) const
{
return validPoint(l.strt()) && validPoint(l.end());
}
template <class T>
bool Seq2D<T>::validPath(PathT pth) const
{
for(nat i = 0; i < pth.size(); ++i)
if(!validLine(pth.line(i)))
return false;
return true;
}
template <class T>
vector<PointT> Seq2D<T>::pointsInLine(LineT ln) const
{
vector<PointT> pts;
int xFactor = 0;
int yFactor = 0;
switch(ln.orient()){
case N:
yFactor = 1;
break;
case S:
yFactor = -1;
break;
case E:
xFactor = 1;
break;
case W:
xFactor = -1;
break;
}
for(nat i = 0; i < ln.len(); ++i)
pts.push_back(ln.strt().translate(i*xFactor, i*yFactor));
return pts;
}
template <class T>
vector<PointT> Seq2D<T>::pointsInPath(PathT pth) const
{
vector<PointT> pts;
for(nat i = 0; i < pth.size(); ++i)
for(auto pt : pointsInLine(pth.line(i)))
pts.push_back(pt);
return pts;
}
// explicit instantiations of Seq2D
template class Seq2D<LanduseT>;
template class Seq2D<int>;
#include "catch.h"
#include "DEM.h"
#include <vector>
TEST_CASE( "tests for DEMT" , "[DEMT]" ) {
vector<vector<int>> v;
/* TEST GRID 'v':
*
* 3 3 3 0
* 0 1 3 1
* 1 1 3 1
* 1 2 3 3
*/
v.push_back( vector<int> {1,2,3,3} );
v.push_back( vector<int> {1,1,3,1} );
v.push_back( vector<int> {0,1,3,1} );
v.push_back( vector<int> {3,3,3,0} );
DEMT dem(v, 3.0);
SECTION( "get" ){
REQUIRE( dem.get(PointT(2,2)) == 3 );
}
SECTION( "connected"){
REQUIRE( dem.connected(PointT(0,0), PointT(1,2)) );
REQUIRE( !dem.connected(PointT(0,0), PointT(3,2)) );
REQUIRE( dem.connected(PointT(3,0), PointT(0,3)) );
REQUIRE( !dem.connected(PointT(0,2), PointT(3,3)) );
REQUIRE( !dem.connected(PointT(2,1), PointT(0,0)) );
}
}
\ No newline at end of file
#include "catch.h"
#include "PointADT.h"
#include "PathADT.h"
#include "MapTypes.h"
TEST_CASE( "tests for PathT" , "[PathT]" ) {
PathT p1(PointT(0, 0), N, 4);
SECTION( "Self-crossing path" ){
p1.append(E, 3);
p1.append(S, 3);
p1.append(W, 2);
p1.append(N, 2);
p1.append(E, 1);
p1.append(S, 1);
}
}
\ No newline at end of file
#include "catch.h"
#include "PointADT.h"
TEST_CASE( "tests for PointT" , "[PointT]" ) {
PointT p1(0, 0);
PointT p2(0, 1);
PointT p3(1, 0);
PointT p4(1, 1);
// the test below aren't necessary for the assignment
SECTION( "PointT equality" ){
REQUIRE( p1 == PointT(0, 0) );
REQUIRE( !(p1 == p2) );
}
SECTION( "PointT inequality" ){
REQUIRE( !(p1 != PointT(0, 0)) );
REQUIRE( p1 != p2 );
}
}
\ No newline at end of file
// don't change or add anything to this file.
// this automatically creates a main method for testing
#define CATCH_CONFIG_MAIN
#include "catch.h"
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment