-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday12_lib.tal
283 lines (225 loc) · 4.64 KB
/
day12_lib.tal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
( get-byte -- success )
@parse-line
[ ;&get-byte-addr STA2 ]
;&get-byte JSR2
DUP #00 NEQ ,¬-done JCN
POP #00 RTN
¬-done
;&get-byte JSR2
&scan-for-dash
;&get-byte JSR2
LIT '- NEQ ,&scan-for-dash JCN
;&get-byte JSR2 ;&get-byte JSR2
;append-bi-path JSR2
&scan-for-lf
;&get-byte JSR2
#0a NEQ ,&scan-for-lf JCN
#01
RTN
&get-byte
LIT2 [ &get-byte-addr $2 ] JMP2
( get-byte -- )
@parse-lines
&more
DUP2 ;parse-line JSR2 ,&more JCN
POP2
RTN
( -- )
@init-paths
#ffff [ ;paths STA2 ]
;paths [ ;paths-end STA2 ]
#0000 [ ;path-count STA2 ]
;path-so-far [ ;path-so-far-end STA2 ]
#00 [ ;path-so-far STA ]
#00 [ ;second-visit-done STA ]
#00 #2000 ;visited ;memset JSR2
RTN
( -- )
@dump-paths
;paths ( path* )
&next
DUP2 2++ SWP2 LDA2
DUP2 #ffff EQU2 ,&done JCN
OVR #80 AND NOT ,¬-modified JCN
LIT '* EMIT
SWP #7f AND SWP
¬-modified
DBGSHORTCHAR POP2
P< "- >P
DUP2 2++ SWP2 LDA2 DBGSHORTCHAR POP2
SP
,&next JMP
&done
POP2
POP2
RTN
( from to -- )
@append-bi-path
DUP4 ;append-path JSR2
SWP2 ;append-path JSR2
RTN
( from to -- )
@append-path
DUP2 LIT2 "st EQU2 ,&skip JCN
OVR2 LIT2 "en EQU2 ,&skip JCN
[ ;paths-end LDA2 ] STA4
[ ;paths-end *4++ ]
#ffff [ ;paths-end LDA2 ] STA2
RTN
&skip
POP4 RTN
%PATH_FROM { LDA2 }
%PATH_TO { 2++ LDA2 }
%PATH_ISTERMINATOR { LDA2 #ffff NEQ2 }
( -- )
@walk-paths
#ffff
;initial-path ( path* )
DUP2 PATH_TO ;enter-room JSR2
;walk-path JSR2
POP2
POP2
RTN
( -- )
@walk-path
( LIT '< EMIT SP ;unwind-path-always JSR2 )
;paths ( path* )
&next
( path* )
DUP2 PATH_ISTERMINATOR ;¬-done JCN2
( path* )
POP2
RTN
¬-done
( path* )
DUP2 PATH_FROM ;get-current-room JSR2 NEQ2 ,&try-next JCN
DUP2 PATH_TO ;can-visit JSR2 NOT ;&already-visited JCN2
( save second visit flag )
[ ;second-visit-done LDA ] STH
( matching-path* )
LIT '> ;&trace JSR2 POP
( path* )
DUP2 PATH_TO ;enter-room JSR2
;unwind-path JSR2
( recurse 😱 )
;walk-path JSR2
LIT '< ;&trace JSR2 POP
;leave-room JSR2
( restore second visit flag )
STHr [ ;second-visit-done STA ]
&already-visited
&try-next
4++ ( path* )
,&next JMP
&trace
RTN
EMIT SP DUP2 LDA2 DBGSHORTCHAR POP2 LIT '- EMIT DUP2 2++ LDA2 DBGSHORTCHAR POP2 LF #00
( room -- )
@enter-room
( P< "entering 20 >P DBGSHORTCHAR LF )
STH2k #01 STH2r ;add-visitcount JSR2
DUP2 ;get-visitcount JSR2 #01 LEQ ,¬-second-visit JCN
DUP2 [ ;twice-visited-room STA2 ]
¬-second-visit
[ ;path-so-far-end LDA2 ] STA2
[ ;path-so-far-end *2++ ]
#00 [ ;path-so-far-end LDA2 ] STA
( ;path-so-far ;print JSR2 LF )
RTN
( -- )
@leave-room
( P< "leaving 20 >P ;get-current-room JSR2 DBGSHORTCHAR POP2 LF )
;get-current-room JSR2 [ ;twice-visited-room LDA2 ]
NEQ2 ,¬-second-exit JCN
#0000 [ ;twice-visited-room STA2 ]
¬-second-exit
#ff ;get-current-room JSR2 ;add-visitcount JSR2
#00 [ ;path-so-far-end LDA2 ] STA
[ ;path-so-far-end *2-- ]
( ;path-so-far ;print JSR2 LF )
RTN
( -- room )
@get-current-room
[ ;path-so-far-end LDA2 ] 2-- LDA2
RTN
( delta room -- )
@add-visitcount
;get-visitcount-ptr JSR2
DUP2 #0000 EQU2 ,&nope JCN
*ADD
RTN
&nope
POP2 POP
RTN
( room -- )
@get-visitcount
;get-visitcount-ptr JSR2
DUP2 #0000 EQU2 ,&nope JCN
LDA
RTN
&nope
POP2
#00
RTN
( room -- visited-ptr )
@get-visitcount-ptr
DUP2 LIT2 "aa LTH2 ,&big-room JCN
LIT2 "aa SUB2 ;visited ADD2
RTN
&big-room
POP2 #0000
RTN
@dump-visited
LIT 'V EMIT
;visited ( p* )
#0000 STH2 ( p* : cnt )
&loop
DUP2 LDA #00 EQU ,&skip JCN
STH2rk LIT2 "aa ADD2 DBGSHORTCHAR POP2 SP
&skip
INC2 INC2r
STH2rk #2000 LTH2 ,&loop JCN
POP2r
POP2
LF
RTN
( -- )
@unwind-path
( check if last path arrives at end )
;get-current-room JSR2 LIT2 "en EQU2 ,&at-end JCN
RTN
&at-end
;path-count #01 ;add64-byte JSR2
;unwind-path-always JMP2
( -- )
@unwind-path-always
;path-so-far ;print JSR2 LIT '. EMIT LF
RTN
( room -- visited )
@can-visit
(
LIT '? EMIT ;unwind-path-always JSR2
;dump-visited JSR2
)
( allow if visitcount is 0 )
;get-visitcount JSR2 #00 EQU
( also allow if the double-visit slot is free )
[ ;twice-visited-room LDA2 ] #0000 EQU2
ORA RTN
~library/console.lib.tal
~library/string.tal
~library/math.tal
|8000
@initial-path
"__ "st
@paths
( from to )
$1000
@paths-end $2
@path-count $8
@path-so-far $100
@path-so-far-end $2
@second-visit-done $1
@twice-visited-room $2
|b000
@visited $2000