about summary refs log tree commit diff stats
path: root/linux/advent2020
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-07-16 08:09:42 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-07-16 08:28:56 -0700
commit44d26b77c45668c9b0c99894a4294cec004361fe (patch)
tree68a5dcd4971873efd4ce184e9bf9a531c2161813 /linux/advent2020
parentac45f097153afd3a89f43886e4124c5b2c26b98a (diff)
downloadmu-44d26b77c45668c9b0c99894a4294cec004361fe.tar.gz
.
Diffstat (limited to 'linux/advent2020')
-rw-r--r--linux/advent2020/1a.mu97
-rw-r--r--linux/advent2020/1b.mu113
-rw-r--r--linux/advent2020/2a.mu92
-rw-r--r--linux/advent2020/2b.mu122
-rw-r--r--linux/advent2020/3a.mu107
-rw-r--r--linux/advent2020/3b.mu137
-rw-r--r--linux/advent2020/4a.mu75
-rw-r--r--linux/advent2020/4b.mu314
-rw-r--r--linux/advent2020/5a.mu79
-rw-r--r--linux/advent2020/5b.mu81
-rw-r--r--linux/advent2020/vimrc.vim2
11 files changed, 0 insertions, 1219 deletions
diff --git a/linux/advent2020/1a.mu b/linux/advent2020/1a.mu
deleted file mode 100644
index 886329f1..00000000
--- a/linux/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 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/linux/advent2020/1b.mu b/linux/advent2020/1b.mu
deleted file mode 100644
index bfdbe47c..00000000
--- a/linux/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 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/linux/advent2020/2a.mu b/linux/advent2020/2a.mu
deleted file mode 100644
index ce678eb8..00000000
--- a/linux/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 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 valid?/eax: boolean <- valid? start, end, letter, line
-    compare 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 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/linux/advent2020/2b.mu b/linux/advent2020/2b.mu
deleted file mode 100644
index 121e9dfa..00000000
--- a/linux/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 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 valid?/eax: boolean <- valid? pos1, pos2, letter, line
-    compare 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 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/linux/advent2020/3a.mu b/linux/advent2020/3a.mu
deleted file mode 100644
index d2dfc15e..00000000
--- a/linux/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 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/linux/advent2020/3b.mu b/linux/advent2020/3b.mu
deleted file mode 100644
index 7db91eea..00000000
--- a/linux/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 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/linux/advent2020/4a.mu b/linux/advent2020/4a.mu
deleted file mode 100644
index 1b16712d..00000000
--- a/linux/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 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/linux/advent2020/4b.mu b/linux/advent2020/4b.mu
deleted file mode 100644
index 2dc6c6a2..00000000
--- a/linux/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 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 <- 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/linux/advent2020/5a.mu b/linux/advent2020/5a.mu
deleted file mode 100644
index 19d342c4..00000000
--- a/linux/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 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/linux/advent2020/5b.mu b/linux/advent2020/5b.mu
deleted file mode 100644
index e6a3520f..00000000
--- a/linux/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 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/linux/advent2020/vimrc.vim b/linux/advent2020/vimrc.vim
deleted file mode 100644
index 348fe364..00000000
--- a/linux/advent2020/vimrc.vim
+++ /dev/null
@@ -1,2 +0,0 @@
-" when opening files in this directory, load vimrc from cwd (top-level)
-source vimrc.vim