diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-12-02 19:36:10 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-12-02 19:36:10 -0800 |
commit | f60ebed0fb53ebc9cc0c9d3914359fee8b48ca3b (patch) | |
tree | f8cd919e2853e7dcbca0b12f12507c6e278c7e8a /apps/advent2020/2b.mu | |
parent | a41a6eadd167b26e95c4bc2253cb3fe8dc79667f (diff) | |
download | mu-f60ebed0fb53ebc9cc0c9d3914359fee8b48ca3b.tar.gz |
7318 - advent day 2 done
Funny story: I got the right answer for part 1 even though I missed the ':' in the line format. But of course that didn't work for part 2.
Diffstat (limited to 'apps/advent2020/2b.mu')
-rw-r--r-- | apps/advent2020/2b.mu | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/apps/advent2020/2b.mu b/apps/advent2020/2b.mu new file mode 100644 index 00000000..116029b0 --- /dev/null +++ b/apps/advent2020/2b.mu @@ -0,0 +1,122 @@ +# https://adventofcode.com/2020/day/2 +# +# To run (on Linux): +# $ git clone https://github.com/akkartik/mu +# $ cd mu +# $ ./translate_mu apps/advent2020/2b.mu +# $ ./a.elf < input +# +# You'll need to register to download the 'input' file for yourself. + +fn main -> _/ebx: int { + var valid-password-count/edi: int <- copy 0 + var line-storage: (stream byte 0x100) # 256 bytes + var line/edx: (addr stream byte) <- address line-storage + var slice-storage: slice + var slice/ecx: (addr slice) <- address slice-storage + { + # 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 + # slice = next-token(line, '-') + next-token line, 0x2d, slice + # pos1 = parse-int(slice) + var _pos1/eax: int <- parse-decimal-int-from-slice slice + var pos1/ebx: int <- copy _pos1 + var dash/eax: byte <- read-byte line # skip '-' + # slice = next-token(line, ' ') + next-token line, 0x20, slice + var _pos2/eax: int <- parse-decimal-int-from-slice slice + var pos2/esi: int <- copy _pos2 + print-int32-decimal 0, pos1 + print-string 0, " " + print-int32-decimal 0, pos2 + print-string 0, "\n" + compare pos1, pos2 + { + break-if-<= + print-string 0, "out of order!\n" + return 1 + } + # letter = next non-space + skip-chars-matching-whitespace line + var letter/eax: byte <- read-byte line + # skip some stuff + { + var colon/eax: byte <- read-byte line # skip ':' + } + skip-chars-matching-whitespace line + # now check the rest of the line + var is-valid?/eax: boolean <- is-valid? pos1, pos2, letter, line + compare is-valid?, 0 # false + { + break-if-= + print-string 0, "valid!\n" + valid-password-count <- increment + } + loop + } + print-int32-decimal 0, valid-password-count + print-string 0, "\n" + return 0 +} + +# ideally password would be a random-access array +# we'll just track an index +# one benefit: we can easily start at 1 +fn is-valid? pos1: int, pos2: int, letter: byte, password: (addr stream byte) -> _/eax: boolean { + var i/esi: int <- copy 1 + var letter-count/edi: int <- copy 0 + # while password stream isn't empty + # c = read byte from password + # if (c == letter) + # if (i == pos1) + # ++letter-count + # if (i == pos2) + # ++letter-count + # ++i + { +#? print-string 0, " " +#? print-int32-decimal 0, i +#? print-string 0, "\n" + var done?/eax: boolean <- stream-empty? password + compare done?, 0 # false + break-if-!= + var c/eax: byte <- read-byte password +#? { +#? var c2/eax: int <- copy c +#? print-int32-decimal 0, c2 +#? print-string 0, "\n" +#? } + compare c, letter + { + break-if-!= + compare i, pos1 + { + break-if-!= + letter-count <- increment +#? print-string 0, " hit\n" + } + compare i, pos2 + { + break-if-!= + letter-count <- increment +#? print-string 0, " hit\n" + } + } + i <- increment + loop + } + # return (letter-count == 1) + compare letter-count, 1 + { + break-if-!= + return 1 # true + } + return 0 # false +} |