Skip to content

Commit

Permalink
day 05: improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
sreedevk committed Dec 5, 2024
1 parent 704859d commit 651075f
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 56 deletions.
1 change: 1 addition & 0 deletions gleam.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ version = "1.0.0"
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"

[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
4 changes: 3 additions & 1 deletion manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ packages = [
{ name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" },
{ 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" },
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
{ name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" },
]

[requirements]
gleam_regexp = { version = ">= 1.0.0 and < 2.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" }
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
simplifile = { version = ">= 2.2.0 and < 3.0.0" }
77 changes: 24 additions & 53 deletions src/print_queue.gleam
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import gleam/bool
import gleam/int
import gleam/io
import gleam/list
import gleam/pair
import gleam/pair.{first as pf, second as ps}
import gleam/result
import gleam/string
import gleam/yielder
import utils/list as li

type Rule =
#(Int, Int)
Expand Down Expand Up @@ -34,31 +36,8 @@ fn parse_file(input: String) -> #(List(Rule), List(Order)) {
#(parsed_rules, parsed_orders)
}

fn contains(ls: List(a), item: a) -> Bool {
result.is_ok(list.find(ls, fn(x) { x == item }))
}

fn filter_with_index(ls: List(a), f: fn(Int, a) -> Bool) -> List(a) {
list.index_map(ls, fn(item, index) { #(index, item) })
|> list.filter(fn(x) { f(pair.first(x), pair.second(x)) })
|> list.map(fn(y) { pair.second(y) })
}

fn at(ls: List(a), idx: Int) -> Result(a, Nil) {
list.index_map(ls, fn(item, index) { #(index, item) })
|> list.find(fn(x) { pair.first(x) == idx })
|> result.map(fn(res) { pair.second(res) })
}

fn rule_applicable(order: Order, rule: Rule) -> Bool {
let #(x, y) = rule
contains(order, x) && contains(order, y)
}

fn index(ls: List(a), item: a) -> Result(Int, Nil) {
list.index_map(ls, fn(x, index) { #(index, x) })
|> list.find(fn(x) { pair.second(x) == item })
|> result.map(fn(x) { pair.first(x) })
list.all(li.from_pair(rule), li.contains(order, _))
}

fn rule_satisfied(order: Order, rule: Rule) -> Bool {
Expand All @@ -71,47 +50,39 @@ fn rule_satisfied(order: Order, rule: Rule) -> Bool {
fn order_follows_rules(order: Order, rules: List(Rule)) -> Bool {
rules
|> list.filter(rule_applicable(order, _))
|> list.all(fn(rule) { rule_satisfied(order, rule) })
|> list.all(rule_satisfied(order, _))
}

fn rule_satisfied_or_swap(order: Order, rule: Rule) -> Order {
case rule_satisfied(order, rule) {
True -> order
False -> li.swap(order, pf(rule), ps(rule))
}
}

fn make_order_follow_rules(order: Order, rules: List(Rule)) -> Order {
rules
|> list.filter(rule_applicable(order, _))
|> list.fold(order, fn(oc, rule) {
case rule_satisfied(oc, rule) {
True -> oc
False -> swap(oc, pair.first(rule), pair.second(rule))
}
})
|> fn(oc) {
case order_follows_rules(oc, rules) {
True -> oc
False -> make_order_follow_rules(oc, rules)
case order_follows_rules(order, rules) {
True -> order
False -> {
list.filter(rules, rule_applicable(order, _))
|> list.fold(order, rule_satisfied_or_swap)
|> make_order_follow_rules(rules)
}
}
}

fn middle(order: Order) -> Int {
order
|> at(list.length(order) / 2)
|> yielder.from_list
|> yielder.at(list.length(order) / 2)
|> result.unwrap(0)
}

fn swap(ls: List(a), ea: a, eb: a) -> List(a) {
list.map(ls, fn(x) {
case x {
val if val == ea -> eb
val if val == eb -> ea
val -> val
}
})
}

pub fn solve_a(input: String) -> Int {
let #(rules, orders) = parse_file(input)

orders
|> list.filter(fn(order) { order_follows_rules(order, rules) })
|> list.filter(order_follows_rules(_, rules))
|> list.map(middle)
|> list.fold(0, int.add)
}
Expand All @@ -120,8 +91,8 @@ pub fn solve_b(input: String) -> Int {
let #(rules, orders) = parse_file(input)

orders
|> list.filter(fn(order) { !order_follows_rules(order, rules) })
|> list.map(fn(order) { make_order_follow_rules(order, rules) })
|> list.filter(fn(order) { bool.negate(order_follows_rules(order, rules)) })
|> list.map(make_order_follow_rules(_, rules))
|> list.map(middle)
|> list.fold(0, int.add)
}
32 changes: 32 additions & 0 deletions src/utils/list.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import gleam/list as li
import gleam/pair.{first as pf, second as ps}
import gleam/result as res

pub fn index(ls: List(a), item: a) -> Result(Int, Nil) {
li.index_map(ls, fn(x, index) { #(index, x) })
|> li.find(fn(x) { ps(x) == item })
|> res.map(pf)
}

pub fn from_pair(p: #(a, a)) -> List(a) {
[pf(p), ps(p)]
}

pub fn index_filter(ls: List(a), f: fn(Int, a) -> Bool) -> List(a) {
li.index_map(ls, fn(item, index) { #(index, item) })
|> li.filter(fn(x) { f(pf(x), ps(x)) })
|> li.map(ps)
}

pub fn contains(ls: List(a), item: a) -> Bool {
res.is_ok(li.find(ls, fn(x) { x == item }))
}

pub fn swap(ls: List(a), ea: a, eb: a) -> List(a) {
use x <- li.map(ls)
case x {
val if val == ea -> eb
val if val == eb -> ea
val -> val
}
}
1 change: 0 additions & 1 deletion test/advent_of_code_test.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import gleeunit
import gleeunit/should

pub fn main() {
gleeunit.main()
Expand Down
1 change: 0 additions & 1 deletion test/print_queue_test.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import gleam/io
import gleam/string
import gleeunit/should
import print_queue as day05
Expand Down

0 comments on commit 651075f

Please sign in to comment.