From 1d19b0548a649c6434291fee6194d28af0f2da87 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Tue, 5 Dec 2023 05:39:28 -0500 Subject: [PATCH] Finished day 5, part 1! --- src/advent/day1.rb | 2 +- src/advent/day2.rb | 4 +- src/advent/day3.rb | 16 +-- src/advent/day3_test.rb | 8 +- src/advent/day4.rb | 10 +- src/advent/day5.rb | 109 ++++++++++++++++++ src/advent/day5_test.rb | 96 ++++++++++++++++ src/advent/day_5_input.txt | 219 +++++++++++++++++++++++++++++++++++++ 8 files changed, 444 insertions(+), 20 deletions(-) create mode 100644 src/advent/day5.rb create mode 100644 src/advent/day5_test.rb create mode 100644 src/advent/day_5_input.txt diff --git a/src/advent/day1.rb b/src/advent/day1.rb index 57d6ed5..a911594 100644 --- a/src/advent/day1.rb +++ b/src/advent/day1.rb @@ -39,7 +39,7 @@ def get_calibration_code(line) end def get_sum_of_calibration_code(document) - calibration_codes = document.split("\n").map do |line| + calibration_codes = document.split("\n").hash do |line| get_calibration_code line end calibration_codes.reduce 0, :+ diff --git a/src/advent/day2.rb b/src/advent/day2.rb index cd3e6da..4da225f 100644 --- a/src/advent/day2.rb +++ b/src/advent/day2.rb @@ -43,13 +43,13 @@ class Game def self.deserialize(line) id = /\s*Game\s+(\d+):/.match(line)[1].to_i draws_as_text = line[line.index(":") + 1..] - draws = draws_as_text.split(";").map(&Draw.method(:deserialize)) + draws = draws_as_text.split(";").hash(&Draw.method(:deserialize)) self.new id, draws end def fewer_number_of_cubes [:blue, :red, :green].map do |color| - @draws.map {|draw| draw.send color } + @draws.hash {|draw| draw.send color } .max || 0 end end diff --git a/src/advent/day3.rb b/src/advent/day3.rb index 832df4b..261fc92 100644 --- a/src/advent/day3.rb +++ b/src/advent/day3.rb @@ -98,7 +98,7 @@ class EngineLine def extract_engine_numbers digit_indexes = extract_digit_indexes @line - group_digit_indexes(digit_indexes).map &method(:create_engine_number) + group_digit_indexes(digit_indexes).hash &method(:create_engine_number) end def extract_gears @@ -119,13 +119,13 @@ class Engine end def self.deserialize(ser) - els = ser.strip.split("\n").each_with_index.map { |line, idx| EngineLine.new idx, line} + els = ser.strip.split("\n").each_with_index.hash { |line, idx| EngineLine.new idx, line} return self.new els end def extract_engine_numbers @engine_lines - .map {|line| line.extract_engine_numbers} + .hash {|line| line.extract_engine_numbers} .flatten end @@ -159,7 +159,7 @@ class Engine def is_adjacent(engine_number, gear) gear.get_neighbourhood - .map {|point| engine_number.is_located_on(point[:line_index], point[:column_index])} + .hash {|point| engine_number.is_located_on(point[:line_index], point[:column_index])} .any? end @@ -170,15 +170,15 @@ class Engine def extract_gears @engine_lines - .map {|line| line.extract_gears} + .hash {|line| line.extract_gears} .flatten end def get_gear_ratios extract_gears - .map {|gear| get_adjacent_number_parts(gear)} + .hash {|gear| get_adjacent_number_parts(gear)} .filter {|adjacent_numbers| adjacent_numbers.length == 2} - .map {|adjacent_numbers| adjacent_numbers.map {|a| a.value} .reduce(1, :*)} + .hash {|adjacent_numbers| adjacent_numbers.hash {|a| a.value}.reduce(1, :*)} end attr_accessor :engine_lines end @@ -190,6 +190,6 @@ input_content = File.open(input_file_name).read engine = Engine.deserialize input_content -puts engine.extract_engine_numbers_that_touches_symbols.map {|e| e.value} .sum +puts engine.extract_engine_numbers_that_touches_symbols.hash {|e| e.value}.sum puts engine.get_gear_ratios.sum diff --git a/src/advent/day3_test.rb b/src/advent/day3_test.rb index e196b16..dd2fb00 100644 --- a/src/advent/day3_test.rb +++ b/src/advent/day3_test.rb @@ -67,7 +67,7 @@ class EngineLineTest < Test::Unit::TestCase def test_extract_engine_numbers engine = Engine.deserialize @@easy_engine expt = [467, 114, 35, 633, 617, 58, 592, 755, 664, 598] - assert_equal expt, engine.extract_engine_numbers.map {|e| e.value} + assert_equal expt, engine.extract_engine_numbers.hash {|e| e.value} end def test_touches_symbol @@ -79,7 +79,7 @@ class EngineLineTest < Test::Unit::TestCase def test_extract_engine_numbers_that_touches_symbols engine = Engine.deserialize @@easy_engine expt = [467, 35, 633, 617, 592, 755, 664, 598] - assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.map {|e| e.value} + assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.hash {|e| e.value} end def test_empty @@ -96,14 +96,14 @@ class EngineLineTest < Test::Unit::TestCase .........." engine = Engine.deserialize input expt = [] - assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.map {|e| e.value} + assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.hash {|e| e.value} end def test_day_3_part_1_easy engine = Engine.deserialize @@easy_engine expt = 4361 - assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.map {|e| e.value} .sum + assert_equal expt, engine.extract_engine_numbers_that_touches_symbols.hash {|e| e.value}.sum end def test_extract_gears diff --git a/src/advent/day4.rb b/src/advent/day4.rb index bfb80d3..0a3a33e 100644 --- a/src/advent/day4.rb +++ b/src/advent/day4.rb @@ -19,8 +19,8 @@ class Card def self.deserialize(line) id_match = /Card\s+(\d+)/.match(line) id = id_match[1].to_i - winning_numbers = line[(line.index(":") + 1)..(line.index("|") - 1)].split(/\s+/).filter {|x| !x.empty?}.map {|x| x.to_i} - selected_numbers = line[(line.index("|") + 1)..line.length].split(/\s+/).filter {|x| !x.empty?}.map {|x| x.to_i} + winning_numbers = line[(line.index(":") + 1)..(line.index("|") - 1)].split(/\s+/).filter {|x| !x.empty?}.hash {|x| x.to_i} + selected_numbers = line[(line.index("|") + 1)..line.length].split(/\s+/).filter {|x| !x.empty?}.hash {|x| x.to_i} Card.new id, selected_numbers, winning_numbers end @@ -40,12 +40,12 @@ class Cards cards = ser .split("\n") .filter {|line| !line.empty?} - .map {|line| Card.deserialize line} + .hash {|line| Card.deserialize line} self.new cards end def scores - @cards.map {|card| card.score} + @cards.hash {|card| card.score} end def scratchcards_generated_by_card(card) @@ -57,7 +57,7 @@ class Cards if score > 0 sub_cards = @cards.filter {|sub_card| sub_card.id > card.id and sub_card.id <= card.id + score } ret += sub_cards - .map {|sub_card| scratchcards_generated_by_card(sub_card)} + .hash {|sub_card| scratchcards_generated_by_card(sub_card)} .flatten end @scratchcards_generated_by_card_cache[card.id] = ret diff --git a/src/advent/day5.rb b/src/advent/day5.rb new file mode 100644 index 0000000..994a7da --- /dev/null +++ b/src/advent/day5.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +class WeirMapRange + def initialize(destination, source, range_length) + @destination = destination + @source = source + @range_length = range_length + end + + def includes_source?(source) + @source <= source and source <= (@source + @range_length) + end + + def destination_for_source(source) + @destination + (source - @source) + end + + def self.deserialize(ser) + parts = ser.strip.split(/\s+/).map {|p| p.to_i} + self.new parts[0], parts[1], parts[2] + end + + attr_accessor :destination + attr_accessor :source + attr_accessor :range_length +end + +class WeirdMap + def initialize(weird_map_ranges) + @weird_map_ranges = weird_map_ranges + end + + def [](source) + @weird_map_ranges.each do |wmr| + if wmr.includes_source? source + return wmr.destination_for_source source + end + end + source + end + + def self.deserialize(ser) + wmr = ser.strip.split("\n") + .filter {|line| !line.empty?} + .map {|line| WeirMapRange.deserialize line} + self.new wmr + end +end + + +class TodoMap + def initialize(from, to, hash) + @from = from + @to = to + @hash = hash + end + + def self.deserialize(ser) + ser = ser.strip + from_to =ser[(0...ser.index(/\s+/))].split("-") + weird_map_ser = ser[ser.index("\n")..ser.length] + self.new from_to[0], from_to[2], WeirdMap.deserialize(weird_map_ser) + end + + def [](source) + @hash[source] + end + + attr_accessor :from + attr_accessor :to + attr_accessor :hash +end + +class PlanningMaps + def initialize(seeds, toto_maps) + @seeds = seeds + @toto_maps = toto_maps + end + + def [](source) + ret = source + @toto_maps.each {|tm| ret = tm[ret]} + ret + end + + def self.deserialize(ser) + blocks = ser.strip.split(/^$/) + seeds = blocks[0].split(" ")[(1..)].map {|s| s.to_i} + toto_maps = blocks[(1..)].map {|b| TodoMap.deserialize b} + self.new seeds, toto_maps + end + + def min_destinations + @seeds.map {|seed| self[seed]} + .min + end + + attr_accessor :seeds +end + + +if __FILE__ == $0 + input_file_name = File.join(File.dirname(__FILE__), "day_5_input.txt") + input_content = File.open(input_file_name).read + pms = PlanningMaps.deserialize input_content + + puts "Solution to part 1: #{pms.min_destinations}" + +end diff --git a/src/advent/day5_test.rb b/src/advent/day5_test.rb new file mode 100644 index 0000000..c64d03f --- /dev/null +++ b/src/advent/day5_test.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +require 'test/unit' +require_relative './day5' + + +class TestWeirMapRange < Test::Unit::TestCase + def test_deserialize + wmr = WeirMapRange.deserialize "37 52 2" + + assert_equal 37, wmr.destination + assert_equal 52, wmr.source + assert_equal 2, wmr.range_length + end +end + + +class TestWeirdMap < Test::Unit::TestCase + def test_deserialize + ser = " +50 98 2 +52 50 48" + wm = WeirdMap.deserialize ser + assert_equal 0, wm[0] + assert_equal 48, wm[48] + assert_equal 49, wm[49] + assert_equal 52, wm[50] + assert_equal 53, wm[51] + assert_equal 98, wm[96] + assert_equal 99, wm[97] + assert_equal 50, wm[98] + assert_equal 51, wm[99] + end +end + +class TestTodoMap < Test::Unit::TestCase + def test_deserialize + ser = " +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13" + tm = TodoMap.deserialize ser + assert_equal "light", tm.from + assert_equal "temperature", tm.to + assert_equal 86, tm[50] + + end +end + + +class TestPlanningMaps < Test::Unit::TestCase + @@easy_input = "seeds: 79 14 55 13 + +seed-to-soil map: +50 98 2 +52 50 48 + +soil-to-fertilizer map: +0 15 37 +37 52 2 +39 0 15 + +fertilizer-to-water map: +49 53 8 +0 11 42 +42 0 7 +57 7 4 + +water-to-light map: +88 18 7 +18 25 70 + +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13 + +temperature-to-humidity map: +0 69 1 +1 0 69 + +humidity-to-location map: +60 56 37 +56 93 4" + + def test_deserialization + pms = PlanningMaps.deserialize @@easy_input + assert_equal [79, 14, 55, 13], pms.seeds + end + + def test_day_4_part_1 + pms = PlanningMaps.deserialize @@easy_input + assert_equal 2, pms.min_destinations + end +end \ No newline at end of file diff --git a/src/advent/day_5_input.txt b/src/advent/day_5_input.txt new file mode 100644 index 0000000..6cfe421 --- /dev/null +++ b/src/advent/day_5_input.txt @@ -0,0 +1,219 @@ +seeds: 2041142901 113138307 302673608 467797997 1787644422 208119536 143576771 99841043 4088720102 111819874 946418697 13450451 3459931852 262303791 2913410855 533641609 2178733435 26814354 1058342395 175406592 + +seed-to-soil map: +1270068015 1235603193 242614277 +13415696 1478217470 21049126 +825250550 1160341941 75261252 +3786189027 1971702238 242038712 +3191605340 3433644052 172752250 +2389904665 3088515862 345128190 +0 1499266596 13415696 +1197451933 0 72616082 +2139929050 1721726623 249975615 +900511802 222541761 147014452 +1047526254 72616082 149925679 +34464822 980591812 179750129 +2735032855 2631943377 456572485 +3364357590 3606396302 421831437 +214214951 369556213 611035599 +1721726623 2213740950 418202427 + +soil-to-fertilizer map: +226793587 358613369 356867344 +0 1838890301 226793587 +2741010192 0 358613369 +2257843811 715480713 173982825 +3099623561 1264222741 3082010 +1810570233 2912833547 326150077 +4038242924 3815312886 256724372 +2431826636 3268919687 279247493 +866869902 1671637223 167253078 +3102705571 889463538 374759203 +1615333950 2646894858 125679350 +2136720310 1550513722 121123501 +3477464774 2772574208 140259339 +1034122980 2065683888 581210970 +2711074129 3238983624 29936063 +583660931 1267304751 283208971 +1741013300 3548167180 69556933 +3815312886 4072037258 222930038 + +fertilizer-to-water map: +2197389106 1911800263 305927673 +3117278994 244526473 20512291 +2957263700 4069704360 136102838 +1536592951 2749121858 245216219 +3093366538 840656765 23912456 +815267737 2718368501 30753357 +3137791285 3392529258 82147206 +3770129899 390297301 198889495 +2168252150 2217727936 29136956 +770420674 2367771416 44847063 +3304122356 4205807198 44047643 +94626393 318562852 71734449 +2518697514 2262245627 10899396 +1967704281 265038764 53524088 +846021094 2994338077 264934624 +1215514867 3881882833 187821527 +1781809170 2556752263 100818318 +1882627488 1690877042 85076793 +208796777 631622731 209034034 +2583608714 3508227847 39876494 +519341481 1587040614 19652563 +599791964 104559149 139967324 +3430004623 1246915338 340125276 +1110955718 0 104559149 +2623485208 3548104341 333778492 +1403336394 3259272701 133256557 +0 2273145023 94626393 +2529596910 1857788459 54011804 +166360842 589186796 42435935 +3219938491 1606693177 84183865 +2165362153 3505337850 2889997 +2021228369 2412618479 72557496 +538994044 2657570581 60797920 +739759288 3474676464 30661386 +417830811 1154801218 92114120 +509944931 864569221 9396550 +2093785865 2485175975 71576288 +3969019394 873965771 280835447 +2503316779 2246864892 15380735 +3348169999 1775953835 81834624 + +water-to-light map: +3059617387 1101868951 93963271 +2772853640 2098642805 169363292 +193287974 683814429 1482323 +3780234682 1734000399 364642406 +194770297 193287974 490526455 +3550500423 902417243 199451708 +3466829263 2268006097 83671160 +3379471616 2976813583 87357647 +2283311570 2369871058 489542070 +3768145932 1195832222 12088750 +1202605712 3064171230 1080705858 +2942216932 2859413128 107440729 +3749952131 2351677257 18193801 +3049657661 2966853857 9959726 +902417243 1433811930 300188469 +3153580658 1207920972 225890958 + +light-to-temperature map: +1088722200 1345179841 10000894 +4202170199 3029124889 92797097 +3016749137 3130683307 53232372 +534766220 331633133 9297796 +190275035 286706851 44926282 +3069981509 1355180735 96127340 +1579189291 3913052943 379484702 +3918942962 3793498681 21754451 +262413801 377451173 88614642 +2452226090 2443004441 143726844 +1958673993 2586731285 188604820 +2595952934 3815253132 97799811 +882433672 754981589 206288528 +608195463 3121921986 8761321 +393888178 145828809 140878042 +3166108849 1530740045 97835767 +351028443 139489318 6339491 +3410232629 961270117 222147493 +2449796439 4292537645 2429651 +2401067597 1890048598 48728842 +3263944616 2376148398 66856043 +3330800659 1451308075 79431970 +3632380122 2019388074 205952206 +1548873457 1323582243 21597598 +2693752745 2225340280 142089882 +357367934 340930929 36520244 +0 493278299 50785717 +768194739 645497224 68742488 +2876584504 1183417610 140164633 +235201317 466065815 27212484 +1570471055 2367430162 8718236 +2147278813 2775336105 253788784 +874238988 3335153634 8194684 +2835842627 714239712 40741877 +3838332328 1938777440 80610634 +50785717 0 139489318 +616956784 3183915679 151237955 +836937227 608195463 37301761 +1098723094 3343348318 450150363 +3940697413 1628575812 261472786 + +temperature-to-humidity map: +3865679795 3411240257 137388137 +0 569718370 128927628 +2284256983 1093255418 349419361 +2189606444 2745948834 16886013 +3861728218 3796217004 3951577 +700036088 2134161201 67667679 +2639129496 1078899666 14355752 +4003067932 4146768977 27598493 +569558723 2311178479 130477365 +4125126694 3887925067 11822916 +1884679865 1442674779 129657290 +2633676344 1572332069 5453152 +862461784 1577785221 531688422 +4030666425 4120171499 26597478 +195554894 115268399 39538402 +235093296 235252943 334465427 +2132287170 698645998 57319274 +4158735055 3550090086 136232241 +2206492457 157488417 77764526 +3562496130 3899747983 220423516 +2653485248 2201828880 109349599 +2014337155 154806801 2681616 +1580787383 2536413861 97415145 +3453031511 3880534101 7390966 +1394150206 2633829006 45492562 +4057263903 3686322327 7821024 +4157273363 3548628394 1461692 +3460422477 3694143351 102073653 +4136949610 3800168581 20323753 +1678202528 872422329 206477337 +1556099825 2109473643 24687558 +128927628 2679321568 66627266 +2017018771 0 115268399 +4065084927 3820492334 60041767 +3411240257 4253176042 41791254 +767703767 2441655844 94758017 +1439642768 755965272 116457057 +3782919646 4174367470 78808572 + +humidity-to-location map: +347042062 4204488573 2962316 +877642375 2878291222 23518224 +3638916554 3484768713 5466055 +2890676240 3280663590 83564486 +201731623 3228655138 52008452 +1692198890 1946017811 25211210 +1717410100 1270737209 92827656 +3598929376 3630765534 39987178 +2226479211 1578430526 262844314 +687169155 3670752712 117494406 +3884728324 1515480569 62949957 +3494186405 1841274840 104742971 +2753482998 2630924017 120642845 +572458731 2235388494 114710424 +3947678281 3490234768 140530766 +3433348031 3167816764 60838374 +350004378 2406580589 222454353 +804663561 1442501755 72978814 +4132461733 2901809446 35781203 +4088209047 2937590649 38937925 +1441554453 2350098918 56481671 +3644382609 201731623 240345715 +2489323525 1971229021 264159473 +2974240726 3086380958 81435806 +4127146972 3364228076 5314761 +901160599 4207450889 87516407 +988677006 442077338 350976352 +1498036124 3369542837 115225876 +1810237756 3788247118 416241455 +1613262000 1363564865 78936890 +253740075 2993078971 93301987 +3055676532 894954785 375782424 +1339653358 793053690 101901095 +2874125843 2976528574 16550397 +3431458956 2629034942 1889075 +4168242936 2751566862 126724360 \ No newline at end of file