diff options
Diffstat (limited to 'linux/advent2020/2b.mu')
-rw-r--r-- | linux/advent2020/2b.mu | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/linux/advent2020/2b.mu b/linux/advent2020/2b.mu new file mode 100644 index 00000000..13f60f0f --- /dev/null +++ b/linux/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 +} |