diff options
Diffstat (limited to 'apps/advent2020')
-rw-r--r-- | apps/advent2020/1a.mu | 97 | ||||
-rw-r--r-- | apps/advent2020/1b.mu | 113 | ||||
-rw-r--r-- | apps/advent2020/2a.mu | 92 | ||||
-rw-r--r-- | apps/advent2020/2b.mu | 122 | ||||
-rw-r--r-- | apps/advent2020/3a.mu | 107 | ||||
-rw-r--r-- | apps/advent2020/3b.mu | 137 | ||||
-rw-r--r-- | apps/advent2020/4a.mu | 75 | ||||
-rw-r--r-- | apps/advent2020/4b.mu | 314 | ||||
-rw-r--r-- | apps/advent2020/5a.mu | 79 | ||||
-rw-r--r-- | apps/advent2020/5b.mu | 81 | ||||
-rw-r--r-- | apps/advent2020/vimrc.vim | 2 |
11 files changed, 0 insertions, 1219 deletions
diff --git a/apps/advent2020/1a.mu b/apps/advent2020/1a.mu deleted file mode 100644 index 67fdc358..00000000 --- a/apps/advent2020/1a.mu +++ /dev/null @@ -1,97 +0,0 @@ -# https://adventofcode.com/2020/day/1 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/1a.mu -# $ ./a.elf < input -# found -# 1353 667 -# 902451 -# -# You'll need to register to download the 'input' file for yourself. - -fn main -> _/ebx: int { - # data structure - var numbers-storage: (array int 0x100) # 256 ints - var numbers/esi: (addr array int) <- address numbers-storage - var numbers-index/ecx: int <- copy 0 - # phase 1: parse each line from stdin and add it to numbers - { - var line-storage: (stream byte 0x100) # 256 bytes - var line/edx: (addr stream byte) <- address line-storage - { -#? print-string 0, "== iter\n" - # 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 - # convert line to int and append it to numbers - var n/eax: int <- parse-decimal-int-from-stream line -#? print-int32-decimal 0, n -#? print-string 0, "\n" - var dest/ebx: (addr int) <- index numbers, numbers-index - copy-to *dest, n - numbers-index <- increment -#? print-string 0, "== " -#? print-int32-decimal 0, numbers-index -#? print-string 0, "\n" - loop - } - } - # phase 2: for each number in the array, check if 2020-it is in the rest of - # the array - var i/eax: int <- copy 0 - { - compare i, numbers-index - break-if->= - var src/ebx: (addr int) <- index numbers, i -#? print-int32-decimal 0, *src -#? print-string 0, "\n" - var target/ecx: int <- copy 0x7e4 # 2020 - target <- subtract *src - { - var found?/eax: boolean <- find-after numbers, i, target - compare found?, 0/false - break-if-= - print-string 0, "found\n" - print-int32-decimal 0, *src - print-string 0, " " - print-int32-decimal 0, target - print-string 0, "\n" - target <- multiply *src - print-int32-decimal 0, target - print-string 0, "\n" - return 0/success - } - i <- increment - loop - } - return 1/not-found -} - -fn find-after _numbers: (addr array int), start: int, _target: int -> _/eax: boolean { - var numbers/esi: (addr array int) <- copy _numbers - var target/edi: int <- copy _target - var len/ecx: int <- length numbers - var i/eax: int <- copy start - i <- increment - { - compare i, len - break-if->= - var src/edx: (addr int) <- index numbers, i - # if *src == target, return true - compare *src, target - { - break-if-!= - return 1/true - } - i <- increment - loop - } - return 0/false -} diff --git a/apps/advent2020/1b.mu b/apps/advent2020/1b.mu deleted file mode 100644 index a638d228..00000000 --- a/apps/advent2020/1b.mu +++ /dev/null @@ -1,113 +0,0 @@ -# https://adventofcode.com/2020/day/1 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/1b.mu -# $ ./a.elf < input -# found -# 143 407 1470 -# 85555470 -# -# You'll need to register to download the 'input' file for yourself. - -fn main -> _/ebx: int { - # data structure - var numbers-storage: (array int 0x100) # 256 ints - var numbers/esi: (addr array int) <- address numbers-storage - var numbers-index/ecx: int <- copy 0 - # phase 1: parse each line from stdin and add it to numbers - { - var line-storage: (stream byte 0x100) # 256 bytes - var line/edx: (addr stream byte) <- address line-storage - { -#? print-string 0, "== iter\n" - # 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 - # convert line to int and append it to numbers - var n/eax: int <- parse-decimal-int-from-stream line -#? print-int32-decimal 0, n -#? print-string 0, "\n" - var dest/ebx: (addr int) <- index numbers, numbers-index - copy-to *dest, n - numbers-index <- increment -#? print-string 0, "== " -#? print-int32-decimal 0, numbers-index -#? print-string 0, "\n" - loop - } - } - # phase 2: for every pair of distinct numbers, check if the rest of the - # array has 2020-it - var i/edi: int <- copy 0 - { - compare i, numbers-index - break-if->= - # for j from i+1 to end - var j/edx: int <- copy i - j <- increment - { - compare j, numbers-index - break-if->= - { - compare i, j - break-if-= - var target/ebx: int <- copy 0x7e4 # 2020 - var src/edi: (addr int) <- index numbers, i - target <- subtract *src - var src2/ecx: (addr int) <- index numbers, j - target <- subtract *src2 - { - var found?/eax: boolean <- find-after numbers, j, target - compare found?, 0/false - break-if-= - print-string 0, "found\n" - print-int32-decimal 0, *src - print-string 0, " " - print-int32-decimal 0, *src2 - print-string 0, " " - print-int32-decimal 0, target - print-string 0, "\n" - target <- multiply *src - target <- multiply *src2 - print-int32-decimal 0, target - print-string 0, "\n" - return 0/success - } - } - j <- increment - loop - } - i <- increment - loop - } - return 1/not-found -} - -fn find-after _numbers: (addr array int), start: int, _target: int -> _/eax: boolean { - var numbers/esi: (addr array int) <- copy _numbers - var target/edi: int <- copy _target - var len/ecx: int <- length numbers - var i/eax: int <- copy start - i <- increment - { - compare i, len - break-if->= - var src/edx: (addr int) <- index numbers, i - # if *src == target, return true - compare *src, target - { - break-if-!= - return 1/true - } - i <- increment - loop - } - return 0/false -} diff --git a/apps/advent2020/2a.mu b/apps/advent2020/2a.mu deleted file mode 100644 index dc67b94a..00000000 --- a/apps/advent2020/2a.mu +++ /dev/null @@ -1,92 +0,0 @@ -# https://adventofcode.com/2020/day/2 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/2a.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 - # start = parse-int(slice) - var _start/eax: int <- parse-decimal-int-from-slice slice - var start/ebx: int <- copy _start - var dash/eax: byte <- read-byte line # skip '-' - # slice = next-token(line, ' ') - next-token line, 0x20, slice - var _end/eax: int <- parse-decimal-int-from-slice slice - var end/esi: int <- copy _end - print-int32-decimal 0, start - print-string 0, " " - print-int32-decimal 0, end - print-string 0, "\n" - # 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? start, end, 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 -} - -fn is-valid? start: int, end: int, letter: byte, password: (addr stream byte) -> _/eax: boolean { - var letter-count/edi: int <- copy 0 - # for every c in password - # if (c == letter) - # ++letter-count - { - var done?/eax: boolean <- stream-empty? password - compare done?, 0/false - break-if-!= - var c/eax: byte <- read-byte password - compare c, letter - { - break-if-!= - letter-count <- increment - } - loop - } - # return (start <= letter-count <= end) - compare letter-count, start - { - break-if->= - return 0/false - } - compare letter-count, end - { - break-if-<= - return 0/false - } - return 1/true -} diff --git a/apps/advent2020/2b.mu b/apps/advent2020/2b.mu deleted file mode 100644 index 13f60f0f..00000000 --- a/apps/advent2020/2b.mu +++ /dev/null @@ -1,122 +0,0 @@ -# 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 -} diff --git a/apps/advent2020/3a.mu b/apps/advent2020/3a.mu deleted file mode 100644 index 76bda961..00000000 --- a/apps/advent2020/3a.mu +++ /dev/null @@ -1,107 +0,0 @@ -# https://adventofcode.com/2020/day/3 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/3a.mu -# $ ./a.elf < input -# -# You'll need to register to download the 'input' file for yourself. - -fn main -> _/ebx: int { - # represent trees in a 2D array of ints - # wasteful since each tree is just one bit - var trees-storage: (array int 0x2800) # 10k ints - var trees/esi: (addr array int) <- address trees-storage - var trees-length/ecx: int <- copy 0 - var num-rows: int - var width: int - # phase 1: parse each row of trees from stdin - { - var line-storage: (stream byte 0x40) # 64 bytes - var line/edx: (addr stream byte) <- address line-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-!= - # wastefully recompute width on every line - # zero error-checking; we assume input lines are all equally long - copy-to width, 0 - # turn each byte into a tree and append it - $main:line-loop: { - var done?/eax: boolean <- stream-empty? line - compare done?, 0/false - break-if-!= -#? print-int32-decimal 0, num-rows -#? print-string 0, " " -#? print-int32-decimal 0, width -#? print-string 0, "\n" - var dest/ebx: (addr int) <- index trees, trees-length - var c/eax: byte <- read-byte line - # newline comes only at end of line - compare c, 0xa/newline - break-if-= - # '#' = tree - compare c, 0x23/hash - { - break-if-!= - copy-to *dest, 1 - } - # anything else = no tree - { - break-if-= - copy-to *dest, 0 - } - increment width - trees-length <- increment - loop - } - increment num-rows - loop - } - } - # phase 2: compute - print-int32-decimal 0, num-rows - print-string 0, "x" - print-int32-decimal 0, width - print-string 0, "\n" - var row/ecx: int <- copy 0 - var col/edx: int <- copy 0 - var num-trees-hit/edi: int <- copy 0 - { - compare row, num-rows - break-if->= - var curr/eax: int <- index2d trees, row, col, width - compare curr, 0 - { - break-if-= - num-trees-hit <- increment - } - # right 3, down 1 - col <- add 3 - row <- add 1 - loop - } - print-int32-decimal 0, num-trees-hit - print-string 0, "\n" - return 0 -} - -fn index2d _arr: (addr array int), _row: int, _col: int, width: int -> _/eax: int { - # handle repeating columns of trees - var dummy/eax: int <- copy 0 - var col/edx: int <- copy 0 - dummy, col <- integer-divide _col, width - # compute index - var index/eax: int <- copy _row - index <- multiply width - index <- add col - # look up array - var arr/esi: (addr array int) <- copy _arr - var src/eax: (addr int) <- index arr, index - return *src -} diff --git a/apps/advent2020/3b.mu b/apps/advent2020/3b.mu deleted file mode 100644 index fcc9261a..00000000 --- a/apps/advent2020/3b.mu +++ /dev/null @@ -1,137 +0,0 @@ -# https://adventofcode.com/2020/day/3 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/3a.mu -# $ ./a.elf < input -# -# You'll need to register to download the 'input' file for yourself. - -fn main -> _/ebx: int { - # represent trees in a 2D array of ints - # wasteful since each tree is just one bit - var trees-storage: (array int 0x2800) # 10k ints - var trees/esi: (addr array int) <- address trees-storage - var trees-length/ecx: int <- copy 0 - var num-rows: int - var width: int - # phase 1: parse each row of trees from stdin - { - var line-storage: (stream byte 0x40) # 64 bytes - var line/edx: (addr stream byte) <- address line-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-!= - # wastefully recompute width on every line - # zero error-checking; we assume input lines are all equally long - copy-to width, 0 - # turn each byte into a tree and append it - $main:line-loop: { - var done?/eax: boolean <- stream-empty? line - compare done?, 0/false - break-if-!= -#? print-int32-decimal 0, num-rows -#? print-string 0, " " -#? print-int32-decimal 0, width -#? print-string 0, "\n" - var dest/ebx: (addr int) <- index trees, trees-length - var c/eax: byte <- read-byte line - # newline comes only at end of line - compare c, 0xa/newline - break-if-= - # '#' = tree - compare c, 0x23/hash - { - break-if-!= - copy-to *dest, 1 - } - # anything else = no tree - { - break-if-= - copy-to *dest, 0 - } - increment width - trees-length <- increment - loop - } - increment num-rows - loop - } - } - # phase 2: compute - var product/edi: int <- copy 1 - var result/eax: int <- num-trees-hit trees, width, num-rows, 1, 1 - print-int32-decimal 0, result - print-string 0, " x " - product <- multiply result - var result/eax: int <- num-trees-hit trees, width, num-rows, 3, 1 - print-int32-decimal 0, result - print-string 0, " x " - product <- multiply result - var result/eax: int <- num-trees-hit trees, width, num-rows, 5, 1 - print-int32-decimal 0, result - print-string 0, " x " - product <- multiply result - var result/eax: int <- num-trees-hit trees, width, num-rows, 7, 1 - print-int32-decimal 0, result - print-string 0, " x " - product <- multiply result - var result/eax: int <- num-trees-hit trees, width, num-rows, 1, 2 - print-int32-decimal 0, result - print-string 0, " = " - product <- multiply result - print-int32-hex 0, product - print-string 0, "\n" - return 0 -} - -fn num-trees-hit trees: (addr array int), width: int, num-rows: int, right: int, down: int -> _/eax: int { -#? print-string 0, "== " -#? print-int32-decimal 0, right -#? print-string 0, " " -#? print-int32-decimal 0, down -#? print-string 0, "\n" - var row/ecx: int <- copy 0 - var col/edx: int <- copy 0 - var num-trees-hit/edi: int <- copy 0 - { - compare row, num-rows - break-if->= -#? print-int32-decimal 0, col -#? print-string 0, "\n" - var curr/eax: int <- index2d trees, row, col, width - compare curr, 0 - { - break-if-= - num-trees-hit <- increment - } - col <- add right - row <- add down - loop - } - return num-trees-hit -} - -fn index2d _arr: (addr array int), _row: int, _col: int, width: int -> _/eax: int { - # handle repeating columns of trees - var dummy/eax: int <- copy 0 - var col/edx: int <- copy 0 - dummy, col <- integer-divide _col, width -#? print-string 0, " " -#? print-int32-decimal 0, col -#? print-string 0, "\n" - # compute index - var index/eax: int <- copy _row - index <- multiply width - index <- add col - # look up array - var arr/esi: (addr array int) <- copy _arr - var src/eax: (addr int) <- index arr, index - return *src -} diff --git a/apps/advent2020/4a.mu b/apps/advent2020/4a.mu deleted file mode 100644 index e645da24..00000000 --- a/apps/advent2020/4a.mu +++ /dev/null @@ -1,75 +0,0 @@ -# https://adventofcode.com/2020/day/4 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/4a.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 slice-storage: slice - var slice/edx: (addr slice) <- address 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: { - next-word line, slice - var done?/eax: boolean <- slice-empty? slice - compare done?, 0/false - break-if-!= - print-string 0, " " - print-slice-to-real-screen slice - # treat cid as optional - var optional?/eax: boolean <- slice-starts-with? 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 -} diff --git a/apps/advent2020/4b.mu b/apps/advent2020/4b.mu deleted file mode 100644 index 1ab29456..00000000 --- a/apps/advent2020/4b.mu +++ /dev/null @@ -1,314 +0,0 @@ -# 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 cid?/eax: boolean <- slice-equal? key-slice, "cid" - compare cid?, 0/false - loop-if-!= - # increment field count - curr-passport-field-count <- increment - # - validate fields one by one, setting curr-passport-field-count to impossibly high value to signal invalid - # byr - { - var byr?/eax: boolean <- slice-equal? key-slice, "byr" - compare byr?, 0/false - break-if-= - # 1920 <= byr <= 2002 - var byr/eax: int <- parse-decimal-int-from-slice val-slice - compare byr, 0x780 # 1920 - { - break-if->= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - compare byr, 0x7d2 # 2002 - { - break-if-<= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - } - # iyr - { - var iyr?/eax: boolean <- slice-equal? key-slice, "iyr" - compare iyr?, 0/false - break-if-= - # 2010 <= iyr <= 2020 - var iyr/eax: int <- parse-decimal-int-from-slice val-slice - compare iyr, 0x7da # 2010 - { - break-if->= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - compare iyr, 0x7e4 # 2020 - { - break-if-<= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - } - # eyr - { - var eyr?/eax: boolean <- slice-equal? key-slice, "eyr" - compare eyr?, 0/false - break-if-= - # 2020 <= eyr <= 2030 - var eyr/eax: int <- parse-decimal-int-from-slice val-slice - compare eyr, 0x7e4 # 2020 - { - break-if->= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - compare eyr, 0x7ee # 2030 - { - break-if-<= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - } - # hgt - { - var hgt?/eax: boolean <- slice-equal? key-slice, "hgt" - compare hgt?, 0/false - break-if-= - # convert val - var s: (handle array byte) - var s2/eax: (addr handle array byte) <- address s - _slice-to-string val-slice, s2 - var s3/eax: (addr array byte) <- lookup *s2 - var s4/ebx: (addr array byte) <- copy s3 - # check suffix - var start/edx: int <- length s4 - start <- subtract 2 # luckily both 'in' and 'cm' have the same length - { - var suffix-h: (handle array byte) - var suffix-ah/ecx: (addr handle array byte) <- address suffix-h - substring s4, start, 2, suffix-ah - var suffix/eax: (addr array byte) <- lookup *suffix-ah - { - var match?/eax: boolean <- string-equal? suffix, "in" - compare match?, 0/false - break-if-= - # if suffix is "in", 59 <= val <= 96 - var num-h: (handle array byte) - var num-ah/ecx: (addr handle array byte) <- address num-h - substring s4, 0, start, num-ah - var num/eax: (addr array byte) <- lookup *num-ah - var val/eax: int <- parse-decimal-int num - compare val, 0x3b # 59 - { - break-if->= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - compare val, 0x60 # 96 - { - break-if-<= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - loop $main:word-loop - } - { - var match?/eax: boolean <- string-equal? suffix, "cm" - compare match?, 0/false - break-if-= - # if suffix is "cm", 150 <= val <= 193 - var num-h: (handle array byte) - var num-ah/ecx: (addr handle array byte) <- address num-h - substring s4, 0, start, num-ah - var num/eax: (addr array byte) <- lookup *num-ah - var val/eax: int <- parse-decimal-int num - compare val, 0x96 # 150 - { - break-if->= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - compare val, 0xc1 # 193 - { - break-if-<= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - loop $main:word-loop - } - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - loop $main:word-loop - } - } - # hcl - { - var hcl?/eax: boolean <- slice-equal? key-slice, "hcl" - compare hcl?, 0/false - break-if-= - # convert val - var s: (handle array byte) - var s2/eax: (addr handle array byte) <- address s - _slice-to-string val-slice, s2 - var s3/eax: (addr array byte) <- lookup *s2 - # check length - var len/ebx: int <- length s3 - compare len, 7 - { - break-if-= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - loop $main:word-loop - } - # check first byte - { - var c/eax: (addr byte) <- index s3, 0 - var c2/eax: byte <- copy-byte *c - compare c2, 0x23/hash - break-if-= - print-string 0, "invalid2\n" - curr-passport-field-count <- copy 8 - loop $main:word-loop - } - # check remaining bytes - var i/ebx: int <- copy 1 # skip 0 - { - compare i, 7 - break-if->= - var c/eax: (addr byte) <- index s3, i - { - var c2/eax: byte <- copy-byte *c - var valid?/eax: boolean <- is-hex-digit? c2 - compare valid?, 0 - loop-if-= $main:word-loop - } - i <- increment - loop - } - } - # ecl - { - var ecl?/eax: boolean <- slice-equal? key-slice, "ecl" - compare ecl?, 0/false - break-if-= - var amb?/eax: boolean <- slice-equal? val-slice, "amb" - compare amb?, 0/false - loop-if-!= $main:word-loop - var blu?/eax: boolean <- slice-equal? val-slice, "blu" - compare blu?, 0/false - loop-if-!= $main:word-loop - var brn?/eax: boolean <- slice-equal? val-slice, "brn" - compare brn?, 0/false - loop-if-!= $main:word-loop - var gry?/eax: boolean <- slice-equal? val-slice, "gry" - compare gry?, 0/false - loop-if-!= $main:word-loop - var grn?/eax: boolean <- slice-equal? val-slice, "grn" - compare grn?, 0/false - loop-if-!= $main:word-loop - var hzl?/eax: boolean <- slice-equal? val-slice, "hzl" - compare hzl?, 0/false - loop-if-!= $main:word-loop - var oth?/eax: boolean <- slice-equal? val-slice, "oth" - compare oth?, 0/false - loop-if-!= $main:word-loop - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - # pid - { - var pid?/eax: boolean <- slice-equal? key-slice, "pid" - compare pid?, 0/false - break-if-= - # convert val - var s: (handle array byte) - var s2/eax: (addr handle array byte) <- address s - _slice-to-string val-slice, s2 - var s3/eax: (addr array byte) <- lookup *s2 - # check length - var len/eax: int <- length s3 - compare len, 9 - { - break-if-= - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - loop $main:word-loop - } - # check valid decimal int - # parse-decimal-int-from-slice currently returns 0 on invalid parse, - # which isn't ideal but suffices for our purposes - var val/eax: int <- parse-decimal-int-from-slice val-slice - compare val, 0 - { - break-if-> - print-string 0, "invalid\n" - curr-passport-field-count <- copy 8 - } - } - 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 -} diff --git a/apps/advent2020/5a.mu b/apps/advent2020/5a.mu deleted file mode 100644 index 5a456608..00000000 --- a/apps/advent2020/5a.mu +++ /dev/null @@ -1,79 +0,0 @@ -# https://adventofcode.com/2020/day/5 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/5a.mu -# $ ./a.elf < input -# -# You'll need to register to download the 'input' file for yourself. - -fn main -> _/ebx: int { - var line-storage: (stream byte 0x10) # 16 bytes is enough - var line/edx: (addr stream byte) <- address line-storage - var max-seat-id/edi: int <- copy 0 - { - # read line from stdin - clear-stream line - read-line-from-real-keyboard line - print-stream-to-real-screen line - # if line is empty (not even a newline), quit - var done?/eax: boolean <- stream-empty? line - compare done?, 0/false - break-if-!= - # process line - var seat-id/eax: int <- convert-from-binary line - compare seat-id, max-seat-id - { - break-if-<= - max-seat-id <- copy seat-id - } - loop - } - print-int32-decimal 0, max-seat-id - print-string 0, "\n" - return 0 -} - -fn convert-from-binary in: (addr stream byte) -> _/eax: int { - var result/edi: int <- copy 0 - var i/ecx: int <- copy 9 # loop counter and also exponent - { - compare i, 0 - break-if-< - var c/eax: byte <- read-byte in -#? print-string 0, "char: " -#? { -#? var c2/eax: int <- copy c -#? print-int32-hex 0, c2 -#? } -#? print-string 0, "\n" - var bit/edx: int <- copy 0 - { - compare c, 0x42/B - break-if-!= - bit <- copy 1 - } - { - compare c, 0x52/R - break-if-!= - bit <- copy 1 - } -#? print-string 0, "bit: " -#? print-int32-decimal 0, bit -#? print-string 0, "\n" - var bit-value/eax: int <- repeated-shift-left bit, i -#? print-string 0, "bit value: " -#? print-int32-decimal 0, bit-value -#? print-string 0, "\n" - result <- add bit-value -#? print-string 0, "result: " -#? print-int32-decimal 0, result -#? print-string 0, "\n" - i <- decrement - loop - } - print-int32-decimal 0, result - print-string 0, "\n" - return result -} diff --git a/apps/advent2020/5b.mu b/apps/advent2020/5b.mu deleted file mode 100644 index fbc0d618..00000000 --- a/apps/advent2020/5b.mu +++ /dev/null @@ -1,81 +0,0 @@ -# https://adventofcode.com/2020/day/5 -# -# To run (on Linux): -# $ git clone https://github.com/akkartik/mu -# $ cd mu -# $ ./translate_mu apps/advent2020/5b.mu -# $ ./a.elf < input -# -# You'll need to register to download the 'input' file for yourself. - -fn main -> _/ebx: int { - var pass-storage: (array int 0x400) # 1k ints - var pass/esi: (addr array int) <- address pass-storage - # phase 1: populate pass array - var line-storage: (stream byte 0x10) # 16 bytes is enough - var line/edx: (addr stream byte) <- address line-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-!= - # process line - var seat-id/eax: int <- convert-from-binary line - var dest/eax: (addr int) <- index pass, seat-id - copy-to *dest, 1 - loop - } - # phase 2: skip empty seats - var i/eax: int <- copy 0 - { - compare i, 0x400 - break-if->= - var src/ecx: (addr int) <- index pass, i - compare *src, 0 - break-if-!= - i <- increment - loop - } - # phase 3: skip non-empty seats - { - compare i, 0x400 - break-if->= - var src/ecx: (addr int) <- index pass, i - compare *src, 0 - break-if-= - i <- increment - loop - } - print-int32-decimal 0, i - print-string 0, "\n" - return 0 -} - -fn convert-from-binary in: (addr stream byte) -> _/eax: int { - var result/edi: int <- copy 0 - var i/ecx: int <- copy 9 # loop counter and also exponent - { - compare i, 0 - break-if-< - var c/eax: byte <- read-byte in - var bit/edx: int <- copy 0 - { - compare c, 0x42/B - break-if-!= - bit <- copy 1 - } - { - compare c, 0x52/R - break-if-!= - bit <- copy 1 - } - var bit-value/eax: int <- repeated-shift-left bit, i - result <- add bit-value - i <- decrement - loop - } - return result -} diff --git a/apps/advent2020/vimrc.vim b/apps/advent2020/vimrc.vim deleted file mode 100644 index 348fe364..00000000 --- a/apps/advent2020/vimrc.vim +++ /dev/null @@ -1,2 +0,0 @@ -" when opening files in this directory, load vimrc from cwd (top-level) -source vimrc.vim |