37 lines
925 B
Ruby
37 lines
925 B
Ruby
|
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}"
|