1
+ import ISolution from "./ISolution.ts" ;
2
+ import routine from "https://deno.land/x/routine/mod.ts" ;
3
+
4
+ export default class S2406 implements ISolution {
5
+ firstPart ( input : string ) : ( number | string ) | Promise < number | string > {
6
+ const coords = input . split ( "\n" ) . map ( line => line . split ( "" ) ) ;
7
+ const currentPos = { x : 0 , y : 0 } ;
8
+ let direction = "up" ;
9
+ for ( const y in coords ) {
10
+ for ( const x in coords [ y ] ) {
11
+ if ( coords [ y ] [ x ] === "^" ) {
12
+ currentPos . x = Number ( x ) ;
13
+ currentPos . y = Number ( y ) ;
14
+ }
15
+ }
16
+ }
17
+ const poss : { x : number , y : number } [ ] = [ ] ;
18
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
19
+ walk: while ( true ) {
20
+ switch ( direction ) {
21
+ case "up" :
22
+ if ( ! coords [ currentPos . y - 1 ] ) {
23
+ break walk;
24
+ }
25
+ if ( coords [ currentPos . y - 1 ] [ currentPos . x ] === "#" ) {
26
+ direction = "right" ;
27
+
28
+ } else {
29
+ currentPos . y -- ;
30
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
31
+ }
32
+ break ;
33
+ case "right" :
34
+ if ( ! coords [ currentPos . y ] [ currentPos . x + 1 ] ) {
35
+ break walk;
36
+ }
37
+ if ( coords [ currentPos . y ] [ currentPos . x + 1 ] === "#" ) {
38
+ direction = "down" ;
39
+
40
+ } else {
41
+ currentPos . x ++ ;
42
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
43
+ }
44
+ break ;
45
+ case "down" :
46
+ if ( ! coords [ currentPos . y + 1 ] ) {
47
+ break walk;
48
+ }
49
+ if ( coords [ currentPos . y + 1 ] [ currentPos . x ] === "#" ) {
50
+ direction = "left" ;
51
+ } else {
52
+ currentPos . y ++ ;
53
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
54
+ }
55
+ break ;
56
+ case "left" :
57
+ if ( ! coords [ currentPos . y ] [ currentPos . x - 1 ] ) {
58
+ break walk;
59
+ }
60
+ if ( coords [ currentPos . y ] [ currentPos . x - 1 ] === "#" ) {
61
+ direction = "up" ;
62
+ } else {
63
+ currentPos . x -- ;
64
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
65
+ }
66
+ break ;
67
+
68
+ }
69
+ }
70
+ return poss . filter ( ( pos , index ) => poss . findIndex ( p => p . x === pos . x && p . y === pos . y ) === index ) . length ;
71
+ }
72
+ async secondPart ( input : string ) : Promise < string | number > {
73
+ const coords = input . split ( "\n" ) . map ( line => line . split ( "" ) ) ;
74
+ function tryWith ( coords : string [ ] [ ] ) : number {
75
+ const poss : { x : number , y : number } [ ] = [ ] ;
76
+ let direction = "up" ;
77
+ const currentPos = { x : 0 , y : 0 } ;
78
+ for ( const y in coords ) {
79
+ for ( const x in coords [ y ] ) {
80
+ if ( coords [ y ] [ x ] === "^" ) {
81
+ currentPos . x = Number ( x ) ;
82
+ currentPos . y = Number ( y ) ;
83
+ }
84
+ }
85
+ }
86
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
87
+ walk: while ( true ) {
88
+ if ( poss . length - poss . filter ( ( pos , index ) => poss . findIndex ( p => p . x === pos . x && p . y === pos . y ) === index ) . length > coords . length * coords [ 0 ] . length ) {
89
+ console . log ( "probably infinite loop" ) ;
90
+ return 1 ;
91
+ }
92
+ switch ( direction ) {
93
+ case "up" :
94
+ if ( ! coords [ currentPos . y - 1 ] ) {
95
+ break walk;
96
+ }
97
+ if ( coords [ currentPos . y - 1 ] [ currentPos . x ] === "#" ) {
98
+ direction = "right" ;
99
+ } else {
100
+ currentPos . y -- ;
101
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
102
+ }
103
+ break ;
104
+ case "right" :
105
+ if ( ! coords [ currentPos . y ] [ currentPos . x + 1 ] ) {
106
+ break walk;
107
+ }
108
+ if ( coords [ currentPos . y ] [ currentPos . x + 1 ] === "#" ) {
109
+ direction = "down" ;
110
+ } else {
111
+ currentPos . x ++ ;
112
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
113
+ }
114
+ break ;
115
+ case "down" :
116
+ if ( ! coords [ currentPos . y + 1 ] ) {
117
+ break walk;
118
+ }
119
+ if ( coords [ currentPos . y + 1 ] [ currentPos . x ] === "#" ) {
120
+ direction = "left" ;
121
+ } else {
122
+ currentPos . y ++ ;
123
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
124
+ }
125
+ break ;
126
+ case "left" :
127
+ if ( ! coords [ currentPos . y ] [ currentPos . x - 1 ] ) {
128
+ break walk;
129
+ }
130
+ if ( coords [ currentPos . y ] [ currentPos . x - 1 ] === "#" ) {
131
+ direction = "up" ;
132
+ } else {
133
+ currentPos . x -- ;
134
+ poss . push ( { x : currentPos . x , y : currentPos . y } ) ;
135
+ }
136
+ break ;
137
+
138
+ }
139
+ }
140
+ return 0 ;
141
+ }
142
+ const routines = [ ] ;
143
+ for ( const y in coords ) {
144
+ for ( const x in coords [ y ] ) {
145
+ if ( coords [ y ] [ x ] === "." ) {
146
+ coords [ y ] [ x ] = "#" ;
147
+ routines . push ( routine ( tryWith , coords ) ) ;
148
+ coords [ y ] [ x ] = "." ;
149
+ }
150
+ }
151
+ }
152
+ return await Promise . all ( routines ) . then ( res => res . reduce ( ( a , b ) => a + b , 0 ) ) ;
153
+ }
154
+ }
0 commit comments