1
1
import fs from "fs/promises" ;
2
2
import _ from "lodash" ;
3
3
const sampleSol = 8 ;
4
- const sample2Sol = 0 ;
4
+ const sample2Sol = 8 ;
5
5
6
6
// 0 - up
7
7
// 1 - right
@@ -19,10 +19,14 @@ interface Position {
19
19
x : number ;
20
20
y : number ;
21
21
o : number ;
22
- po : number ;
22
+ po : number ; // previous orientation
23
23
}
24
24
25
- function nextPosition ( grid : string [ ] [ ] , { x, y, o } : Position ) : Position {
25
+ function nextPosition (
26
+ grid : string [ ] [ ] ,
27
+ { x, y, o } : Position ,
28
+ startingPos : Position [ ] = [ ]
29
+ ) : Position {
26
30
const connecting = FACING_TO_CONNECTING_PIPES [ o ] ;
27
31
28
32
const nextCoord = [
@@ -45,7 +49,9 @@ function nextPosition(grid: string[][], { x, y, o }: Position): Position {
45
49
const nextValue = grid [ nextCoord [ 1 ] ] [ nextCoord [ 0 ] ] ;
46
50
const orientationChange = connecting . indexOf ( nextValue ) - 1 ;
47
51
48
- if ( orientationChange === - 2 && nextValue !== "S" ) {
52
+ if ( nextValue === "S" ) {
53
+ return startingPos . find ( ( { po } ) => po === o ) as Position ;
54
+ } else if ( orientationChange === - 2 ) {
49
55
throw new Error (
50
56
"invalid connection" + JSON . stringify ( { x, y, o, nextCoord, nextValue } )
51
57
) ;
@@ -63,26 +69,21 @@ function getStartingPositions(grid: string[][]): Position[] | null {
63
69
for ( let y = 0 ; y < grid . length ; y ++ ) {
64
70
for ( let x = 0 ; x < grid [ 0 ] . length ; x ++ ) {
65
71
if ( grid [ y ] [ x ] === "S" ) {
66
- const out : Position [ ] = [ ] ;
67
-
72
+ const validOrientations : number [ ] = [ ] ;
68
73
for ( let o = 0 ; o < 4 ; o ++ ) {
69
74
let pos : Position | null = null ;
70
75
try {
71
76
pos = nextPosition ( grid , { x, y, o, po : - 1 } ) ;
72
77
} catch ( e ) {
73
- console . log ( e ) ;
74
78
// ignore
75
79
}
76
- if ( pos === null ) continue ;
77
-
78
- if ( FACING_TO_CONNECTING_PIPES [ o ] . includes ( grid [ pos . y ] [ pos . x ] ) ) {
79
- const orientationChange =
80
- FACING_TO_CONNECTING_PIPES [ o ] . indexOf ( grid [ pos . y ] [ pos . x ] ) - 1 ;
81
- out . push ( { x, y, o, po : ( o - orientationChange + 4 ) % 4 } ) ;
82
- }
80
+ if ( pos !== null ) validOrientations . push ( o ) ;
83
81
}
84
82
85
- return out ;
83
+ return [
84
+ { x, y, o : validOrientations [ 0 ] , po : ( validOrientations [ 1 ] + 2 ) % 4 } ,
85
+ { x, y, o : validOrientations [ 1 ] , po : ( validOrientations [ 0 ] + 2 ) % 4 } ,
86
+ ] ;
86
87
}
87
88
}
88
89
}
@@ -99,20 +100,29 @@ function partOne(rawLines: string[]) {
99
100
throw new Error ( "Failed to find starting pos" ) ;
100
101
}
101
102
102
- let pos = nextPosition ( grid , startingPos [ 0 ] ) ,
103
- i = 1 ;
103
+ let pos = startingPos [ 0 ] ,
104
+ i = 0 ;
104
105
105
- while (
106
+ do {
107
+ pos = nextPosition ( grid , pos , startingPos ) ;
108
+ i ++ ;
109
+ } while (
106
110
! ( startingPos [ 0 ] . x === pos . x && startingPos [ 0 ] . y === pos . y ) &&
107
111
i < 10000000
108
- ) {
109
- pos = nextPosition ( grid , pos ) ;
110
- i ++ ;
111
- }
112
+ ) ;
112
113
113
114
return i / 2 ;
114
115
}
115
116
117
+ function getVerticalO ( pos : Position ) : number {
118
+ if ( pos . o % 2 == 0 && pos . po % 2 === 0 ) {
119
+ throw new Error ( "passed bad position" ) ;
120
+ }
121
+
122
+ if ( pos . o % 2 === 0 ) return pos . o ;
123
+ return pos . po ;
124
+ }
125
+
116
126
function partTwo ( rawLines : string [ ] ) {
117
127
const grid = rawLines . map ( ( x ) => x . split ( "" ) ) ;
118
128
@@ -122,46 +132,82 @@ function partTwo(rawLines: string[]) {
122
132
throw new Error ( "Failed to find starting pos" ) ;
123
133
}
124
134
125
- let pos = nextPosition ( grid , startingPos [ 0 ] ) ,
126
- i = 1 ;
135
+ let pos = startingPos [ 0 ] ,
136
+ i = 0 ;
127
137
128
- const positions = [ startingPos [ 0 ] , pos ] ;
129
- while (
130
- ! ( startingPos [ 0 ] . x === pos . x && startingPos [ 0 ] . y === pos . y ) &&
131
- i < 10000000
132
- ) {
133
- pos = nextPosition ( grid , pos ) ;
138
+ const positions : Position [ ] = [ pos ] ;
139
+ do {
140
+ pos = nextPosition ( grid , pos , startingPos ) ;
134
141
positions . push ( pos ) ;
135
142
i ++ ;
136
- }
143
+ } while (
144
+ ! ( startingPos [ 0 ] . x === pos . x && startingPos [ 0 ] . y === pos . y ) &&
145
+ i < 10000000
146
+ ) ;
137
147
138
148
const lookUp = positions . reduce ( ( acc , pos ) => {
139
149
acc [ `${ pos . x } :${ pos . y } ` ] = pos ;
140
150
return acc ;
141
151
} , { } as Record < string , Position > ) ;
142
- const printMap : string [ ] = [ ] ;
143
- const isOdd = false ;
144
- const interior = 0 ;
152
+ let interior = 0 ;
153
+ let out = "" ;
154
+ let print = "" ;
145
155
for ( let y = 0 ; y < grid . length ; y ++ ) {
156
+ let isOdd = false ;
157
+ let lastPO = null ;
158
+ let inSegment = false ;
146
159
for ( let x = 0 ; x < grid [ 0 ] . length ; x ++ ) {
147
160
const pos = lookUp [ `${ x } :${ y } ` ] ;
148
161
if ( pos ) {
149
- row += grid [ y ] [ x ] ;
162
+ const val = grid [ pos . y ] [ pos . x ] ;
163
+
164
+ print += val ;
165
+ if ( pos . o % 2 === 0 && pos . po % 2 === 0 ) {
166
+ isOdd = ! isOdd ;
167
+ out += isOdd ? "^" : "V" ;
168
+ } else if ( ! inSegment ) {
169
+ lastPO = getVerticalO ( pos ) ;
170
+ inSegment = true ;
171
+ out += "?" ;
172
+ } else {
173
+ if ( pos . o % 2 === 1 && pos . po % 2 === 1 ) {
174
+ out += "-" ;
175
+ } else {
176
+ const newPO = getVerticalO ( pos ) ;
177
+
178
+ if ( newPO === lastPO ) {
179
+ isOdd = ! isOdd ;
180
+ out += isOdd ? "^" : "V" ;
181
+ } else {
182
+ out += "U" ;
183
+ }
184
+ inSegment = false ;
185
+ lastPO = null ;
186
+ }
187
+ }
188
+ } else if ( isOdd ) {
189
+ interior ++ ;
190
+ out += "O" ;
150
191
} else {
151
- row += "X" ;
192
+ print += " " ;
193
+ out += "." ;
152
194
}
153
195
}
154
- printMap . push ( row ) ;
196
+ out += "\n" ;
197
+ print += "\n" ;
155
198
}
156
-
157
- console . log ( printMap . join ( "\n" ) ) ;
158
- return 0 ;
199
+ // console.log(print);
200
+ // console.log(out );
201
+ return interior ;
159
202
}
160
203
161
204
( async function main ( ) {
162
205
const sample = await fs
163
206
. readFile ( __dirname + "/sample.txt" , "utf8" )
164
207
. then ( ( txt ) => txt . split ( "\n" ) ) ;
208
+ const sample2 = await fs
209
+ . readFile ( __dirname + "/sample2.txt" , "utf8" )
210
+ . then ( ( txt ) => txt . split ( "\n" ) ) ;
165
211
const input = await fs
166
212
. readFile ( __dirname + "/input.txt" , "utf8" )
167
213
. then ( ( txt ) => txt . split ( "\n" ) ) ;
@@ -176,7 +222,7 @@ function partTwo(rawLines: string[]) {
176
222
const sol1 = await partOne ( input ) ;
177
223
console . log ( "part 1 sol:" , sol1 ) ;
178
224
179
- const test2 = await partTwo ( sample ) ;
225
+ const test2 = await partTwo ( sample2 ) ;
180
226
console . log ( "part 2 sample" , test2 ) ;
181
227
if ( test2 !== sample2Sol ) {
182
228
console . log ( "Failed the part 2 test" ) ;
0 commit comments