| import { readFileSync } from "fs"; |
| |
| const input = readFileSync('./testdata.txt').toString().split('\n'); |
| |
| type coord = `${number}:${number}` |
| |
| const coords: Record<coord, string> = {}; |
| |
| const ignoreCoords: coord[] = [] |
| |
| function formatCoords(x: number, y: number): coord {return `${x}:${y}`} |
| function getCoords(crd: coord): {x: number, y: number} { |
| const [x,y] = crd.match(/\d+/g)!.map(s => parseInt(s)) as [number, number] |
| return {x,y} |
| } |
| |
| // INPUT CURRENT COORDS |
| function checkNumChar(x: number, y: number, currentNum?: string): undefined | string { |
| if (ignoreCoords.includes(formatCoords(x,y))) return |
| currentNum = currentNum ?? "" |
| const char = input[y][x]; |
| if(isNaN(parseInt(char))) return currentNum; |
| ignoreCoords.push(formatCoords(x,y)) |
| currentNum += char; |
| return checkNumChar(x+1, y, currentNum); |
| } |
| |
| let i = 0; |
| for(const line of input) { |
| let j = 0; |
| for (const char of line) { |
| if (char === ".") { |
| j++; |
| continue; |
| } else if(isNaN(parseInt(char))) { |
| coords[formatCoords(j,i)] = char |
| } else { |
| const num = checkNumChar(j,i); |
| // console.log(num) |
| if(num) coords[formatCoords(j,i)] = num as string |
| } |
| j++; |
| } |
| i++; |
| } |
| |
| // Part 1 |
| let sum = 0; |
| for(const [loc, val] of Object.entries(coords)) { |
| if(isNaN(parseInt(val))) continue; |
| |
| // Parse Coords |
| const [x,y] = loc.match(/\d+/g)!.map(s => parseInt(s)) as [number, number] |
| |
| // Next to |
| const lx = x-1; |
| const rx = x + val.length; |
| |
| // Above / Below w/ diagonals |
| const ay = y - 1; |
| const by = y + 1; |
| |
| console.log(`${loc} (${val})`) |
| if( |
| (coords[formatCoords(lx,y)] && isNaN(parseInt(coords[formatCoords(lx,y)]))) |
| ) { |
| console.log(`${loc} (${val}) next to: ${formatCoords(lx,y)} (${coords[formatCoords(lx,y)]})`); |
| sum += parseInt(val); |
| continue; |
| } else if( |
| coords[formatCoords(rx,y)] && isNaN(parseInt(coords[formatCoords(rx,y)])) |
| ) { |
| console.log(`${loc} (${val}) next to: ${formatCoords(rx,y)} (${coords[formatCoords(rx,y)]})`); |
| sum += parseInt(val); |
| continue; |
| } else { |
| for(let i = -1; i <= val.length; i++) { |
| if( |
| coords[formatCoords(x+i,ay)] && isNaN(parseInt(coords[formatCoords(x+i,ay)])) |
| ) { |
| console.log(`${loc} (${val}) next to: ${formatCoords(x+i,ay)} (${coords[formatCoords(x+i,ay)]})`); |
| sum += parseInt(val) |
| break; |
| } else if ( |
| coords[formatCoords(x+i, by)] && isNaN(parseInt(coords[formatCoords(x+i, by)])) |
| ) { |
| console.log(`${loc} (${val}) next to: ${formatCoords(x+i,by)} (${coords[formatCoords(x+i,by)]})`); |
| sum += parseInt(val) |
| break; |
| } |
| } |
| } |
| } |
| |
| console.log(sum); |
| |
| function getNumFromRight(x: number, y: number, curCoord?: coord): coord { |
| curCoord = curCoord ?? formatCoords(x,y) |
| const char = input[y][x]; |
| if(isNaN(parseInt(char))) return curCoord; |
| curCoord = formatCoords(x,y) |
| return getNumFromRight(x-1, y, curCoord); |
| } |
| |
| |
| // Part 2 |
| |
| let ratio = 0; |
| for(const [loc, val] of Object.entries(coords)) { |
| if(val !== "*") continue; |
| let curratio = 1; |
| let curgears = 0; |
| |
| // Parse Coords |
| const [x,y] = loc.match(/\d+/g)!.map(s => parseInt(s)) as [number, number] |
| |
| // Next to |
| const lx = x-1; |
| const rx = x + val.length; |
| |
| // Above / Below w/ diagonals |
| const ay = y - 1; |
| const by = y + 1; |
| |
| //left |
| if(!isNaN(parseInt(input[y][lx]))) { |
| if(coords[formatCoords(lx,y)]) { |
| console.log(`${loc} next to: `) |
| curratio *= parseInt(coords[formatCoords(lx,y)]); |
| curgears++; |
| } else { |
| const n = getNumFromRight(lx,y) |
| curratio *= n ? parseInt(coords[n]) : 1 |
| curgears++; |
| } |
| } |
| |
| //right |
| if(!isNaN(parseInt(input[y][rx]))) { |
| if(coords[formatCoords(rx,y)]) { |
| curratio *= parseInt(coords[formatCoords(rx,y)]); |
| curgears++; |
| } else { |
| const n = getNumFromRight(rx,y) |
| curratio *= n ? parseInt(coords[n]) : 1 |
| curgears++; |
| } |
| } |
| |
| //above and below |
| for(let i = -1; i <= 1; i++) { |
| //above |
| if(!isNaN(parseInt(input[ay][x+i]))) { |
| if(coords[formatCoords(x+i,ay)]) { |
| curratio *= parseInt(coords[formatCoords(x+i,ay)]); |
| curgears++; |
| } else { |
| const n = getNumFromRight(x+i,ay) |
| curratio *= n ? parseInt(coords[n]) : 1 |
| curgears++; |
| } |
| } |
| //below |
| if(!isNaN(parseInt(input[by][x+i]))) { |
| if(coords[formatCoords(x+i,by)]) { |
| curratio *= parseInt(coords[formatCoords(x+i,by)]); |
| curgears++; |
| } else { |
| const n = getNumFromRight(x+i,by) |
| curratio *= n ? parseInt(coords[n]) : 1 |
| curgears++; |
| } |
| } |
| } |
| if(curgears === 2) ratio += curratio |
| } |
| |
| console.log(ratio) |