changeset 43:865325736c6f

Day 05 Part 1
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 05 Dec 2023 21:04:58 +0100
parents 95af5cf548c5
children 070e01565b16
files 2023/day05.ml 2023/dune 2023/input/05.txt 2023/input/05_test.txt
diffstat 4 files changed, 375 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2023/day05.ml	Tue Dec 05 21:04:58 2023 +0100
@@ -0,0 +1,126 @@
+open Angstrom
+open Base
+open Core
+module Hashtbl = Base.Hashtbl
+
+type rangemap = { dst_start : int; src_start : int; length : int }
+[@@deriving sexp]
+
+type input = { seeds : int list; maps : (string, rangemap list) Hashtbl.t }
+
+let sexp_of_input { seeds; maps } =
+  Sexp.List
+    [
+      Sexp.List [ Sexp.Atom "seeds"; List.sexp_of_t Int.sexp_of_t seeds ];
+      Sexp.List
+        [
+          Sexp.Atom "maps";
+          Hashtbl.sexp_of_t String.sexp_of_t
+            (List.sexp_of_t sexp_of_rangemap)
+            maps;
+        ];
+    ]
+
+module Parse = struct
+  let maybe p = option () (p >>= fun _ -> return ())
+
+  let intP =
+    take_while1 (function '0' .. '9' -> true | _ -> false) >>| Int.of_string
+
+  let int_listP = skip_many (char ' ') *> sep_by1 (skip_many1 (char ' ')) intP
+
+  let rangeP =
+    int_listP >>= function
+    | dst_start :: src_start :: length :: _rest ->
+        return { dst_start; src_start; length }
+    | _ -> assert false
+
+  let map_nameP = take_while1 (fun c -> not (Char.is_whitespace c))
+  let map_headerP = map_nameP <* string " map:\n"
+  let rangesP = many1 (rangeP <* char '\n') <* maybe (char '\n')
+
+  let mapP =
+    let open Angstrom.Let_syntax in
+    let%bind mapname = map_headerP in
+    let%bind ranges = rangesP in
+    return (mapname, ranges)
+
+  let seedsP = string "seeds: " *> int_listP <* string "\n\n"
+
+  let inputP =
+    let open Angstrom.Let_syntax in
+    let%bind seeds = seedsP in
+    let%bind maps = many1 mapP in
+    return (seeds, maps)
+
+  exception Parse_exn of string
+
+  let parse input =
+    match parse_string ~consume:All inputP input with
+    | Ok (seeds, maps) ->
+        let maps = Hashtbl.of_alist_exn (module String) maps in
+        { seeds; maps }
+    | Error e -> raise (Parse_exn e)
+
+  let _test_parse input =
+    let inp = parse input in
+    Out_channel.print_endline (Sexp.to_string_hum (sexp_of_input inp))
+end
+
+module Part1 = struct
+  let steps_names =
+    [
+      "seed-to-soil";
+      "soil-to-fertilizer";
+      "fertilizer-to-water";
+      "water-to-light";
+      "light-to-temperature";
+      "temperature-to-humidity";
+      "humidity-to-location";
+    ]
+
+  (* for a single step, resolve the number using the provided range maps. Return None if no mapping was found. *)
+  let resolve_step_maybe { dst_start; src_start; length } number =
+    if src_start <= number && number <= src_start + length then
+      Some (dst_start + (number - src_start))
+    else None
+
+  (* For all maps in a step, determine the final next number. *)
+  let rec resolve_step maps number =
+    match maps with
+    | map :: maps' -> (
+        match resolve_step_maybe map number with
+        | Some ok -> ok
+        | None -> resolve_step maps' number)
+    | [] -> number
+
+  (* Traverse steps for one seed *)
+  let rec traverse_for_seed seed = function
+    | step :: steps ->
+        let next = resolve_step step seed in
+        traverse_for_seed next steps
+    | [] -> seed
+
+  (* optain list of steps from hashmap *)
+  let maps_list maps_hm =
+    let f = Hashtbl.find_exn maps_hm in
+    List.map steps_names ~f
+
+  (* For all seeds, find resulting location (end number). *)
+  let traverse_all { seeds; maps } =
+    let maps = maps_list maps in
+    let results = List.map seeds ~f:(fun seed -> traverse_for_seed seed maps) in
+    results
+
+  (* Read, parse, and process input from channel. *)
+  let process ch =
+    let input = In_channel.input_all ch in
+    let input' = Parse.parse input in
+    let result = traverse_all input' in
+    Out_channel.print_endline
+      (Sexp.to_string_hum (List.sexp_of_t Int.sexp_of_t result));
+    Out_channel.printf "Result is %d\n"
+      (List.fold ~init:Int.max_value ~f:Int.min result)
+end
+
+let () = Part1.process In_channel.stdin
--- a/2023/dune	Mon Dec 04 23:02:33 2023 +0100
+++ b/2023/dune	Tue Dec 05 21:04:58 2023 +0100
@@ -25,3 +25,10 @@
  (libraries base core angstrom)
  (preprocess
   (pps ppx_let ppx_sexp_conv)))
