From 2baaf46a44c80cb364b20db93ec1ee48a66a5784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Charv=C3=A1t?= Date: Sun, 8 Dec 2024 14:08:33 +0100 Subject: [PATCH] Day08 --- day08/gleam.toml | 22 +++++++ day08/input.txt | 50 +++++++++++++++ day08/manifest.toml | 18 ++++++ day08/small-in.txt | 12 ++++ day08/src/day08.gleam | 121 ++++++++++++++++++++++++++++++++++++ day08/test/day08_test.gleam | 27 ++++++++ 6 files changed, 250 insertions(+) create mode 100644 day08/gleam.toml create mode 100644 day08/input.txt create mode 100644 day08/manifest.toml create mode 100644 day08/small-in.txt create mode 100644 day08/src/day08.gleam create mode 100644 day08/test/day08_test.gleam diff --git a/day08/gleam.toml b/day08/gleam.toml new file mode 100644 index 0000000..4f2f262 --- /dev/null +++ b/day08/gleam.toml @@ -0,0 +1,22 @@ +name = "day08" +version = "1.0.0" + +# Fill out these fields if you intend to generate HTML documentation or publish +# your project to the Hex package manager. +# +# description = "" +# licences = ["Apache-2.0"] +# repository = { type = "github", user = "", repo = "" } +# links = [{ title = "Website", href = "" }] +# +# For a full reference of all the available options, you can have a look at +# https://gleam.run/writing-gleam/gleam-toml/. + +[dependencies] +gleam_stdlib = ">= 0.34.0 and < 2.0.0" +simplifile = ">= 2.2.0 and < 3.0.0" +gleam_yielder = ">= 1.1.0 and < 2.0.0" +gleam_community_maths = ">= 1.1.1 and < 2.0.0" + +[dev-dependencies] +gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/day08/input.txt b/day08/input.txt new file mode 100644 index 0000000..82d26e9 --- /dev/null +++ b/day08/input.txt @@ -0,0 +1,50 @@ +.I.........................................U...... +.....................9.......N........G.........U. +....................................GN............ +...j.....A...S.................................... +.j...o...S......t.....9........................... +.................................................. +.....3...................9.....................G.. +..I.....3...........................iG.x..2....... +......o...j...Sh.......x...t..........U....2...... +.r...I.o.b.w.....h...............U............M..i +3...w......7...................................... +......S.r.......h...................N............. +........7..r..........5.h......................... +....J.......7B......x...O..........y.............. +......I...J..a..x..............O.......H.......... +w..Fj..............t.O................H......2.... +........a..m..........y...O.4.............l....... +.....Jm....................4...................... +..m.......................2.Ny..............M.H... +.......a................X.....5k.....M.........H.. +.........F...........A...................M.K...... +.......7...........m....t...y.........K........... +....i.....................B....................... +.................5................6............... +........b..T................ABK....i.............. +....................s..................K.......... +.....w...J.............s.................W......n. +..............F........X...8...................... +...........4..................s...........W....f.. +.........g.....so.B.9..Y........4............6...f +.................................................. +b......1....................8..................W.. +Lb...g.R..0...................Y................l.. +................................n...........f...l. +..........g..............n8.....k......6.......... +.....R....A0.......................n..........W..l +...............................d..............6... +........................k..................D...... +...0............X......8.k........F............... +....a....L..............Y.................D....... +.........1...L.........u...D.......Yd............. +.............................d...u................ +........R...................................D....X +............L.g.0................................. +.................................................. +..............................T................... +........................T......................... +....................u..........T.................. +....1...................u......................... +..................R...................d........... diff --git a/day08/manifest.toml b/day08/manifest.toml new file mode 100644 index 0000000..e2cfc07 --- /dev/null +++ b/day08/manifest.toml @@ -0,0 +1,18 @@ +# This file was generated by Gleam +# You typically do not need to edit this file + +packages = [ + { name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" }, + { name = "gleam_community_maths", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_maths", source = "hex", outer_checksum = "6C4ED7BC7E7DF6977719B5F2CFE717EE8280D1CF6EA81D55FD9953758C7FD14E" }, + { name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" }, + { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" }, + { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" }, + { name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" }, +] + +[requirements] +gleam_community_maths = { version = ">= 1.1.1 and < 2.0.0" } +gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } +gleam_yielder = { version = ">= 1.1.0 and < 2.0.0" } +gleeunit = { version = ">= 1.0.0 and < 2.0.0" } +simplifile = { version = ">= 2.2.0 and < 3.0.0" } diff --git a/day08/small-in.txt b/day08/small-in.txt new file mode 100644 index 0000000..78a1e91 --- /dev/null +++ b/day08/small-in.txt @@ -0,0 +1,12 @@ +............ +........0... +.....0...... +.......0.... +....0....... +......A..... +............ +............ +........A... +.........A.. +............ +............ diff --git a/day08/src/day08.gleam b/day08/src/day08.gleam new file mode 100644 index 0000000..b56457a --- /dev/null +++ b/day08/src/day08.gleam @@ -0,0 +1,121 @@ +import gleam/io +import gleam/list +import gleam/result +import gleam/set +import gleam/string +import gleam/yielder +import gleam_community/maths/arithmetics +import simplifile + +type Coord { + Coord(row: Int, col: Int) +} + +fn smallest_step(c: Coord) { + let gcd = arithmetics.gcd(c.row, c.col) + Coord(c.row / gcd, c.col / gcd) +} + +fn add_coord(a: Coord, b: Coord) { + Coord(a.row + b.row, a.col + b.col) +} + +fn sub_coord(a: Coord, b: Coord) { + Coord(a.row - b.row, a.col - b.col) +} + +fn neg_coord(c: Coord) { + Coord(-c.row, -c.col) +} + +type Map { + Map(rows: Int, cols: Int, map: List(List(Coord))) +} + +fn parse_grid(input: String) -> Map { + let lines = string.split(input, "\n") + + let height = list.length(lines) + let width = + string.length(list.first(lines) |> result.lazy_unwrap(fn() { panic })) + + let grid = + lines + |> list.index_map(fn(row, y) { + string.split(row, "") + |> list.index_map(fn(el, x) { #(el, Coord(y, x)) }) + |> list.filter(fn(x) { x.0 != "." }) + }) + |> list.flatten + |> list.sort(fn(a, b) { string.compare(a.0, b.0) }) + |> list.chunk(fn(x) { x.0 }) + |> list.map(fn(chunk) { chunk |> list.map(fn(x) { x.1 }) }) + + Map(height, width, grid) +} + +fn calc_interference(antennas: List(Coord)) -> set.Set(Coord) { + antennas + |> list.combination_pairs + |> list.map(fn(p) { + let #(a, b) = p + let d = sub_coord(b, a) + set.from_list([sub_coord(a, d), add_coord(b, d)]) + }) + |> list.fold(set.new(), set.union) +} + +fn in_grid(c: Coord, rows: Int, cols: Int) -> Bool { + c.row >= 0 && c.col >= 0 && c.row < rows && c.col < cols +} + +pub fn part1(input: String) -> Int { + let Map(rows, cols, map) = parse_grid(input) + + map + |> list.map(calc_interference) + |> list.fold(set.new(), set.union) + |> set.filter(in_grid(_, rows, cols)) + |> set.size +} + +fn calc_infinite_interference( + antennas: List(Coord), + rows: Int, + cols: Int, +) -> set.Set(Coord) { + let step = fn(from: Coord, by: Coord) -> set.Set(Coord) { + from + |> yielder.iterate(add_coord(_, by)) + |> yielder.take_while(in_grid(_, rows, cols)) + |> yielder.fold(set.new(), set.insert) + } + + antennas + |> list.combination_pairs + |> list.map(fn(p) { + let #(a, b) = p + let d = smallest_step(Coord(a.row - b.row, a.col - b.col)) + set.union(step(a, d), step(b, neg_coord(d))) + }) + |> list.fold(set.new(), set.union) +} + +pub fn part2(input: String) -> Int { + let Map(rows, cols, map) = parse_grid(input) + + map + |> list.map(calc_infinite_interference(_, rows, cols)) + |> list.fold(set.new(), set.union) + |> set.size +} + +pub fn main() { + let input = + simplifile.read("input.txt") + |> result.lazy_unwrap(fn() { panic }) + |> string.trim + + io.println("Part 1: " <> string.inspect(part1(input))) + io.println("Part 2: " <> string.inspect(part2(input))) +} diff --git a/day08/test/day08_test.gleam b/day08/test/day08_test.gleam new file mode 100644 index 0000000..a185d71 --- /dev/null +++ b/day08/test/day08_test.gleam @@ -0,0 +1,27 @@ +import gleam/result +import gleam/string +import gleeunit +import gleeunit/should +import simplifile + +import day08 + +fn input() -> String { + simplifile.read("small-in.txt") + |> result.lazy_unwrap(fn() { panic }) + |> string.trim +} + +pub fn main() { + gleeunit.main() +} + +pub fn part1_test() { + day08.part1(input()) + |> should.equal(14) +} + +pub fn part2_test() { + day08.part2(input()) + |> should.equal(34) +}