summaryrefslogtreecommitdiff
path: root/aoc/2024/03/rust/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'aoc/2024/03/rust/src/main.rs')
-rw-r--r--aoc/2024/03/rust/src/main.rs68
1 files changed, 68 insertions, 0 deletions
diff --git a/aoc/2024/03/rust/src/main.rs b/aoc/2024/03/rust/src/main.rs
new file mode 100644
index 0000000..b268463
--- /dev/null
+++ b/aoc/2024/03/rust/src/main.rs
@@ -0,0 +1,68 @@
+use std::io::{self, Read};
+
+#[derive(Debug)]
+enum Instruction {
+ Do,
+ Dont,
+ Mul(u64, u64),
+}
+
+impl From<&Instruction> for u64 {
+ fn from(val: &Instruction) -> Self {
+ match val {
+ Instruction::Mul(x, y) => x * y,
+ _ => 0,
+ }
+ }
+}
+
+fn main() -> io::Result<()> {
+ let mut program = String::new();
+ io::stdin().read_to_string(&mut program)?;
+
+ let instrs = (0..program.len())
+ .filter_map(|idx| {
+ let next = &program[idx..];
+ if next.starts_with("do()") {
+ Some(Instruction::Do)
+ } else if next.starts_with("don't()") {
+ Some(Instruction::Dont)
+ } else if next.starts_with("mul(") {
+ let mut first = 0;
+ let mut curr = 0;
+
+ for ch in next.bytes().skip(4) {
+ match (ch, curr) {
+ ((b'0'..=b'9'), _) => curr = curr * 10 + (ch - b'0') as u64,
+ (_, 0) => return None,
+ (b',', _) => {
+ first = curr;
+ curr = 0;
+ }
+ (b')', _) => {
+ return Some(Instruction::Mul(first, curr));
+ }
+ _ => return None,
+ };
+ }
+ None
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>();
+
+ let silver: u64 = instrs.iter().map(u64::from).sum();
+ let (gold, _) = instrs
+ .iter()
+ .fold((0 as u64, true), |(acc, on), instr| match (instr, on) {
+ (Instruction::Do, _) => (acc, true),
+ (Instruction::Dont, _) => (acc, false),
+ (Instruction::Mul(_, _), true) => (acc + u64::from(instr), true),
+ _ => (acc, on),
+ });
+ println!("silver: {silver}");
+ println!("gold: {gold}");
+
+ return Ok(());
+}