123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- use "collections"
- use "files"
- use "format"
- 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_op_data(env: Env): (I64, I64, I64, I64, I64) ? =>
- let addr1 = storage(pc+1)?
- let addr2 = storage(pc+2)?
- let tgt = storage(pc+3)?
- let val1 = storage(addr1.usize())?
- let val2 = storage(addr2.usize())?
- (addr1, val1, addr2, val2, tgt)
- fun ref do_add(env: Env) ? =>
- (let x1, let op1, let x2, let op2, let tgt) = get_op_data(env)?
- storage.update(tgt.usize(), op1 + op2)?
- pc = pc + 4
- run(env)
- fun ref do_mul(env: Env) ? =>
- (let x1, let op1, let x2, let op2, let tgt) = get_op_data(env)?
- storage.update(tgt.usize(), op1 * op2)?
- pc = pc + 4
- run(env)
- fun ref run(env: Env) =>
- try
- match storage(pc)?
- | 1 => do_add(env)?
- | 2 => do_mul(env)?
- | 99 => None
- | let x: I64 => env.err.print("Unknown opcode " + Format.int[I64](x))
- end
- else
- env.err.print("PC " + Format.int[USize](pc) + " out of bounds")
- end
- fun make_trial(a: I64, b: I64): Program ? =>
- var arr = storage.clone()
- arr.update(1, a)?
- arr.update(2, b)?
- Program(arr)
- fun ref run_trial(env: Env): Bool =>
- run(env)
- 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
|