main.pony 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. use "collections"
  2. use "files"
  3. use "format"
  4. class Program
  5. var storage: Array[I64]
  6. var pc: USize = 0
  7. new create(s: Array[I64]) =>
  8. storage = s
  9. new from_file(file: File) =>
  10. storage = Array[I64](0)
  11. for line in file.lines() do
  12. for chunk in line.split(",").values() do
  13. try
  14. storage.push(chunk.i64()?)
  15. end
  16. end
  17. end
  18. fun print(env: Env) =>
  19. env.out.write("[")
  20. for x in storage.values() do
  21. env.out.write(Format.int[I64](x))
  22. env.out.write(" ")
  23. end
  24. env.out.print("]")
  25. fun ref get_op_data(env: Env): (I64, I64, I64, I64, I64) ? =>
  26. let addr1 = storage(pc+1)?
  27. let addr2 = storage(pc+2)?
  28. let tgt = storage(pc+3)?
  29. let val1 = storage(addr1.usize())?
  30. let val2 = storage(addr2.usize())?
  31. (addr1, val1, addr2, val2, tgt)
  32. fun ref do_add(env: Env) ? =>
  33. (let x1, let op1, let x2, let op2, let tgt) = get_op_data(env)?
  34. storage.update(tgt.usize(), op1 + op2)?
  35. pc = pc + 4
  36. run(env)
  37. fun ref do_mul(env: Env) ? =>
  38. (let x1, let op1, let x2, let op2, let tgt) = get_op_data(env)?
  39. storage.update(tgt.usize(), op1 * op2)?
  40. pc = pc + 4
  41. run(env)
  42. fun ref run(env: Env) =>
  43. try
  44. match storage(pc)?
  45. | 1 => do_add(env)?
  46. | 2 => do_mul(env)?
  47. | 99 => None
  48. | let x: I64 => env.err.print("Unknown opcode " + Format.int[I64](x))
  49. end
  50. else
  51. env.err.print("PC " + Format.int[USize](pc) + " out of bounds")
  52. end
  53. fun make_trial(a: I64, b: I64): Program ? =>
  54. var arr = storage.clone()
  55. arr.update(1, a)?
  56. arr.update(2, b)?
  57. Program(arr)
  58. fun ref run_trial(env: Env): Bool =>
  59. run(env)
  60. try
  61. storage(0)? == 19690720
  62. else
  63. false
  64. end
  65. actor Main
  66. new create(env: Env) =>
  67. let caps = recover val FileCaps.>set(FileRead).>set(FileStat) end
  68. try
  69. with
  70. file = OpenFile(FilePath(env.root as AmbientAuth, "input.txt", caps)?) as File
  71. do
  72. let program = Program.from_file(file)
  73. program.print(env)
  74. for a in Range[I64](0, 100) do
  75. for b in Range[I64](0, 100) do
  76. let trial = program.make_trial(a, b)?
  77. if trial.run_trial(env) then
  78. env.out.print("noun=" + Format.int[I64](a) + ", verb=" + Format.int[I64](b))
  79. env.out.print("result=" + Format.int[I64]((a * 100) + b))
  80. end
  81. end
  82. end
  83. end
  84. else
  85. // if something failed, then print an error message of some kind and exit
  86. env.err.print("Couldn't read expected file `input.txt'")
  87. env.exitcode(99)
  88. end