@@ -6,12 +6,12 @@ const inputLines = (await Bun.file("input").text()).trim().split(EOL);
6
6
type Grid = Array < Array < string > > ;
7
7
type Vector = [ number , number ] ; // [x, y]
8
8
9
- const SEARCH_STRING = "MAS" ;
10
- const VALID_DIRECTIONS : Array < Vector > = [
11
- [ - 1 , - 1 ] , [ 1 , - 1 ] , [ - 1 , 1 ] , [ 1 , 1 ] // Diagonals
12
- ] ;
9
+ const STRAIGHT_DIRECTIONS : Array < Vector > = [ [ - 1 , 0 ] , [ 1 , 0 ] , [ 0 , - 1 ] , [ 0 , 1 ] ]
10
+ const DIAGONAL_DIRECTIONS : Array < Vector > = [ [ - 1 , - 1 ] , [ 1 , - 1 ] , [ - 1 , 1 ] , [ 1 , 1 ] ]
13
11
14
- const HINT_SYMBOL = SEARCH_STRING . split ( "" ) [ 1 ] ;
12
+ function VALID_DIRECTIONS ( part2 : boolean ) : Array < Vector > {
13
+ return part2 ? DIAGONAL_DIRECTIONS : STRAIGHT_DIRECTIONS . concat ( DIAGONAL_DIRECTIONS ) ;
14
+ }
15
15
16
16
function vecAdd ( one : Vector , two : Vector ) : Vector {
17
17
return [ one [ 0 ] + two [ 0 ] , one [ 1 ] + two [ 1 ] ] ;
@@ -32,40 +32,53 @@ function isInBounds(point: Vector, grid: Grid) {
32
32
)
33
33
}
34
34
35
- function locateHints ( grid : Grid ) : Array < Vector > {
35
+ function locateHints ( grid : Grid , hintSymbol : String ) : Array < Vector > {
36
36
const hints : Array < Vector > = [ ] ;
37
37
for ( let y : number = 0 ; y < grid . length ; y ++ ) {
38
38
const line = grid [ y ] ;
39
39
for ( let x : number = 0 ; x < line . length ; x ++ ) {
40
- if ( line [ x ] == HINT_SYMBOL ) hints . push ( [ x , y ] ) ;
40
+ if ( line [ x ] == hintSymbol ) hints . push ( [ x , y ] ) ;
41
41
}
42
42
}
43
43
return hints ;
44
44
}
45
45
46
- function investigateHint ( hint : Vector ) : boolean {
46
+ function investigateHint ( hint : Vector , searchString : String , part2 : boolean = false ) : number {
47
47
let hitCount : number = 0 ;
48
- for ( let searchDirection of VALID_DIRECTIONS ) {
48
+ for ( let searchDirection of VALID_DIRECTIONS ( part2 ) ) {
49
49
const directionString : Array < String > = [ ] ;
50
50
51
- let searchLocation = vecAdd ( hint , vecNeg ( searchDirection ) ) ;
51
+ let searchLocation = part2 ? vecAdd ( hint , vecNeg ( searchDirection ) ) : hint ;
52
52
let searchStringIndex = 0 ;
53
53
while (
54
54
isInBounds ( searchLocation , inputGrid )
55
- && searchStringIndex < SEARCH_STRING . length
55
+ && searchStringIndex < searchString . length
56
56
) {
57
57
// TODO: Maybe fail the direction on first wrong letter?
58
58
59
59
directionString . push ( getFromGrid ( searchLocation , inputGrid ) ) ;
60
60
searchLocation = vecAdd ( searchLocation , searchDirection ) ;
61
61
searchStringIndex += 1 ;
62
62
}
63
- if ( directionString . join ( "" ) == SEARCH_STRING ) hitCount += 1 ;
63
+ if ( directionString . join ( "" ) == searchString ) hitCount += 1 ;
64
64
}
65
- return hitCount == 2 ;
65
+ if ( part2 ) return Number ( hitCount == 2 ) ;
66
+ else return hitCount ;
66
67
}
67
68
68
69
const inputGrid : Grid = inputLines . map ( ( inputLine : string ) => inputLine . split ( "" ) ) ;
69
- const hints : Array < Vector > = locateHints ( inputGrid ) ;
70
- const totalHitCount = hints . map ( investigateHint ) . reduce ( ( acc , didHit ) => didHit ? acc + 1 : acc , 0 ) ;
71
- console . log ( "Part 2:" , totalHitCount ) ;
70
+
71
+ function part1 ( ) {
72
+ const hints : Array < Vector > = locateHints ( inputGrid , "X" ) ;
73
+ const hitCounts : Array < number > = hints . map ( ( hint ) => investigateHint ( hint , "XMAS" ) ) ;
74
+ return hitCounts . reduce ( ( acc , hitCount ) => acc + hitCount ) ;
75
+ }
76
+
77
+ function part2 ( ) {
78
+ const hints : Array < Vector > = locateHints ( inputGrid , "A" ) ;
79
+ const hitCounts : Array < number > = hints . map ( ( hint ) => investigateHint ( hint , "MAS" , true ) ) ;
80
+ return hitCounts . reduce ( ( acc , hitCount ) => acc + hitCount ) ;
81
+ }
82
+
83
+ console . log ( "Part 1:" , part1 ( ) ) ;
84
+ console . log ( "Part 2:" , part2 ( ) ) ;
0 commit comments