@@ -22,9 +22,9 @@ function programReadLine(rl) {
2222 } ) ;
2323
2424 rl . on ( "close" , ( ) => {
25- let data = run ( JSON . parse ( JSON . stringify ( CLAY_INPUT ) ) ) ;
26- console . log ( "Answer (part I):" , data . part1 ) ;
27- console . log ( "Answer (part II):" , data . part2 ) ;
25+ let data = run ( CLAY_INPUT ) ;
26+ console . log ( "Answer (part I):" , data . part1 ) ; // expected: 33724
27+ console . log ( "Answer (part II):" , data . part2 ) ; // expected: ?
2828 console . timeEnd ( "d17" ) ;
2929 } ) ;
3030}
@@ -46,112 +46,104 @@ function run(clayInput) {
4646
4747 data . part1 = Object . values ( data . filledByXY ) . filter ( contents => contents === WATER || contents === WATER_FLOW ) . length ;
4848
49- //printData(data, 494, 507, 0, data.maxY );
49+ //printData(data);
5050
5151 return data ;
5252}
5353
5454function flowWater ( data , cursor ) {
5555 if ( cursor . y >= data . maxY ) return ; // recursion end condition
5656
57+ //console.log("flow", cursor);
58+
5759 let cursorDown = { ...cursor , y : cursor . y + 1 } ;
5860 let cursorLeft = { ...cursor , x : cursor . x - 1 } ;
5961 let cursorRight = { ...cursor , x : cursor . x + 1 } ;
6062
61- //console.log("flow", cursor);
62-
6363 if ( isEmpty ( data , cursorDown ) ) {
64- fill ( data , cursorDown , WATER_FLOW ) ;
64+ // can keep flowing down, call recursively
65+ if ( cursorDown . y >= data . minY ) fill ( data , cursorDown , WATER_FLOW ) ; // careful, answer expects only water from first row with clay!
6566 flowWater ( data , cursorDown ) ;
6667 }
6768
6869 if ( isStale ( data , cursorDown ) && isEmpty ( data , cursorLeft ) ) {
70+ // we have either stale water or clay below and free space to the left, water can flow that way
6971 fill ( data , cursorLeft , WATER_FLOW ) ;
7072 flowWater ( data , cursorLeft ) ;
7173 }
7274
7375 if ( isStale ( data , cursorDown ) && isEmpty ( data , cursorRight ) ) {
76+ // we have either stale water or clay below and free space to the right, water can flow that way
7477 fill ( data , cursorRight , WATER_FLOW ) ;
7578 flowWater ( data , cursorRight ) ;
7679 }
7780
78- if ( isBetweenWalls ( data , cursor ) ) {
79- fillToWalls ( data , cursor ) ;
81+ if ( isStale ( data , cursorDown ) && hasWallLeft ( data , cursor ) && hasWallRight ( data , cursor ) ) {
82+ // we are either stale water or clay below and walls on both sides, water will fill that space
83+ fillLeft ( data , cursor , WATER ) ;
84+ fillRight ( data , cursor , WATER ) ;
8085 fill ( data , cursor , WATER ) ;
8186 }
8287}
8388
84- function isBetweenWalls ( { filledByXY } , cursor ) {
85- // see if we reach a wall on each side
86- let wallLeft , wallRight ;
89+ function isEmpty ( data , cursor ) {
90+ return ! getContents ( data , cursor ) ;
91+ }
92+
93+ function isStale ( data , cursor ) {
94+ return [ WATER , CLAY ] . indexOf ( getContents ( data , cursor ) ) > - 1 ;
95+ }
96+
97+ function isClay ( data , cursor ) {
98+ return getContents ( data , cursor ) === CLAY ;
99+ }
100+
101+ function hasWallLeft ( data , cursor ) {
87102 let offset = - 1 ;
88- searchLeft: while ( true ) {
89- let cursorLeft = { ...cursor , x : cursor . x + offset } ;
90- if ( isEmpty ( { filledByXY } , cursorLeft ) ) {
91- wallLeft = false ;
92- break searchLeft;
93- }
94- if ( isWall ( { filledByXY } , cursorLeft ) ) {
95- wallLeft = true ;
96- break searchLeft;
97- }
98- // water (either stale or flow), keep looking left
103+ while ( true ) {
104+ let cursorOffset = { ...cursor , x : cursor . x + offset } ;
105+ if ( isEmpty ( data , cursorOffset ) ) return false ;
106+ if ( isClay ( data , cursorOffset ) ) return true ;
99107 offset -- ;
100108 }
101- offset = 1 ;
102- searchRight: while ( true ) {
103- let cursorRight = { ...cursor , x : cursor . x + offset } ;
104- if ( isEmpty ( { filledByXY } , cursorRight ) ) {
105- wallRight = false ;
106- break searchRight;
107- }
108- if ( isWall ( { filledByXY } , cursorRight ) ) {
109- wallRight = true ;
110- break searchRight;
111- }
112- // water (either stale or flow), keep looking right
109+ }
110+
111+ function hasWallRight ( data , cursor ) {
112+ let offset = 1 ;
113+ while ( true ) {
114+ let cursorOffset = { ...cursor , x : cursor . x + offset } ;
115+ if ( isEmpty ( data , cursorOffset ) ) return false ;
116+ if ( isClay ( data , cursorOffset ) ) return true ;
113117 offset ++ ;
114118 }
115- return wallLeft && wallRight ;
116119}
117120
118- function fillToWalls ( { filledByXY } , cursor ) {
121+ function fillLeft ( data , cursor , contents ) {
119122 let offset = - 1 ;
120- fillLeft: while ( true ) {
121- let cursorLeft = { ...cursor , x : cursor . x + offset } ;
122- if ( isWall ( { filledByXY } , cursorLeft ) ) {
123- break fillLeft;
124- }
125- fill ( { filledByXY } , cursorLeft , WATER ) ;
123+ while ( true ) {
124+ let cursorOffset = { ...cursor , x : cursor . x + offset } ;
125+ if ( isClay ( data , cursorOffset ) ) return ;
126+ fill ( data , cursorOffset , contents ) ;
126127 offset -- ;
127128 }
128- offset = 1 ;
129- fillRight: while ( true ) {
130- let cursorRight = { ...cursor , x : cursor . x + offset } ;
131- if ( isWall ( { filledByXY } , cursorRight ) ) {
132- break fillRight;
133- }
134- fill ( { filledByXY } , cursorRight , WATER ) ;
135- offset ++ ;
136- }
137129}
138130
139- function isEmpty ( { filledByXY } , cursor ) {
140- return ! filledByXY [ strXY ( cursor ) ] ;
141- }
142-
143- function isStale ( { filledByXY } , cursor ) {
144- let contents = filledByXY [ strXY ( cursor ) ] ;
145- return contents === WATER || contents === CLAY ;
131+ function fillRight ( data , cursor , contents ) {
132+ let offset = 1 ;
133+ while ( true ) {
134+ let cursorOffset = { ...cursor , x : cursor . x + offset } ;
135+ if ( isClay ( data , cursorOffset ) ) return ;
136+ fill ( data , cursorOffset , contents ) ;
137+ offset ++ ;
138+ }
146139}
147140
148- function isWall ( { filledByXY } , cursor ) {
149- return filledByXY [ strXY ( cursor ) ] === CLAY ;
141+ function getContents ( data , cursor ) {
142+ return data . filledByXY [ strXY ( cursor ) ] ;
150143}
151144
152- function fill ( { filledByXY } , cursor , contents ) {
153- //console.log("fill", cursor, contents);
154- filledByXY [ strXY ( cursor ) ] = contents ;
145+ function fill ( data , cursor , contents ) {
146+ data . filledByXY [ strXY ( cursor ) ] = contents ;
155147}
156148
157149function strXY ( { x, y } ) {
@@ -165,14 +157,34 @@ function parseLineContents(var1, start1, end1, var2, start2, end2) {
165157 return contents ;
166158}
167159
168- function printData ( data , minX , maxX , minY , maxY ) {
160+ function printData ( data ) {
161+ let boundaries = Object . keys ( data . filledByXY )
162+ . map ( xy => xy . split ( "," ) . map ( Number ) )
163+ . reduce (
164+ ( acc , [ x , y ] ) => {
165+ acc . minX = Math . min ( acc . minX , x ) ;
166+ acc . maxX = Math . max ( acc . maxX , x ) ;
167+ acc . minY = Math . min ( acc . minY , y ) ;
168+ acc . maxY = Math . max ( acc . maxY , y ) ;
169+ return acc ;
170+ } ,
171+ {
172+ minX : Infinity ,
173+ maxX : - Infinity ,
174+ minY : Infinity ,
175+ maxY : - Infinity
176+ }
177+ ) ;
178+
169179 let str = "" ;
170- for ( let yi = minY ; yi <= maxY ; yi ++ ) {
171- for ( let xi = minX ; xi <= maxX ; xi ++ ) {
172- str += data . filledByXY [ strXY ( { x : xi , y : yi } ) ] || "." ;
180+ for ( let yi = boundaries . minY ; yi <= boundaries . maxY ; yi ++ ) {
181+ for ( let xi = boundaries . minX ; xi <= boundaries . maxX ; xi ++ ) {
182+ str += getContents ( data , { x : xi , y : yi } ) || "." ;
173183 }
174184 str += "\n" ;
175185 }
186+
187+ console . log ( boundaries ) ;
176188 console . log ( str ) ;
177189}
178190
0 commit comments