From 2d12f6ec2294e36ae090fdd1e10025452ec1a480 Mon Sep 17 00:00:00 2001 From: alyx Date: Sun, 19 Nov 2023 14:55:43 -0500 Subject: Initial commit, done up to 2015.7 --- 2015/rs/src/seven.rs | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 2015/rs/src/seven.rs (limited to '2015/rs/src/seven.rs') diff --git a/2015/rs/src/seven.rs b/2015/rs/src/seven.rs new file mode 100644 index 0000000..7d44f0e --- /dev/null +++ b/2015/rs/src/seven.rs @@ -0,0 +1,94 @@ +use std::collections::HashMap; + +static INPUT: &[u8] = include_bytes!("seven.txt"); + +#[derive(Debug, Copy, Clone)] +enum WireOrLiteral { + Wire([u8; 2]), + Literal(u16) +} + +#[derive(Debug, Copy, Clone)] +enum Connection { + Direct(WireOrLiteral), + Not (WireOrLiteral), + And (WireOrLiteral, WireOrLiteral), + Or (WireOrLiteral, WireOrLiteral), + LShift(WireOrLiteral, WireOrLiteral), + RShift(WireOrLiteral, WireOrLiteral), +} + +#[derive(Debug, Copy, Clone)] +enum Cache { + Cached(u16), + Uncached(Connection) +} + +fn main() { + let valueified = INPUT + .split(|b| *b == b'\n').filter(|b| !b.is_empty()) + .map(|line| { + let mut bits = line.split(|b| *b == b'-'); + let (rhs, lhs) = (bits.next().unwrap().strip_suffix(b" ").unwrap(), bits.next().unwrap().strip_prefix(b"> ").unwrap()); + let mut cmdbits = rhs.split(|b| *b == b' '); + let cmdbits = (cmdbits.next().unwrap(), cmdbits.next().unwrap_or(&[]), cmdbits.next().unwrap_or(&[])); + + let connection = match cmdbits { + (wol, &[], &[]) => Connection::Direct(parse_wol(wol)), + (b"NOT", wol, &[]) => Connection::Not(parse_wol(wol)), + (wol1, b"AND", wol2) => Connection::And(parse_wol(wol1), parse_wol(wol2)), + (wol1, b"OR", wol2) => Connection::Or(parse_wol(wol1), parse_wol(wol2)), + (wol1, b"LSHIFT", wol2) => Connection::LShift(parse_wol(wol1), parse_wol(wol2)), + (wol1, b"RSHIFT", wol2) => Connection::RShift(parse_wol(wol1), parse_wol(wol2)), + _ => unreachable!() + }; + + let wire = [lhs[0], *lhs.get(1).unwrap_or(&0)]; + + (wire, Cache::Uncached(connection)) + }) + .collect::>(); + + let mut part1 = valueified.clone(); + let a_val = walk(*b"a\0", &mut part1); + println!("a: {a_val}"); + + + let mut part2 = valueified.clone(); + part2.insert(*b"b\0", Cache::Uncached(Connection::Direct(WireOrLiteral::Literal(a_val)))); + let a_val_2 = walk(*b"a\0", &mut part2); + println!("a with b={a_val}: {a_val_2}"); +} + +fn parse_wol(bytes: &[u8]) -> WireOrLiteral { + if bytes.iter().all(u8::is_ascii_digit) { + WireOrLiteral::Literal(std::str::from_utf8(bytes).unwrap().parse().unwrap()) + } else { + WireOrLiteral::Wire([bytes[0], *bytes.get(1).unwrap_or(&0)]) + } +} + +fn walk(key: [u8; 2], map: &mut HashMap<[u8; 2], Cache>) -> u16 { + match map[&key] { + Cache::Cached(val) => val, + Cache::Uncached(conn) => { + let val = match conn { + Connection::Direct(wol) => get_wol(wol, map), + Connection::Not(wol) => !get_wol(wol, map), + Connection::And(wol1, wol2) => get_wol(wol1, map) & get_wol(wol2, map), + Connection::Or(wol1, wol2) => get_wol(wol1, map) | get_wol(wol2, map), + Connection::LShift(wol1, wol2) => get_wol(wol1, map) << get_wol(wol2, map), + Connection::RShift(wol1, wol2) => get_wol(wol1, map) >> get_wol(wol2, map) + }; + map.insert(key, Cache::Cached(val)); + val + } + } +} + +fn get_wol(wol: WireOrLiteral, map: &mut HashMap<[u8; 2], Cache>) -> u16 { + match wol { + WireOrLiteral::Wire(wire) => walk(wire, map), + WireOrLiteral::Literal(literal) => literal + } +} -- cgit v1.2.3-54-g00ecf