1
1
AdventOfCode . day03 = {
2
2
3
- part1 : n => {
3
+ part1 : ( n , render ) => {
4
+ // Functions
5
+ let sideFn = level => 2 * level + 1
6
+ let startFn = level => Math . pow ( sideFn ( level - 1 ) , 2 ) + 1
7
+
8
+ // Which level of the spiral we're on
9
+ // Also the numbers of intial outward steps
10
+ let level = Math . floor ( Math . ceil ( Math . sqrt ( n ) ) / 2 )
11
+ let side = sideFn ( level )
12
+ let start = startFn ( level )
13
+ let offset = level - 1 // Offset from lowest value in level to middle
14
+
15
+ let distance = n
16
+
17
+ for ( let i = 0 ; i < 4 ; i ++ ) { // Loop each side
18
+ let side_middle = start + offset + ( side - 1 ) * i // Middle value for this side
19
+ let side_distance = Math . abs ( side_middle - n )
20
+ distance = Math . min ( distance , side_distance ) // Keep shortest side distance
21
+ }
22
+
23
+ if ( render ) AdventOfCode . day03 . render ( parseInt ( n ) , level , distance , 0 )
24
+
25
+ return level + distance
26
+ } ,
27
+
28
+ part1_2 : n => {
4
29
let level = Math . floor ( Math . ceil ( Math . sqrt ( n ) ) / 2 )
5
30
let side = 2 * level + 1
6
31
let highest = Math . pow ( side , 2 )
7
32
while ( n + side < highest ) n += side
8
33
return level + Math . abs ( highest - ( side - 1 ) / 2 - n )
9
34
} ,
10
35
36
+ processMove : ( grid , x , y ) => {
37
+ let g = ( x , y ) => grid [ x + ',' + y ] ? grid [ x + ',' + y ] : 0 // value of cell in grid
38
+ let c = ( x , y ) => ! g ( x , y ) // is cell clear
39
+
40
+ // NORTH EAST SOUTH WEST
41
+ if ( c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) x += 1 // Everything is empty
42
+
43
+ else if ( c ( x , y - 1 ) && c ( x + 1 , y ) && ! c ( x , y + 1 ) && c ( x - 1 , y ) ) x -= 1 // Just south is blocked
44
+ else if ( c ( x , y - 1 ) && ! c ( x + 1 , y ) && ! c ( x , y + 1 ) && c ( x - 1 , y ) ) x -= 1 // Just south and east are blocked
45
+
46
+ else if ( c ( x , y - 1 ) && ! c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) y += 1 // Just east is blocked
47
+ else if ( ! c ( x , y - 1 ) && ! c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) y += 1 // Just north and east are blocked
48
+
49
+ else if ( ! c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) x += 1 // Just north is blocked
50
+ else if ( ! c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && ! c ( x - 1 , y ) ) x += 1 // Just north and west are blocked
51
+
52
+ else if ( c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && ! c ( x - 1 , y ) ) y -= 1 // Just west is blocked
53
+ else if ( c ( x , y - 1 ) && c ( x + 1 , y ) && ! c ( x , y + 1 ) && ! c ( x - 1 , y ) ) y -= 1 // Just south and west are blocked
54
+
55
+ return { x : x , y : y }
56
+ } ,
57
+
11
58
part2 : input => {
12
59
let grid = {
13
60
'0,0' : 1
14
61
}
15
- let g = ( x , y ) => grid [ x + ',' + y ] ? grid [ x + ',' + y ] : 0 // value of cell in grid
62
+ let g = ( x , y ) => grid [ x + ',' + y ] ? grid [ x + ',' + y ] : 0 // value of cell in grid
16
63
let c = ( x , y ) => ! g ( x , y ) // is cell clear
17
64
let set = ( x , y , value ) => grid [ x + ',' + y ] = value
18
65
@@ -22,21 +69,9 @@ AdventOfCode.day03 = {
22
69
23
70
while ( value < input ) {
24
71
// Move to next cell
25
-
26
- // NORTH EAST SOUTH WEST
27
- if ( c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) x += 1 // Everything is empty
28
-
29
- else if ( c ( x , y - 1 ) && c ( x + 1 , y ) && ! c ( x , y + 1 ) && c ( x - 1 , y ) ) x -= 1 // Just south is blocked
30
- else if ( c ( x , y - 1 ) && ! c ( x + 1 , y ) && ! c ( x , y + 1 ) && c ( x - 1 , y ) ) x -= 1 // Just south and east are blocked
31
-
32
- else if ( c ( x , y - 1 ) && ! c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) y += 1 // Just east is blocked
33
- else if ( ! c ( x , y - 1 ) && ! c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) y += 1 // Just north and east are blocked
34
-
35
- else if ( ! c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && c ( x - 1 , y ) ) x += 1 // Just north is blocked
36
- else if ( ! c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && ! c ( x - 1 , y ) ) x += 1 // Just north and west are blocked
37
-
38
- else if ( c ( x , y - 1 ) && c ( x + 1 , y ) && c ( x , y + 1 ) && ! c ( x - 1 , y ) ) y -= 1 // Just west is blocked
39
- else if ( c ( x , y - 1 ) && c ( x + 1 , y ) && ! c ( x , y + 1 ) && ! c ( x - 1 , y ) ) y -= 1 // Just south and west are blocked
72
+ let pos = AdventOfCode . day03 . processMove ( grid , x , y )
73
+ x = pos . x
74
+ y = pos . y
40
75
41
76
// Calculate total
42
77
value = g ( x - 1 , y - 1 ) + g ( x + 0 , y - 1 ) + g ( x + 1 , y - 1 )
@@ -47,6 +82,54 @@ AdventOfCode.day03 = {
47
82
48
83
return value
49
84
85
+ } ,
86
+
87
+ renderHtml : '<canvas id="canvas3_1" style="height: 500px;"></canvas>' ,
88
+
89
+ render : async ( n , level , distance , frame ) => {
90
+ let c = document . getElementById ( 'canvas3_1' ) . getContext ( '2d' )
91
+ let w = c . canvas . width = document . getElementById ( 'canvas3_1' ) . clientWidth
92
+ let h = c . canvas . height = document . getElementById ( 'canvas3_1' ) . clientHeight
93
+ let max = 2000
94
+ c . font = '8px Verdana'
95
+ while ( ! n || parseInt ( n ) <= 1 || parseInt ( n ) > max ) n = parseInt ( prompt ( `Number to find (Integer from 2 - ${ max } )` ) )
96
+ console . log ( parseInt ( n ) )
97
+ let grid = { }
98
+ let size = 22
99
+ let x = 0
100
+ let y = 0
101
+ let i = 1
102
+
103
+ // Draw grid
104
+ while ( i <= n ) {
105
+ let pos = AdventOfCode . day03 . processMove ( grid , x , y )
106
+ x = pos . x
107
+ y = pos . y
108
+ c . fillText ( i , w / 2 + x * size , h / 2 + y * size / 2 )
109
+ grid [ x + ',' + y ] = i + 1
110
+ i ++
111
+ await sleep ( 1 )
112
+ }
113
+
114
+ let xa = x / Math . abs ( x )
115
+ let ya = y / Math . abs ( y )
116
+ let cx = 0
117
+ let cy = 0
118
+ let colour = 0
119
+ for ( cx = 0 ; Math . abs ( cx ) <= Math . abs ( x ) + ( x > 0 ?- 2 :0 ) ; cx += xa ) {
120
+ c . fillStyle = `hsla(${ 137 * colour ++ } , 100%, 50%, 0.5)`
121
+ c . fillRect ( w / 2 + ( cx + 0.8 ) * size , h / 2 + ( cy - 0.8 ) * size / 2 , size , size / 2 )
122
+ await sleep ( 25 )
123
+ }
124
+ for ( cy = 0 ; Math . abs ( cy ) <= Math . abs ( y ) ; cy += ya ) {
125
+ c . fillStyle = `hsla(${ 137 * colour ++ } , 100%, 50%, 0.5)`
126
+ c . fillRect ( w / 2 + ( cx + 0.8 ) * size , h / 2 + ( cy - 0.8 ) * size / 2 , size , size / 2 )
127
+ await sleep ( 25 )
128
+ }
129
+ c . fillRect = w / 2 - 5
130
+
131
+
132
+
50
133
}
51
134
52
135
}
0 commit comments