Skip to content

Commit

Permalink
Siege: Problems and solution added
Browse files Browse the repository at this point in the history
  • Loading branch information
Granjow committed Oct 23, 2015
1 parent aa304eb commit c402252
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
**.pdf
node_modules/
npm-debug.log
samples-*
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ to solve various types of problems. More exercises will be added. Current progre
Reading Problems ————————————·—————————————————·————————————————————O
Read large graphs from files.

Under Siege —————————————————·————————————
Under Siege —————————————————·——————————————
Help the city Bohandur, which is under siege, to defend itself
with your new knowledge!

Expand Down
13 changes: 13 additions & 0 deletions exercises/ex4-siege/samples/sample1.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
5 4 3
Ozryn
Meteli
Emall
Ironforge
Tarrin
ARRH
AXE
LANCE
BURN
ARRH Ozryn
AXE Emall
LANCE Tarrin
8 changes: 8 additions & 0 deletions exercises/ex4-siege/samples/sample2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
3 2 2
1
2
3
A
B
A 1
B 1
Empty file.
95 changes: 95 additions & 0 deletions exercises/ex4-siege/solution/bohandur-reader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
var fs = require( 'fs' ),
readline = require( 'readline' ),
Graph = require( './graph.js' );

function mostNeighbours( villages, attackers, edges ) {

// In the graph, we have to reverse the edges so we can re-use the neighbours function,
// which only calculates outgoing neighbours. Edges from attackers to villages are incoming,
// so we reverse them.
var reversedEdges = edges.map( function ( edge ) {
return [ edge[ 1 ], edge[ 0 ] ];
} );

var graph = new Graph( villages.concat( attackers ), reversedEdges ),
neighbours = [],
max;

graph.vertices.forEach( function ( vertex ) {
neighbours.push( {
vertex: vertex,
neighbourCount: vertex.neighbours().length
} );
} );

max = neighbours.reduce( function ( acc, cur ) {
return Math.max( cur.neighbourCount, acc );
}, 0 );

return neighbours.filter( function ( entry ) {
return entry.neighbourCount == max;
} ).map( function ( entry ) {
return entry.vertex.id;
} );
}

function reader( inFilePath, callback ) {

var V, A, S,
initialised = false,
pos = 'init',
villages = [],
attackers = [],
edges = [],
c = 0;

readline.createInterface( {
input: fs.createReadStream( inFilePath )
} ).on( 'line', function ( line ) {

if ( pos === 'init' ) {
var vas = line.split( ' ' );
V = parseInt( vas[ 0 ] );
A = parseInt( vas[ 1 ] );
S = parseInt( vas[ 2 ] );
pos = 'villages';
initialised = true;
} else {
if ( pos === 'villages' ) {
if ( c + 1 <= V ) {
villages.push( line );
c++;
return;
} else {
c = 0;
pos = 'attackers';
}
}
if ( pos === 'attackers' ) {
if ( c + 1 <= A ) {
attackers.push( line );
c++;
return;
} else {
c = 0;
pos = 'edges';
}
}
if ( pos === 'edges' ) {
if ( c + 1 <= S ) {
edges.push( line.split( ' ' ) );
c++;
} else {
console.log( 'Spare line: ' + line );
}
}
}
} ).on( 'close', function () {
// Call the callback function, if it is given
if ( typeof callback === 'function' ) {
callback( mostNeighbours( villages, attackers, edges ) );
}
} );
}

module.exports = reader;
95 changes: 95 additions & 0 deletions exercises/ex4-siege/solution/graph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
var fs = require( 'fs' ),
readline = require( 'readline' );

/**
* Vertex in a graph
* @param {*} id This vertex's ID
* @returns {Vertex}
*/
var Vertex = function ( id ) {

this.id = id;
this._edges = [];

return this;
};
Vertex.prototype = {
neighbours: function () {
return this._edges.map( function ( edge ) {
return edge.vTo;
} );
},
addEdge: function ( edge ) {
this._edges.push( edge );
}
};

/**
* Directed edge in a graph
* @param {Vertex} vFrom Source vertex
* @param {Vertex} vTo Target vertex
* @returns {Edge}
*/
var Edge = function ( vFrom, vTo ) {

/** @type {Vertex} */
this.vFrom = vFrom;
/** @type {Vertex} */
this.vTo = vTo;

this.vFrom.addEdge( this );

return this;
};

/**
* Graph containing edges and vertices
* @param {Array} vertices
* @param {Array.<Array>} edges Array of edges; each entry is an array of size 2
*/
var Graph = function ( vertices, edges ) {

/**
* We use a ES6 Map for storing vertices. Maps have the advantage over objects that
* they can be iterated over with forEach.
* @type {Map.<Vertex>}
*/
this._vertices = new Map();

/**
* If you do not know why we don't just use `this` in the forEach loop, read this article:
* http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
*/
var me = this;

// Read and store all vertices
vertices.forEach( function ( id ) {
me._vertices.set( id, new Vertex( id ) );
} );

// Create the edges
edges.forEach( function ( pair ) {
var idFrom = pair[ 0 ],
idTo = pair[ 1 ];
new Edge( me.v( idFrom ), me.v( idTo ) );
} );

};
Graph.prototype = {
/**
* Retrieve a vertex identified by the given ID.
* @param id Vertex ID
* @returns {Vertex}
*/
v: function ( id ) {
return this._vertices.get( id );
},
/**
* @returns {Map.<Vertex>} All vertices of this graph
*/
get vertices() {
return this._vertices;
}
};

module.exports = Graph;
5 changes: 5 additions & 0 deletions exercises/ex4-siege/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var solver = require( './solution/bohandur-reader' );

solver( __dirname + '/samples/sample1.in', function ( result ) {
console.dir( result );
} );
6 changes: 3 additions & 3 deletions runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ shop.add( 'Graph Structure', function () {
shop.add( 'Reading Problems', function () {
return require( './exercises/ex3-reading-problems/reading-problems' );
} );
shop.add( 'Under Siege', function () {
return require( './exercises/ex4-siege/siege' );
} );
//shop.add( 'Under Siege', function () {
// return require( './exercises/ex4-siege/siege' );
//} );

shop.execute( process.argv.slice( 2 ) );

0 comments on commit c402252

Please sign in to comment.