function edgeCrossing(row, col, dir) {
const fSize = 50;
const maxF = fSize - 1;
const nCols = 3;
const toFace = (r, c) =>
Math.floor(r / fSize) * nCols + Math.floor(c / fSize);
const fromFace = (f) => [fSize * Math.floor(f / nCols), fSize * (f % nCols)];
const fRow = row % fSize;
const fCol = col % fSize;
const currentFace = toFace(row, col);
if (currentFace === 1) {
return dir.case({
Right: () => [Dir.Right, AOC.vAdd(fromFace(2), [fRow, maxF - fCol])],
Down: () => [Dir.Down, AOC.vAdd(fromFace(4), [maxF - fRow, fCol])],
Left: () => [Dir.Right, AOC.vAdd(fromFace(6), [maxF - fRow, fCol])],
Up: () => [Dir.Right, AOC.vAdd(fromFace(9), [fCol, fRow])]
});
}
if (currentFace === 2) {
return dir.case({
Left: () => [Dir.Left, AOC.vAdd(fromFace(1), [fRow, maxF - fCol])],
Down: () => [Dir.Left, AOC.vAdd(fromFace(4), [fCol, fRow])],
Right: () => [Dir.Left, AOC.vAdd(fromFace(7), [maxF - fRow, fCol])],
Up: () => [Dir.Up, AOC.vAdd(fromFace(9), [maxF - fRow, fCol])]
});
}
if (currentFace === 4) {
return dir.case({
Up: () => [Dir.Up, AOC.vAdd(fromFace(1), [maxF - fRow, fCol])],
Right: () => [Dir.Up, AOC.vAdd(fromFace(2), [fCol, fRow])],
Left: () => [Dir.Down, AOC.vAdd(fromFace(6), [fCol, fRow])],
Down: () => [Dir.Down, AOC.vAdd(fromFace(7), [maxF - fRow, fCol])]
});
}
if (currentFace === 6) {
return dir.case({
Left: () => [Dir.Right, AOC.vAdd(fromFace(1), [maxF - fRow, fCol])],
Up: () => [Dir.Right, AOC.vAdd(fromFace(4), [fCol, fRow])],
Right: () => [Dir.Right, AOC.vAdd(fromFace(7), [fRow, maxF - fCol])],
Down: () => [Dir.Down, AOC.vAdd(fromFace(9), [maxF - fRow, fCol])]
});
}
if (currentFace === 7) {
return dir.case({
Right: () => [Dir.Left, AOC.vAdd(fromFace(2), [maxF - fRow, fCol])],
Up: () => [Dir.Up, AOC.vAdd(fromFace(4), [maxF - fRow, fCol])],
Left: () => [Dir.Left, AOC.vAdd(fromFace(6), [fRow, maxF - fCol])],
Down: () => [Dir.Left, AOC.vAdd(fromFace(9), [fCol, fRow])]
});
}
if (currentFace === 9) {
return dir.case({
Left: () => [Dir.Down, AOC.vAdd(fromFace(1), [fCol, fRow])],
Down: () => [Dir.Down, AOC.vAdd(fromFace(2), [maxF - fRow, fCol])],
Up: () => [Dir.Up, AOC.vAdd(fromFace(6), [maxF - fRow, fCol])],
Right: () => [Dir.Up, AOC.vAdd(fromFace(7), [fCol, fRow])]
});
}
}