Day 19 and 20
This commit is contained in:
46
2024/19/index.ts
Normal file
46
2024/19/index.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8').split("\n");
|
||||||
|
|
||||||
|
const towels: Array<string> = input[0].split(', ');
|
||||||
|
|
||||||
|
const shortestTowel = Math.min(...towels.map((t: string) => t.length));
|
||||||
|
const longestTowel = Math.max(...towels.map((t: string) => t.length));
|
||||||
|
|
||||||
|
const designs = input.slice(2);
|
||||||
|
|
||||||
|
let possible = 0;
|
||||||
|
|
||||||
|
let permSum = 0;
|
||||||
|
|
||||||
|
let patternMap: { [key: string]: number } = {};
|
||||||
|
|
||||||
|
function canBeDone(pattern: string): number {
|
||||||
|
if (Object.hasOwn(patternMap, pattern)) {
|
||||||
|
return patternMap[pattern];
|
||||||
|
}
|
||||||
|
let perms = 0;
|
||||||
|
towels.forEach((t) => {
|
||||||
|
if (t === pattern) {
|
||||||
|
patternMap[pattern] = 1;
|
||||||
|
perms++;
|
||||||
|
} else if (pattern.startsWith(t)) {
|
||||||
|
const subPerms = canBeDone(pattern.substring(t.length));
|
||||||
|
perms += subPerms;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
patternMap[pattern] = perms;
|
||||||
|
return perms;
|
||||||
|
}
|
||||||
|
|
||||||
|
designs.forEach((d: string, i: number)=> {
|
||||||
|
patternMap = {};
|
||||||
|
console.log(Math.floor(i / designs.length * 100));
|
||||||
|
const designPerms = canBeDone(d);
|
||||||
|
if (designPerms) {
|
||||||
|
possible++;
|
||||||
|
permSum += designPerms;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(possible, permSum);
|
||||||
107
2024/20/index.ts
Normal file
107
2024/20/index.ts
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
|
||||||
|
|
||||||
|
interface Coord {
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Dir {
|
||||||
|
Up,
|
||||||
|
Right,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
};
|
||||||
|
|
||||||
|
const map: Array<Array<string>> = input.split("\n").map((row: string) => row.split(''));
|
||||||
|
|
||||||
|
const width = map[0].length;
|
||||||
|
const height = map.length;
|
||||||
|
|
||||||
|
const startIndex = input.indexOf('S');
|
||||||
|
let startPos = { x: startIndex % (width + 1), y: Math.floor(startIndex / height) };
|
||||||
|
|
||||||
|
function get(pos: Coord): string {
|
||||||
|
if (map[pos.y] && map[pos.y][pos.x]) {
|
||||||
|
return map[pos.y][pos.x];
|
||||||
|
}
|
||||||
|
return '#';
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(pos: Coord, val: string): void {
|
||||||
|
map[pos.y][pos.x] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextDir(dir: Dir): Dir {
|
||||||
|
const directions = [Dir.Up, Dir.Right, Dir.Down, Dir.Left];
|
||||||
|
const i = (directions.indexOf(dir) + 1) % directions.length;
|
||||||
|
return directions[i];
|
||||||
|
}
|
||||||
|
function prevDir(dir: Dir): Dir {
|
||||||
|
const directions = [Dir.Up, Dir.Right, Dir.Down, Dir.Left];
|
||||||
|
const i = directions.indexOf(dir) - 1;
|
||||||
|
if (i < 0) {
|
||||||
|
return directions[directions.length - 1];
|
||||||
|
}
|
||||||
|
return directions[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextCoord(pos: Coord, direction: Dir): Coord {
|
||||||
|
return direction === Dir.Up ? { x: pos.x, y: pos.y - 1 }
|
||||||
|
: (direction === Dir.Right ? { x: pos.x + 1, y: pos.y }
|
||||||
|
: (direction === Dir.Down ? { x: pos.x, y: pos.y + 1 } : { x: pos.x - 1, y: pos.y })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const shortCuts: Array<number> = [];
|
||||||
|
|
||||||
|
const pathCoords: Array<Coord> = [startPos];
|
||||||
|
|
||||||
|
const cheatTime = 20;
|
||||||
|
const minShortCut = 100;
|
||||||
|
|
||||||
|
let speedMap: { [key: string]: number } = {};
|
||||||
|
|
||||||
|
function findShortCuts(pos: Coord): void {
|
||||||
|
for (let i = 0; i < pathCoords.length - minShortCut; i++) {
|
||||||
|
const possibleSC = pathCoords[i];
|
||||||
|
const dx = possibleSC.x - pos.x;
|
||||||
|
const dy = possibleSC.y - pos.y;
|
||||||
|
const cheatLength = Math.abs(dx) + Math.abs(dy);
|
||||||
|
if (cheatLength <= cheatTime) {
|
||||||
|
const shortCutLength = pathCoords.length - i - cheatLength;
|
||||||
|
if (shortCutLength >= minShortCut) {
|
||||||
|
shortCuts.push(shortCutLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let dir of [Dir.Up, Dir.Right, Dir.Down, Dir.Left]) {
|
||||||
|
if (get(nextCoord(startPos, dir)) === '.') {
|
||||||
|
let pos = startPos;
|
||||||
|
loop:
|
||||||
|
while (true) {
|
||||||
|
for (let newDir of [dir, nextDir(dir), prevDir(dir)]) {
|
||||||
|
const next = nextCoord(pos, newDir);
|
||||||
|
const nextStr = `${next.x},${next.y}`;
|
||||||
|
const nextChar = get(next);
|
||||||
|
if (nextChar === 'E') {
|
||||||
|
findShortCuts(next);
|
||||||
|
pathCoords.push(next);
|
||||||
|
break loop;
|
||||||
|
} else if (nextChar === '.') {
|
||||||
|
findShortCuts(next);
|
||||||
|
pathCoords.push(next);
|
||||||
|
pos = next;
|
||||||
|
dir = newDir;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(shortCuts.length);
|
||||||
Reference in New Issue
Block a user