my solutions to advent of code
aoc advent-of-code

day 9 2015 - took a long fucking time for this one because im dumb

aylac.top dd99347c 04ef5bc3

verified
Changed files
+203 -1
.zed
2015
+1 -1
.zed/settings.json
···
-
{ "disable_ai": true, "edit_predictions": { "disabled_globs": ["*"] } }
+
{ "disable_ai": true, "edit_predictions": { "disabled_globs": ["*"] }, "agent": {"enabled": false, "button": false}, "inline_code_actions": false }
+20
2015/9/gleam/gleam.toml
···
+
name = "main"
+
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.44.0 and < 2.0.0"
+
simplifile = ">= 2.3.0 and < 3.0.0"
+
+
[dev-dependencies]
+
gleeunit = ">= 1.0.0 and < 2.0.0"
+14
2015/9/gleam/manifest.toml
···
+
# This file was generated by Gleam
+
# You typically do not need to edit this file
+
+
packages = [
+
{ name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" },
+
{ name = "gleam_stdlib", version = "0.65.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "7C69C71D8C493AE11A5184828A77110EB05A7786EBF8B25B36A72F879C3EE107" },
+
{ name = "gleeunit", version = "1.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "CD701726CBCE5588B375D157B4391CFD0F2F134CD12D9B6998A395484DE05C58" },
+
{ name = "simplifile", version = "2.3.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0A868DAC6063D9E983477981839810DC2E553285AB4588B87E3E9C96A7FB4CB4" },
+
]
+
+
[requirements]
+
gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
+
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
+
simplifile = { version = ">= 2.3.0 and < 3.0.0" }
+168
2015/9/gleam/src/main.gleam
···
+
import gleam/dict.{type Dict}
+
import gleam/int.{to_string}
+
import gleam/io.{println}
+
import gleam/list
+
import gleam/result.{unwrap}
+
import gleam/set.{type Set}
+
import gleam/string.{trim}
+
import simplifile.{read}
+
+
type Distance {
+
Distance(place1: String, place2: String, value: Int)
+
}
+
+
type TwoPlaces {
+
TwoPlaces(place1: String, place2: String)
+
}
+
+
type DistanceDict =
+
Dict(TwoPlaces, Int)
+
+
type MapPlaces {
+
MapPlaces(dict: DistanceDict, places: Set(String))
+
}
+
+
fn find_shortest_path(distance_dict, places, shortest_path, path, place place1) {
+
case set.size(places) == 0 {
+
True -> path
+
False ->
+
places
+
|> set.fold(shortest_path, fn(shortest_path, place2) {
+
let assert Ok(dist) = dict.get(distance_dict, TwoPlaces(place1, place2))
+
let path = path + dist
+
case path < shortest_path {
+
True ->
+
find_shortest_path(
+
distance_dict,
+
places |> set.delete(place2),
+
shortest_path,
+
path,
+
place2,
+
)
+
False -> shortest_path
+
}
+
})
+
}
+
}
+
+
fn find_shortest_path_helper(distance_dict: DistanceDict, places: Set(String)) {
+
places
+
|> set.fold(1_000_000, fn(shortest_path, place1) {
+
let places = places |> set.delete(place1)
+
let path =
+
places
+
|> set.fold(shortest_path, fn(shortest_path, place2) {
+
let assert Ok(path) = dict.get(distance_dict, TwoPlaces(place1, place2))
+
find_shortest_path(
+
distance_dict,
+
places |> set.delete(place2),
+
shortest_path,
+
path,
+
place2,
+
)
+
})
+
case path < shortest_path {
+
True -> path
+
False -> shortest_path
+
}
+
})
+
}
+
+
fn find_longest_path(distance_dict, places, longest_path, path, place place1) {
+
case set.size(places) == 0 {
+
True ->
+
case path > longest_path {
+
True -> path
+
False -> longest_path
+
}
+
False -> {
+
let #(place2, longest_distance) =
+
places
+
|> set.fold(#("", 0), fn(longest_distance_tuple, place2) {
+
let assert Ok(distance) =
+
dict.get(distance_dict, TwoPlaces(place1, place2))
+
let #(_, longest_distance) = longest_distance_tuple
+
case distance > longest_distance {
+
True -> #(place2, distance)
+
False -> longest_distance_tuple
+
}
+
})
+
+
let path = path + longest_distance
+
find_longest_path(
+
distance_dict,
+
places |> set.delete(place2),
+
longest_path,
+
path,
+
place2,
+
)
+
}
+
}
+
}
+
+
fn find_longest_path_helper(distance_dict: DistanceDict, places: Set(String)) {
+
places
+
|> set.fold(0, fn(longest_path, place1) {
+
let places = places |> set.delete(place1)
+
let path =
+
places
+
|> set.fold(longest_path, fn(longest_path, place2) {
+
let assert Ok(path) = dict.get(distance_dict, TwoPlaces(place1, place2))
+
find_longest_path(
+
distance_dict,
+
places |> set.delete(place2),
+
longest_path,
+
path,
+
place2,
+
)
+
})
+
case path > longest_path {
+
True -> path
+
False -> longest_path
+
}
+
})
+
}
+
+
pub fn main() {
+
let input =
+
read(from: "../input.txt")
+
|> unwrap("")
+
|> trim()
+
|> string.split("\n")
+
|> list.map(fn(v) {
+
case string.split(v, " ") {
+
[place1, "to", place2, "=", distance] ->
+
Distance(place1, place2, distance |> int.base_parse(10) |> unwrap(0))
+
_ -> Distance("silent_fail", "because_we_are_lazy", 0)
+
}
+
})
+
+
let MapPlaces(distance_dict, places) =
+
input
+
|> list.fold(MapPlaces(dict.new(), set.new()), fn(v, distance) {
+
let map =
+
dict.insert(
+
v.dict,
+
TwoPlaces(distance.place1, distance.place2),
+
distance.value,
+
)
+
let map =
+
dict.insert(
+
map,
+
TwoPlaces(distance.place2, distance.place1),
+
distance.value,
+
)
+
let places = set.insert(v.places, distance.place1)
+
let places = set.insert(places, distance.place2)
+
MapPlaces(map, places)
+
})
+
+
println(
+
find_shortest_path_helper(distance_dict, places)
+
|> to_string,
+
)
+
println(
+
find_longest_path_helper(distance_dict, places)
+
|> to_string,
+
)
+
}