| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 | 
							- use "collections"
 
- use "files"
 
- use "format"
 
- class Value
 
-   let _addr: I64
 
-   let _value: I64
 
-   new create(__addr: I64, __value: I64) =>
 
-     _addr = __addr
 
-     _value = __value
 
-   fun addr(): I64 => _addr
 
-   fun value(): I64 => _value
 
- class Operands
 
-   let _lhs: Value
 
-   let _rhs: Value
 
-   let _tgt: I64
 
-   new create(__lhs: Value, __rhs: Value, __tgt: I64) =>
 
-     _lhs = __lhs
 
-     _rhs = __rhs
 
-     _tgt = __tgt
 
-   fun val1(): I64 => _lhs.value()
 
-   fun val2(): I64 => _rhs.value()
 
-   fun tgt(): USize => _tgt.usize()
 
- trait Error
 
-   fun message(): String
 
- class OutOfBounds is Error
 
-   let _loc: USize
 
-   new create(loc: USize) => _loc = loc
 
-   fun message(): String =>
 
-     "Memory access out of bounds: " + Format.int[USize](_loc)
 
- class UnknownOperand is Error
 
-   let _op: I64
 
-   new create(op: I64) => _op = op
 
-   fun message(): String =>
 
-     "Unknown operand: " + Format.int[I64](_op)
 
- primitive Handler
 
-   fun run(env: Env, result: (None | Error)) =>
 
-     match result
 
-       | None => None
 
-       | let e: Error => env.err.print(e.message())
 
-     end
 
- class Program
 
-   var storage: Array[I64]
 
-   var pc: USize = 0
 
-   new create(s: Array[I64]) =>
 
-     storage = s
 
-   new from_file(file: File) =>
 
-     storage = Array[I64](0)
 
-     for line in file.lines() do
 
-       for chunk in line.split(",").values() do
 
-         try
 
-           storage.push(chunk.i64()?)
 
-         end
 
-       end
 
-     end
 
-   fun print(env: Env) =>
 
-     env.out.write("[")
 
-     for x in storage.values() do
 
-       env.out.write(Format.int[I64](x))
 
-       env.out.write(" ")
 
-     end
 
-     env.out.print("]")
 
-   fun ref get_value(addr_loc: USize): (Value | Error) =>
 
-     let addr = try storage(addr_loc)? else return OutOfBounds(addr_loc) end
 
-     let value = try storage(addr.usize())? else return OutOfBounds(addr.usize()) end
 
-     Value(addr, value)
 
-   fun ref get_op_data(): (Operands | Error) =>
 
-     let lhs = match get_value(pc+1)
 
-     | let v: Value => v
 
-     | let e: Error => return e
 
-     end
 
-     let rhs = match get_value(pc+2)
 
-     | let v: Value => v
 
-     | let e: Error => return e
 
-     end
 
-     let tgt = try storage(pc+3)? else return OutOfBounds(pc+1) end
 
-     Operands(lhs, rhs, tgt)
 
-   fun ref do_add(): (None | Error) =>
 
-     let data = match get_op_data()
 
-     | let o: Operands => o
 
-     | let e: Error => return e
 
-     end
 
-     try
 
-       storage(data.tgt())? = data.val1() + data.val2()
 
-     else
 
-       return OutOfBounds(data.tgt())
 
-     end
 
-     pc = pc + 4
 
-     None
 
-   fun ref do_mul(): (None | Error) =>
 
-     let data = match get_op_data()
 
-     | let o: Operands => o
 
-     | let e: Error => return e
 
-     end
 
-     try
 
-       storage(data.tgt())? = data.val1() * data.val2()
 
-     else
 
-       return OutOfBounds(data.tgt())
 
-     end
 
-     pc = pc + 4
 
-     None
 
-   fun ref run(): (None | Error) =>
 
-     try
 
-       match storage(pc)?
 
-         | 1 => do_add()
 
-         | 2 => do_mul()
 
-         | 99 => return None
 
-         | let x: I64 => return UnknownOperand(x)
 
-       end
 
-     else
 
-       return OutOfBounds(pc)
 
-     end
 
-     run()
 
-   fun make_trial(a: I64, b: I64): Program ? =>
 
-     var arr = storage.clone()
 
-     arr(1)? = a
 
-     arr(2)? = b
 
-     Program(arr)
 
-   fun ref run_trial(env: Env): Bool =>
 
-     Handler.run(env, run())
 
-     try
 
-       storage(0)? == 19690720
 
-     else
 
-       false
 
-     end
 
- actor Main
 
-   new create(env: Env) =>
 
-     let caps = recover val FileCaps.>set(FileRead).>set(FileStat) end
 
-     try
 
-       with
 
-         file = OpenFile(FilePath(env.root as AmbientAuth, "input.txt", caps)?) as File
 
-       do
 
-         let program = Program.from_file(file)
 
-         program.print(env)
 
-         for a in Range[I64](0, 100) do
 
-           for b in Range[I64](0, 100) do
 
-             let trial = program.make_trial(a, b)?
 
-             if trial.run_trial(env) then
 
-               env.out.print("noun=" + Format.int[I64](a) + ", verb=" + Format.int[I64](b))
 
-               env.out.print("result=" + Format.int[I64]((a * 100) + b))
 
-             end
 
-           end
 
-         end
 
-       end
 
-     else
 
-       // if something failed, then print an error message of some kind and exit
 
-       env.err.print("Couldn't read expected file `input.txt'")
 
-       env.exitcode(99)
 
-     end
 
 
  |