From 3dda906d2457a6ff577d6fa34274f43529a87dbe Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 4 Dec 2020 23:57:35 -0800 Subject: 7335 --- html/apps/advent2020/4a.mu.html | 137 +++++++++++++++ html/apps/advent2020/4b.mu.html | 376 ++++++++++++++++++++++++++++++++++++++++ html/apps/advent2020/5a.mu.html | 142 +++++++++++++++ html/apps/advent2020/5b.mu.html | 143 +++++++++++++++ 4 files changed, 798 insertions(+) create mode 100644 html/apps/advent2020/4a.mu.html create mode 100644 html/apps/advent2020/4b.mu.html create mode 100644 html/apps/advent2020/5a.mu.html create mode 100644 html/apps/advent2020/5b.mu.html (limited to 'html/apps/advent2020') diff --git a/html/apps/advent2020/4a.mu.html b/html/apps/advent2020/4a.mu.html new file mode 100644 index 00000000..95dd953a --- /dev/null +++ b/html/apps/advent2020/4a.mu.html @@ -0,0 +1,137 @@ + + + + +Mu - apps/advent2020/4a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/apps/advent2020/4a.mu +
+ 1 # https://adventofcode.com/2020/day/4
+ 2 #
+ 3 # To run (on Linux):
+ 4 #   $ git clone https://github.com/akkartik/mu
+ 5 #   $ cd mu
+ 6 #   $ ./translate_mu apps/advent2020/4a.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 curr-passport-field-count/esi: int <- copy 0
+13   var valid-passport-count/edi: int <- copy 0
+14   var line-storage: (stream byte 0x100)  # 256 bytes
+15   var line/ecx: (addr stream byte) <- address line-storage
+16   var slice-storage: slice
+17   var slice/edx: (addr slice) <- address slice-storage
+18   $main:line-loop: {
+19     # read line from stdin
+20     clear-stream line
+21     read-line-from-real-keyboard line
+22     # if line is empty (not even a newline), quit
+23     var done?/eax: boolean <- stream-empty? line
+24     compare done?, 0  # false
+25     break-if-!=
+26     print-stream-to-real-screen line
+27     # if line has just a newline, process passport
+28     skip-chars-matching-whitespace line
+29     var new-passport?/eax: boolean <- stream-empty? line
+30     {
+31       compare new-passport?, 0  # false
+32       break-if-=
+33       compare curr-passport-field-count, 7
+34       {
+35         break-if-!=
+36         valid-passport-count <- increment
+37         print-string 0, "=> "
+38         print-int32-decimal 0, valid-passport-count
+39         print-string 0, "\n"
+40       }
+41       curr-passport-field-count <- copy 0
+42       loop $main:line-loop
+43     }
+44     $main:word-loop: {
+45       next-word line, slice
+46       var done?/eax: boolean <- slice-empty? slice
+47       compare done?, 0  # false
+48       break-if-!=
+49       print-string 0, "  "
+50       print-slice-to-real-screen slice
+51       # treat cid as optional
+52       var optional?/eax: boolean <- slice-starts-with? slice, "cid:"
+53       compare optional?, 0  # false
+54       {
+55         break-if-!=
+56         # otherwise assume there are no invalid fields and no duplicate fields
+57         curr-passport-field-count <- increment
+58         print-string 0, " => "
+59         print-int32-decimal 0, curr-passport-field-count
+60       }
+61       print-string 0, "\n"
+62       loop
+63     }
+64     loop
+65   }
+66   # process final passport
+67   compare curr-passport-field-count, 7
+68   {
+69     break-if-!=
+70     valid-passport-count <- increment
+71   }
+72   print-int32-decimal 0, valid-passport-count
+73   print-string 0, "\n"
+74   return 0
+75 }
+
+ + + diff --git a/html/apps/advent2020/4b.mu.html b/html/apps/advent2020/4b.mu.html new file mode 100644 index 00000000..379fa0a5 --- /dev/null +++ b/html/apps/advent2020/4b.mu.html @@ -0,0 +1,376 @@ + + + + +Mu - apps/advent2020/4b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/apps/advent2020/4b.mu +
+  1 # https://adventofcode.com/2020/day/4
+  2 #
+  3 # To run (on Linux):
+  4 #   $ git clone https://github.com/akkartik/mu
+  5 #   $ cd mu
+  6 #   $ ./translate_mu apps/advent2020/4b.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 curr-passport-field-count/esi: int <- copy 0
+ 13   var valid-passport-count/edi: int <- copy 0
+ 14   var line-storage: (stream byte 0x100)  # 256 bytes
+ 15   var line/ecx: (addr stream byte) <- address line-storage
+ 16   var key-slice-storage: slice
+ 17   var key-slice/edx: (addr slice) <- address key-slice-storage
+ 18   var val-slice-storage: slice
+ 19   var val-slice/ebx: (addr slice) <- address val-slice-storage
+ 20   $main:line-loop: {
+ 21     # read line from stdin
+ 22     clear-stream line
+ 23     read-line-from-real-keyboard line
+ 24     # if line is empty (not even a newline), quit
+ 25     var done?/eax: boolean <- stream-empty? line
+ 26     compare done?, 0  # false
+ 27     break-if-!=
+ 28     print-stream-to-real-screen line
+ 29     # if line has just a newline, process passport
+ 30     skip-chars-matching-whitespace line
+ 31     var new-passport?/eax: boolean <- stream-empty? line
+ 32     {
+ 33       compare new-passport?, 0  # false
+ 34       break-if-=
+ 35       compare curr-passport-field-count, 7
+ 36       {
+ 37         break-if-!=
+ 38         valid-passport-count <- increment
+ 39         print-string 0, "=> "
+ 40         print-int32-decimal 0, valid-passport-count
+ 41         print-string 0, "\n"
+ 42       }
+ 43       curr-passport-field-count <- copy 0
+ 44       loop $main:line-loop
+ 45     }
+ 46     $main:word-loop: {
+ 47       skip-chars-matching-whitespace line
+ 48       var done?/eax: boolean <- stream-empty? line
+ 49       compare done?, 0  # false
+ 50       break-if-!=
+ 51       next-token line, 0x3a, key-slice  # ':'
+ 52       var dummy/eax: byte <- read-byte line  # skip ':'
+ 53       next-raw-word line, val-slice
+ 54       print-slice-to-real-screen key-slice
+ 55       print-string 0, " : "
+ 56       print-slice-to-real-screen val-slice
+ 57       print-string 0, "\n"
+ 58       # treat cid as optional
+ 59       var cid?/eax: boolean <- slice-equal? key-slice, "cid"
+ 60       compare cid?, 0  # false
+ 61       loop-if-!=
+ 62       # increment field count
+ 63       curr-passport-field-count <- increment
+ 64       # - validate fields one by one, setting curr-passport-field-count to impossibly high value to signal invalid
+ 65       # byr
+ 66       {
+ 67         var byr?/eax: boolean <- slice-equal? key-slice, "byr"
+ 68         compare byr?, 0  # false
+ 69         break-if-=
+ 70         # 1920 <= byr <= 2002
+ 71         var byr/eax: int <- parse-decimal-int-from-slice val-slice
+ 72         compare byr, 0x780  # 1920
+ 73         {
+ 74           break-if->=
+ 75           print-string 0, "invalid\n"
+ 76           curr-passport-field-count <- copy 8
+ 77         }
+ 78         compare byr, 0x7d2  # 2002
+ 79         {
+ 80           break-if-<=
+ 81           print-string 0, "invalid\n"
+ 82           curr-passport-field-count <- copy 8
+ 83         }
+ 84       }
+ 85       # iyr
+ 86       {
+ 87         var iyr?/eax: boolean <- slice-equal? key-slice, "iyr"
+ 88         compare iyr?, 0  # false
+ 89         break-if-=
+ 90         # 2010 <= iyr <= 2020
+ 91         var iyr/eax: int <- parse-decimal-int-from-slice val-slice
+ 92         compare iyr, 0x7da  # 2010
+ 93         {
+ 94           break-if->=
+ 95           print-string 0, "invalid\n"
+ 96           curr-passport-field-count <- copy 8
+ 97         }
+ 98         compare iyr, 0x7e4  # 2020
+ 99         {
+100           break-if-<=
+101           print-string 0, "invalid\n"
+102           curr-passport-field-count <- copy 8
+103         }
+104       }
+105       # eyr
+106       {
+107         var eyr?/eax: boolean <- slice-equal? key-slice, "eyr"
+108         compare eyr?, 0  # false
+109         break-if-=
+110         # 2020 <= eyr <= 2030
+111         var eyr/eax: int <- parse-decimal-int-from-slice val-slice
+112         compare eyr, 0x7e4  # 2020
+113         {
+114           break-if->=
+115           print-string 0, "invalid\n"
+116           curr-passport-field-count <- copy 8
+117         }
+118         compare eyr, 0x7ee  # 2030
+119         {
+120           break-if-<=
+121           print-string 0, "invalid\n"
+122           curr-passport-field-count <- copy 8
+123         }
+124       }
+125       # hgt
+126       {
+127         var hgt?/eax: boolean <- slice-equal? key-slice, "hgt"
+128         compare hgt?, 0  # false
+129         break-if-=
+130         # convert val
+131         var s: (handle array byte)
+132         var s2/eax: (addr handle array byte) <- address s
+133         _slice-to-string val-slice, s2
+134         var s3/eax: (addr array byte) <- lookup *s2
+135         var s4/ebx: (addr array byte) <- copy s3
+136         # check suffix
+137         var start/edx: int <- length s4
+138         start <- subtract 2  # luckily both 'in' and 'cm' have the same length
+139         {
+140           var suffix-h: (handle array byte)
+141           var suffix-ah/ecx: (addr handle array byte) <- address suffix-h
+142           substring s4, start, 2, suffix-ah
+143           var suffix/eax: (addr array byte) <- lookup *suffix-ah
+144           {
+145             var match?/eax: boolean <- string-equal? suffix, "in"
+146             compare match?, 0  # false
+147             break-if-=
+148             # if suffix is "in", 59 <= val <= 96
+149             var num-h: (handle array byte)
+150             var num-ah/ecx: (addr handle array byte) <- address num-h
+151             substring s4, 0, start, num-ah
+152             var num/eax: (addr array byte) <- lookup *num-ah
+153             var val/eax: int <- parse-decimal-int num
+154             compare val, 0x3b  # 59
+155             {
+156               break-if->=
+157           print-string 0, "invalid\n"
+158               curr-passport-field-count <- copy 8
+159             }
+160             compare val, 0x60  # 96
+161             {
+162               break-if-<=
+163           print-string 0, "invalid\n"
+164               curr-passport-field-count <- copy 8
+165             }
+166             loop $main:word-loop
+167           }
+168           {
+169             var match?/eax: boolean <- string-equal? suffix, "cm"
+170             compare match?, 0  # false
+171             break-if-=
+172             # if suffix is "cm", 150 <= val <= 193
+173             var num-h: (handle array byte)
+174             var num-ah/ecx: (addr handle array byte) <- address num-h
+175             substring s4, 0, start, num-ah
+176             var num/eax: (addr array byte) <- lookup *num-ah
+177             var val/eax: int <- parse-decimal-int num
+178             compare val, 0x96  # 150
+179             {
+180               break-if->=
+181           print-string 0, "invalid\n"
+182               curr-passport-field-count <- copy 8
+183             }
+184             compare val, 0xc1  # 193
+185             {
+186               break-if-<=
+187           print-string 0, "invalid\n"
+188               curr-passport-field-count <- copy 8
+189             }
+190             loop $main:word-loop
+191           }
+192           print-string 0, "invalid\n"
+193           curr-passport-field-count <- copy 8
+194           loop $main:word-loop
+195         }
+196       }
+197       # hcl
+198       {
+199         var hcl?/eax: boolean <- slice-equal? key-slice, "hcl"
+200         compare hcl?, 0  # false
+201         break-if-=
+202         # convert val
+203         var s: (handle array byte)
+204         var s2/eax: (addr handle array byte) <- address s
+205         _slice-to-string val-slice, s2
+206         var s3/eax: (addr array byte) <- lookup *s2
+207         # check length
+208         var len/ebx: int <- length s3
+209         compare len, 7
+210         {
+211           break-if-=
+212           print-string 0, "invalid\n"
+213           curr-passport-field-count <- copy 8
+214           loop $main:word-loop
+215         }
+216         # check first byte
+217         {
+218           var c/eax: (addr byte) <- index s3, 0
+219           var c2/eax: byte <- copy-byte *c
+220           compare c2, 0x23  # '#'
+221           break-if-=
+222           print-string 0, "invalid2\n"
+223           curr-passport-field-count <- copy 8
+224           loop $main:word-loop
+225         }
+226         # check remaining bytes
+227         var i/ebx: int <- copy 1  # skip 0
+228         {
+229           compare i, 7
+230           break-if->=
+231           var c/eax: (addr byte) <- index s3, i
+232           {
+233             var c2/eax: byte <- copy-byte *c
+234             var valid?/eax: boolean <- is-hex-digit? c2
+235             compare valid?, 0
+236             loop-if-= $main:word-loop
+237           }
+238           i <- increment
+239           loop
+240         }
+241       }
+242       # ecl
+243       {
+244         var ecl?/eax: boolean <- slice-equal? key-slice, "ecl"
+245         compare ecl?, 0  # false
+246         break-if-=
+247         var amb?/eax: boolean <- slice-equal? val-slice, "amb"
+248         compare amb?, 0  # false
+249         loop-if-!= $main:word-loop
+250         var blu?/eax: boolean <- slice-equal? val-slice, "blu"
+251         compare blu?, 0  # false
+252         loop-if-!= $main:word-loop
+253         var brn?/eax: boolean <- slice-equal? val-slice, "brn"
+254         compare brn?, 0  # false
+255         loop-if-!= $main:word-loop
+256         var gry?/eax: boolean <- slice-equal? val-slice, "gry"
+257         compare gry?, 0  # false
+258         loop-if-!= $main:word-loop
+259         var grn?/eax: boolean <- slice-equal? val-slice, "grn"
+260         compare grn?, 0  # false
+261         loop-if-!= $main:word-loop
+262         var hzl?/eax: boolean <- slice-equal? val-slice, "hzl"
+263         compare hzl?, 0  # false
+264         loop-if-!= $main:word-loop
+265         var oth?/eax: boolean <- slice-equal? val-slice, "oth"
+266         compare oth?, 0  # false
+267         loop-if-!= $main:word-loop
+268         print-string 0, "invalid\n"
+269         curr-passport-field-count <- copy 8
+270       }
+271       # pid
+272       {
+273         var pid?/eax: boolean <- slice-equal? key-slice, "pid"
+274         compare pid?, 0  # false
+275         break-if-=
+276         # convert val
+277         var s: (handle array byte)
+278         var s2/eax: (addr handle array byte) <- address s
+279         _slice-to-string val-slice, s2
+280         var s3/eax: (addr array byte) <- lookup *s2
+281         # check length
+282         var len/eax: int <- length s3
+283         compare len, 9
+284         {
+285           break-if-=
+286           print-string 0, "invalid\n"
+287           curr-passport-field-count <- copy 8
+288           loop $main:word-loop
+289         }
+290         # check valid decimal int
+291         # parse-decimal-int-from-slice currently returns 0 on invalid parse,
+292         # which isn't ideal but suffices for our purposes
+293         var val/eax: int <- parse-decimal-int-from-slice val-slice
+294         compare val, 0
+295         {
+296           break-if->
+297           print-string 0, "invalid\n"
+298           curr-passport-field-count <- copy 8
+299         }
+300       }
+301       loop
+302     }
+303     loop
+304   }
+305   # process final passport
+306   compare curr-passport-field-count, 7
+307   {
+308     break-if-!=
+309     valid-passport-count <- increment
+310   }
+311   print-int32-decimal 0, valid-passport-count
+312   print-string 0, "\n"
+313   return 0
+314 }
+
+ + + diff --git a/html/apps/advent2020/5a.mu.html b/html/apps/advent2020/5a.mu.html new file mode 100644 index 00000000..d45c6e54 --- /dev/null +++ b/html/apps/advent2020/5a.mu.html @@ -0,0 +1,142 @@ + + + + +Mu - apps/advent2020/5a.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/apps/advent2020/5a.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_mu apps/advent2020/5a.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 line-storage: (stream byte 0x10)  # 16 bytes is enough
+13   var line/edx: (addr stream byte) <- address line-storage
+14   var max-seat-id/edi: int <- copy 0
+15   {
+16     # read line from stdin
+17     clear-stream line
+18     read-line-from-real-keyboard line
+19     print-stream-to-real-screen line
+20     # if line is empty (not even a newline), quit
+21     var done?/eax: boolean <- stream-empty? line
+22     compare done?, 0  # false
+23     break-if-!=
+24     # process line
+25     var seat-id/eax: int <- convert-from-binary line
+26     compare seat-id, max-seat-id
+27     {
+28       break-if-<=
+29       max-seat-id <- copy seat-id
+30     }
+31     loop
+32   }
+33   print-int32-decimal 0, max-seat-id
+34   print-string 0, "\n"
+35   return 0
+36 }
+37 
+38 fn convert-from-binary in: (addr stream byte) -> _/eax: int {
+39   var result/edi: int <- copy 0
+40   var i/ecx: int <- copy 9  # loop counter and also exponent
+41   {
+42     compare i, 0
+43     break-if-<
+44     var c/eax: byte <- read-byte in
+45 #?     print-string 0, "char: "
+46 #?     {
+47 #?       var c2/eax: int <- copy c
+48 #?       print-int32-hex 0, c2
+49 #?     }
+50 #?     print-string 0, "\n"
+51     var bit/edx: int <- copy 0
+52     {
+53       compare c, 0x42  # 'B'
+54       break-if-!=
+55       bit <- copy 1
+56     }
+57     {
+58       compare c, 0x52  # 'R'
+59       break-if-!=
+60       bit <- copy 1
+61     }
+62 #?     print-string 0, "bit: "
+63 #?     print-int32-decimal 0, bit
+64 #?     print-string 0, "\n"
+65     var bit-value/eax: int <- repeated-shift-left bit, i
+66 #?     print-string 0, "bit value: "
+67 #?     print-int32-decimal 0, bit-value
+68 #?     print-string 0, "\n"
+69     result <- add bit-value
+70 #?     print-string 0, "result: "
+71 #?     print-int32-decimal 0, result
+72 #?     print-string 0, "\n"
+73     i <- decrement
+74     loop
+75   }
+76   print-int32-decimal 0, result
+77   print-string 0, "\n"
+78   return result
+79 }
+
+ + + diff --git a/html/apps/advent2020/5b.mu.html b/html/apps/advent2020/5b.mu.html new file mode 100644 index 00000000..372d83b3 --- /dev/null +++ b/html/apps/advent2020/5b.mu.html @@ -0,0 +1,143 @@ + + + + +Mu - apps/advent2020/5b.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/apps/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_mu apps/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 }
+
+ + + -- cgit 1.4.1-2-gfad0