Commit 32d8ab0d authored by Chris Dutchyn (cjd032)'s avatar Chris Dutchyn (cjd032)
Browse files

Added randomized testing example.

parent 7f5941a0
......@@ -5,11 +5,8 @@ CC=c++
CXXFLAGS=-Wall -pedantic -ansi
# binaries
BIN=pm
# the default target
all: $(BIN)
all: pm pmr
pm.o: pm.cc pm.h
......@@ -17,8 +14,13 @@ io.o: io.cc pm.h
gs.o: gs.cc pm.h
rio.o: rio.cc pm.h
pm: pm.o io.o gs.o
pmr: pm.o rio.o gs.o
$(CC) -o pmr pm.o rio.o gs.o
# tests
tests: test0.out test1.out test2A.out test2B.out test2C.out test2D.out test2E.out
......@@ -36,4 +38,4 @@ clean:
-$(RM) -rf *.log *.o *.dSYM *~
squeaky: clean
-$(RM) -rf *.out $(BIN)
-$(RM) -rf *.out pm pmr
#define DEBUG 1
#define DEBUG
#include <cassert>
#include <iostream>
#include "pm.h"
......@@ -70,7 +71,7 @@ static bool company_prefers(const company& c, const intern& i1, const intern& i2
assert(false); // cannot happen
}
void check_matching() {
static void check_matching() {
#ifdef DEBUG
// see each company once
bool* seen_companies = new bool[N+1];
......@@ -109,14 +110,28 @@ void check_matching() {
for (int in1=1; in1<N; in1+=1) {
const intern& i1 = interns[in1];
const company& c1 = companies[i1.company];
for (int in2=2; in2<=N; in2+=1) {
for (int in2=in1+1; in2<=N; in2+=1) {
assert(in1 != in2);
const intern& i2 = interns[in2];
const company& c2 = companies[i2.company];
assert(!(intern_prefers(i1, c2, c1)
&& company_prefers(c2, i1, i2)));
assert(!(intern_prefers(i2, c1, c2)
&& company_prefers(c1, i2, i1)));
if (intern_prefers(i1, c2, c1)
&& company_prefers(c2, i1, i2)) {
cerr << "!!Instability: " << i1.name << " prefers "
<< c2.name << " over existing " << c1.name << endl;
cerr << " and " << c2.name << " prefers "
<< i1.name << " over existing " << i2.name << endl;
assert(false);
}
if (intern_prefers(i2, c1, c2)
&& company_prefers(c1, i2, i1)) {
cerr << "!!Instability: " << i2.name << " prefers "
<< c1.name << " over existing " << c2.name << endl;
cerr << " and " << c1.name << " prefers "
<< i2.name << " over existing " << i1.name << endl;
assert(false);
}
}
}
#endif //DEBUG
......
#define DEBUG
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <random>
#include "pm.h"
const int OUR_SIZE=5;
// cribbed from S.T. Lavavej @ Microsoft
static random_device rd;
static mt19937 mt(rd());
uniform_int_distribution<> dist(0,OUR_SIZE-1);
static int uniform(const int x) {
assert(x>0);
return dist(mt);
}
static void swap(int& a, int &b) {
int t=a;
a=b;
b=t;
}
static void knuth_shuffle(int elts[], const int C) {
for (int s=0; s<=C-2; s+=1) {
int t = uniform(C-s);
swap(elts[s], elts[t]);
}
}
static void make_company(company& c) {
c.name = "C" + to_string(c.number);
c.ordered_interns = new int[N];
for (int o=0; o<N; o+=1) {
c.ordered_interns[o] = o+1;
}
knuth_shuffle(c.ordered_interns, N);
c.offered = new bool[N];
for (int o=0; o<N; o+=1) {
c.offered[o] = false;
}
c.intern = FREE;
}
static bool valid_company(const company& c) {
// interns are all represented once in preferences
bool* seen = new bool[N+1];
seen[0] = false;
for (int in=1; in<=N; in+=1) {
seen[in] = false;
}
for (int o=0; o<N; o+=1) {
int in = c.ordered_interns[o];
assert(!seen[in]);
seen[in] = true;
}
// no interns offered yet
assert(!c.offered[0]);
for (int in=1; in<=N; in+=1) {
assert(!c.offered[in]);
}
assert(c.intern == FREE);
return true;
}
static void make_intern(intern& i) {
i.name = "I" + to_string(i.number);
i.ordered_companies = new int[N+1];
i.ordered_companies[0] = FREE;
for (int o=0; o<N; o+=1) {
i.ordered_companies[o] = o+1;
}
knuth_shuffle(i.ordered_companies, N);
i.company = FREE;
}
static bool valid_intern(const intern& i) {
bool* seen = new bool[N+1];
for (int cn=1; cn<=N; cn+=1) {
seen[cn] = false;
}
for (int o=0; o<N; o+=1) {
int cn = i.ordered_companies[o];
assert(!seen[cn]);
seen[cn] = true;
}
assert(i.company == FREE);
return true;
}
void read_input() {
N = OUR_SIZE;
companies = new company[N+1];
companies[FREE].number = FREE;
companies[FREE].name = "INVALID COMPANY"; // !NB! impossible company name
companies[FREE].ordered_interns = NULL;
companies[FREE].offered = NULL;
companies[FREE].intern = FREE;
for (int cn=1; cn<=N; cn+=1) {
companies[cn].number = cn;
make_company(companies[cn]);
valid_company(companies[cn]);
}
interns = new intern[N+1];
interns[FREE].number = FREE;
interns[FREE].name = "INVALID INTERN"; // !NB! impossible intern name
interns[FREE].ordered_companies = NULL;
interns[FREE].company = FREE;
for (int in=1; in<=N; in+=1) {
interns[in].number = in;
make_intern(interns[in]);
valid_intern(interns[in]);
}
#ifdef DEBUG
for (int cn=1; cn<=N; cn+=1) {
company& c = companies[cn];
cerr << "Company " << c.name << " wants";
for (int o=0; o<N; o+=1) {
int in = c.ordered_interns[o];
assert(in > 0 && in <= N);
cerr << " " << interns[in].name << "(" << in << ") ";
}
cerr << endl;
}
for (int in=1; in<=N; in+=1) {
intern& i = interns[in];
cerr << "Intern " << i.name << " wants";
for (int o=0; o<N; o+=1) {
int cn = i.ordered_companies[o];
assert(cn > 0 && cn <= N);
cerr << " " << companies[cn].name << "(" << cn << ") ";
}
cerr << endl;
}
#endif //DEBUG
}
void write_output() {
for (int cn=1; cn<=N; cn+=1) {
company& c = companies[cn];
intern& i = interns[c.intern];
cout << c.name << " <- " << i.name << endl;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment