class Room attr_reader :name, :sector_id, :checksum def initialize(string) @name = string.split("-")[..-2].join("-") @sector_id = string.split("-")[-1].split("[")[0].to_i @checksum = string.split("[")[1][..-2] end def calculated_checksum letter_counts.sort_by { |k, v| [-v, -k] }.map(&:first)[0...5].join end def real? calculated_checksum == checksum end def letter_counts (name.chars - ["-"]).group_by(&:itself).to_h { |k, v| [k, v.count] } end def rotated_name 1.upto(sector_id % 26).reduce(name) { |n, _| n.codepoints.map{ |c| ((((c + 1) - 97) % 26) + 97).chr }.join("") } end end input = STDIN.read.chomp room_lines = input.split("\n") rooms = room_lines.map { |line| Room.new line } part_1 = rooms.select(&:real?).sum(&:sector_id) puts "Part 1: #{part_1}" part_2 = rooms.find { |room| room.rotated_name.include? "northpole" }.sector_id puts "Part 2: #{part_2}"