https://github.com/akkartik/mu/blob/main/linux/apps/advent2020/1a.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 apps/advent2020/1a.mu
 7 #   $ ./a.elf < input
 8 #   found
 9 #   1353 667
10 #   902451
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 each number in the array, check if 2020-it is in the rest of
47   # the array
48   var i/eax: int <- copy 0
49   {
50     compare i, numbers-index
51     break-if->=
52     var src/ebx: (addr int) <- index numbers, i
53 #?     print-int32-decimal 0, *src
54 #?     print-string 0, "\n"
55     var target/ecx: int <- copy 0x7e4  # 2020
56     target <- subtract *src
57     {
58       var found?/eax: boolean <- find-after numbers, i, target
59       compare found?, 0/false
60       break-if-=
61       print-string 0, "found\n"
62       print-int32-decimal 0, *src
63       print-string 0, " "
64       print-int32-decimal 0, target
65       print-string 0, "\n"
66       target <- multiply *src
67       print-int32-decimal 0, target
68       print-string 0, "\n"
69       return 0/success
70     }
71     i <- increment
72     loop
73   }
74   return 1/not-found
75 }
76 
77 fn find-after _numbers: (addr array int), start: int, _target: int -> _/eax: boolean {
78   var numbers/esi: (addr array int) <- copy _numbers
79   var target/edi: int <- copy _target
80   var len/ecx: int <- length numbers
81   var i/eax: int <- copy start
82   i <- increment
83   {
84     compare i, len
85     break-if->=
86     var src/edx: (addr int) <- index numbers, i
87     # if *src == target, return true
88     compare *src, target
89     {
90       break-if-!=
91       return 1/true
92     }
93     i <- increment
94     loop
95   }
96   return 0/false
97 }