Last active
August 29, 2015 14:22
-
-
Save pfirpfel/3aad1b7d44c8fa3744d7 to your computer and use it in GitHub Desktop.
Challenge #218 [Intermediate] Generating Polyominoes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Polyomino | |
*/ | |
function Polyomino(){ | |
this.points = []; | |
} | |
Polyomino.prototype.print = function(){ | |
var allX = this.points.map(function(p){ return p.x; }); | |
var allY = this.points.map(function(p){ return p.y; }); | |
var minX = Math.min.apply(null, allX); | |
var maxY = Math.max.apply(null, allY); | |
var currX = minX, currY = maxY, printString = ""; | |
this.getPointsSorted().forEach(function(currPoint){ | |
while(currPoint.y < currY){ | |
printString += "\n"; | |
currY--; | |
currX = minX; | |
} | |
while(currPoint.x > currX){ | |
printString += " "; | |
currX++; | |
} | |
printString += "#"; | |
currX++; | |
}); | |
console.log(printString); | |
}; | |
Polyomino.prototype.getPointsSorted = function(){ | |
return this.points.sort(function(a, b){ | |
var diffY = b.y - a.y; | |
if(diffY !== 0){ | |
// higher y comes first | |
return diffY; | |
} else { | |
// same y, then most left one is first | |
return a.x - b.x; | |
} | |
}); | |
}; | |
Polyomino.prototype.clone = function(){ | |
var clone = new Polyomino(); | |
this.points.forEach(function(p){ | |
clone.points.push(p.clone()); | |
}); | |
return clone; | |
}; | |
Polyomino.prototype.toString = function(){ | |
return this.getPointsSorted().map(function(p){ return p.toString();}).join(); | |
}; | |
Polyomino.prototype.equals = function(other){ | |
return this.toString() == other.toString(); | |
}; | |
Polyomino.prototype.getRotated = function(){ | |
var rotated = new Polyomino(); | |
rotated.points = this.points.map(function(p){ | |
return new Point(p.y, -p.x); | |
}); | |
return rotated; | |
}; | |
Polyomino.prototype.getReflected = function(){ | |
var rotated = new Polyomino(); | |
rotated.points = this.points.map(function(p){ | |
return new Point(-p.x, p.y); | |
}); | |
return rotated; | |
}; | |
Polyomino.prototype.getVariations = function(){ | |
var ownVariantions = []; | |
var current = this; | |
var i; | |
for(i = 0; i < 4; i++){ | |
ownVariantions.push(current); | |
ownVariantions.push(current.getReflected()); | |
current = current.getRotated(); | |
} | |
return ownVariantions; | |
}; | |
Polyomino.prototype.isVariationOf = function(other){ | |
// deprecated in favour of getNormalized + equals | |
var ownVariantions = this.getVariations(); | |
var i; | |
var isVariation = false; | |
for(i = 0; !isVariation && i < ownVariantions.length; i++){ | |
isVariation = other.equals(ownVariantions[i]); | |
} | |
return isVariation; | |
}; | |
Polyomino.prototype.getNormalized = function(){ | |
var sortedVariations = this.getVariations() | |
.map(function(v){ | |
return v.getPointsSorted(); | |
}) | |
.sort(function(a, b){ | |
var diffX = b.x - a.x; | |
if(diffX !== 0) return diffX; | |
return b.y - a.y; | |
}); | |
var normalizedVersion = new Polyomino(); | |
normalizedVersion.points = sortedVariations[0]; | |
return normalizedVersion; | |
}; | |
Polyomino.prototype.hasPoint = function(p){ | |
var hasPoint = false, i; | |
for(i = 0; !hasPoint && i < this.points.length; i++){ | |
hasPoint = p.equals(this.points[i]); | |
} | |
return hasPoint; | |
}; | |
/** | |
* Point | |
*/ | |
function Point(x, y){ | |
this.x = x; | |
this.y = y; | |
} | |
Point.prototype.equals = function(other){ | |
return this.x === other.x && this.y === other.y; | |
}; | |
Point.prototype.clone = function(){ | |
return new Point(this.x, this.y); | |
}; | |
Point.prototype.toString = function(){ | |
return this.x + '/' + this.y; | |
}; | |
Point.prototype.getConnectedPoints = function(){ | |
return [ | |
new Point(this.x - 1, this.y), | |
new Point(this.x + 1, this.y), | |
new Point(this.x, this.y - 1), | |
new Point(this.x, this.y + 1) | |
]; | |
}; | |
var polyominoes = []; | |
function genPolyominoesRec(current, depth){ | |
// save the point and return if desired length is reached | |
if(depth <= 0){ | |
polyominoes.push(current); | |
return; | |
} | |
depth--; | |
var origin = current.points[current.points.length - 1], clone; | |
origin.getConnectedPoints().forEach(function(p){ | |
if(!current.hasPoint(p)){ | |
clone = current.clone(); | |
clone.points.push(p); | |
genPolyominoesRec(clone, depth); | |
} | |
}); | |
} | |
var inital = new Polyomino(); | |
inital.points.push(new Point(0, 0)); | |
genPolyominoesRec(inital, 3); | |
var normalizedPolyominoes = polyominoes.map(function(p){ return p.getNormalized(); }); | |
var uniquePolyominoes = [], i, j, current, notUnique; | |
for(i = 0; i < normalizedPolyominoes.length; i++){ | |
current = normalizedPolyominoes[i]; | |
notUnique = false; | |
for(j = 0; !notUnique && j < uniquePolyominoes.length; j++){ | |
notUnique = uniquePolyominoes[j].equals(current); | |
} | |
if(!notUnique) uniquePolyominoes.push(current); | |
} | |
uniquePolyominoes.forEach(function(p){ | |
p.print(); | |
console.log('\n'); | |
}); | |
console.log('variations: ' + uniquePolyominoes.length); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment