forked from akramer/advent
Implemented 18 part 1
=
This commit is contained in:
parent
d2bfa9043e
commit
94a85094bc
104
Cargo.lock
generated
104
Cargo.lock
generated
@ -5,6 +5,7 @@ name = "advent"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -12,3 +13,106 @@ name = "anyhow"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ba62103ce691c2fd80fbae2213dfdda9ce60804973ac6b6e97de818ea7f52c8"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||
|
||||
@ -7,4 +7,5 @@ edition = "2018"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
anyhow = "1.0"
|
||||
nom = "6.0"
|
||||
141
src/bin/18.rs
Normal file
141
src/bin/18.rs
Normal file
@ -0,0 +1,141 @@
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
// call with a starting parenthesis.
|
||||
// returns the offset of the closing parenthesis
|
||||
fn find_matching_paren(input: &str) -> usize {
|
||||
let mut parens_count = 0;
|
||||
for (i, item) in input.chars().enumerate() {
|
||||
match item {
|
||||
'(' => parens_count += 1,
|
||||
')' => parens_count -= 1,
|
||||
_ => (),
|
||||
}
|
||||
if parens_count == 0 {
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// call with a first number, returns the length of the number
|
||||
fn find_number(input: &str) -> usize {
|
||||
let mut i= 0;
|
||||
for item in input.chars() {
|
||||
match item {
|
||||
'0'..='9' => (),
|
||||
_ => return i,
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Token<'a> {
|
||||
Number(i64),
|
||||
Operator(Binop),
|
||||
Parens(&'a str),
|
||||
End,
|
||||
}
|
||||
|
||||
type Binop = fn(i64, i64) -> i64;
|
||||
|
||||
fn add(a: i64, b: i64) -> i64 {
|
||||
a + b
|
||||
}
|
||||
|
||||
fn mul(a: i64, b: i64) -> i64 {
|
||||
a * b
|
||||
}
|
||||
|
||||
// returns the number of chars consumed, as well as a token.
|
||||
fn get_token(input: &str) -> (usize, Token) {
|
||||
let mut i : usize = 0;
|
||||
for item in input.chars() {
|
||||
match item {
|
||||
'(' => {
|
||||
let len = find_matching_paren(&input[i..]);
|
||||
return (i + len, Token::Parens(&input[i..i + len]));
|
||||
}
|
||||
'+' => {
|
||||
return (i + 1, Token::Operator(add));
|
||||
}
|
||||
'*' => {
|
||||
return (i + 1, Token::Operator(mul));
|
||||
}
|
||||
'0'..='9' => {
|
||||
let len = find_number(&input[i..]);
|
||||
let val = input[i..i+len].parse::<i64>().unwrap();
|
||||
return (i + len, Token::Number(val));
|
||||
}
|
||||
' ' => (),
|
||||
_ => panic!("Unexpected input!"),
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
(i, Token::End)
|
||||
}
|
||||
|
||||
// finds a left argument, right argument, and operator.
|
||||
// calls the operator on the args and returns the result.
|
||||
fn evaluate(input: &str) -> i64 {
|
||||
let mut left_val;
|
||||
let (offset, tok) = get_token(&input);
|
||||
match tok {
|
||||
Token::Number(n) => {
|
||||
left_val = n;
|
||||
},
|
||||
Token::Parens(p) => {
|
||||
left_val = evaluate(&p[1..p.len()-1]);
|
||||
},
|
||||
_ => panic!("expected a number or a parenthetical"),
|
||||
}
|
||||
|
||||
let mut input = &input[offset..];
|
||||
loop {
|
||||
let operator;
|
||||
let (offset, op) = get_token(&input);
|
||||
match op {
|
||||
Token::Operator(o) => {
|
||||
operator = o;
|
||||
},
|
||||
Token::End => {
|
||||
return left_val;
|
||||
}
|
||||
_ => panic!("expected an operator"),
|
||||
}
|
||||
|
||||
let right_val;
|
||||
input = &input[offset..];
|
||||
let (offset, right) = get_token(&input);
|
||||
match right {
|
||||
Token::Number(n) => {
|
||||
right_val = n;
|
||||
},
|
||||
Token::Parens(p) => {
|
||||
right_val = evaluate(&p[1..p.len()-1]);
|
||||
},
|
||||
_ => panic!("expected a number or a parenthetical"),
|
||||
}
|
||||
input = &input[offset..];
|
||||
left_val = operator(left_val, right_val)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let file = File::open("18.input")?;
|
||||
let reader = BufReader::new(file);
|
||||
let mut answer = 0;
|
||||
|
||||
for line in reader.lines() {
|
||||
answer += evaluate(&line?);
|
||||
}
|
||||
//println!("eval: {}", evaluate("6 * 2 * 6 + (8 + 8 * (5 + 4 * 7 + 6 + 6 + 3)) * 8"));
|
||||
println!("answer is: {}", answer);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user