Skip to content

Instantly share code, notes, and snippets.

@alpaylan
Created April 16, 2024 00:55
Show Gist options
  • Save alpaylan/ce3321f41bfa367997847b2ef79ea10f to your computer and use it in GitHub Desktop.
Save alpaylan/ce3321f41bfa367997847b2ef79ea10f to your computer and use it in GitHub Desktop.
type Color = "blue" | "pink";
type Canvas = Color[][];
const generateCanvas = (): Canvas => {
// A Canvas is a 3x3 grid of colors
const genColor = (): Color => {
return Math.random() > 0.5 ? "blue" : "pink";
}
const canvas: Canvas = [];
for (let i = 0; i < 3; i++) {
canvas.push([]);
for (let j = 0; j < 3; j++) {
canvas[i].push(genColor());
}
}
return canvas;
}
const copyCanvas = (canvas: Canvas): Canvas => {
const newCanvas : Color[][] = [];
for (let i = 0; i < 3; i++) {
newCanvas.push([]);
for (let j = 0; j < 3; j++) {
newCanvas[i].push(canvas[i][j]);
}
}
return newCanvas;
}
const paintRow = (canvas: Canvas, row: number): Canvas => {
const newCanvas = copyCanvas(canvas);
for (let i = 0; i < 3; i++) {
newCanvas[row][i] = "pink";
}
return newCanvas;
}
const paintColumn = (canvas: Canvas, column: number): Canvas => {
const newCanvas = copyCanvas(canvas);
for (let i = 0; i < 3; i++) {
newCanvas[i][column] = "blue";
}
return newCanvas;
}
type DiffColor = "pink" | "blue" | "same";
type DiffCanvas = DiffColor[][];
const diff = (canvas1: Canvas, canvas2: Canvas): DiffCanvas => {
const diffCanvas: DiffCanvas = [];
for (let i = 0; i < 3; i++) {
diffCanvas.push([]);
for (let j = 0; j < 3; j++) {
if (canvas1[i][j] === canvas2[i][j]) {
diffCanvas[i].push("same");
} else {
diffCanvas[i].push(canvas2[i][j]);
}
}
}
return diffCanvas;
}
const getPinkedRows = (canvas: DiffCanvas): number[] => {
const hasPink = (row: DiffColor[]): boolean => {
return row.some((color) => color === "pink");
}
const pinkedRows: number[] = [];
for (let i = 0; i < 3; i++) {
if (hasPink(canvas[i])) {
pinkedRows.push(i);
}
}
return pinkedRows;
}
const getBluedColumns = (canvas: DiffCanvas): number[] => {
const hasBlue = (column: DiffColor[]): boolean => {
return column.some((color) => color === "blue");
}
const bluedColumns: number[] = [];
for (let i = 0; i < 3; i++) {
if (hasBlue([canvas[0][i], canvas[1][i], canvas[2][i]])) {
bluedColumns.push(i);
}
}
return bluedColumns;
}
type Directive = {
orient: "row" | "column";
index: number;
}
const different = (canvas1: Canvas, canvas2: Canvas): boolean => {
return diff(canvas1, canvas2).some((row) => row.some((color) => color !== "same"));
}
const getDirectives = (diffCanvas: DiffCanvas): Directive[] => {
const pr = getPinkedRows(diffCanvas);
const bc = getBluedColumns(diffCanvas);
const directives: Directive[] = [];
pr.forEach((row) => {
directives.push({orient: "row", index: row});
});
bc.forEach((column) => {
directives.push({orient: "column", index: column});
});
return directives;
}
const printCanvas = (canvas: Canvas): void => {
const printCell = (color: Color): string => {
return color === "blue" ? "O" : "X";
}
canvas.forEach((row) => {
console.log(row.map(printCell).join(""));
});
}
const applyDirective = (canvas: Canvas, directive: Directive): Canvas => {
return directive.orient === "row" ? paintRow(canvas, directive.index) : paintColumn(canvas, directive.index);
}
const order = (d1: Directive, d2: Directive, c: Canvas): number => {
if (d1.orient === d2.orient) {
return 0;
}
let dr = d1.orient === "row" ? d1 : d2;
let dc = d1.orient === "column" ? d1 : d2;
let t = c[dr.index][dc.index];
if (d1.orient === "row" && t === "pink") {
return -1;
} else if (d1.orient === "column" && t === "blue") {
return -1;
} else {
return 1;
}
}
const solve = (c1: Canvas, c2: Canvas): Directive[] => {
let path : Directive[] = [];
while (different(c1, c2)) {
let d = diff(c1, c2);
let dirs = getDirectives(d);
let sortedDirs = dirs.sort((d1, d2) => order(d1, d2, c2));
let dir = sortedDirs.pop() as Directive;
console.log("Applying directive: ", dir);
c1 = applyDirective(c1, dir);
path.push(dir);
}
return path;
}
const genDirective = (): Directive => {
return {orient: Math.random() > 0.5 ? "row" : "column", index: Math.floor(Math.random() * 3)};
}
const genTarget = (c1: Canvas): Canvas => {
let c2 = copyCanvas(c1);
for(let i = 0; i < 100; i++) {
let d = genDirective();
c2 = applyDirective(c2, d);
}
return c2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment