diff --git a/2015/07/Cargo.lock b/2015/07/Cargo.lock new file mode 100644 index 0000000..3a72b1c --- /dev/null +++ b/2015/07/Cargo.lock @@ -0,0 +1,105 @@ +[root] +name = "07" +version = "0.1.0" +dependencies = [ + "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "thread-id" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" +"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70" +"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" +"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" +"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" +"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" +"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" +"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/2015/07/Cargo.toml b/2015/07/Cargo.toml new file mode 100644 index 0000000..4a8b125 --- /dev/null +++ b/2015/07/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "07" +version = "0.1.0" +authors = ["logaritmisk "] + +[dependencies] +lazy_static = "0.1" +regex = "0.1" diff --git a/2015/07/example.txt b/2015/07/example.txt new file mode 100644 index 0000000..27b4f8d --- /dev/null +++ b/2015/07/example.txt @@ -0,0 +1,8 @@ +123 -> x +456 -> y +x AND y -> d +x OR y -> e +x LSHIFT 2 -> f +y RSHIFT 2 -> g +NOT x -> h +NOT y -> i diff --git a/2015/07/input.txt b/2015/07/input.txt new file mode 100644 index 0000000..1b7dfc9 --- /dev/null +++ b/2015/07/input.txt @@ -0,0 +1,339 @@ +bn RSHIFT 2 -> bo +lf RSHIFT 1 -> ly +fo RSHIFT 3 -> fq +cj OR cp -> cq +fo OR fz -> ga +t OR s -> u +lx -> a +NOT ax -> ay +he RSHIFT 2 -> hf +lf OR lq -> lr +lr AND lt -> lu +dy OR ej -> ek +1 AND cx -> cy +hb LSHIFT 1 -> hv +1 AND bh -> bi +ih AND ij -> ik +c LSHIFT 1 -> t +ea AND eb -> ed +km OR kn -> ko +NOT bw -> bx +ci OR ct -> cu +NOT p -> q +lw OR lv -> lx +NOT lo -> lp +fp OR fv -> fw +o AND q -> r +dh AND dj -> dk +ap LSHIFT 1 -> bj +bk LSHIFT 1 -> ce +NOT ii -> ij +gh OR gi -> gj +kk RSHIFT 1 -> ld +lc LSHIFT 1 -> lw +lb OR la -> lc +1 AND am -> an +gn AND gp -> gq +lf RSHIFT 3 -> lh +e OR f -> g +lg AND lm -> lo +ci RSHIFT 1 -> db +cf LSHIFT 1 -> cz +bn RSHIFT 1 -> cg +et AND fe -> fg +is OR it -> iu +kw AND ky -> kz +ck AND cl -> cn +bj OR bi -> bk +gj RSHIFT 1 -> hc +iu AND jf -> jh +NOT bs -> bt +kk OR kv -> kw +ks AND ku -> kv +hz OR ik -> il +b RSHIFT 1 -> v +iu RSHIFT 1 -> jn +fo RSHIFT 5 -> fr +be AND bg -> bh +ga AND gc -> gd +hf OR hl -> hm +ld OR le -> lf +as RSHIFT 5 -> av +fm OR fn -> fo +hm AND ho -> hp +lg OR lm -> ln +NOT kx -> ky +kk RSHIFT 3 -> km +ek AND em -> en +NOT ft -> fu +NOT jh -> ji +jn OR jo -> jp +gj AND gu -> gw +d AND j -> l +et RSHIFT 1 -> fm +jq OR jw -> jx +ep OR eo -> eq +lv LSHIFT 15 -> lz +NOT ey -> ez +jp RSHIFT 2 -> jq +eg AND ei -> ej +NOT dm -> dn +jp AND ka -> kc +as AND bd -> bf +fk OR fj -> fl +dw OR dx -> dy +lj AND ll -> lm +ec AND ee -> ef +fq AND fr -> ft +NOT kp -> kq +ki OR kj -> kk +cz OR cy -> da +as RSHIFT 3 -> au +an LSHIFT 15 -> ar +fj LSHIFT 15 -> fn +1 AND fi -> fj +he RSHIFT 1 -> hx +lf RSHIFT 2 -> lg +kf LSHIFT 15 -> kj +dz AND ef -> eh +ib OR ic -> id +lf RSHIFT 5 -> li +bp OR bq -> br +NOT gs -> gt +fo RSHIFT 1 -> gh +bz AND cb -> cc +ea OR eb -> ec +lf AND lq -> ls +NOT l -> m +hz RSHIFT 3 -> ib +NOT di -> dj +NOT lk -> ll +jp RSHIFT 3 -> jr +jp RSHIFT 5 -> js +NOT bf -> bg +s LSHIFT 15 -> w +eq LSHIFT 1 -> fk +jl OR jk -> jm +hz AND ik -> im +dz OR ef -> eg +1 AND gy -> gz +la LSHIFT 15 -> le +br AND bt -> bu +NOT cn -> co +v OR w -> x +d OR j -> k +1 AND gd -> ge +ia OR ig -> ih +NOT go -> gp +NOT ed -> ee +jq AND jw -> jy +et OR fe -> ff +aw AND ay -> az +ff AND fh -> fi +ir LSHIFT 1 -> jl +gg LSHIFT 1 -> ha +x RSHIFT 2 -> y +db OR dc -> dd +bl OR bm -> bn +ib AND ic -> ie +x RSHIFT 3 -> z +lh AND li -> lk +ce OR cd -> cf +NOT bb -> bc +hi AND hk -> hl +NOT gb -> gc +1 AND r -> s +fw AND fy -> fz +fb AND fd -> fe +1 AND en -> eo +z OR aa -> ab +bi LSHIFT 15 -> bm +hg OR hh -> hi +kh LSHIFT 1 -> lb +cg OR ch -> ci +1 AND kz -> la +gf OR ge -> gg +gj RSHIFT 2 -> gk +dd RSHIFT 2 -> de +NOT ls -> lt +lh OR li -> lj +jr OR js -> jt +au AND av -> ax +0 -> c +he AND hp -> hr +id AND if -> ig +et RSHIFT 5 -> ew +bp AND bq -> bs +e AND f -> h +ly OR lz -> ma +1 AND lu -> lv +NOT jd -> je +ha OR gz -> hb +dy RSHIFT 1 -> er +iu RSHIFT 2 -> iv +NOT hr -> hs +as RSHIFT 1 -> bl +kk RSHIFT 2 -> kl +b AND n -> p +ln AND lp -> lq +cj AND cp -> cr +dl AND dn -> do +ci RSHIFT 2 -> cj +as OR bd -> be +ge LSHIFT 15 -> gi +hz RSHIFT 5 -> ic +dv LSHIFT 1 -> ep +kl OR kr -> ks +gj OR gu -> gv +he RSHIFT 5 -> hh +NOT fg -> fh +hg AND hh -> hj +b OR n -> o +jk LSHIFT 15 -> jo +gz LSHIFT 15 -> hd +cy LSHIFT 15 -> dc +kk RSHIFT 5 -> kn +ci RSHIFT 3 -> ck +at OR az -> ba +iu RSHIFT 3 -> iw +ko AND kq -> kr +NOT eh -> ei +aq OR ar -> as +iy AND ja -> jb +dd RSHIFT 3 -> df +bn RSHIFT 3 -> bp +1 AND cc -> cd +at AND az -> bb +x OR ai -> aj +kk AND kv -> kx +ao OR an -> ap +dy RSHIFT 3 -> ea +x RSHIFT 1 -> aq +eu AND fa -> fc +kl AND kr -> kt +ia AND ig -> ii +df AND dg -> di +NOT fx -> fy +k AND m -> n +bn RSHIFT 5 -> bq +km AND kn -> kp +dt LSHIFT 15 -> dx +hz RSHIFT 2 -> ia +aj AND al -> am +cd LSHIFT 15 -> ch +hc OR hd -> he +he RSHIFT 3 -> hg +bn OR by -> bz +NOT kt -> ku +z AND aa -> ac +NOT ak -> al +cu AND cw -> cx +NOT ie -> if +dy RSHIFT 2 -> dz +ip LSHIFT 15 -> it +de OR dk -> dl +au OR av -> aw +jg AND ji -> jj +ci AND ct -> cv +dy RSHIFT 5 -> eb +hx OR hy -> hz +eu OR fa -> fb +gj RSHIFT 3 -> gl +fo AND fz -> gb +1 AND jj -> jk +jp OR ka -> kb +de AND dk -> dm +ex AND ez -> fa +df OR dg -> dh +iv OR jb -> jc +x RSHIFT 5 -> aa +NOT hj -> hk +NOT im -> in +fl LSHIFT 1 -> gf +hu LSHIFT 15 -> hy +iq OR ip -> ir +iu RSHIFT 5 -> ix +NOT fc -> fd +NOT el -> em +ck OR cl -> cm +et RSHIFT 3 -> ev +hw LSHIFT 1 -> iq +ci RSHIFT 5 -> cl +iv AND jb -> jd +dd RSHIFT 5 -> dg +as RSHIFT 2 -> at +NOT jy -> jz +af AND ah -> ai +1 AND ds -> dt +jx AND jz -> ka +da LSHIFT 1 -> du +fs AND fu -> fv +jp RSHIFT 1 -> ki +iw AND ix -> iz +iw OR ix -> iy +eo LSHIFT 15 -> es +ev AND ew -> ey +ba AND bc -> bd +fp AND fv -> fx +jc AND je -> jf +et RSHIFT 2 -> eu +kg OR kf -> kh +iu OR jf -> jg +er OR es -> et +fo RSHIFT 2 -> fp +NOT ca -> cb +bv AND bx -> by +u LSHIFT 1 -> ao +cm AND co -> cp +y OR ae -> af +bn AND by -> ca +1 AND ke -> kf +jt AND jv -> jw +fq OR fr -> fs +dy AND ej -> el +NOT kc -> kd +ev OR ew -> ex +dd OR do -> dp +NOT cv -> cw +gr AND gt -> gu +dd RSHIFT 1 -> dw +NOT gw -> gx +NOT iz -> ja +1 AND io -> ip +NOT ag -> ah +b RSHIFT 5 -> f +NOT cr -> cs +kb AND kd -> ke +jr AND js -> ju +cq AND cs -> ct +il AND in -> io +NOT ju -> jv +du OR dt -> dv +dd AND do -> dq +b RSHIFT 2 -> d +jm LSHIFT 1 -> kg +NOT dq -> dr +bo OR bu -> bv +gk OR gq -> gr +he OR hp -> hq +NOT h -> i +hf AND hl -> hn +gv AND gx -> gy +x AND ai -> ak +bo AND bu -> bw +hq AND hs -> ht +hz RSHIFT 1 -> is +gj RSHIFT 5 -> gm +g AND i -> j +gk AND gq -> gs +dp AND dr -> ds +b RSHIFT 3 -> e +gl AND gm -> go +gl OR gm -> gn +y AND ae -> ag +hv OR hu -> hw +1674 -> b +ab AND ad -> ae +NOT ac -> ad +1 AND ht -> hu +NOT hn -> ho diff --git a/2015/07/src/main.rs b/2015/07/src/main.rs new file mode 100644 index 0000000..0f365a0 --- /dev/null +++ b/2015/07/src/main.rs @@ -0,0 +1,240 @@ +#[macro_use] extern crate lazy_static; +extern crate regex; + +use std::str::FromStr; +use std::io::{self, BufRead}; +use std::collections::{VecDeque, HashMap}; + +use regex::Regex; + + +type Id = String; +type Value = u16; + + +#[derive(Debug)] +enum Input { + Value(Value), + Wire(Id) +} + +impl FromStr for Input { + type Err = (); + + fn from_str(s: &str) -> Result { + match s.parse::() { + Ok(value) => Ok(Input::Value(value)), + Err(_) => Ok(Input::Wire(String::from(s))), + } + } +} + + +#[derive(Debug)] +enum Instruction { + Signal(Input, Id), + + And(Input, Input, Id), + Or(Input, Input, Id), + Not(Input, Id), + + LShift(Input, Input, Id), + RShift(Input, Input, Id) +} + +impl FromStr for Instruction { + type Err = (); + + fn from_str(s: &str) -> Result { + lazy_static! { + static ref SIGNAL: Regex = Regex::new(r"^(\d+|[a-z]+) -> ([a-z]+)$").unwrap(); + + static ref AND: Regex = Regex::new(r"^(\d+|[a-z]+) AND (\d+|[a-z]+) -> ([a-z]+)$").unwrap(); + static ref OR: Regex = Regex::new(r"^(\d+|[a-z]+) OR (\d+|[a-z]+) -> ([a-z]+)$").unwrap(); + static ref NOT: Regex = Regex::new(r"^NOT (\d+|[a-z]+) -> ([a-z]+)$").unwrap(); + + static ref LSHIFT: Regex = Regex::new(r"^(\d+|[a-z]+) LSHIFT (\d+|[a-z]+) -> ([a-z]+)$").unwrap(); + static ref RSHIFT: Regex = Regex::new(r"^(\d+|[a-z]+) RSHIFT (\d+|[a-z]+) -> ([a-z]+)$").unwrap(); + } + + if let Some(caps) = SIGNAL.captures(s) { + let x = caps.at(1).unwrap().parse::().unwrap(); + let y = String::from(caps.at(2).unwrap()); + + return Ok(Instruction::Signal(x, y)); + } + + if let Some(caps) = AND.captures(s) { + let x = caps.at(1).unwrap().parse::().unwrap(); + let y = caps.at(2).unwrap().parse::().unwrap(); + let z = String::from(caps.at(3).unwrap()); + + return Ok(Instruction::And(x, y, z)); + } + + if let Some(caps) = OR.captures(s) { + let x = caps.at(1).unwrap().parse::().unwrap(); + let y = caps.at(2).unwrap().parse::().unwrap(); + let z = String::from(caps.at(3).unwrap()); + + return Ok(Instruction::Or(x, y, z)); + } + + if let Some(caps) = NOT.captures(s) { + let x = caps.at(1).unwrap().parse::().unwrap(); + let y = String::from(caps.at(2).unwrap()); + + return Ok(Instruction::Not(x, y)); + } + + if let Some(caps) = LSHIFT.captures(s) { + let x = caps.at(1).unwrap().parse::().unwrap(); + let y = caps.at(2).unwrap().parse::().unwrap(); + let z = String::from(caps.at(3).unwrap()); + + return Ok(Instruction::LShift(x, y, z)); + } + + if let Some(caps) = RSHIFT.captures(s) { + let x = caps.at(1).unwrap().parse::().unwrap(); + let y = caps.at(2).unwrap().parse::().unwrap(); + let z = String::from(caps.at(3).unwrap()); + + return Ok(Instruction::RShift(x, y, z)); + } + + Err(()) + } +} + + +fn main() { + let stdin = io::stdin(); + + let mut instructions = stdin.lock().lines() + .filter_map(|line| line.ok()) + .filter_map(|line| Instruction::from_str(&line).ok()) + .collect::>(); + + // Second answer. + instructions.push_back(Instruction::from_str("46065 -> b").unwrap()); + + let mut op_map: HashMap = HashMap::new(); + + while !instructions.is_empty() { + let instruction = instructions.pop_front().unwrap(); + + let push = match instruction { + Instruction::Signal(ref x, ref wire) => { + let x = match x { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + if x.is_some() { + op_map.insert(wire.clone(), x.unwrap()); + + false + } else { + true + } + } + Instruction::And(ref x, ref y, ref wire) => { + let x = match x { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + let y = match y { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + if x.is_some() && y.is_some() { + op_map.insert(wire.clone(), x.unwrap() & y.unwrap()); + + false + } else { + true + } + } + Instruction::Or(ref x, ref y, ref wire) => { + let x = match x { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + let y = match y { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + if x.is_some() && y.is_some() { + op_map.insert(wire.clone(), x.unwrap() | y.unwrap()); + + false + } else { + true + } + } + Instruction::Not(ref x, ref wire) => { + let x = match x { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + if x.is_some() { + op_map.insert(wire.clone(), !x.unwrap()); + + false + } else { + true + } + } + Instruction::LShift(ref x, ref y, ref wire) => { + let x = match x { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + let y = match y { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + if x.is_some() && y.is_some() { + op_map.insert(wire.clone(), x.unwrap() << y.unwrap()); + + false + } else { + true + } + } + Instruction::RShift(ref x, ref y, ref wire) => { + let x = match x { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + let y = match y { + &Input::Value(value) => Some(value.clone()), + &Input::Wire(ref wire) => if let Some(value) = op_map.get(wire) { Some(*value) } else { None } + }; + + if x.is_some() && y.is_some() { + op_map.insert(wire.clone(), x.unwrap() >> y.unwrap()); + + false + } else { + true + } + } + }; + + if push { + instructions.push_back(instruction); + } + } + + println!("{:#?}", op_map); +}