Skip to content

Commit

Permalink
day 06: parallelized
Browse files Browse the repository at this point in the history
  • Loading branch information
sreedevk committed Dec 6, 2024
1 parent 0afe658 commit 012b0d5
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 18 deletions.
1 change: 1 addition & 0 deletions gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ gleam_stdlib = ">= 0.34.0 and < 2.0.0"
simplifile = ">= 2.2.0 and < 3.0.0"
gleam_regexp = ">= 1.0.0 and < 2.0.0"
gleam_yielder = ">= 1.1.0 and < 2.0.0"
gleam_otp = ">= 0.14.1 and < 1.0.0"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
3 changes: 3 additions & 0 deletions manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

packages = [
{ name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" },
{ name = "gleam_erlang", version = "0.33.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "A1D26B80F01901B59AABEE3475DD4C18D27D58FA5C897D922FCB9B099749C064" },
{ name = "gleam_otp", version = "0.14.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5A8CE8DBD01C29403390A7BD5C0A63D26F865C83173CF9708E6E827E53159C65" },
{ name = "gleam_regexp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "A3655FDD288571E90EE9C4009B719FEF59FA16AFCDF3952A76A125AF23CF1592" },
{ 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" },
Expand All @@ -11,6 +13,7 @@ packages = [
]

[requirements]
gleam_otp = { version = ">= 0.14.1 and < 1.0.0" }
gleam_regexp = { version = ">= 1.0.0 and < 2.0.0" }
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
gleam_yielder = { version = ">= 1.1.0 and < 2.0.0" }
Expand Down
3 changes: 2 additions & 1 deletion src/advent_of_code.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ pub fn main() {
"[6] Guard Gallivant (Part 1): " <> int.to_string(day06.solve_a(data)),
)
io.println(
"[6] Guard Gallivant (Part 2): " <> int.to_string(day06.solve_b(data)),
"[6] Guard Gallivant (Part 2): skipped execution (runtime 9m30s)",
// <> int.to_string(day06.solve_b(data)),
)
}),
Nil,
Expand Down
44 changes: 27 additions & 17 deletions src/guard_gallivant.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import gleam/dict.{type Dict}
import gleam/list
import gleam/option.{type Option}
import gleam/option.{type Option, Some}
import gleam/otp/task
import gleam/pair
import gleam/result
import gleam/string
Expand Down Expand Up @@ -39,7 +40,7 @@ type State =
type AdvState =
#(State, Bool)

fn parse_line(line, y) {
fn parse_column(line, y) {
use grid, char, x <- list.index_fold(line, dict.new())
dict.insert(grid, #(x, y), case char {
"." -> Path
Expand All @@ -54,7 +55,7 @@ fn parse_grid(input: String) -> Grid {
|> string.trim()
|> string.split("\n")
|> list.map(string.to_graphemes)
|> list.index_map(parse_line)
|> list.index_map(parse_column)
|> list.reduce(dict.merge)
|> result.unwrap(dict.new())
}
Expand All @@ -72,9 +73,9 @@ fn guard_position(grid: Grid) -> Result(Point, Nil) {
|> result.map(fn(set) { pair.first(set) })
}

fn init_state(grid: Grid) -> State {
let assert Ok(gp) = guard_position(grid)
#(gp, Up, grid, [#(gp, Up)], #(max_x(grid), max_y(grid)))
fn init_state(g: Grid) -> State {
let assert Ok(gp) = guard_position(g)
#(gp, Up, g, [#(gp, Up)], #(max_x(g), max_y(g)))
}

fn init_adv_state(grid: Grid) -> AdvState {
Expand Down Expand Up @@ -124,8 +125,8 @@ fn next_coordinates(pos: Point, dir: Direction, g: Grid) -> #(Point, Direction)

fn guard_exited(pos: Point, bounds: #(Int, Int)) -> Bool {
let #(x, y) = pos
let #(max_x, max_y) = bounds
x > max_x || x < 0 || y < 0 || y > max_y
let #(mx, my) = bounds
x > mx || x < 0 || y < 0 || y > my
}

fn emulate(state: State) -> State {
Expand Down Expand Up @@ -164,18 +165,29 @@ fn iterate(astate: AdvState) -> AdvState {
fn add_obst(g: Grid, pt: Point) -> Grid {
dict.upsert(g, pt, fn(ent: Option(Entity)) {
case ent {
option.Some(Guard) -> Guard
Some(Guard) -> Guard
_ -> UserObst
}
})
}

fn computer_obst_var_res(g: Grid) -> Int {
fn computer_obst_chunk_var(g: Grid, points: List(Point)) -> List(Bool) {
use obs_pos <- list.map(points)
add_obst(g, obs_pos)
|> init_adv_state
|> iterate
|> pair.second
}

fn computer_obst_all_var(g: Grid) -> Int {
dict.keys(g)
|> list.map(add_obst(g, _))
|> list.map(init_adv_state)
|> list.map(iterate)
|> list.count(pair.second)
|> list.sized_chunk(5000)
|> list.map(fn(pos_chunk) {
task.async(fn() { computer_obst_chunk_var(g, pos_chunk) })
})
|> list.map(task.await_forever)
|> list.flatten
|> list.count(fn(x) { x })
}

pub fn solve_a(input: String) -> Int {
Expand All @@ -185,9 +197,7 @@ pub fn solve_a(input: String) -> Int {
|> visited_count
}

// NOTE: WORKS FOR EXAMPLE BUT NEVER FINISHES RUNNING FOR ACTUAL INPUT
// TODO: Optimize
pub fn solve_b(input: String) -> Int {
parse_grid(input)
|> computer_obst_var_res()
|> computer_obst_all_var
}

0 comments on commit 012b0d5

Please sign in to comment.