day 7
This commit is contained in:
parent
68d39d8896
commit
24bae29e6e
3 changed files with 159 additions and 0 deletions
9
sample/day7-sample.txt
Normal file
9
sample/day7-sample.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
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
|
68
src/day7_p1.gleam
Normal file
68
src/day7_p1.gleam
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import gleam/int
|
||||||
|
import gleam/io
|
||||||
|
import gleam/iterator
|
||||||
|
import gleam/list.{Continue, Stop, count, filter, fold, map}
|
||||||
|
import gleam/pair
|
||||||
|
import gleam/result
|
||||||
|
import gleam/string
|
||||||
|
import stdin.{stdin}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
stdin()
|
||||||
|
|> read_input
|
||||||
|
|> filter(is_valid)
|
||||||
|
|> map(pair.first)
|
||||||
|
|> fold(0, int.add)
|
||||||
|
|> io.debug
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_valid(equation: #(Int, List(Int))) -> Bool {
|
||||||
|
let assert #(total, [base, ..operands]) = equation
|
||||||
|
let op_size = list.length(operands)
|
||||||
|
let limit = int.bitwise_shift_left(1, op_size)
|
||||||
|
|
||||||
|
list.range(0, limit)
|
||||||
|
|> list.any(fn(index) {
|
||||||
|
let operations =
|
||||||
|
index
|
||||||
|
|> int.to_base2
|
||||||
|
|> string.pad_start(to: op_size, with: "0")
|
||||||
|
|> string.to_graphemes
|
||||||
|
|
||||||
|
list.zip(operands, operations)
|
||||||
|
|> list.fold(base, fn(acc, op) {
|
||||||
|
let #(num, operation) = op
|
||||||
|
case operation {
|
||||||
|
"0" -> acc + num
|
||||||
|
"1" -> acc * num
|
||||||
|
_ -> panic as "unreachable"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|> fn(x) { x == total }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_input(it: iterator.Iterator(String)) -> List(#(Int, List(Int))) {
|
||||||
|
it
|
||||||
|
|> iterator.to_list
|
||||||
|
|> map(string.trim)
|
||||||
|
|> filter(not(string.is_empty))
|
||||||
|
|> map(parse_line)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_line(line: String) -> #(Int, List(Int)) {
|
||||||
|
let assert Ok(#(total_str, ops_str)) = line |> string.split_once(":")
|
||||||
|
let assert Ok(total) = total_str |> int.parse
|
||||||
|
let assert Ok(ops) =
|
||||||
|
ops_str
|
||||||
|
|> string.trim
|
||||||
|
|> string.split(" ")
|
||||||
|
|> map(int.parse)
|
||||||
|
|> result.all
|
||||||
|
|
||||||
|
#(total, ops)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn not(a: fn(a) -> Bool) {
|
||||||
|
fn(param: a) -> Bool { !a(param) }
|
||||||
|
}
|
82
src/day7_p2.gleam
Normal file
82
src/day7_p2.gleam
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import gleam/float
|
||||||
|
import gleam/int
|
||||||
|
import gleam/io
|
||||||
|
import gleam/iterator
|
||||||
|
import gleam/list.{Continue, Stop, count, filter, fold, map}
|
||||||
|
import gleam/pair
|
||||||
|
import gleam/result
|
||||||
|
import gleam/string
|
||||||
|
import stdin.{stdin}
|
||||||
|
|
||||||
|
pub fn main() {
|
||||||
|
stdin()
|
||||||
|
|> read_input
|
||||||
|
|> filter(is_valid)
|
||||||
|
|> map(pair.first)
|
||||||
|
|> fold(0, int.add)
|
||||||
|
|> io.debug
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_valid(equation: #(Int, List(Int))) -> Bool {
|
||||||
|
let assert #(total, [base, ..operands]) = equation
|
||||||
|
let op_size = list.length(operands)
|
||||||
|
let assert Ok(limit) =
|
||||||
|
int.power(3, of: op_size |> int.to_float) |> result.map(float.round)
|
||||||
|
|
||||||
|
list.range(0, limit)
|
||||||
|
|> list.any(fn(index) {
|
||||||
|
let assert Ok(operation_string) =
|
||||||
|
index
|
||||||
|
|> int.to_base_string(3)
|
||||||
|
|
||||||
|
let operations =
|
||||||
|
operation_string
|
||||||
|
|> string.pad_start(to: op_size, with: "0")
|
||||||
|
|> string.to_graphemes
|
||||||
|
|
||||||
|
list.zip(operands, operations)
|
||||||
|
|> list.fold(base, fn(acc, op) {
|
||||||
|
let #(num, operation) = op
|
||||||
|
case operation {
|
||||||
|
"0" -> acc + num
|
||||||
|
"1" -> acc * num
|
||||||
|
"2" -> concat(acc, num)
|
||||||
|
_ -> panic as "unreachable"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|> fn(x) { x == total }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn concat(x: Int, y: Int) -> Int {
|
||||||
|
let assert Ok(x_digits) = int.digits(x, 10)
|
||||||
|
let assert Ok(y_digits) = int.digits(y, 10)
|
||||||
|
|
||||||
|
let assert Ok(num) = [x_digits, y_digits] |> list.flatten |> int.undigits(10)
|
||||||
|
num
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_input(it: iterator.Iterator(String)) -> List(#(Int, List(Int))) {
|
||||||
|
it
|
||||||
|
|> iterator.to_list
|
||||||
|
|> map(string.trim)
|
||||||
|
|> filter(not(string.is_empty))
|
||||||
|
|> map(parse_line)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_line(line: String) -> #(Int, List(Int)) {
|
||||||
|
let assert Ok(#(total_str, ops_str)) = line |> string.split_once(":")
|
||||||
|
let assert Ok(total) = total_str |> int.parse
|
||||||
|
let assert Ok(ops) =
|
||||||
|
ops_str
|
||||||
|
|> string.trim
|
||||||
|
|> string.split(" ")
|
||||||
|
|> map(int.parse)
|
||||||
|
|> result.all
|
||||||
|
|
||||||
|
#(total, ops)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn not(a: fn(a) -> Bool) {
|
||||||
|
fn(param: a) -> Bool { !a(param) }
|
||||||
|
}
|
Loading…
Reference in a new issue