Skip to content

Commit

Permalink
2024 day 3 pt1 and day 4
Browse files Browse the repository at this point in the history
  • Loading branch information
TanklesXL committed Dec 4, 2024
1 parent 1113537 commit 39ff337
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 0 deletions.
3 changes: 3 additions & 0 deletions gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ gleam_json = "~> 2.0"
gladvent = "~> 2.0"
gleam_yielder = ">= 1.0.0 and < 2.0.0"
tote = ">= 1.0.2 and < 2.0.0"
nibble = ">= 1.1.1 and < 2.0.0"

[dev-dependencies]
gleeunit = ">= 1.2.0 and < 2.0.0"
Expand Down Expand Up @@ -58,3 +59,5 @@ gleeunit = ">= 1.2.0 and < 2.0.0"
[gladvent.2024]
1 = { pt_1 = 1579939, pt_2 = 20351745 }
2 = { pt_1 = 282, pt_2 = 349 }
3 = { pt_1 = 166905464 }
4 = { pt_1 = 2718, pt_2 = 2046 }
2 changes: 2 additions & 0 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ packages = [
{ name = "glearray", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glearray", source = "hex", outer_checksum = "B99767A9BC63EF9CC8809F66C7276042E5EFEACAA5B25188B552D3691B91AC6D" },
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
{ name = "glint", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_community_colour", "gleam_stdlib", "snag"], otp_app = "glint", source = "hex", outer_checksum = "5F6720081150AED8023131B0F3A35F9B0D6426A96CE02BEC52AD7018DF70566A" },
{ name = "nibble", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "nibble", source = "hex", outer_checksum = "67C6BEBC1AB6D771AB893B4A7B3E66C92668C6E7774C335FEFCD545B06435FE5" },
{ name = "parallel_map", version = "2.1.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_otp", "gleam_stdlib"], otp_app = "parallel_map", source = "hex", outer_checksum = "DE2BA9878728EF9EE34BE83FEDC7A18A1ABE4B2AC1E79C710E3E5D95F5E73404" },
{ name = "repeatedly", version = "2.1.2", build_tools = ["gleam"], requirements = [], otp_app = "repeatedly", source = "hex", outer_checksum = "93AE1938DDE0DC0F7034F32C1BF0D4E89ACEBA82198A1FE21F604E849DA5F589" },
{ name = "shellout", version = "1.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "shellout", source = "hex", outer_checksum = "E2FCD18957F0E9F67E1F497FC9FF57393392F8A9BAEAEA4779541DE7A68DD7E0" },
Expand All @@ -33,4 +34,5 @@ gleam_json = { version = "~> 2.0" }
gleam_stdlib = { version = "~> 0.39" }
gleam_yielder = { version = ">= 1.0.0 and < 2.0.0" }
gleeunit = { version = ">= 1.2.0 and < 2.0.0" }
nibble = { version = ">= 1.1.1 and < 2.0.0" }
tote = { version = ">= 1.0.2 and < 2.0.0" }
97 changes: 97 additions & 0 deletions src/aoc_2024/day_3.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import gleam/int
import gleam/io
import gleam/list
import gleam/option
import gleam/string
import nibble.{do, return}
import nibble/lexer

pub type T {
M
U
L
Open
Close
Comma
Number(Int)
Other
}

pub fn pt_1(input: String) {
let assert Ok(out) =
[
lexer.token("m", M),
lexer.token("u", U),
lexer.token("l", L),
lexer.token("(", Open),
lexer.token(")", Close),
lexer.token(",", Comma),
lexer.int(Number),
lexer.keep(fn(the_string, _) {
case
the_string
|> string.to_graphemes
|> list.map(fn(char) { string.contains("mul(),0123456789", char) })
|> list.all(fn(x) { x })
{
True -> Error(Nil)
False -> Ok(Other)
}
}),
]
|> lexer.simple()
|> lexer.run(input, _)

let int_parser = {
// Use `take_map` to only consume certain kinds of tokens and transform the
// result.
use tok <- nibble.take_map("expected number")
case tok {
Number(n) -> option.Some(n)
_ -> option.None
}
}

let parser = {
use acc <- nibble.loop(0)
nibble.one_of([
{
use _ <- do(nibble.token(M))
use _ <- do(nibble.token(U))
use _ <- do(nibble.token(L))
use _ <- do(nibble.token(Open))
use x <- do(int_parser)
use _ <- do(nibble.token(Comma))
use y <- do(int_parser)
use _ <- do(nibble.token(Close))

{ x * y }
|> return
}
|> nibble.backtrackable
|> nibble.map(int.add(acc, _))
|> nibble.map(nibble.Continue),
// if that fails take everything until we find another `m`
nibble.take_until1("wtf bro", fn(tok) { tok == M })
|> nibble.replace(acc)
|> nibble.map(nibble.Continue),
// we need to explicitly handle the case where we have an `m`
// but `mul_parser` failed
nibble.token(M)
|> nibble.replace(acc)
|> nibble.map(nibble.Continue),
// we reached the end, return our list
nibble.eof()
|> nibble.map(fn(_) { acc })
|> nibble.map(nibble.Break),
])
}

let assert Ok(out) = nibble.run(out, parser)

out
}

pub fn pt_2(input: String) {
todo as "part 2 not implemented"
}
127 changes: 127 additions & 0 deletions src/aoc_2024/day_4.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import gleam/bool
import gleam/dict
import gleam/list
import gleam/string

pub type Pos {
Pos(row: Int, col: Int)
}

pub type Displacement {
Displacement(row: Int, col: Int)
}

pub type Letter {
X
M
A
S
}

pub fn parse(input: String) -> dict.Dict(Pos, Letter) {
use acc, line, row <- list.index_fold(string.split(input, "\n"), dict.new())
use acc, letter, col <- list.index_fold(string.to_graphemes(line), acc)
case letter {
"X" -> X
"M" -> M
"A" -> A
"S" -> S
_ -> panic as { "unexpected letter: " <> letter }
}
|> dict.insert(acc, Pos(row:, col:), _)
}

fn verify(
sequence: List(Letter),
pos: Pos,
data: dict.Dict(Pos, Letter),
direction: Displacement,
) -> Bool {
case sequence {
[] -> True
[head, ..tail] ->
case dict.get(data, pos) {
Ok(letter) if letter == head ->
verify(
tail,
Pos(row: pos.row + direction.row, col: pos.col + direction.col),
data,
direction,
)
_ -> False
}
}
}

pub fn pt_1(input: dict.Dict(Pos, Letter)) {
use acc, start, letter <- dict.fold(input, 0)
use <- bool.guard(when: letter != X, return: acc)
acc
+ list.count(
[
// down to the left
Displacement(1, -1),
// down
Displacement(1, 0),
//down to the right
Displacement(1, 1),
// to the right
Displacement(0, 1),
// to the left
Displacement(0, -1),
// up to the left
Displacement(-1, -1),
// up
Displacement(-1, 0),
// up to the right
Displacement(-1, 1),
],
verify([X, M, A, S], start, input, _),
)
}

pub fn pt_2(input: dict.Dict(Pos, Letter)) {
use acc, a_position, letter <- dict.fold(input, 0)
use <- bool.guard(when: letter != A, return: acc)
acc
+ list.count(
[
// M S
// A
// M S
#(Displacement(row: 1, col: 1), Displacement(row: -1, col: 1)),
// M M
// A
// S S
#(Displacement(row: 1, col: 1), Displacement(row: 1, col: -1)),
// S M
// A
// S M
#(Displacement(row: 1, col: -1), Displacement(row: -1, col: -1)),
// S S
// A
// M M
#(Displacement(row: -1, col: 1), Displacement(row: -1, col: -1)),
],
fn(starts) {
verify(
[M, A, S],
Pos(
row: a_position.row - { starts.0 }.row,
col: a_position.col - { starts.0 }.col,
),
input,
starts.0,
)
&& verify(
[M, A, S],
Pos(
row: a_position.row - { starts.1 }.row,
col: a_position.col - { starts.1 }.col,
),
input,
starts.1,
)
},
)
}

0 comments on commit 39ff337

Please sign in to comment.