Skip to content

Instantly share code, notes, and snippets.

@pfirpfel
Last active August 29, 2015 14:22
Show Gist options
  • Save pfirpfel/3aad1b7d44c8fa3744d7 to your computer and use it in GitHub Desktop.
Save pfirpfel/3aad1b7d44c8fa3744d7 to your computer and use it in GitHub Desktop.
Challenge #218 [Intermediate] Generating Polyominoes
/**
* 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