# --- Day 4: Security Through Obscurity ---
#
# Finally, you come across an information kiosk with a list of rooms. Of course, the list is
# encrypted and full of decoy data, but the instructions to decode the list are barely hidden
# nearby. Better remove the decoy data first.
#
# Each room consists of an encrypted name (lowercase letters separated by dashes) followed by a
# dash, a sector ID, and a checksum in square brackets.
#
# A room is real (not a decoy) if the checksum is the five most common letters in the encrypted
# name, in order, with ties broken by alphabetization. For example:
#
# aaaaa-bbb-z-y-x-123[abxyz] is a real room because the most common letters are a (5), b (3), and
# then a tie between x, y, and z, which are listed alphabetically.
#
# a-b-c-d-e-f-g-h-987[abcde] is a real room because although the letters are all tied (1 of each),
# the first five are listed alphabetically.
#
# not-a-real-room-404[oarel] is a real room.
#
# totally-real-room-200[decoy] is not.
#
# Of the real rooms from the list above, the sum of their sector IDs is 1514.
#
# What is the sum of the sector IDs of the real rooms?

# --- Part Two ---
#
# With all the decoy data out of the way, it's time to decrypt this list and get moving.
#
# The room names are encrypted by a state-of-the-art shift cipher, which is nearly unbreakable
# without the right software. However, the information kiosk designers at Easter Bunny HQ were not
# expecting to deal with a master cryptographer like yourself.
#
# To decrypt a room name, rotate each letter forward through the alphabet a number of times equal
# to the room's sector ID. A becomes B, B becomes C, Z becomes A, and so on. Dashes become spaces.
#
# For example, the real name for qzmt-zixmtkozy-ivhz-343 is very encrypted name.
#
# What is the sector ID of the room where North Pole objects are stored?
#

require_relative 'input'

day = __FILE__[/\d+/].to_i(10)
input = Input.for_day(day)

# input = <<-EOF
# aaaaa-bbb-z-y-x-123[abxyz]
# a-b-c-d-e-f-g-h-987[abcde]
# not-a-real-room-404[oarel]
# totally-real-room-200[decoy]
# EOF
# puts "solving day #{day} from input\n#{input.inspect}"

module Enumerable
  def count_by
    counts = Hash.new(0)
    each {|e| counts[block_given? ? yield(e) : e] += 1}
    counts
  end
end

def checksum(string)
  string.scan(/[a-z]/).count_by.sort_by {|l,c| [-c,l]}.map{|k,v|k}.first(5).join
end

parts = /\A([-a-z]+)-(\d+)[\[]([a-z]+)[\]]$/
total = 0
input.each_line do |room|
  code, id, check = room.match(parts).captures
  # puts({room: room, code: code, id: id, check: check, checksum: checksum(code)}.inspect)
  if check == checksum(code)
    total += id.to_i
    plain = code.tr('-',' ')
    (id.to_i % 26).times { plain = plain.tr(('a'..'z').to_a.join, [*('b'..'z').to_a, 'a'].join) }
    puts({id: id, name: plain}.inspect) if plain == "northpole object storage"
  end
end
puts total
# puts "should be 1514"
