Created
April 16, 2024 00:55
-
-
Save alpaylan/ce3321f41bfa367997847b2ef79ea10f to your computer and use it in GitHub Desktop.
This file contains 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
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