2019-12-18 in class
This commit is contained in:
parent
6b3e3a2da9
commit
b3b4b52882
9 changed files with 650 additions and 1 deletions
37
checker/checker.cc
Normal file
37
checker/checker.cc
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// vim: set ts=2 sw=2 et tw=80:
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class checker {
|
||||||
|
struct pos {
|
||||||
|
unsigned x;
|
||||||
|
unsigned y;
|
||||||
|
pos(unsigned x, unsigned y) : x(x), y(y) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned c;
|
||||||
|
unsigned r;
|
||||||
|
std::map<pos, bool> map;
|
||||||
|
|
||||||
|
public:
|
||||||
|
checker(unsigned c, unsigned r) : c(c), r(r), map() {}
|
||||||
|
|
||||||
|
void visit(unsigned int x, unsigned int y);
|
||||||
|
bool visited(unsigned x, unsigned y);
|
||||||
|
};
|
||||||
|
|
||||||
|
void checker::visit(unsigned x, unsigned y) {
|
||||||
|
this->map[pos(] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checker::visited(unsigned x, unsigned y) {
|
||||||
|
return this->map[x * this->c + y];
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
checker a(10, 10);
|
||||||
|
a.visit(1, 1);
|
||||||
|
assert(a.visited(1,1));
|
||||||
|
assert(!a.visited(1,0));
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ unsigned long table_total_size(const struct chessboard*);
|
||||||
unsigned long table_hash(const struct chessboard*, unsigned, unsigned);
|
unsigned long table_hash(const struct chessboard*, unsigned, unsigned);
|
||||||
|
|
||||||
inline unsigned long table_total_size(const struct chessboard* c) {
|
inline unsigned long table_total_size(const struct chessboard* c) {
|
||||||
return 100;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned long table_hash(const struct chessboard* c, unsigned col,
|
inline unsigned long table_hash(const struct chessboard* c, unsigned col,
|
||||||
|
|
142
roadmap/Makefile
Normal file
142
roadmap/Makefile
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
OBJECTS = roadmap.o
|
||||||
|
CFLAGS=-Wall -g
|
||||||
|
CXXFLAGS=-Wall -g
|
||||||
|
SHELL=/bin/bash
|
||||||
|
|
||||||
|
TIMEOUT=8
|
||||||
|
|
||||||
|
TESTS_DIR=tests
|
||||||
|
|
||||||
|
TESTS_SH:=$(wildcard $(TESTS_DIR)/*.sh)
|
||||||
|
TESTS_SH_NAMES:=$(patsubst $(TESTS_DIR)/%.sh, %, $(TESTS_SH))
|
||||||
|
|
||||||
|
TESTS_IO:=$(wildcard $(TESTS_DIR)/*.in)
|
||||||
|
TESTS_IO_NAMES:=$(patsubst $(TESTS_DIR)/%.in, %, $(TESTS_IO))
|
||||||
|
|
||||||
|
TESTS_C:=$(wildcard $(TESTS_DIR)/*.c)
|
||||||
|
TESTS_CXX:=$(wildcard $(TESTS_DIR)/*.cpp)
|
||||||
|
TESTS_BIN:=$(patsubst $(TESTS_DIR)/%.c, $(TESTS_DIR)/%, $(TESTS_C)) \
|
||||||
|
$(patsubst $(TESTS_DIR)/%.cpp, $(TESTS_DIR)/%, $(TESTS_CXX))
|
||||||
|
TESTS_BIN_NAMES:=$(patsubst $(TESTS_DIR)/%.c, %, $(TESTS_C)) $(patsubst $(TESTS_DIR)/%.cpp, %, $(TESTS_CXX))
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: compile check
|
||||||
|
|
||||||
|
.PHONY: compile-program
|
||||||
|
|
||||||
|
compile: $(PROGRAMS) $(OBJECTS)
|
||||||
|
|
||||||
|
.PHONY: check
|
||||||
|
check: check-bin check-io-sh
|
||||||
|
|
||||||
|
.PHONY: check-io-sh
|
||||||
|
check-io-sh: compile $(TESTS_IO) $(TESTS_SH)
|
||||||
|
@exec 2> /dev/null; \
|
||||||
|
for p in $(foreach prog,$(PROGRAMS),$(dir $(prog))$(prog)); do \
|
||||||
|
echo "Testing $${p}:" ; \
|
||||||
|
for t in $(TESTS_IO_NAMES); do \
|
||||||
|
echo -n "Running test $$t..." ; \
|
||||||
|
"$$p" < "$(TESTS_DIR)/$$t.in" > "$$t.out" 2>&1 & \
|
||||||
|
prog_pid=$$!; \
|
||||||
|
( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \
|
||||||
|
killer_pid=$$!; \
|
||||||
|
wait $$prog_pid; \
|
||||||
|
res=$$?; \
|
||||||
|
if test $$res -gt 128; \
|
||||||
|
then \
|
||||||
|
case `kill -l $$(($$res - 128))` in \
|
||||||
|
ABRT ) echo "FAIL"; ;; \
|
||||||
|
TERM ) echo "TIME OUT"; ;; \
|
||||||
|
* ) echo "UNKNOWN ERROR"; ;; \
|
||||||
|
esac ; \
|
||||||
|
echo "see $(TESTS_DIR)/$$t.in" ;\
|
||||||
|
echo "you may run $$p < $(TESTS_DIR)/$$t.in" ;\
|
||||||
|
echo "to see what went wrong";\
|
||||||
|
rm -f "$$t.out" ;\
|
||||||
|
else \
|
||||||
|
kill $$killer_pid > /dev/null 2>&1 ;\
|
||||||
|
wait $$killer_pid; \
|
||||||
|
if cmp -s "$$t.out" "$(TESTS_DIR)/$$t.expected"; \
|
||||||
|
then \
|
||||||
|
echo "PASS" ;\
|
||||||
|
rm -f "$$t.out" ;\
|
||||||
|
else \
|
||||||
|
echo "FAIL" ;\
|
||||||
|
echo "see $(TESTS_DIR)/$$t.sh" ;\
|
||||||
|
echo "run diff $$t.out $(TESTS_DIR)/$$t.expected";\
|
||||||
|
echo "to see the difference between the actual and expected output";\
|
||||||
|
fi; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
for t in $(TESTS_SH_NAMES); do \
|
||||||
|
echo -n "Running test $$t..." ; \
|
||||||
|
$(SHELL) "$(TESTS_DIR)/$$t.sh" "$$p" > "$$t.out" 2>&1 & \
|
||||||
|
prog_pid=$$!; \
|
||||||
|
( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \
|
||||||
|
killer_pid=$$!; \
|
||||||
|
wait $$prog_pid; \
|
||||||
|
res=$$?; \
|
||||||
|
if test $$res -gt 128; \
|
||||||
|
then \
|
||||||
|
case `kill -l $$(($$res - 128))` in \
|
||||||
|
ABRT ) echo "FAIL"; ;; \
|
||||||
|
TERM ) echo "TIME OUT"; ;; \
|
||||||
|
* ) echo "UNKNOWN ERROR"; ;; \
|
||||||
|
esac ; \
|
||||||
|
echo "see $(TESTS_DIR)/$$t.sh" ;\
|
||||||
|
echo "you may run $(TESTS_DIR)/$$t.sh $$p" ;\
|
||||||
|
echo "to see what went wrong";\
|
||||||
|
rm -f "$$t.out" ;\
|
||||||
|
else \
|
||||||
|
kill $$killer_pid > /dev/null 2>&1 ;\
|
||||||
|
wait $$killer_pid; \
|
||||||
|
if cmp -s "$$t.out" "$(TESTS_DIR)/$$t.expected"; \
|
||||||
|
then \
|
||||||
|
echo "PASS" ;\
|
||||||
|
rm -f "$$t.out" ;\
|
||||||
|
else \
|
||||||
|
echo "FAIL" ;\
|
||||||
|
echo "see $(TESTS_DIR)/$$t.sh" ;\
|
||||||
|
echo "run diff $$t.out $(TESTS_DIR)/$$t.expected";\
|
||||||
|
echo "to see the difference between the actual and expected output";\
|
||||||
|
fi; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
done
|
||||||
|
|
||||||
|
$(TESTS_DIR)/%: $(TESTS_DIR)/%.c $(OBJECTS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) $(TESTS_DIR)/$*.c $(OBJECTS) -o $@
|
||||||
|
|
||||||
|
$(TESTS_DIR)/%: $(TESTS_DIR)/%.cpp $(OBJECTS)
|
||||||
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TESTS_DIR)/$*.cpp $(OBJECTS) -o $@
|
||||||
|
|
||||||
|
.PHONY: check-bin
|
||||||
|
check-bin: $(TESTS_BIN)
|
||||||
|
@exec 2> /dev/null; \
|
||||||
|
for t in $(TESTS_BIN_NAMES); do \
|
||||||
|
echo -n "Running test $$t..." ; \
|
||||||
|
"$(TESTS_DIR)/$$t" &\
|
||||||
|
prog_pid=$$!; \
|
||||||
|
( sleep $(TIMEOUT); kill $$prog_pid > /dev/null 2>&1 ) & \
|
||||||
|
killer_pid=$$!; \
|
||||||
|
wait $$prog_pid; \
|
||||||
|
res=$$?; \
|
||||||
|
if test $$res -gt 128; \
|
||||||
|
then \
|
||||||
|
case `kill -l $$(($$res - 128))` in \
|
||||||
|
ABRT ) echo "FAIL"; ;; \
|
||||||
|
TERM ) echo "TIME OUT"; ;; \
|
||||||
|
* ) echo "UNKNOWN ERROR"; ;; \
|
||||||
|
esac ; \
|
||||||
|
echo "you may run $(TESTS_DIR)/$$t to see what went wrong" ;\
|
||||||
|
else \
|
||||||
|
kill $$killer_pid > /dev/null 2>&1 ;\
|
||||||
|
wait $$killer_pid; \
|
||||||
|
echo "PASS" ;\
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f $(PROGRAMS) $(OBJECTS) tests/*.o $(TESTS_BIN)
|
44
roadmap/roadmap.cpp
Normal file
44
roadmap/roadmap.cpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#include "roadmap.h"
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using std::map;
|
||||||
|
using std::set;
|
||||||
|
|
||||||
|
class ConcreteRoadMap : public AbstractRoadMap {
|
||||||
|
private:
|
||||||
|
int cities;
|
||||||
|
|
||||||
|
map< string, set<string> > adj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds in the map for key city1 a new set with city2 inside if there is no
|
||||||
|
* prior set, otherwise it appends city2 into the existing set
|
||||||
|
*/
|
||||||
|
void addPair(const string& city1, const string& city2) {
|
||||||
|
this->adj[city1].insert(city2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ConcreteRoadMap() : adj(), cities(0) {};
|
||||||
|
|
||||||
|
void addRoad(const string& city1, const string& city2) override {
|
||||||
|
addPair(city1, city2);
|
||||||
|
addPair(city2, city1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addRoad(const vector<string>& cities) override {
|
||||||
|
for (size_t i = 0; i < cities.size() - 1; i++) {
|
||||||
|
addRoad(cities[i], cities[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override {
|
||||||
|
this->adj.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int neighborCountForCity(const string& city) const override {
|
||||||
|
auto i = this->adj.find(city);
|
||||||
|
return i->second.size();
|
||||||
|
}
|
||||||
|
};
|
59
roadmap/roadmap.h
Normal file
59
roadmap/roadmap.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#ifndef __ROADMAP_H__
|
||||||
|
#define __ROADMAP_H__
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
class AbstractRoadMap {
|
||||||
|
public:
|
||||||
|
/* Add a road that connects city1 with city2. All roads are bidirectional.
|
||||||
|
*/
|
||||||
|
virtual void addRoad(const string & city1, const string & city2) = 0;
|
||||||
|
|
||||||
|
/* Add a road that goes through all the cities in the cities
|
||||||
|
* vector. In other words, add a road between each pair of
|
||||||
|
* adjacent cities in the vector.
|
||||||
|
*/
|
||||||
|
virtual void addRoad(const vector<string> & cities) = 0;
|
||||||
|
|
||||||
|
/* Clear the road map completely.
|
||||||
|
*/
|
||||||
|
virtual void clear() = 0;
|
||||||
|
|
||||||
|
/* Return the number of neighboring cities for the given city, or
|
||||||
|
* -1 if the given city is not in the map.
|
||||||
|
*/
|
||||||
|
virtual int neighborCountForCity(const string & city) const = 0;
|
||||||
|
|
||||||
|
/* Return true if and only if there is a path that starts from a
|
||||||
|
* city X and then leads back to X by taking each no more than
|
||||||
|
* once.
|
||||||
|
*/
|
||||||
|
virtual bool hasLoop() const = 0;
|
||||||
|
|
||||||
|
/* Return true if there is a path from city1 to city2.
|
||||||
|
*/
|
||||||
|
virtual bool reachable(const string & city1, const string & city2) const = 0;
|
||||||
|
|
||||||
|
/* Return the number of "islands" in the map. An island is a
|
||||||
|
* maximal group of cities that are reachable from each other.
|
||||||
|
* All cities in an island are reachable from each other, but they
|
||||||
|
* are not reachable from any another city from another island.
|
||||||
|
*/
|
||||||
|
virtual int countIslands() const = 0;
|
||||||
|
|
||||||
|
/* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~AbstractRoadMap() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return a new road map object that implements AbstractRoadMap. The
|
||||||
|
* new road map must be empty, meaning that it does not contain any
|
||||||
|
* road or city.
|
||||||
|
*/
|
||||||
|
extern AbstractRoadMap * createRoadMap();
|
||||||
|
|
||||||
|
#endif // __ROADMAP_H__
|
112
roadmap/tests/basic_testing.h
Normal file
112
roadmap/tests/basic_testing.h
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#ifndef BASIC_TESTING_H_INCLUDED
|
||||||
|
#define BASIC_TESTING_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ck_assert_msg(expr, ...) \
|
||||||
|
if (!(expr)) { \
|
||||||
|
fprintf(stderr, "%s:%d: Assertion '"#expr"' failed\n" , __FILE__, __LINE__); \
|
||||||
|
fprintf(stderr, ## __VA_ARGS__, NULL); \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ck_assert_int(X, OP, Y) do { \
|
||||||
|
intmax_t _ck_x = (X); \
|
||||||
|
intmax_t _ck_y = (Y); \
|
||||||
|
if (!(_ck_x OP _ck_y)) { \
|
||||||
|
fprintf(stderr, "%s:%d: Assertion '%s' failed: %s == %jd, %s == %jd\n", \
|
||||||
|
__FILE__, __LINE__, #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ck_assert_uint(X, OP, Y) do { \
|
||||||
|
uintmax_t _ck_x = (X); \
|
||||||
|
uintmax_t _ck_y = (Y); \
|
||||||
|
if (!(_ck_x OP _ck_y)) { \
|
||||||
|
fprintf(stderr, "%s:%d: Assertion '%s' failed: %s == %ju, %s == %ju\n", \
|
||||||
|
__FILE__, __LINE__, #X" "#OP" "#Y, #X, _ck_x, #Y, _ck_y); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define assert_int_eq(X, Y) ck_assert_int(X,==,Y)
|
||||||
|
#define assert_uint_eq(X, Y) ck_assert_uint(X,==,Y)
|
||||||
|
|
||||||
|
#define assert_true(X) do { \
|
||||||
|
if (!(X)) { \
|
||||||
|
fprintf(stderr, "%s:%d: Assertion failed: '"#X"' is false (should be true)\n", __FILE__, __LINE__); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define assert_false(X) do { \
|
||||||
|
if (X) { \
|
||||||
|
fprintf(stderr, "%s:%d: Assertion failed: '"#X"' is true (should be false)\n", __FILE__, __LINE__); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char * name;
|
||||||
|
int (*test_function)();
|
||||||
|
const char * file;
|
||||||
|
int line;
|
||||||
|
} test_descriptor;
|
||||||
|
|
||||||
|
#define TEST(_Name) \
|
||||||
|
static int _Name ## _fn (); \
|
||||||
|
static const test_descriptor _Name ## _descr = { # _Name, _Name ## _fn, __FILE__, __LINE__}; \
|
||||||
|
static const test_descriptor * _Name = & _Name ## _descr; \
|
||||||
|
static int _Name ## _fn ()
|
||||||
|
|
||||||
|
#define TEST_PASSED do { return (1); } while(0)
|
||||||
|
|
||||||
|
#define TEST_SUITE(_Name) \
|
||||||
|
unsigned int _Name ## _failed; \
|
||||||
|
unsigned int _Name ## _passed; \
|
||||||
|
const test_descriptor * _Name ## _suite []
|
||||||
|
|
||||||
|
#define RUN_SUITE(_Name) \
|
||||||
|
do { \
|
||||||
|
_Name ## _failed = 0; \
|
||||||
|
_Name ## _passed = 0; \
|
||||||
|
for (int _i = 0; _i < sizeof( _Name ## _suite )/sizeof(test_descriptor *); ++_i) { \
|
||||||
|
if (!(_Name ## _suite [_i]->test_function())) { \
|
||||||
|
_Name ## _failed += 1; \
|
||||||
|
fprintf(stderr, "Test suite "#_Name": test %s failed\n", _Name ## _suite [_i]->name); \
|
||||||
|
} else { \
|
||||||
|
_Name ## _passed += 1; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define TEST_SUITE_PASS(_Name) (_Name ## _failed == 0)
|
||||||
|
|
||||||
|
#define PRINT_SUITE_RESULTS(_Name) \
|
||||||
|
do { \
|
||||||
|
printf("Test suite "#_Name": pass %u/%u ", _Name ## _passed, _Name ## _passed + _Name ## _failed); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
static unsigned int tests_run_fail = 0;
|
||||||
|
static unsigned int tests_run_pass = 0;
|
||||||
|
|
||||||
|
#define RUN_TEST(_Name) \
|
||||||
|
do { \
|
||||||
|
if (!(_Name ->test_function())) { \
|
||||||
|
tests_run_fail += 1; \
|
||||||
|
fprintf(stderr, "Test %s failed\n", _Name ->name); \
|
||||||
|
} else { \
|
||||||
|
tests_run_pass += 1; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define PRINT_TEST_RESULTS do { \
|
||||||
|
printf(" %u/%u ", tests_run_pass, tests_run_pass + tests_run_fail); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define ALL_TESTS_PASSED (tests_run_fail == 0)
|
||||||
|
|
||||||
|
#endif /* BASIC_TESTING_H_INCLUDED */
|
18
roadmap/tests/test0.cpp
Normal file
18
roadmap/tests/test0.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "basic_testing.h"
|
||||||
|
|
||||||
|
#include "../roadmap.h"
|
||||||
|
|
||||||
|
TEST(empty) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
RUN_TEST(empty);
|
||||||
|
PRINT_TEST_RESULTS;
|
||||||
|
assert(ALL_TESTS_PASSED);
|
||||||
|
}
|
40
roadmap/tests/test1.cpp
Normal file
40
roadmap/tests/test1.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "basic_testing.h"
|
||||||
|
|
||||||
|
#include "../roadmap.h"
|
||||||
|
|
||||||
|
TEST(example) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
// Add roads on one island:
|
||||||
|
m->addRoad("Sengkol", "Sakra");
|
||||||
|
m->addRoad({"Mataram", "Mangsit", "Pamenang"});
|
||||||
|
m->addRoad({"Mataram", "Sengkol", "Koeta"});
|
||||||
|
|
||||||
|
assert_int_eq(m->countIslands(), 1);
|
||||||
|
assert_true(m->reachable("Sengkol", "Mataram"));
|
||||||
|
assert_int_eq(m->neighborCountForCity("Mataram"), 2);
|
||||||
|
assert_int_eq(m->neighborCountForCity("Pamenang"), 1);
|
||||||
|
assert_false(m->hasLoop());
|
||||||
|
|
||||||
|
// Create a loop:
|
||||||
|
m->addRoad("Sakra", "Mataram");
|
||||||
|
assert_true(m->hasLoop());
|
||||||
|
|
||||||
|
// Add roads on another island:
|
||||||
|
m->addRoad({"Denpasar", "Sukawati", "Ubud"});
|
||||||
|
assert_int_eq(m->countIslands(), 2);
|
||||||
|
|
||||||
|
// Cities on different islands are not reachable:
|
||||||
|
assert_false(m->reachable("Sengkol", "Sukawati"));
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
RUN_TEST(example);
|
||||||
|
PRINT_TEST_RESULTS;
|
||||||
|
assert(ALL_TESTS_PASSED);
|
||||||
|
}
|
197
roadmap/tests/test2.cpp
Normal file
197
roadmap/tests/test2.cpp
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <cassert>
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "basic_testing.h"
|
||||||
|
|
||||||
|
#include "../roadmap.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
TEST(basic_reachability) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
assert_false(m->reachable("Sengkol", "Sakra"));
|
||||||
|
assert_false(m->reachable("Sakra", "Sengkol"));
|
||||||
|
|
||||||
|
m->addRoad("Sengkol", "Sakra");
|
||||||
|
|
||||||
|
assert_true(m->reachable("Sengkol", "Sakra"));
|
||||||
|
assert_true(m->reachable("Sakra", "Sengkol"));
|
||||||
|
|
||||||
|
m->addRoad({"Mataram", "Mangsit", "Pamenang"});
|
||||||
|
|
||||||
|
assert_true(m->reachable("Mataram", "Pamenang"));
|
||||||
|
assert_true(m->reachable("Pamenang", "Mataram"));
|
||||||
|
|
||||||
|
assert_false(m->reachable("Sakra", "Pamenang"));
|
||||||
|
assert_false(m->reachable("Sengkol", "Mataram"));
|
||||||
|
|
||||||
|
m->addRoad({"Mataram", "Sengkol", "Koeta"});
|
||||||
|
|
||||||
|
assert_true(m->reachable("Sakra", "Pamenang"));
|
||||||
|
assert_true(m->reachable("Sengkol", "Mataram"));
|
||||||
|
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(clear) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
assert_false(m->reachable("Sengkol", "Sakra"));
|
||||||
|
assert_false(m->reachable("Sakra", "Sengkol"));
|
||||||
|
|
||||||
|
m->addRoad("Sengkol", "Sakra");
|
||||||
|
|
||||||
|
assert_true(m->reachable("Sengkol", "Sakra"));
|
||||||
|
assert_true(m->reachable("Sakra", "Sengkol"));
|
||||||
|
|
||||||
|
m->clear();
|
||||||
|
|
||||||
|
assert_false(m->reachable("Sengkol", "Sakra"));
|
||||||
|
assert_false(m->reachable("Sakra", "Sengkol"));
|
||||||
|
|
||||||
|
m->addRoad("Sengkol", "Sakra");
|
||||||
|
assert_true(m->reachable("Sengkol", "Sakra"));
|
||||||
|
assert_true(m->reachable("Sakra", "Sengkol"));
|
||||||
|
|
||||||
|
m->addRoad({"Mataram", "Mangsit", "Pamenang"});
|
||||||
|
|
||||||
|
assert_true(m->reachable("Mataram", "Pamenang"));
|
||||||
|
assert_true(m->reachable("Pamenang", "Mataram"));
|
||||||
|
|
||||||
|
assert_false(m->reachable("Sakra", "Pamenang"));
|
||||||
|
assert_false(m->reachable("Sengkol", "Mataram"));
|
||||||
|
|
||||||
|
m->addRoad({"Mataram", "Sengkol", "Koeta"});
|
||||||
|
|
||||||
|
assert_true(m->reachable("Sakra", "Pamenang"));
|
||||||
|
assert_true(m->reachable("Sengkol", "Mataram"));
|
||||||
|
|
||||||
|
m->clear();
|
||||||
|
|
||||||
|
assert_false(m->reachable("Sakra", "Pamenang"));
|
||||||
|
assert_false(m->reachable("Sengkol", "Mataram"));
|
||||||
|
assert_false(m->reachable("Mataram", "Pamenang"));
|
||||||
|
assert_false(m->reachable("Pamenang", "Mataram"));
|
||||||
|
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(tree) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
std::deque<string> Q;
|
||||||
|
Q.push_back("0");
|
||||||
|
while (!Q.empty()) {
|
||||||
|
string s = Q.back();
|
||||||
|
Q.pop_back();
|
||||||
|
if (s.length() >= 8)
|
||||||
|
continue;
|
||||||
|
string s0 = s + "0";
|
||||||
|
string s1 = s + "1";
|
||||||
|
m->addRoad(s, s0);
|
||||||
|
m->addRoad(s, s1);
|
||||||
|
Q.push_back(s0);
|
||||||
|
Q.push_back(s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_int_eq(m->countIslands(), 1);
|
||||||
|
assert_false(m->hasLoop());
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(islands) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
std::deque<string> Q;
|
||||||
|
Q.push_back("0");
|
||||||
|
while (!Q.empty()) {
|
||||||
|
string s = Q.back();
|
||||||
|
Q.pop_back();
|
||||||
|
if (s.length() >= 8)
|
||||||
|
continue;
|
||||||
|
string s0 = s + "0";
|
||||||
|
string s1 = s + "1";
|
||||||
|
m->addRoad(s1, s0);
|
||||||
|
Q.push_back(s0);
|
||||||
|
Q.push_back(s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_int_eq(m->countIslands(), 127);
|
||||||
|
assert_false(m->hasLoop());
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(big_loop) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
std::deque<string> Q;
|
||||||
|
Q.push_back("0");
|
||||||
|
while (!Q.empty()) {
|
||||||
|
string s = Q.back();
|
||||||
|
Q.pop_back();
|
||||||
|
if (s.length() >= 8) {
|
||||||
|
m->addRoad(s, "0");
|
||||||
|
} else {
|
||||||
|
string s0 = s + "0";
|
||||||
|
string s1 = s + "1";
|
||||||
|
m->addRoad(s, s0);
|
||||||
|
m->addRoad(s, s1);
|
||||||
|
Q.push_back(s0);
|
||||||
|
Q.push_back(s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_int_eq(m->countIslands(), 1);
|
||||||
|
assert_true(m->hasLoop());
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(big_island) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
std::vector<string> cities = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < cities.size(); ++i)
|
||||||
|
for (unsigned int j = i + 1; j < cities.size(); ++j)
|
||||||
|
m->addRoad(cities[i], cities[j]);
|
||||||
|
|
||||||
|
assert_int_eq(m->countIslands(), 1);
|
||||||
|
assert_true(m->hasLoop());
|
||||||
|
for (unsigned int i = 0; i < cities.size(); ++i)
|
||||||
|
assert_int_eq(m->neighborCountForCity(cities[i]), cities.size()-1);
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(unknown_city) {
|
||||||
|
std::unique_ptr<AbstractRoadMap> m(createRoadMap());
|
||||||
|
|
||||||
|
std::vector<string> cities = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" };
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < cities.size(); ++i)
|
||||||
|
assert_int_eq(m->neighborCountForCity(cities[i]), -1);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < cities.size(); ++i)
|
||||||
|
for (unsigned int j = i + 1; j < cities.size(); ++j)
|
||||||
|
m->addRoad(cities[i], cities[j]);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < cities.size(); ++i) {
|
||||||
|
string s = cities[i] + "X";
|
||||||
|
assert_int_eq(m->neighborCountForCity(s), -1);
|
||||||
|
}
|
||||||
|
TEST_PASSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
RUN_TEST(basic_reachability);
|
||||||
|
RUN_TEST(clear);
|
||||||
|
RUN_TEST(tree);
|
||||||
|
RUN_TEST(islands);
|
||||||
|
RUN_TEST(big_loop);
|
||||||
|
RUN_TEST(big_island);
|
||||||
|
RUN_TEST(unknown_city);
|
||||||
|
PRINT_TEST_RESULTS;
|
||||||
|
assert(ALL_TESTS_PASSED);
|
||||||
|
}
|
Reference in a new issue