123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- use "files"
- use "format"
- use "itertools"
- primitive Fuel
- // calculate the amount of fuel needed
- fun calc(x: U64) : U64 => (x / 3) - 2
- // calculate the amount of fuel needed, naively recursively taking
- //in account the weight of the fuel
- fun calc_recursive(x: U64) : U64 =>
- let weight = calc(x)
- if weight > 6 then
- weight + calc_recursive(weight)
- else
- weight
- end
- actor Main
- new create(env: Env) =>
- // use a command-line flag to figure out which version of the fuel
- //calculation to use
- let part_one = env.args.contains("--part-one", {(l, r) => l == r})
- let part_two = env.args.contains("--part-two", {(l, r) => l == r})
- if part_one or part_two then
- calculate_fuel(env, part_one)
- else
- env.err.print("Usage: 01 [--part-one|--part-two]")
- env.exitcode(99)
- end
- fun calculate_fuel(env: Env, part_one: Bool) =>
- // since we're storing the input list externally, we'll need the
- //ability to read and also stat files, so build that capability
- let caps = recover val FileCaps.>set(FileRead).>set(FileStat) end
- try
- // try opening the file, whose name we've hard-coded
- with file = OpenFile(FilePath(env.root as AmbientAuth, "input.txt", caps)?) as File
- do
- // iterate through the lines of the file
- let sum = Iter[String](file.lines())
- // try to parse all the lines as a number
- .filter_map[U64]({(str) => try str.u64()? else None end})
- // calculate the amount of fuel required for each one
- .map[U64]({(x) => if part_one then Fuel.calc(x) else Fuel.calc_recursive(x) end })
- // and sum them up
- .fold[U64](0, {(sum, x) => sum + x})
- // print out the resulting number
- env.out.print(Format.int[U64](sum))
- 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
|