Skip to content

Instantly share code, notes, and snippets.

@cjavdev
Created December 20, 2022 00:45
Show Gist options
  • Save cjavdev/3d4df947d785d04bde080d3d4bf20b28 to your computer and use it in GitHub Desktop.
Save cjavdev/3d4df947d785d04bde080d3d4bf20b28 to your computer and use it in GitHub Desktop.
if ARGV.empty?
data = DATA.readlines(chomp: true)
else
data = File.readlines(ARGV.first, chomp: true)
end
def blueprints(data)
data.map do |line|
match = /Blueprint (?<id>\d+): Each ore robot costs (?<ore_robot_ore>\d+) ore. Each clay robot costs (?<clay_robot_ore>\d+) ore. Each obsidian robot costs (?<obsidian_robot_ore>\d+) ore and (?<obsidian_robot_clay>\d+) clay. Each geode robot costs (?<geode_robot_ore>\d+) ore and (?<geode_robot_obsidian>\d+) obsidian./.match(line)
{
id: match[:id].to_i,
ore_bot_ore: match[:ore_robot_ore].to_i,
clay_bot_ore: match[:clay_robot_ore].to_i,
obsidian_bot_ore: match[:obsidian_robot_ore].to_i,
obsidian_bot_clay: match[:obsidian_robot_clay].to_i,
geode_bot_ore: match[:geode_robot_ore].to_i,
geode_bot_obsidian: match[:geode_robot_obsidian].to_i,
ore_max: [
match[:ore_robot_ore].to_i,
match[:clay_robot_ore].to_i,
match[:obsidian_robot_ore].to_i,
match[:geode_robot_ore].to_i
].max + 1
}
end
end
SEEN = {}
def max_geodes(
blueprint,
ore_robots,
clay_robots,
obsidian_robots,
geode_robots,
ore,
clay,
obsidian,
geodes,
time_left
)
return geodes if time_left == 0
key = [
ore_robots,
clay_robots,
obsidian_robots,
geode_robots,
ore % blueprint[:ore_max] + 1,
clay % blueprint[:obsidian_bot_clay] + 1,
obsidian % blueprint[:geode_bot_obsidian] + 1,
geodes,
time_left
]
return SEEN[key] if SEEN.key?(key)
max = max_geodes(
blueprint,
ore_robots,
clay_robots,
obsidian_robots,
geode_robots,
ore + ore_robots,
clay + clay_robots,
obsidian + obsidian_robots,
geodes + geode_robots,
time_left - 1
)
# Can we buy an ore bot?
if ore >= blueprint[:ore_bot_ore] &&
ore_robots <= blueprint[:ore_max]
option = max_geodes(
blueprint,
ore_robots + 1,
clay_robots,
obsidian_robots,
geode_robots,
ore - blueprint[:ore_bot_ore] + ore_robots,
clay + clay_robots,
obsidian + obsidian_robots,
geodes + geode_robots,
time_left - 1
)
max = option if option > max
end
# Can we buy a clay bot?
if ore >= blueprint[:clay_bot_ore] &&
clay_robots <= blueprint[:obsidian_bot_clay]
option = max_geodes(
blueprint,
ore_robots,
clay_robots + 1,
obsidian_robots,
geode_robots,
ore - blueprint[:clay_bot_ore] + ore_robots,
clay + clay_robots,
obsidian + obsidian_robots,
geodes + geode_robots,
time_left - 1
)
max = option if option > max
end
# Can we buy an obsidian bot?
if ore >= blueprint[:obsidian_bot_ore] &&
clay >= blueprint[:obsidian_bot_clay] &&
obsidian_robots <= blueprint[:geode_bot_obsidian]
option = max_geodes(
blueprint,
ore_robots,
clay_robots,
obsidian_robots + 1,
geode_robots,
ore - blueprint[:obsidian_bot_ore] + ore_robots,
clay - blueprint[:obsidian_bot_clay] + clay_robots,
obsidian + obsidian_robots,
geodes + geode_robots,
time_left - 1
)
max = option if option > max
end
# Can we buy a geode bot?
if ore >= blueprint[:geode_bot_ore] &&
obsidian >= blueprint[:geode_bot_obsidian]
option = max_geodes(
blueprint,
ore_robots,
clay_robots,
obsidian_robots,
geode_robots + 1,
ore - blueprint[:geode_bot_ore] + ore_robots,
clay + clay_robots,
obsidian - blueprint[:geode_bot_obsidian] + obsidian_robots,
geodes + geode_robots,
time_left - 1
)
max = option if option > max
end
SEEN[key] = max
max
end
# sum = 0
# blueprints(data).each do |blueprint|
# puts "Blueprint #{blueprint[:id]}"
# SEEN.clear
# quality = blueprint[:id] * max_geodes(
# blueprint,
# 1, 0, 0, 0, 0, 0, 0, 0, 24
# )
# sum += quality
# end
# puts sum
prints = blueprints(data).take(3)
product = 1
prints.each do |blueprint|
puts "Blueprint #{blueprint[:id]}"
SEEN.clear
product *= max_geodes(
blueprint,
1, 0, 0, 0, 0, 0, 0, 0, 32
)
end
p product
# p max_geodes(
# blueprints(data).last, 1, 0, 0, 0, 0, 0, 0, 0, 24
# )
__END__
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian.
Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian.
@cjavdev
Copy link
Author

cjavdev commented Dec 20, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment