diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-12-04 21:57:51 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-12-04 23:02:53 -0800 |
commit | 18d5bab2b66406ee1e329ef099b375d98f0c2dd8 (patch) | |
tree | 00c29a0b83fc049a9362bd5cb1337926257329e1 /apps/advent2020 | |
parent | 8a8db34f259f12b06f7b87e4f4c1b5530425ff29 (diff) | |
download | mu-18d5bab2b66406ee1e329ef099b375d98f0c2dd8.tar.gz |
7329 - snapshot: advent day 4 part 2
I've found two bugs in SubX libraries: 1. next-word had an out-of-bounds read 2. next-word was skipping comments, because that's what I need during bootstrapping. I've created a new variant called next-raw-word that doesn't skip comments. These really need better names. We're now at the point where 4b.mu has the right structure and returns identical result to 4a.mu.
Diffstat (limited to 'apps/advent2020')
-rw-r--r-- | apps/advent2020/4b.mu | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/apps/advent2020/4b.mu b/apps/advent2020/4b.mu new file mode 100644 index 00000000..acc3b89d --- /dev/null +++ b/apps/advent2020/4b.mu @@ -0,0 +1,82 @@ +# https://adventofcode.com/2020/day/4 +# +# To run (on Linux): +# $ git clone https://github.com/akkartik/mu +# $ cd mu +# $ ./translate_mu apps/advent2020/4b.mu +# $ ./a.elf < input +# +# You'll need to register to download the 'input' file for yourself. + +fn main -> _/ebx: int { + var curr-passport-field-count/esi: int <- copy 0 + var valid-passport-count/edi: int <- copy 0 + var line-storage: (stream byte 0x100) # 256 bytes + var line/ecx: (addr stream byte) <- address line-storage + var key-slice-storage: slice + var key-slice/edx: (addr slice) <- address key-slice-storage + var val-slice-storage: slice + var val-slice/ebx: (addr slice) <- address val-slice-storage + $main:line-loop: { + # read line from stdin + clear-stream line + read-line-from-real-keyboard line + # if line is empty (not even a newline), quit + var done?/eax: boolean <- stream-empty? line + compare done?, 0 # false + break-if-!= + print-stream-to-real-screen line + # if line has just a newline, process passport + skip-chars-matching-whitespace line + var new-passport?/eax: boolean <- stream-empty? line + { + compare new-passport?, 0 # false + break-if-= + compare curr-passport-field-count, 7 + { + break-if-!= + valid-passport-count <- increment + print-string 0, "=> " + print-int32-decimal 0, valid-passport-count + print-string 0, "\n" + } + curr-passport-field-count <- copy 0 + loop $main:line-loop + } + $main:word-loop: { + skip-chars-matching-whitespace line + var done?/eax: boolean <- stream-empty? line + compare done?, 0 # false + break-if-!= + next-token line, 0x3a, key-slice # ':' + var dummy/eax: byte <- read-byte line # skip ':' + next-raw-word line, val-slice + print-slice-to-real-screen key-slice + print-string 0, " : " + print-slice-to-real-screen val-slice + print-string 0, "\n" + # treat cid as optional + var optional?/eax: boolean <- slice-equal? key-slice, "cid" + compare optional?, 0 # false + { + break-if-!= + # otherwise assume there are no invalid fields and no duplicate fields + curr-passport-field-count <- increment + print-string 0, "-> " + print-int32-decimal 0, curr-passport-field-count + print-string 0, "\n" + } + loop + } + loop + } + # process final passport + compare curr-passport-field-count, 7 + { + break-if-!= + valid-passport-count <- increment + } + print-int32-decimal 0, valid-passport-count + print-string 0, "\n" + return 0 +} |