-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
part1.rb
94 lines (85 loc) Β· 2.67 KB
/
part1.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# frozen_string_literal: true
require_relative "game"
require_relative "set"
module AdventOfCode
module Puzzles2023
module Day02
##
# Class for solving Day 2 - Part 1 puzzle
class Part1
##
# Array of games
# @return [Array<Game>] the games of the puzzle
attr_reader :games
##
# @param file [String] path to the input file
def initialize(file: nil)
file ||= "#{File.dirname(__FILE__)}/input.txt"
file_contents = File.readlines(file, chomp: true)
load_games(file_contents)
end
##
# Find games that are valid given the number of blue, green,
# and red cubes.
#
# @param blue [Integer] number of blue cubes
# @param green [Integer] number of green cubes
# @param red [Integer] number of red cubes
#
# @return [Array<Game>] valid games
def valid_games(blue:, green:, red:)
games.select { |game| game.valid?(blue:, green:, red:) }
end
##
# Find the sum of the game ids that are valid given the number
# of blue, green, and red cubes.
#
# @param blue [Integer] number of blue cubes
# @param green [Integer] number of green cubes
# @param red [Integer] number of red cubes
#
# @return [Integer] sum of the game ids
def answer(blue:, green:, red:)
valid_games(blue:, green:, red:).sum(&:id)
end
protected
##
# Load games from the file contents.
#
# @param file_contents [Array<String>] file contents
#
# @return [Array<Game>] games
def load_games(file_contents)
@games = file_contents.map do |line|
id, sets = line.split(": ")
sets = sets.split(%r{;\s+}).map { |set| parse_set(set) }
game_id = parse_game_id(id)
Game.new(id: game_id, sets:)
end
end
##
# Parse the game id from a string.
# The string is in the format "Game X".
#
# @param game [String] game id
#
# @return [Integer] game id
def parse_game_id(game)
game.gsub("Game ", "").to_i
end
##
# Parse a set of cubes from a string.
# The string is in the format "X blue, Y green, Z red".
#
# @param set [String] set of cubes
#
# @return [Set] set of cubes
def parse_set(set)
colors = set.split(%r{,\s+}).map(&:split)
colors = colors.to_h { |number, color| [color.downcase.to_sym, number.to_i] }
Set.new(**colors)
end
end
end
end
end