Skip to content

Commit

Permalink
day 07: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sreedevk committed Dec 7, 2024
1 parent d2510ed commit b6eb1d2
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/advent_of_code.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import argv
import bridge_repair as day07
import ceres_search as day04
import gleam/int
import gleam/io
Expand Down Expand Up @@ -96,6 +97,19 @@ pub fn main() {
Nil,
)
}
["7"] -> {
result.unwrap(
result.map(read("data/day7.txt"), fn(data) {
io.println(
"[7] Bridge Repair (Part 1): " <> int.to_string(day07.solve_a(data)),
)
io.println(
"[7] Bridge Repair (Part 2): " <> int.to_string(day07.solve_b(data)),
)
}),
Nil,
)
}
_ -> io.println_error("invalid arguments!")
}
}
69 changes: 69 additions & 0 deletions src/bridge_repair.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import gleam/int
import gleam/list
import gleam/result
import gleam/string
import utils/list as li

type Equation {
Equation(target: Int, values: List(String))
}

fn parse_eq(line: String) -> Equation {
let assert Ok(#(tar_str, vals_str)) = string.split_once(line, ": ")
let assert Ok(tar_int) = int.parse(tar_str)
let values = string.split(vals_str, " ")

Equation(target: tar_int, values: values)
}

fn parse_file(input: String) -> List(Equation) {
input
|> string.trim
|> string.split("\n")
|> list.map(parse_eq)
}

fn parse_num(x: String) -> Int {
result.unwrap(int.parse(x), 0)
}

fn solve_eq_lr(eq: List(String)) -> List(String) {
case list.length(eq) {
1 -> eq
_ -> {
let #(head, tail) = list.split(eq, 3)
let reduced = case head {
[lhs, opr, rhs] ->
case opr {
"*" -> [int.to_string(int.multiply(parse_num(lhs), parse_num(rhs)))]
"+" -> [int.to_string(int.add(parse_num(lhs), parse_num(rhs)))]
"||" -> [string.join([lhs, rhs], "")]
_ -> ["0"]
}
_ -> ["0"]
}
solve_eq_lr(list.append(reduced, tail))
}
}
}

fn is_satisfiable(eq: Equation, operators: List(String)) -> Bool {
li.repeated_permutation(operators, list.length(eq.values) - 1)
|> list.map(fn(combo) { list.interleave([eq.values, combo]) })
|> list.flat_map(solve_eq_lr)
|> list.any(fn(soln) { eq.target == parse_num(soln) })
}

pub fn solve_a(input: String) -> Int {
parse_file(input)
|> list.filter(is_satisfiable(_, ["*", "+"]))
|> list.map(fn(x) { x.target })
|> list.fold(0, int.add)
}

pub fn solve_b(input: String) -> Int {
parse_file(input)
|> list.filter(is_satisfiable(_, ["*", "+", "||"]))
|> list.map(fn(x) { x.target })
|> list.fold(0, int.add)
}
7 changes: 7 additions & 0 deletions src/utils/list.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,10 @@ pub fn max(ls: List(Int)) -> Int {
}
})
}

pub fn repeated_permutation(ls: List(a), n: Int) {
li.range(1, n)
|> li.fold([[]], fn(acc, _) {
li.flat_map(acc, fn(y) { li.map(ls, fn(z) { li.append(y, li.wrap(z)) }) })
})
}
21 changes: 21 additions & 0 deletions test/bridge_repair_test.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import bridge_repair as day07
import gleam/string
import gleeunit/should

fn test_data() -> String {
string.join(
[
"190: 10 19", "3267: 81 40 27", "83: 17 5", "156: 15 6", "7290: 6 8 6 15",
"161011: 16 10 13", "192: 17 8 14", "21037: 9 7 18 13", "292: 11 6 16 20",
],
"\n",
)
}

pub fn solve_a_test() {
should.equal(day07.solve_a(test_data()), 3749)
}

pub fn solve_b_test() {
should.equal(day07.solve_b(test_data()), 11_387)
}

0 comments on commit b6eb1d2

Please sign in to comment.