aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-12-23 13:33:34 +0100
committerTomasz Chojnacki <tomaszchojnacki2001@gmail.com>2023-12-23 13:33:34 +0100
commit8bafdaf384fd144a61a7d23661a6cc8d56b5d810 (patch)
treefe8eb9c334c86056bebeb3c6cba6f9069a472f09
parent5aa24ac572ab5451e187f9accfa6833634c58215 (diff)
downloadgleam_aoc2020-8bafdaf384fd144a61a7d23661a6cc8d56b5d810.tar.gz
gleam_aoc2020-8bafdaf384fd144a61a7d23661a6cc8d56b5d810.zip
Finish day 24
-rw-r--r--aoc-2020-gleam/src/days/day24.gleam47
-rw-r--r--aoc-2020-gleam/src/ext/setx.gleam7
-rw-r--r--aoc-2020-gleam/src/util/hex.gleam27
-rw-r--r--aoc-2020-gleam/src/util/pos2.gleam21
-rw-r--r--aoc-2020-gleam/src/util/pos3.gleam23
-rw-r--r--aoc-2020-gleam/src/util/pos4.gleam25
6 files changed, 106 insertions, 44 deletions
diff --git a/aoc-2020-gleam/src/days/day24.gleam b/aoc-2020-gleam/src/days/day24.gleam
index 66bedb8..f380530 100644
--- a/aoc-2020-gleam/src/days/day24.gleam
+++ b/aoc-2020-gleam/src/days/day24.gleam
@@ -1,13 +1,14 @@
import gleam/io
-import gleam/set
+import gleam/bool
import gleam/list
+import gleam/set.{type Set}
import ext/setx
import ext/resultx as resx
import util/input_util
import util/parser as p
import util/hex.{type Hex}
-fn parse_tiles(lines: List(String)) -> List(Hex) {
+fn parse_flips(lines: List(String)) -> List(Hex) {
let tile_parser =
[
p.replace(p.literal("e"), with: hex.e),
@@ -28,20 +29,50 @@ fn parse_tiles(lines: List(String)) -> List(Hex) {
})
}
+fn get_black_tiles(flips: List(Hex)) -> Set(Hex) {
+ list.fold(over: flips, from: set.new(), with: setx.toggle)
+}
+
+fn cycle(prev: Set(Hex), times: Int) -> Set(Hex) {
+ use <- bool.guard(when: times == 0, return: prev)
+
+ prev
+ |> setx.flat_map(with: hex.neighbours7)
+ |> set.fold(from: set.new(), with: fn(acc, tile) {
+ let was_black = set.contains(in: prev, this: tile)
+ let adjacent =
+ tile
+ |> hex.neighbours6
+ |> set.intersection(prev)
+ |> set.size
+
+ case #(was_black, adjacent) {
+ #(True, 1) | #(_, 2) -> set.insert(into: acc, this: tile)
+ _ -> acc
+ }
+ })
+ |> cycle(times - 1)
+}
+
fn part1(lines: List(String)) -> Int {
- let tiles = parse_tiles(lines)
- let blacks = list.fold(over: tiles, from: set.new(), with: setx.toggle)
- set.size(blacks)
+ lines
+ |> parse_flips
+ |> get_black_tiles
+ |> set.size
}
-fn part2(lines: List(String)) -> Nil {
- Nil
+fn part2(lines: List(String)) -> Int {
+ lines
+ |> parse_flips
+ |> get_black_tiles
+ |> cycle(100)
+ |> set.size
}
pub fn main() -> Nil {
let testing = input_util.read_lines("test24")
let assert 10 = part1(testing)
- io.debug(part2(testing))
+ let assert 2208 = part2(testing)
let input = input_util.read_lines("day24")
io.debug(part1(input))
diff --git a/aoc-2020-gleam/src/ext/setx.gleam b/aoc-2020-gleam/src/ext/setx.gleam
index 6df9256..4a9c0c1 100644
--- a/aoc-2020-gleam/src/ext/setx.gleam
+++ b/aoc-2020-gleam/src/ext/setx.gleam
@@ -17,6 +17,13 @@ pub fn map(s: Set(a), with fun: fn(a) -> b) -> Set(b) {
|> set.from_list
}
+pub fn flat_map(s: Set(a), with fun: fn(a) -> Set(b)) -> Set(b) {
+ s
+ |> set.to_list
+ |> list.map(with: fun)
+ |> list.fold(from: set.new(), with: set.union)
+}
+
pub fn toggle(in s: Set(a), this value: a) -> Set(a) {
s
|> case set.contains(in: s, this: value) {
diff --git a/aoc-2020-gleam/src/util/hex.gleam b/aoc-2020-gleam/src/util/hex.gleam
index 21db192..070b6e4 100644
--- a/aoc-2020-gleam/src/util/hex.gleam
+++ b/aoc-2020-gleam/src/util/hex.gleam
@@ -1,3 +1,8 @@
+import gleam/bool
+import gleam/list
+import gleam/set.{type Set}
+import ext/setx
+
pub opaque type Hex {
Hex(q: Int, r: Int, s: Int)
}
@@ -19,3 +24,25 @@ pub const ne = Hex(q: 1, r: -1, s: 0)
pub fn add(a: Hex, b: Hex) -> Hex {
Hex(q: a.q + b.q, r: a.r + b.r, s: a.s + b.s)
}
+
+fn directions7() -> Set(Hex) {
+ set.from_list({
+ use q <- list.flat_map([-1, 0, 1])
+ use r <- list.flat_map([-1, 0, 1])
+ use s <- list.flat_map([-1, 0, 1])
+ use <- bool.guard(when: q + r + s != 0, return: [])
+ [Hex(q, r, s)]
+ })
+}
+
+fn directions6() -> Set(Hex) {
+ set.delete(from: directions7(), this: zero)
+}
+
+pub fn neighbours6(h: Hex) -> Set(Hex) {
+ setx.map(directions6(), with: add(h, _))
+}
+
+pub fn neighbours7(h: Hex) -> Set(Hex) {
+ setx.map(directions7(), with: add(h, _))
+}
diff --git a/aoc-2020-gleam/src/util/pos2.gleam b/aoc-2020-gleam/src/util/pos2.gleam
index 3f478ac..976088e 100644
--- a/aoc-2020-gleam/src/util/pos2.gleam
+++ b/aoc-2020-gleam/src/util/pos2.gleam
@@ -1,7 +1,7 @@
import gleam/int
-import gleam/bool
import gleam/list
import gleam/set.{type Set}
+import ext/setx
pub type Pos2 =
#(Int, Int)
@@ -16,16 +16,18 @@ pub fn y(pos: Pos2) -> Int {
pos.1
}
-pub fn directions8() -> Set(Pos2) {
+fn directions9() -> Set(Pos2) {
set.from_list({
- use x <- list.flat_map(over: [-1, 0, 1])
- use y <- list.flat_map(over: [-1, 0, 1])
- let pos = #(x, y)
- use <- bool.guard(when: pos == zero, return: [])
- [pos]
+ use x <- list.flat_map([-1, 0, 1])
+ use y <- list.map([-1, 0, 1])
+ #(x, y)
})
}
+pub fn directions8() -> Set(Pos2) {
+ set.delete(from: directions9(), this: zero)
+}
+
pub fn add(p1: Pos2, p2: Pos2) -> Pos2 {
#(p1.0 + p2.0, p1.1 + p2.1)
}
@@ -39,10 +41,7 @@ pub fn mul(p: Pos2, by scalar: Int) -> Pos2 {
}
pub fn neighbours8(p: Pos2) -> Set(Pos2) {
- directions8()
- |> set.to_list
- |> list.map(with: add(p, _))
- |> set.from_list
+ setx.map(directions8(), with: add(p, _))
}
pub fn manhattan_dist(from p1: Pos2, to p2: Pos2) -> Int {
diff --git a/aoc-2020-gleam/src/util/pos3.gleam b/aoc-2020-gleam/src/util/pos3.gleam
index 3787c19..e493187 100644
--- a/aoc-2020-gleam/src/util/pos3.gleam
+++ b/aoc-2020-gleam/src/util/pos3.gleam
@@ -1,30 +1,29 @@
import gleam/list
-import gleam/bool
import gleam/set.{type Set}
+import ext/setx
pub type Pos3 =
#(Int, Int, Int)
pub const zero = #(0, 0, 0)
-fn directions26() -> Set(Pos3) {
+fn directions27() -> Set(Pos3) {
set.from_list({
- use x <- list.flat_map(over: [-1, 0, 1])
- use y <- list.flat_map(over: [-1, 0, 1])
- use z <- list.flat_map(over: [-1, 0, 1])
- let pos = #(x, y, z)
- use <- bool.guard(when: pos == zero, return: [])
- [pos]
+ use x <- list.flat_map([-1, 0, 1])
+ use y <- list.flat_map([-1, 0, 1])
+ use z <- list.map([-1, 0, 1])
+ #(x, y, z)
})
}
+fn directions26() -> Set(Pos3) {
+ set.delete(from: directions27(), this: zero)
+}
+
pub fn add(p1: Pos3, p2: Pos3) -> Pos3 {
#(p1.0 + p2.0, p1.1 + p2.1, p1.2 + p2.2)
}
pub fn neighbours26(p: Pos3) -> Set(Pos3) {
- directions26()
- |> set.to_list
- |> list.map(with: add(p, _))
- |> set.from_list
+ setx.map(directions26(), with: add(p, _))
}
diff --git a/aoc-2020-gleam/src/util/pos4.gleam b/aoc-2020-gleam/src/util/pos4.gleam
index a96bcca..c2ab1c7 100644
--- a/aoc-2020-gleam/src/util/pos4.gleam
+++ b/aoc-2020-gleam/src/util/pos4.gleam
@@ -1,31 +1,30 @@
import gleam/list
-import gleam/bool
import gleam/set.{type Set}
+import ext/setx
pub type Pos4 =
#(Int, Int, Int, Int)
pub const zero = #(0, 0, 0, 0)
-fn directions80() -> Set(Pos4) {
+fn directions81() -> Set(Pos4) {
set.from_list({
- use x <- list.flat_map(over: [-1, 0, 1])
- use y <- list.flat_map(over: [-1, 0, 1])
- use z <- list.flat_map(over: [-1, 0, 1])
- use w <- list.flat_map(over: [-1, 0, 1])
- let pos = #(x, y, z, w)
- use <- bool.guard(when: pos == zero, return: [])
- [pos]
+ use x <- list.flat_map([-1, 0, 1])
+ use y <- list.flat_map([-1, 0, 1])
+ use z <- list.flat_map([-1, 0, 1])
+ use w <- list.map([-1, 0, 1])
+ #(x, y, z, w)
})
}
+fn directions80() -> Set(Pos4) {
+ set.delete(from: directions81(), this: zero)
+}
+
pub fn add(p1: Pos4, p2: Pos4) -> Pos4 {
#(p1.0 + p2.0, p1.1 + p2.1, p1.2 + p2.2, p1.3 + p2.3)
}
pub fn neighbours80(p: Pos4) -> Set(Pos4) {
- directions80()
- |> set.to_list
- |> list.map(with: add(p, _))
- |> set.from_list
+ setx.map(directions80(), with: add(p, _))
}