From 20852d6e60bee896e84c9bae77f45211773dbf60 Mon Sep 17 00:00:00 2001 From: Tomasz Chojnacki Date: Thu, 6 Apr 2023 14:41:14 +0200 Subject: Finish day 12 --- aoc-2020-gleam/src/util/dir.gleam | 41 +++++++++++++++++++++++++++++++++++++++ aoc-2020-gleam/src/util/pos.gleam | 25 ++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 aoc-2020-gleam/src/util/dir.gleam (limited to 'aoc-2020-gleam/src/util') diff --git a/aoc-2020-gleam/src/util/dir.gleam b/aoc-2020-gleam/src/util/dir.gleam new file mode 100644 index 0000000..6f637d9 --- /dev/null +++ b/aoc-2020-gleam/src/util/dir.gleam @@ -0,0 +1,41 @@ +import gleam/int +import gleam/iterator as iter +import ext/resultx as resx +import ext/iteratorx as iterx +import util/pos.{Pos} + +pub type Dir { + North + East + South + West +} + +pub fn offset(direction: Dir) -> Pos { + case direction { + North -> #(0, 1) + East -> #(1, 0) + South -> #(0, -1) + West -> #(-1, 0) + } +} + +pub fn degree_to_turn(degree: Int) -> Int { + resx.assert_unwrap(int.modulo(degree / 90, by: 4)) +} + +fn rotate_clockwise_once(direction: Dir) -> Dir { + case direction { + North -> East + East -> South + South -> West + West -> North + } +} + +pub fn rotate_clockwise(this direction: Dir, by times: Int) -> Dir { + direction + |> iterx.unfold_infinitely(with: rotate_clockwise_once) + |> iter.at(times) + |> resx.assert_unwrap +} diff --git a/aoc-2020-gleam/src/util/pos.gleam b/aoc-2020-gleam/src/util/pos.gleam index a060440..dd3d01d 100644 --- a/aoc-2020-gleam/src/util/pos.gleam +++ b/aoc-2020-gleam/src/util/pos.gleam @@ -1,9 +1,12 @@ +import gleam/int import gleam/list import gleam/set.{Set} pub type Pos = #(Int, Int) +pub const zero = #(0, 0) + pub const directions8 = [ #(1, 0), #(1, 1), @@ -19,8 +22,26 @@ pub fn add(p1: Pos, p2: Pos) -> Pos { #(p1.0 + p2.0, p1.1 + p2.1) } -pub fn neighbours8(pos: Pos) -> Set(Pos) { +pub fn sub(p1: Pos, p2: Pos) -> Pos { + #(p1.0 - p2.0, p1.1 - p2.1) +} + +pub fn mul(p: Pos, by scalar: Int) -> Pos { + #(p.0 * scalar, p.1 * scalar) +} + +pub fn neighbours8(p: Pos) -> Set(Pos) { directions8 - |> list.map(with: add(pos, _)) + |> list.map(with: add(p, _)) |> set.from_list } + +pub fn manhattan_dist(from p1: Pos, to p2: Pos) -> Int { + int.absolute_value(p1.0 - p2.0) + int.absolute_value(p1.1 - p2.1) +} + +pub fn rotate_around_origin(this p: Pos, by times: Int) -> Pos { + let assert Ok(sin) = list.at([0, -1, 0, 1], times) + let assert Ok(cos) = list.at([1, 0, -1, 0], times) + #(p.0 * cos - p.1 * sin, p.0 * sin + p.1 * cos) +} -- cgit v1.2.3