view day7.rb @ 24:19481b061461

Implement tilting and cycling for Day 14 part 2 Lots of false starts trying to iterate. Eventually looked for "back in same position" to spot a loop. Then took longer to spot that "same position" isn't necessarily "start position" and loop can be offset!
author IBBoard <dev@ibboard.co.uk>
date Sat, 16 Dec 2023 20:39:02 +0000
parents 9ec95ff0d33d
children
line wrap: on
line source

#! /usr/bin/env ruby

require 'set'

if ARGV.length != 1
        abort("Incorrect arguments - needs input file")
elsif not File.exist? (ARGV[0])
	abort("File #{ARGV[0]} did not exist")
end

file = ARGV[0]

Hand = Struct.new(:cards, :score, :bid)

$card_scoring = ("1".."9").to_a.concat(["T", "J", "Q", "K", "A"])

FULL_HOUSE = Set.new([2,3])
TWO_PAIR = {2 => 2, 1 => 1}

def score_hand(cards)
	card_vals = cards.each_char.map {|c| $card_scoring.index(c)}
	card_counts = card_vals.group_by{|v| v}.map {|k, v| v.length}
	card_count_counts = card_counts.group_by{|v| v}.map{|k,v| [k, v.length]}.to_h
	of_a_kind = card_counts.max
	rank = of_a_kind * 2 # 5, 4 or 3 of a kind or a pair => 10, 8, 6 and 4
	if Set.new(card_counts) == FULL_HOUSE
		rank = 7	
	elsif card_count_counts == TWO_PAIR
		rank = 5
	end
	card_vals.reduce("#{rank-1}") {|str, v| "#{str}.#{(v+1).to_s.rjust(2, '0')}"}
end

hands = File.open(file, "r").each_line(chomp: true).map {|line| cards, bid = line.split(" "); Hand.new(cards, score_hand(cards), bid.to_i)}

puts hands.sort {|a, b| a.score <=> b.score}.map.with_index(1) {|val, i| i * val.bid}.sum
# Rest of algorithm here