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

      1 # https://adventofcode.com/2020/day/1
      2 #
      3 # To run (on Linux):
      4 #   $ git clone https://github.com/akkartik/mu
      5 #   $ cd mu
      6 #   $ ./translate advent2020/1b.mu
      7 #   $ ./a.elf < input
      8 #   found
      9 #   143 407 1470
     10 #   85555470
     11 #
     12 # You'll need to register to download the 'input' file for yourself.
     13
     14 fn main -> _/ebx: int {
     15   # data structure
     16   var numbers-storage: (array int 0x100)  # 256 ints
     17   var numbers/esi: (addr array int) <- address numbers-storage
     18   var numbers-index/ecx: int <- copy 0
     19   # phase 1: parse each line from stdin and add it to numbers
     20   {
     21     var line-storage: (stream byte 0x100)  # 256 bytes
     22     var line/edx: (addr stream byte) <- address line-storage
     23     {
     24 #?       print-string 0, "== iter\n"
     25       # read line from stdin
     26       clear-stream line
     27       read-line-from-real-keyboard line
     28       # if line is empty (not even a newline), quit
     29       var done?/eax: boolean <- stream-empty? line
     30       compare done?, 0/false
     31       break-if-!=
     32 #?       print-stream-to-real-screen line
     33       # convert line to int and append it to numbers
     34       var n/eax: int <- parse-decimal-int-from-stream line
     35 #?       print-int32-decimal 0, n
     36 #?       print-string 0, "\n"
     37       var dest/ebx: (addr int) <- index numbers, numbers-index
     38       copy-to *dest, n
     39       numbers-index <- increment
     40 #?       print-string 0, "== "
     41 #?       print-int32-decimal 0, numbers-index
     42 #?       print-string 0, "\n"
     43       loop
     44     }
     45   }
     46   # phase 2: for every pair of distinct numbers, check if the rest of the
     47   # array has 2020-it
     48   var i/edi: int <- copy 0
     49   {
     50     compare i, numbers-index
     51     break-if->=
     52     # for j from i+1 to end
     53     var j/edx: int <- copy i
     54     j <- increment
     55     {
     56       compare j, numbers-index
     57       break-if->=
     58       {
     59         compare i, j
     60         break-if-=
     61         var target/ebx: int <- copy 0x7e4  # 2020
     62         var src/edi: (addr int) <- index numbers, i
     63         target <- subtract *src
     64         var src2/ecx: (addr int) <- index numbers, j
     65         target <- subtract *src2
     66         {
     67           var found?/eax: boolean <- find-after numbers, j, target
     68           compare found?, 0/false
     69           break-if-=
     70           print-string 0, "found\n"
     71           print-int32-decimal 0, *src
     72           print-string 0, " "
     73           print-int32-decimal 0, *src2
     74           print-string 0, " "
     75           print-int32-decimal 0, target
     76           print-string 0, "\n"
     77           target <- multiply *src
     78           target <- multiply *src2
     79           print-int32-decimal 0, target
     80           print-string 0, "\n"
     81           return 0/success
     82         }
     83       }
     84       j <- increment
     85       loop
     86     }
     87     i <- increment
     88     loop
     89   }
     90   return 1/not-found
     91 }
     92
     93 fn find-after _numbers: (addr array int), start: int, _target: int -> _/eax: boolean {
     94   var numbers/esi: (addr array int) <- copy _numbers
     95   var target/edi: int <- copy _target
     96   var len/ecx: int <- length numbers
     97   var i/eax: int <- copy start
     98   i <- increment
     99   {
    100     compare i, len
    101     break-if->=
    102     var src/edx: (addr int) <- index numbers, i
    103     # if *src == target, return true
    104     compare *src, target
    105     {
    106       break-if-!=
    107       return 1/true
    108     }
    109     i <- increment
    110     loop
    111   }
    112   return 0/false
    113 }