https://github.com/akkartik/mu/blob/main/linux/advent2020/5b.mu

     1 # https://adventofcode.com/2020/day/5
     2 #
     3 # To run (on Linux):
     4 #   $ git clone https://github.com/akkartik/mu
     5 #   $ cd mu
     6 #   $ ./translate advent2020/5b.mu
     7 #   $ ./a.elf < input
     8 #
     9 # You'll need to register to download the 'input' file for yourself.
    10
    11 fn main -> _/ebx: int {
    12   var pass-storage: (array int 0x400)  # 1k ints
    13   var pass/esi: (addr array int) <- address pass-storage
    14   # phase 1: populate pass array
    15   var line-storage: (stream byte 0x10)  # 16 bytes is enough
    16   var line/edx: (addr stream byte) <- address line-storage
    17   {
    18     # read line from stdin
    19     clear-stream line
    20     read-line-from-real-keyboard line
    21     # if line is empty (not even a newline), quit
    22     var done?/eax: boolean <- stream-empty? line
    23     compare done?, 0/false
    24     break-if-!=
    25     # process line
    26     var seat-id/eax: int <- convert-from-binary line
    27     var dest/eax: (addr int) <- index pass, seat-id
    28     copy-to *dest, 1
    29     loop
    30   }
    31   # phase 2: skip empty seats
    32   var i/eax: int <- copy 0
    33   {
    34     compare i, 0x400
    35     break-if->=
    36     var src/ecx: (addr int) <- index pass, i
    37     compare *src, 0
    38     break-if-!=
    39     i <- increment
    40     loop
    41   }
    42   # phase 3: skip non-empty seats
    43   {
    44     compare i, 0x400
    45     break-if->=
    46     var src/ecx: (addr int) <- index pass, i
    47     compare *src, 0
    48     break-if-=
    49     i <- increment
    50     loop
    51   }
    52   print-int32-decimal 0, i
    53   print-string 0, "\n"
    54   return 0
    55 }
    56
    57 fn convert-from-binary in: (addr stream byte) -> _/eax: int {
    58   var result/edi: int <- copy 0
    59   var i/ecx: int <- copy 9  # loop counter and also exponent
    60   {
    61     compare i, 0
    62     break-if-<
    63     var c/eax: byte <- read-byte in
    64     var bit/edx: int <- copy 0
    65     {
    66       compare c, 0x42/B
    67       break-if-!=
    68       bit <- copy 1
    69     }
    70     {
    71       compare c, 0x52/R
    72       break-if-!=
    73       bit <- copy 1
    74     }
    75     var bit-value/eax: int <- repeated-shift-left bit, i
    76     result <- add bit-value
    77     i <- decrement
    78     loop
    79   }
    80   return result
    81 }