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 }