[javascript] Advent Of Code 2022 Day 23 Part 1
Viewer
*** This page was generated with the meta tag "noindex, nofollow". This happened because you selected this option before saving or the system detected it as spam. This means that this page will never get into the search engines and the search bot will not crawl it. There is nothing to worry about, you can still share it with anyone.
- // 3:6 weird
- const hash = (x: number, y: number): string => `${x}:${y}`;
- const unHash = (h: string): IRawPosition => {
- const [x, y] = h.split(":").map(Number);
- return { x, y };
- };
- const parse = (lines: string[]): IPositions => {
- const positions: IPositions = {};
- for (let y = 0; y < lines.length; y++) {
- const line = lines[y];
- for (let x = 0; x < line.length; x++) {
- const char = line[x];
- if (char === "#") {
- positions[hash(x, y)] = {
- priority: [
- EDirection.NORTH,
- EDirection.SOUTH,
- EDirection.WEST,
- EDirection.EAST,
- ],
- decision: EDirection.NONE,
- duplicate: false,
- };
- }
- }
- }
- return positions;
- };
- const markDuplicateDecisions = (positions: IPositions) => {
- const counts: { [h: string]: number } = {};
- for (let h in positions) {
- if (positions.hasOwnProperty(h)) {
- const { decision } = positions[h];
- const pos = unHash(h);
- const targetPos = movePosition(pos, decision);
- const targetH = hash(targetPos.x, targetPos.y);
- counts[targetH] = counts[targetH] ? counts[targetH] + 1 : 1;
- }
- }
- for (let h in positions) {
- if (positions.hasOwnProperty(h)) {
- const position = positions[h];
- const pos = unHash(h);
- const targetPos = movePosition(pos, position.decision);
- const targetH = hash(targetPos.x, targetPos.y);
- position.duplicate = counts[targetH] > 1;
- }
- }
- };
- const isSomeoneClose = (h: string, positions: IPositions) => {
- const pos = unHash(h);
- const dependencies = [
- EDirection.NORTH,
- EDirection.EAST,
- EDirection.SOUTH,
- EDirection.WEST,
- ]
- .flatMap((direction) => getDependencyPositions(pos, direction))
- .filter(
- (item, index, data) => data.findIndex((test) => test === item) === index
- );
- return Boolean(
- dependencies.find(({ x, y }) => positions[hash(x, y)] !== undefined)
- );
- };
- const makeInitialDecision = (h: string, positions: IPositions) => {
- const pos = unHash(h);
- const position = positions[h];
- const needMove = isSomeoneClose(h, positions);
- const decision = needMove
- ? position.priority.find((potentialDecision) => {
- const dependencies = getDependencyPositions(pos, potentialDecision);
- return dependencies.every(
- ({ x, y }) => positions[hash(x, y)] === undefined
- );
- }) ?? EDirection.NONE
- : EDirection.NONE;
- position.decision = decision;
- };
- const makeInitialDecisions = (positions: IPositions) => {
- for (let h in positions) {
- if (positions.hasOwnProperty(h)) {
- makeInitialDecision(h, positions);
- }
- }
- };
- const downgradeChosenDecisions = (positions: IPositions) => {
- for (let h in positions) {
- if (positions.hasOwnProperty(h)) {
- const position = positions[h];
- const priority = position.priority.shift();
- position.priority.push(priority as EDirection);
- // if (position.decision !== EDirection.NONE) {
- // const decisionIndex = position.priority.findIndex(
- // (item) => item === position.decision
- // );
- // position.priority.splice(decisionIndex, 1);
- // position.priority.push(position.decision);
- // }
- }
- }
- };
- const getDependencyPositions = (
- pos: IRawPosition,
- direction: EDirection
- ): IRawPosition[] => {
- if (direction === EDirection.NORTH) {
- return [
- { x: pos.x, y: pos.y - 1 },
- { x: pos.x - 1, y: pos.y - 1 },
- { x: pos.x + 1, y: pos.y - 1 },
- ];
- } else if (direction === EDirection.EAST) {
- return [
- { x: pos.x + 1, y: pos.y },
- { x: pos.x + 1, y: pos.y - 1 },
- { x: pos.x + 1, y: pos.y + 1 },
- ];
- } else if (direction === EDirection.SOUTH) {
- return [
- { x: pos.x, y: pos.y + 1 },
- { x: pos.x - 1, y: pos.y + 1 },
- { x: pos.x + 1, y: pos.y + 1 },
- ];
- } else if (direction === EDirection.WEST) {
- return [
- { x: pos.x - 1, y: pos.y },
- { x: pos.x - 1, y: pos.y - 1 },
- { x: pos.x - 1, y: pos.y + 1 },
- ];
- }
- return [];
- };
- const movePosition = (
- pos: IRawPosition,
- direction: EDirection
- ): IRawPosition => {
- if (direction === EDirection.NORTH) {
- return { x: pos.x, y: pos.y - 1 };
- } else if (direction === EDirection.EAST) {
- return { x: pos.x + 1, y: pos.y };
- } else if (direction === EDirection.SOUTH) {
- return { x: pos.x, y: pos.y + 1 };
- } else if (direction === EDirection.WEST) {
- return { x: pos.x - 1, y: pos.y };
- }
- return pos;
- };
- const moveItem = (h: string, positions: IPositions) => {
- const pos = unHash(h);
- const position = positions[h];
- const { decision, duplicate } = position;
- if (decision !== EDirection.NONE && !duplicate) {
- const { x, y } = movePosition(pos, decision);
- delete positions[h];
- const newH = hash(x, y);
- positions[newH] = position;
- // console.log(`${h} -> ${newH}`);
- }
- };
- const moveItems = (positions: IPositions) => {
- for (let h in positions) {
- if (positions.hasOwnProperty(h)) {
- moveItem(h, positions);
- }
- }
- };
- const getBoundingRectangle = (positions: IPositions): IBoundingRectangle => {
- let minX = Infinity;
- let minY = Infinity;
- let maxX = -Infinity;
- let maxY = -Infinity;
- for (let h in positions) {
- if (positions.hasOwnProperty(h)) {
- const { x, y } = unHash(h);
- if (x < minX) {
- minX = x;
- }
- if (x > maxX) {
- maxX = x;
- }
- if (y < minY) {
- minY = y;
- }
- if (y > maxY) {
- maxY = y;
- }
- }
- }
- return { minX, minY, maxX, maxY };
- };
- const getBoundingEmptySpaces = (positions: IPositions): number => {
- const { minX, minY, maxX, maxY } = getBoundingRectangle(positions);
- let count = 0;
- for (let x = minX; x <= maxX; x++) {
- for (let y = minY; y <= maxY; y++) {
- if (positions[hash(x, y)] === undefined) {
- count++;
- }
- }
- }
- return count;
- };
- const print = (positions: IPositions) => {
- const { minX, maxX, minY, maxY } = getBoundingRectangle(positions);
- console.log("");
- for (let y = minY; y <= maxY; y++) {
- for (let x = minX; x <= maxX; x++) {
- process.stdout.write(positions[hash(x, y)] === undefined ? "." : "#");
- }
- process.stdout.write("\n");
- }
- console.log("\n");
- };
- export const solution = async (lines: string[]) => {
- const positions = parse(lines);
- for (let i = 0; i < 10; i++) {
- makeInitialDecisions(positions);
- markDuplicateDecisions(positions);
- moveItems(positions);
- downgradeChosenDecisions(positions);
- // print(positions);
- }
- const emptySpaces = getBoundingEmptySpaces(positions);
- return emptySpaces;
- };
- enum EDirection {
- NORTH = "N",
- EAST = "E",
- SOUTH = "S",
- WEST = "W",
- NONE = "-",
- }
- interface IPosition {
- decision: EDirection;
- priority: EDirection[];
- duplicate: boolean;
- }
- interface IPositions {
- [hash: string]: IPosition;
- }
- interface IBoundingRectangle {
- minX: number;
- minY: number;
- maxX: number;
- maxY: number;
- }
- interface IRawPosition {
- x: number;
- y: number;
- }
Editor
You can edit this paste and save as new: