2022/07/script.rb

73 lines
1.8 KiB
Ruby
Raw Permalink Normal View History

2022-12-08 15:03:36 +01:00
#!/usr/bin/env ruby
require_relative '../common'
class Day07 < Day
class Tree
attr_reader :tree
def self.parse(input)
input.each_with_object(Tree.new) do |command, tree|
if command.start_with?('$ ')
cmd, directory = command.match(/\A\$ (cd|ls) ?([A-Za-z\/.]*)\z/).captures
tree.cd directory if cmd == "cd"
else
if command.start_with?('dir ')
tree.directory command.split.last
else
size, file = command.match(/\A([0-9]+) (.+)\z/).captures
tree.file file, size
end
end
end
end
def initialize
@current_directory = []
@tree = {}
end
def cd(directory)
if directory == ".."
@current_directory.pop
else
@current_directory << directory
if @tree.dig(*@current_directory).nil?
@current_directory.inject(@tree) do |tree, directory|
tree[directory] = {} if tree[directory].nil?
tree[directory]
end
end
end
end
def directory(name)
@tree.dig(*@current_directory)[name] = {}
end
def file(name, size)
@tree.dig(*@current_directory)[name] = size.to_i
end
def sizes(directory = ["/"])
@tree.dig(*directory).each_with_object({directory.join('/') => 0}) do |(name, content), res|
if content.is_a?(Hash)
res.merge!(sizes(directory + [name]))
res[directory.join('/')] += res[(directory + [name]).join('/')]
else
res[directory.join('/')] += content
end
end
end
end
def part1
Tree.parse(stdin).sizes.values.select { |v| v <= 100000 }.sum
end
def part2
Tree.parse(stdin).sizes.values.select { |v| v >= 8381165 }.min
end
end
Day07.run