Advent of Code 2022: Day 3
The tasks here involve finding duplicates in the characters on different
lines. Most of the complexity of the problem disappears in Icon through
the use of character sets, the cset
data type. In particular, intersection
is calculated with the **
operator.
The two tasks guarantee, under their conditions, that the duplicates in the named sets will consist of a single character, and we need to calculate a priority for that: this is done using the character's ordinal value.
Only two other points of Icon syntax are worth mentioning:
- for a range to finish at the end of the given string, use 0 as its index
-
comparisons return a value, so a number can be checked to be in a range
using two comparisons:
a < x < b
succeeds ifx
is betweena
andb
.
Final Program
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 procedure part_1(filename) local file, line local duplicate, partition_1, partition_2, sum sum := 0 file := open(filename, "r") | stop("Cannot open ", filename) every line := !file do { partition_1 := line[1:(*line/2)+1] partition_2 := line[(*line/2)+1:0] # <1> duplicate := cset(partition_1) ** cset(partition_2) # <2> sum +:= priority(duplicate) } close(file) return sum end procedure part_2(filename) local file, line, lines local duplicate, sum sum := 0 lines := [] file := open(filename, "r") | stop("Cannot open ", filename) every line := !file do { put(lines, line) if *lines = 3 then { duplicate := cset(lines[1]) ** cset(lines[2]) ** cset(lines[3]) sum +:= priority(duplicate) lines := [] } } close(file) return sum end procedure priority(item) local value value := ord(item) if ord("a") <= value <= ord("z") then # <3> return value - ord("a") + 1 else if ord("A") <= value <= ord("Z") then return value - ord("A") + 27 else stop("Error in overlapped character") end
- Note the end of the string is indicated with 0 for the end-range index.
- The strings are converted to character sets, and their intersection computed.
-
Checks if
value
is in the range for lower-case letters.