diff --git a/2020/node/package-lock.json b/2020/node/package-lock.json index 04b9a95..8cbc0b0 100644 --- a/2020/node/package-lock.json +++ b/2020/node/package-lock.json @@ -1569,9 +1569,9 @@ "dev": true }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true }, "deep-is": { diff --git a/2022/ruby/Rakefile b/2022/ruby/Rakefile index c620516..4808588 100644 --- a/2022/ruby/Rakefile +++ b/2022/ruby/Rakefile @@ -1,28 +1,26 @@ require 'erb' +require 'yard/doctest/rake' task :default => :test -def what_day(arg=nil) - if arg - arg - else - if day = ENV.fetch("DAY", nil) - day - else - Time.now.day - end - end.to_s.rjust(2, '0') +def what_day + ENV + .fetch("DAY", Time.now.day) + .to_i + .to_s + .rjust(2, '0') end -task :run, [:day] do |t, args| - day = what_day(args[:day]) +task :run do |t, args| + day = what_day puts "OK. Let's run Day#{day}!\n\n" require "./day#{day}" Object.const_get("Day#{day}").go end -task :test, [:day] do |t, args| - day = what_day(args[:day]) +desc "Run the tests my way; set env var DAY to run a day other than today" +task :test do |t, args| + day = what_day puts "Wooo! Let's test Day#{day}!\n\n" File.open('./doctest_helper.rb', 'w') do |file| @@ -35,7 +33,12 @@ task :test, [:day] do |t, args| TEST_HELPER end - abort unless system("yard doctest -v ./day#{day}.rb") + Rake::Task["yard:doctest"].invoke +end + +YARD::Doctest::RakeTask.new do |task| + task.doctest_opts = %w[-v] << ENV.fetch("TESTOPTS", "").split(" ") + task.pattern = "./day#{what_day}.rb" end task :new do @@ -57,6 +60,6 @@ rule ( /^day\d\d$/ ) do |task| input_file = "../inputs/#{task.name}-input.txt" system("pbpaste > #{input_file}") puts "📝 wrote the clipboard to #{input_file}, hope it was right:" - system("cat #{input_file}") + system("head -n 5 #{input_file}") end end diff --git a/2022/ruby/day07.rb b/2022/ruby/day07.rb index 9755448..2d73844 100644 --- a/2022/ruby/day07.rb +++ b/2022/ruby/day07.rb @@ -7,49 +7,73 @@ def self.go def initialize(input=nil) @input = input || real_input - @dirs = parse_input + @dirs = parse_input(@input) end # @example # day.part1 #=> 95_437 def part1 @dirs - .map { |dir_name, _| - dirs - .select{ |subdir, _| subdir.start_with?(dir_name) } - .map{|dir, files| files.empty? ? 0 : files.map{|name,size| size}.reduce(&:+)} - .reduce(&:+) - } + .map { |dir_name, _| total_dir_size(dir_name) } .select{ |dir_size| dir_size < 100_000 } .reduce(&:+) end + # @example + # day.part2 #=> 24_933_642 def part2 + disk_size = 70_000_000 + space_needed_for_update = 30_000_000 + current_free_space = disk_size - total_dir_size("root") + + delete_at_least_this_big = space_needed_for_update - current_free_space + + @dirs + .map { |dir_name, _| total_dir_size(dir_name) } + .select{ |dir_size| dir_size > delete_at_least_this_big } + .sort + .first end - def parse_input + # @example e + # day.total_dir_size('root/a/e') #=> 584 + # @example a + # day.total_dir_size('root/a') #=> 94853 + # @example d + # day.total_dir_size('root/d') #=> 24933642 + # @example root + # day.total_dir_size('root') #=> 48381165 + def total_dir_size(dir_name) + @dirs + .select{ |subdir, _| subdir.start_with?(dir_name) } + .map{ |_name, size| size } + .reduce(&:+) + end + + # @example + # day.parse_input(Day07::EXAMPLE_INPUT) #=> {"root"=>23352670, "root/a"=>94269, "root/a/e"=>584, "root/d"=>24933642} + def parse_input(input) cwd = "root" - @input + + input .split("$ ") - .each_with_object({}) { |cmd_and_output, dirs| - lines = cmd_and_output.split("\n") - cmd = lines.shift - case cmd - when "cd /" - cwd = "root" - when "cd .." - cwd = cwd.split("/")[0..-2].join("/") - cwd = "root" if cwd == "" - when /cd (\w*)/ - cwd += "/#{$1}" + .each_with_object({}) { |command_and_output, dirs| # dirs is updated by and returned from this loop + command, output = command_and_output.split("\n", 2) + + case command + when "" ; :do_nothing + when "cd /" ; cwd = "root" + when "cd .." ; cwd = cwd.split("/")[0..-2].join("/") + when /cd (\w*)/ ; cwd += "/#{$1}" + when "ls" - dirs[cwd] ||= { } - lines - .reject { |line| line.start_with?("dir")} - .map { |line| line.split(" ") } - .each { |size, filename| dirs[cwd][filename] = size.to_i } - else - :do_nothing + dirs[cwd] ||= output + .split("\n") + .reject { |line| line.start_with?("dir") } + .map { |line| line.split(" ") } + .reduce(0) { |dir_size, (size, _filename)| + dir_size += size.to_i + } end } end