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:

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
  1. Note the end of the string is indicated with 0 for the end-range index.
  2. The strings are converted to character sets, and their intersection computed.
  3. Checks if value is in the range for lower-case letters.

Page from Peter's Scrapbook, output from a VimWiki on 2024-01-29.