+
+(executable
+ (name day05)
+ (modules day05)
+ (libraries base core angstrom)
+ (preprocess
+  (pps ppx_let ppx_sexp_conv)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2023/input/05.txt	Tue Dec 05 21:04:58 2023 +0100
@@ -0,0 +1,209 @@
+seeds: 4088478806 114805397 289354458 164506173 1415635989 166087295 1652880954 340945548 3561206012 483360452 35205517 252097746 1117825174 279314434 3227452369 145640027 2160384960 149488635 2637152665 236791935
+
+seed-to-soil map:
+3333452986 2926455387 455063168
+3222292973 1807198589 111160013
+4073195028 1120843626 221772268
+3215232741 2255546991 7060232
+1658311530 2727928910 32644400
+2680271553 1918358602 337188389
+1690955930 3973557555 28589896
+2081345351 4046183137 248784159
+2374165196 3613106716 306106357
+1553535599 2504868379 49003335
+4018850546 3919213073 54344482
+2050713919 2287201502 30631432
+3183342019 1775307867 31890722
+3975551599 2553871714 43298947
+1120843626 1342615894 432691973
+2330129510 4002147451 44035686
+1719545826 2628348978 99579932
+1819125758 3381518555 231588161
+1627133213 2597170661 31178317
+3017459942 2760573310 165882077
+3788516154 2317832934 187035445
+1602538934 2262607223 24594279
+
+soil-to-fertilizer map:
+2037529808 755544791 28492175
+786265521 51055407 490038659
+4209265112 3740304131 26706989
+1490754905 2631438697 34586718
+1525341623 2263058012 73974507
+1774661286 1921164897 262868522
+3007460847 4099468601 72419286
+3538443051 3849232192 250236409
+1276304180 541094066 214450725
+3913003454 3767011120 59428684
+1599316130 2497793999 133644698
+3079880133 3189897565 426082572
+716780020 784036966 69485501
+1732960828 0 41700458
+2066021983 41700458 9354949
+0 853522467 536962937
+3972432138 2920584245 236832974
+536962937 2337032519 100792490
+4272174908 3826439804 22792388
+3788679460 3615980137 124323994
+2135345922 1446730958 474433939
+637755427 2184033419 79024593
+2884381438 4171887887 123079409
+2075376932 2437825009 59968990
+4235972101 2884381438 36202807
+2609779861 1390485404 56245554
+3505962705 3157417219 32480346
+
+fertilizer-to-water map:
+2573961911 2642757339 200829754
+422488483 458127884 156893128
+2774791665 2843587093 21928567
+579381611 0 138939
+1694098304 2191562282 184724096
+3947192080 3245704277 276559964
+972559115 1385376838 44883044
+3491468609 3875486597 235886348
+1207641311 1359799603 25577235
+2301984556 4185647450 96253759
+3943275635 3001826942 3916445
+901810658 387379427 70748457
+285678041 1226326727 103026012
+0 775143786 192216167
+3304976053 3522264241 95407569
+2086394179 1904419031 20334668
+2797747442 1694098304 113068417
+2398238315 1924753699 175723596
+4223752044 2376286378 71215252
+192216167 1132864853 93461874
+392041619 1329352739 30446864
+736305758 967359953 44331476
+3740421044 2865515660 136311282
+388704053 771806220 3337566
+2796720232 4111372945 1027210
+3727354957 4281901209 13066087
+1017442159 197180275 190199152
+1878822400 4112400155 6703986
+3400383622 2100477295 91084987
+780637234 1011691429 121173424
+1885526386 3674618804 200867793
+2910815859 3617671810 56946994
+2967762853 1807166721 97252310
+3065015163 3005743387 239960890
+1233218546 138939 197041336
+2106728847 2447501630 195255709
+579520550 615021012 156785208
+3876732326 4119104141 66543309
+
+water-to-light map:
+1713604757 2608139445 8097487
+416889953 2083343492 58961768
+1343227622 1417788674 170490633
+2121243443 2549534549 51843959
+3366419885 3580448237 174948163
+2173087402 0 443149530
+3030450490 4139087067 155880229
+3186330719 3883823748 51661818
+1513718255 1282808215 134980459
+1075515973 1815631843 267711649
+967716956 443149530 107799017
+3237992537 3755396400 128427348
+3825109759 3262058246 318389991
+879862906 954959732 80165960
+6760937 1035125692 247682523
+2953403197 3185010953 77047293
+960028866 2541846459 7688090
+4143499750 3033543407 151467546
+2749801696 3935485566 203601501
+1648698714 1750725800 64906043
+254443460 1588279307 162446493
+475851721 550948547 404011185
+3541368048 2749801696 283741711
+1721702244 2142305260 399541199
+0 2601378508 6760937
+
+light-to-temperature map:
+72585995 0 6987206
+3613700480 3337307014 262222114
+3107305066 2641039316 68521519
+1346057837 1130104209 332811266
+1789578875 2709560835 110508022
+1678869103 3335693412 1613602
+4221249401 2413595122 73717895
+1283830508 2273268756 62227329
+2654986608 3645211688 211881713
+1900086897 3599529128 45682560
+866613618 2487313017 153726299
+1945769457 1462915475 224589729
+2170359186 2335496085 78099037
+1020339917 866613618 263490591
+3175826585 3857093401 437873895
+1680482705 3226597242 109096170
+2866868321 1687505204 240436745
+3875922594 1927941949 345326807
+2248458223 2820068857 406528385
+0 6987206 72585995
+
+temperature-to-humidity map:
+688557414 35571309 205276783
+1344556852 4212560627 61250968
+3617960922 3570339727 35153299
+1798596843 4122755682 89804945
+968601622 2840504203 289938389
+3674269922 3395595703 19024769
+2596309702 1911252584 80861179
+2438263727 2065549417 13406592
+1405807820 1518463561 392789023
+617995054 866387965 70562360
+1258540011 2078956009 86016841
+3395085595 2301904832 149439673
+4212818712 3130442592 82148584
+1888401788 968601622 549861939
+3005925897 2451344505 389159698
+3544525268 1992113763 73435654
+929405506 858843146 7544819
+3868591817 3605493026 188507640
+3653114221 4273811595 21155701
+893834197 0 35571309
+2588602301 3387888302 7707401
+2677170881 3794000666 328755016
+4057099457 3414620472 155719255
+0 240848092 617995054
+3693294691 3212591176 175297126
+2451670319 2164972850 136931982
+
+humidity-to-location map:
+3586928302 2065932610 149219519
+709155282 323064563 19167863
+1359021687 3937987878 39697029
+4009761511 2966667063 138486244
+300370292 619673957 122108798
+1230327417 992326977 128694270
+1524755905 3624589590 105592616
+3736147821 2637585432 174385627
+1068077767 3730182206 162249650
+3120252652 1674438017 80200651
+434861301 1581164273 93273744
+3489613286 225749547 97315016
+2210476726 741782755 111642249
+1630348521 1811987842 123678973
+1456067890 2488658901 68688015
+2890604013 917374342 74952635
+2638888586 853425004 63949338
+528135045 2557346916 80238516
+2440002559 2215152129 198886027
+608373561 3105153307 100781721
+3910533448 342232426 99228063
+4148247755 3892431856 45556022
+2702837924 4107201207 187766089
+1754027494 1121021247 298601872
+2322118975 1948049026 117883584
+889864299 441460489 178213468
+3200453303 3559871086 36387444
+225749547 2414038156 74620745
+422479090 1935666815 12382211
+728323145 1419623119 161541154
+1398718716 1754638668 57349174
+2052629366 3977684907 129516300
+4193803777 3458707567 101163519
+2182145666 3596258530 28331060
+2965556648 2811971059 154696004
+3236840747 3205935028 252772539
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/2023/input/05_test.txt	Tue Dec 05 21:04:58 2023 +0100
@@ -0,0 +1,33 @@
+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