This problem has two tasks which are very similar: they each involve mapping a given input line to a value, and returning the sum of the values. The difference in the tasks is the mapping.
For this, we use Icon's table
data structure, which maps a key to a value.
The main calculation part of the program merely looks at each line in the given
file, finds the value for that line in the table, and sums that value.
every (score := 0) +:= mapping[!file]
For the first task, the mapping is as follows:
mapping := table(0) # <1> insert(mapping, "A X", 1 + 3) # <2> insert(mapping, "A Y", 2 + 6) insert(mapping, "A Z", 3 + 0) insert(mapping, "B X", 1 + 0) insert(mapping, "B Y", 2 + 3) insert(mapping, "B Z", 3 + 6) insert(mapping, "C X", 1 + 6) insert(mapping, "C Y", 2 + 0) insert(mapping, "C Z", 3 + 3)
- Create an empty table with a default value of 0.
- Insert into the table the series of mappings from line to value. Each value is a sum, written this way to correspond to the task definition.
The various components are wrapped up into procedures as follows:
procedure main(inputs) local filename if *inputs = 1 then { filename := inputs[1] # Part 1 solution write("Part 1 score is: ", part_1(filename)) # Part 2 solution write("Part 2 score is: ", part_2(filename)) } else { write("Provide a filename of data") } end # Returns score from part 1 procedure part_1(filename) local mapping mapping := table(0) insert(mapping, "A X", 1 + 3) insert(mapping, "A Y", 2 + 6) insert(mapping, "A Z", 3 + 0) insert(mapping, "B X", 1 + 0) insert(mapping, "B Y", 2 + 3) insert(mapping, "B Z", 3 + 6) insert(mapping, "C X", 1 + 6) insert(mapping, "C Y", 2 + 0) insert(mapping, "C Z", 3 + 3) return calculate_score(filename, mapping) end # Returns score from part 2 procedure part_2(filename) local mapping mapping := table(0) insert(mapping, "A X", 3 + 0) insert(mapping, "A Y", 1 + 3) insert(mapping, "A Z", 2 + 6) insert(mapping, "B X", 1 + 0) insert(mapping, "B Y", 2 + 3) insert(mapping, "B Z", 3 + 6) insert(mapping, "C X", 2 + 0) insert(mapping, "C Y", 3 + 3) insert(mapping, "C Z", 1 + 6) return calculate_score(filename, mapping) end procedure calculate_score(filename, mapping) local file, score file := open(filename, "r") | stop("Cannot open ", filename) every (score := 0) +:= mapping[!file] close(file) return score end