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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
|
; Advent of Code 2025 - Day 1
;
; #include <stdio.h>
; #include <stdlib.h>
; #include <stddef.h>
; #include <stdint.h>
;
; int main(void)
; {
; FILE* input = fopen("input/day1.txt", "r");
;
; int32_t angle1 = 50;
; int32_t angle2 = 50;
;
; int32_t password1 = 0;
; int32_t password2 = 0;
;
; char line[256];
; while (fgets(line, sizeof(line), input))
; {
; int32_t direction = (line[0] == 'L') ? -1 : 1;
; int32_t steps = atoi(line + 1);
;
; // part 1
; angle1 += direction * steps;
; angle1 %= 100;
; if (angle1 < 0)
; angle1 += 100;
; if (angle1 == 0)
; password1++;
;
; // part 2
; for (int i = 0; i < steps; i++)
; {
; angle2 += direction;
; if (angle2 == 100)
; angle2 = 0;
; else if (angle2 == -1)
; angle2 = 99;
; if (angle2 == 0)
; password2++;
; }
; }
;
; fclose(input);
;
; printf("Password 1: %d\n", password1);
; printf("Password 2: %d\n", password2);
; }
;
global _start
%define SYS_EXIT 1
%define SYS_READ 3
%define SYS_WRITE 4
%define SYS_OPEN 5
%define SYS_CLOSE 6
%define O_RDONLY 0
%define STDOUT 1
section .data
inputPath db "input/day1.txt", 0
newline db 10
label1 db "Password 1: ", 0
label2 db "Password 2: ", 0
angle1 dd 50
angle2 dd 50
password1 dd 0
password2 dd 0
section .bss
buffer resb 4096
lineBuffer resb 256
numberBuffer resb 16
lineLen resd 1
section .text
_start:
; open file
mov eax, SYS_OPEN
mov ebx, inputPath
mov ecx, O_RDONLY
int 0x80
mov esi, eax ; fd in ESI
mov dword [lineLen], 0 ; no chars in current line yet
ReadLoop:
; read up to 4096 bytes
mov eax, SYS_READ
mov ebx, esi
mov ecx, buffer
mov edx, 4096
int 0x80
cmp eax, 0
jle EOF ; <=0 -> EOF or error
mov edi, buffer ; scan pointer
mov ebp, eax ; bytes remaining in this chunk
ScanChunk:
cmp ebp, 0
je ReadLoop ; chunk done, read next
mov al, [edi]
; windows can be a fucking bitch
; handle CR (13) -> just skip
cmp al, 13
je SkipCR
; handle LF (10) -> end of line
cmp al, 10
je EndOfLine
; normal character -> append to lineBuffer if space left
mov edx, [lineLen]
cmp edx, 255 ; leave 1 byte for NULL
jae SkipStore ; ignore extra characters if too long
mov [lineBuffer+edx], al
inc edx
mov [lineLen], edx
SkipStore:
inc edi
dec ebp
jmp ScanChunk
SkipCR:
inc edi
dec ebp
jmp ScanChunk
EndOfLine:
; terminate current line
mov edx, [lineLen]
mov byte [lineBuffer+edx], 0
; if line isn't empty, process it
cmp edx, 0
je LineDone
push esi
push edi
mov esi, lineBuffer
call HandleLine
pop edi
pop esi
LineDone:
mov dword [lineLen], 0 ; reset line length
inc edi
dec ebp
jmp ScanChunk
; process last line if not newline-terminated, then print result
EOF:
; if there is a partial line at EOF, process it
mov edx, [lineLen]
cmp edx, 0
jle PrintResults
mov byte [lineBuffer+edx], 0
push esi
mov esi, lineBuffer
call HandleLine
pop esi
PrintResults:
mov ecx, label1
call PrintString
mov eax, [password1]
call PrintInt
; newline
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, newline
mov edx, 1
int 0x80
mov ecx, label2
call PrintString
mov eax, [password2]
call PrintInt
; newline
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, newline
mov edx, 1
int 0x80
mov eax, SYS_CLOSE
mov ebx, esi
int 0x80
mov eax, SYS_EXIT
xor ebx, ebx
int 0x80
; Handle one line: ESI -> "L123" or "R45"
HandleLine:
mov al, [esi]
cmp al, 'L'
je .left
mov ebx, 1 ; direction = +1 for 'R' or anything else
jmp .after
.left:
mov ebx, -1 ; direction = -1 for 'L'
.after:
inc esi ; skip 'L' or 'R'
call ParseInt ; EAX = steps
mov ecx, eax
.part1
mov eax, ecx
imul eax, ebx ; EAX = dir*steps
mov edx, [angle1]
add edx, eax ; update angle (can be out of range signed)
; normalize edx into [0; 100[ using repeated +- 100
Norm1:
cmp edx, 0
jl N1Add
cmp edx, 100
jl N1Done
sub edx, 100
jmp Norm1
N1Add:
add edx, 100
jmp Norm1
N1Done:
mov [angle1], edx
cmp edx, 0
jne .startPart2
mov eax, [password1]
inc eax
mov [password1], eax
; Part 2
.startPart2:
mov edi, ebx
part2Loop:
test ecx, ecx
jle .done
dec ecx
mov edx, [angle2]
add edx, edi
cmp edx, 100
jne .checkNegative
mov edx, 0
jmp .p2store
.checkNegative:
cmp edx, -1
jne .p2store
mov edx, 99
.p2store:
mov [angle2], edx
cmp edx, 0
jne part2Loop
mov eax, [password2]
inc eax
mov [password2], eax
jmp part2Loop
.done:
ret
; parse ASCII integer into EAX
ParseInt:
xor eax, eax ; result = 0
.parseLoop:
mov dl, [esi]
cmp dl, '0'
jl .done
cmp dl, '9'
jg .done
sub dl, '0' ; digit value 0..9
movzx edx, dl
imul eax, eax, 10 ; result *= 10
add eax, edx ; result += digit
inc esi
jmp .parseLoop
.done:
ret
PrintInt:
mov edi, numberBuffer+15 ; write digits from the end
mov byte [edi], 0 ; terminator
dec edi
cmp eax, 0
jne .convert
mov byte [edi], '0'
jmp .finish
.convert:
; we will repeatedly compute:
; q = eax / 10
; r = eax % 10
; using only subtraction
.nextDigit:
mov edx, eax ; tmp = current value
mov ecx, 0 ; q = 0
cmp edx, 10 ; if < 0, q=0, r=edx
jb .lastDigit
.subLoop:
sub edx, 10
inc ecx ; q++
cmp edx, 10
jae .subLoop ; while tmp >= 10
.lastDigit:
; now:
; ecx = quotient
; edx = remainder (0..9)
add dl, '0'
mov [edi], dl ; store digit
dec edi
mov eax, ecx ; eax = quotient
test eax, eax
jnz .nextDigit ; more digits to extract?
inc edi ; move to first digit
.finish:
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, edi
mov edx, numberBuffer+15
sub edx, edi ; length
int 0x80
ret
PrintString:
push ecx
push edx
mov edx, 0
.count:
cmp byte [ecx+edx], 0
je .doneCount
inc edx
jmp .count
.doneCount:
mov eax, SYS_WRITE
mov ebx, STDOUT
int 0x80
pop edx
pop ecx
ret
|