11import path from "node:path" ;
22import { readInputLineByLine } from "@utils/io" ;
3- import { forEach } from "mathjs" ;
4-
53export async function part1 ( inputFile : string ) {
64 return await day6 ( inputFile , calcGrantTotal ) ;
75}
86
97export async function part2 ( inputFile : string ) {
10- return await day6 ( inputFile ) ;
8+ return await day6raw ( inputFile , calcGrantTotalCephalopod ) ;
9+ }
10+
11+ async function day6raw ( inputFile : string , calcFn : ( lines : string [ ] ) => number ) {
12+ const inputPath = path . join ( __dirname , inputFile ) ;
13+ const lines = await readInputLineByLine ( inputPath ) ;
14+ return calcFn ( lines ) ;
1115}
1216
1317async function day6 ( inputFile : string , calcFn ?: ( numberRows : number [ ] [ ] , ops : string [ ] ) => number ) {
@@ -20,6 +24,46 @@ async function day6(inputFile: string, calcFn?: (numberRows: number[][], ops: st
2024 return calcFn ?.( numberRows , ops ) ;
2125}
2226
27+ function calcGrantTotalCephalopod ( lines : string [ ] ) : number {
28+ const maxLen = Math . max ( ...lines . map ( l => l . length ) ) ;
29+ const grid = lines . map ( line => line . padEnd ( maxLen , ' ' ) ) ;
30+ const numRows = grid . length - 1 ; // exclude operator row
31+ const opRow = grid [ grid . length - 1 ] ;
32+
33+ // Problems are separated by full blank columns across all rows.
34+ const separatorCols : boolean [ ] = Array . from ( { length : maxLen } , ( _ , c ) =>
35+ grid . every ( row => row [ c ] === ' ' )
36+ ) ;
37+
38+ const spans : Array < [ number , number ] > = [ ] ;
39+ let start = 0 ;
40+ for ( let c = 0 ; c <= maxLen ; c ++ ) {
41+ if ( c === maxLen || separatorCols [ c ] ) {
42+ if ( start <= c - 1 ) spans . push ( [ start , c - 1 ] ) ;
43+ start = c + 1 ;
44+ }
45+ }
46+
47+ let total = 0 ;
48+ for ( let p = spans . length - 1 ; p >= 0 ; p -- ) {
49+ const [ startCol , endCol ] = spans [ p ] ;
50+ const op = opRow . slice ( startCol , endCol + 1 ) . split ( '' ) . find ( ch => ch !== ' ' ) ;
51+ if ( ! op ) continue ;
52+ const numbers : number [ ] = [ ] ;
53+
54+ // Read columns right-to-left within this problem's range
55+ for ( let c = endCol ; c >= startCol ; c -- ) {
56+ const chars = Array . from ( { length : numRows } , ( _ , r ) => grid [ r ] [ c ] ) ;
57+ if ( chars . every ( ch => ch === ' ' ) ) continue ;
58+ const digits = chars . filter ( ch => ch !== ' ' ) . join ( '' ) ;
59+ numbers . push ( Number ( digits ) ) ;
60+ }
61+
62+ total += numbers . reduce ( ( acc , cur ) => op === '+' ? acc + cur : acc * cur , op === '+' ? 0 : 1 ) ;
63+ }
64+ return total ;
65+ }
66+
2367function calcGrantTotal ( numberRows : number [ ] [ ] , ops : string [ ] ) : number {
2468 let total : number = 0 ;
2569 const cols = numberRows [ 0 ] . length ;
@@ -30,4 +74,4 @@ function calcGrantTotal(numberRows: number[][], ops: string[]): number {
3074 total += result ;
3175 }
3276 return total ;
33- }
77+ }
0 commit comments