From 22dc83f62f74e92cccd2a76c2c96dffb8346b878 Mon Sep 17 00:00:00 2001 From: Michael Preisach Date: Wed, 30 May 2018 02:35:22 +0200 Subject: [PATCH] level 7 works --- day7.txt | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/day7.rs | 286 +++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 20 +++ src/tests.rs | 30 +++++ 4 files changed, 675 insertions(+) create mode 100644 day7.txt create mode 100644 src/day7.rs diff --git a/day7.txt b/day7.txt new file mode 100644 index 0000000..61c0185 --- /dev/null +++ b/day7.txt @@ -0,0 +1,339 @@ +af AND ah -> ai +NOT lk -> ll +hz RSHIFT 1 -> is +NOT go -> gp +du OR dt -> dv +x RSHIFT 5 -> aa +at OR az -> ba +eo LSHIFT 15 -> es +ci OR ct -> cu +b RSHIFT 5 -> f +fm OR fn -> fo +NOT ag -> ah +v OR w -> x +g AND i -> j +an LSHIFT 15 -> ar +1 AND cx -> cy +jq AND jw -> jy +iu RSHIFT 5 -> ix +gl AND gm -> go +NOT bw -> bx +jp RSHIFT 3 -> jr +hg AND hh -> hj +bv AND bx -> by +er OR es -> et +kl OR kr -> ks +et RSHIFT 1 -> fm +e AND f -> h +u LSHIFT 1 -> ao +he RSHIFT 1 -> hx +eg AND ei -> ej +bo AND bu -> bw +dz OR ef -> eg +dy RSHIFT 3 -> ea +gl OR gm -> gn +da LSHIFT 1 -> du +au OR av -> aw +gj OR gu -> gv +eu OR fa -> fb +lg OR lm -> ln +e OR f -> g +NOT dm -> dn +NOT l -> m +aq OR ar -> as +gj RSHIFT 5 -> gm +hm AND ho -> hp +ge LSHIFT 15 -> gi +jp RSHIFT 1 -> ki +hg OR hh -> hi +lc LSHIFT 1 -> lw +km OR kn -> ko +eq LSHIFT 1 -> fk +1 AND am -> an +gj RSHIFT 1 -> hc +aj AND al -> am +gj AND gu -> gw +ko AND kq -> kr +ha OR gz -> hb +bn OR by -> bz +iv OR jb -> jc +NOT ac -> ad +bo OR bu -> bv +d AND j -> l +bk LSHIFT 1 -> ce +de OR dk -> dl +dd RSHIFT 1 -> dw +hz AND ik -> im +NOT jd -> je +fo RSHIFT 2 -> fp +hb LSHIFT 1 -> hv +lf RSHIFT 2 -> lg +gj RSHIFT 3 -> gl +ki OR kj -> kk +NOT ak -> al +ld OR le -> lf +ci RSHIFT 3 -> ck +1 AND cc -> cd +NOT kx -> ky +fp OR fv -> fw +ev AND ew -> ey +dt LSHIFT 15 -> dx +NOT ax -> ay +bp AND bq -> bs +NOT ii -> ij +ci AND ct -> cv +iq OR ip -> ir +x RSHIFT 2 -> y +fq OR fr -> fs +bn RSHIFT 5 -> bq +0 -> c +14146 -> b +d OR j -> k +z OR aa -> ab +gf OR ge -> gg +df OR dg -> dh +NOT hj -> hk +NOT di -> dj +fj LSHIFT 15 -> fn +lf RSHIFT 1 -> ly +b AND n -> p +jq OR jw -> jx +gn AND gp -> gq +x RSHIFT 1 -> aq +ex AND ez -> fa +NOT fc -> fd +bj OR bi -> bk +as RSHIFT 5 -> av +hu LSHIFT 15 -> hy +NOT gs -> gt +fs AND fu -> fv +dh AND dj -> dk +bz AND cb -> cc +dy RSHIFT 1 -> er +hc OR hd -> he +fo OR fz -> ga +t OR s -> u +b RSHIFT 2 -> d +NOT jy -> jz +hz RSHIFT 2 -> ia +kk AND kv -> kx +ga AND gc -> gd +fl LSHIFT 1 -> gf +bn AND by -> ca +NOT hr -> hs +NOT bs -> bt +lf RSHIFT 3 -> lh +au AND av -> ax +1 AND gd -> ge +jr OR js -> jt +fw AND fy -> fz +NOT iz -> ja +c LSHIFT 1 -> t +dy RSHIFT 5 -> eb +bp OR bq -> br +NOT h -> i +1 AND ds -> dt +ab AND ad -> ae +ap LSHIFT 1 -> bj +br AND bt -> bu +NOT ca -> cb +NOT el -> em +s LSHIFT 15 -> w +gk OR gq -> gr +ff AND fh -> fi +kf LSHIFT 15 -> kj +fp AND fv -> fx +lh OR li -> lj +bn RSHIFT 3 -> bp +jp OR ka -> kb +lw OR lv -> lx +iy AND ja -> jb +dy OR ej -> ek +1 AND bh -> bi +NOT kt -> ku +ao OR an -> ap +ia AND ig -> ii +NOT ey -> ez +bn RSHIFT 1 -> cg +fk OR fj -> fl +ce OR cd -> cf +eu AND fa -> fc +kg OR kf -> kh +jr AND js -> ju +iu RSHIFT 3 -> iw +df AND dg -> di +dl AND dn -> do +la LSHIFT 15 -> le +fo RSHIFT 1 -> gh +NOT gw -> gx +NOT gb -> gc +ir LSHIFT 1 -> jl +x AND ai -> ak +he RSHIFT 5 -> hh +1 AND lu -> lv +NOT ft -> fu +gh OR gi -> gj +lf RSHIFT 5 -> li +x RSHIFT 3 -> z +b RSHIFT 3 -> e +he RSHIFT 2 -> hf +NOT fx -> fy +jt AND jv -> jw +hx OR hy -> hz +jp AND ka -> kc +fb AND fd -> fe +hz OR ik -> il +ci RSHIFT 1 -> db +fo AND fz -> gb +fq AND fr -> ft +gj RSHIFT 2 -> gk +cg OR ch -> ci +cd LSHIFT 15 -> ch +jm LSHIFT 1 -> kg +ih AND ij -> ik +fo RSHIFT 3 -> fq +fo RSHIFT 5 -> fr +1 AND fi -> fj +1 AND kz -> la +iu AND jf -> jh +cq AND cs -> ct +dv LSHIFT 1 -> ep +hf OR hl -> hm +km AND kn -> kp +de AND dk -> dm +dd RSHIFT 5 -> dg +NOT lo -> lp +NOT ju -> jv +NOT fg -> fh +cm AND co -> cp +ea AND eb -> ed +dd RSHIFT 3 -> df +gr AND gt -> gu +ep OR eo -> eq +cj AND cp -> cr +lf OR lq -> lr +gg LSHIFT 1 -> ha +et RSHIFT 2 -> eu +NOT jh -> ji +ek AND em -> en +jk LSHIFT 15 -> jo +ia OR ig -> ih +gv AND gx -> gy +et AND fe -> fg +lh AND li -> lk +1 AND io -> ip +kb AND kd -> ke +kk RSHIFT 5 -> kn +id AND if -> ig +NOT ls -> lt +dw OR dx -> dy +dd AND do -> dq +lf AND lq -> ls +NOT kc -> kd +dy AND ej -> el +1 AND ke -> kf +et OR fe -> ff +hz RSHIFT 5 -> ic +dd OR do -> dp +cj OR cp -> cq +NOT dq -> dr +kk RSHIFT 1 -> ld +jg AND ji -> jj +he OR hp -> hq +hi AND hk -> hl +dp AND dr -> ds +dz AND ef -> eh +hz RSHIFT 3 -> ib +db OR dc -> dd +hw LSHIFT 1 -> iq +he AND hp -> hr +NOT cr -> cs +lg AND lm -> lo +hv OR hu -> hw +il AND in -> io +NOT eh -> ei +gz LSHIFT 15 -> hd +gk AND gq -> gs +1 AND en -> eo +NOT kp -> kq +et RSHIFT 5 -> ew +lj AND ll -> lm +he RSHIFT 3 -> hg +et RSHIFT 3 -> ev +as AND bd -> bf +cu AND cw -> cx +jx AND jz -> ka +b OR n -> o +be AND bg -> bh +1 AND ht -> hu +1 AND gy -> gz +NOT hn -> ho +ck OR cl -> cm +ec AND ee -> ef +lv LSHIFT 15 -> lz +ks AND ku -> kv +NOT ie -> if +hf AND hl -> hn +1 AND r -> s +ib AND ic -> ie +hq AND hs -> ht +y AND ae -> ag +NOT ed -> ee +bi LSHIFT 15 -> bm +dy RSHIFT 2 -> dz +ci RSHIFT 2 -> cj +NOT bf -> bg +NOT im -> in +ev OR ew -> ex +ib OR ic -> id +bn RSHIFT 2 -> bo +dd RSHIFT 2 -> de +bl OR bm -> bn +as RSHIFT 1 -> bl +ea OR eb -> ec +ln AND lp -> lq +kk RSHIFT 3 -> km +is OR it -> iu +iu RSHIFT 2 -> iv +as OR bd -> be +ip LSHIFT 15 -> it +iw OR ix -> iy +kk RSHIFT 2 -> kl +NOT bb -> bc +ci RSHIFT 5 -> cl +ly OR lz -> ma +z AND aa -> ac +iu RSHIFT 1 -> jn +cy LSHIFT 15 -> dc +cf LSHIFT 1 -> cz +as RSHIFT 3 -> au +cz OR cy -> da +kw AND ky -> kz +lx -> a +iw AND ix -> iz +lr AND lt -> lu +jp RSHIFT 5 -> js +aw AND ay -> az +jc AND je -> jf +lb OR la -> lc +NOT cn -> co +kh LSHIFT 1 -> lb +1 AND jj -> jk +y OR ae -> af +ck AND cl -> cn +kk OR kv -> kw +NOT cv -> cw +kl AND kr -> kt +iu OR jf -> jg +at AND az -> bb +jp RSHIFT 2 -> jq +iv AND jb -> jd +jn OR jo -> jp +x OR ai -> aj +ba AND bc -> bd +jl OR jk -> jm +b RSHIFT 1 -> v +o AND q -> r +NOT p -> q +k AND m -> n +as RSHIFT 2 -> at \ No newline at end of file diff --git a/src/day7.rs b/src/day7.rs new file mode 100644 index 0000000..b062b33 --- /dev/null +++ b/src/day7.rs @@ -0,0 +1,286 @@ +use std::collections::HashMap; + +const DEBUG : bool = false; + +pub struct Data { + head: usize, + tree: HashMap, +} + +impl Data { + pub fn new() -> Data { + Data { + head: 0, + tree: HashMap::new(), + } + } + + pub fn parse(&mut self, input: String) { + for line in input.split("\n") { + let newnode = Node::parse(String::from(line)); + if DEBUG { + println!("{}: {}, {}, {}, {:?}, {}", line, newnode.name, newnode.a, newnode.b, newnode.fun, newnode.value); + } + self.tree.insert(newnode.name.clone(), newnode); + } + } + + pub fn execute(& self, name: String) -> Option { + let mut res = 0u16; + let mut results = HashMap::new(); + let mut start = match self.tree.get(&name) { + Some(val) => { + if DEBUG { + println!("Starting Execution"); + println!("\"{}\": {}, {}, {:?}, {}", val.name, val.a, val.b, val.fun, val.value); + } + val + }, + None => return None, + }; + start.execute(& self.tree, &mut results) + } + + pub fn execute2(&mut self, name: String) -> Option { + { + let mut nodeb = self.tree.get_mut(&String::from("b")).unwrap(); + nodeb.value = 956; + nodeb.fun = Mode::Const; + } + let mut res = 0u16; + let mut results = HashMap::new(); + let mut start = match self.tree.get(&name) { + Some(val) => { + if DEBUG { + println!("Starting Execution"); + println!("\"{}\": {}, {}, {:?}, {}", val.name, val.a, val.b, val.fun, val.value); + } + val + }, + None => return None, + }; + start.execute(& self.tree, &mut results) + } +} + +#[derive(Debug)] +enum Mode { + Const, + Not, + Lshift, + Rshift, + And, + Or, + Andconst, + Orconst, + Equal, +} + +struct Node { + name: String, + a: String, + b: String, + fun: Mode, + value: u16, +} + +impl Node{ + pub fn new() -> Node { + Node { + name: String::new(), + a: String::new(), + b: String::new(), + fun: Mode::Const, + value: 0, + } + } + pub fn execute(& self, tree: & HashMap, results: &mut HashMap) -> Option { + if DEBUG { + println!("{}: {}, {}, {:?}, {}", self.name, self.a, self.b, self.fun, self.value); + } + + match results.get(&self.name) { + Some(&val) => Some(val), + None => { + let res = match self.fun { + Mode::Const => Some(self.value), + Mode::Not => { + match tree.get(&self.a) { + Some(val) => match val.execute(tree, results) { + Some(res) => { + Some(!res) + }, + None => None, + }, + None => None, + } + }, + Mode::Equal => { + match tree.get(&self.a) { + Some(val) => match val.execute(tree, results) { + Some(res) => { + Some(res) + }, + None => None, + }, + None => None, + } + }, + Mode::Lshift => { + match tree.get(&self.a) { + Some(val) => match val.execute(tree, results) { + Some(res) => { + Some(res << self.value) + }, + None => None, + }, + None => None, + } + }, + Mode::Rshift => { + match tree.get(&self.a) { + Some(val) => match val.execute(tree, results) { + Some(res) => { + Some(res >> self.value) + }, + None => None, + }, + None => None, + } + }, + Mode::Andconst => { + match tree.get(&self.a) { + Some(val) => match val.execute(tree, results) { + Some(res) => { + Some(self.value & res) + }, + None => None, + }, + None => None, + } + }, + Mode::Orconst => { + match tree.get(&self.a) { + Some(val) => match val.execute(tree, results) { + Some(res) => { + Some(self.value | res) + }, + None => None, + }, + None => None, + } + }, + Mode::And => { + match tree.get(&self.a) { + Some(vala) => match vala.execute(tree, results) { + Some(resa) => { + match tree.get(&self.b) { + Some(valb) => match valb.execute(tree, results) { + Some(resb) => { + Some(resa & resb) + }, + None => None, + }, + None => None, + } + }, + None => None, + }, + None => None, + } + }, + Mode::Or => { + match tree.get(&self.a) { + Some(vala) => match vala.execute(tree, results) { + Some(resa) => { + match tree.get(&self.b) { + Some(valb) => match valb.execute(tree, results) { + Some(resb) => { + Some(resa | resb) + }, + None => None, + }, + None => None, + } + }, + None => None, + }, + None => None, + } + }, + _ => None, + }; + match res { + Some(val) => { + results.insert(self.name.clone(), val); + }, + None => (), + }; + res + }, + } + } + + pub fn parse(line: String) -> Node { + let mut arg: Vec<&str> = line.split_whitespace().collect(); + let mut newnode = Node::new(); + if arg.len() >= 3 { + let mut s = arg.remove(0); + if s.contains(char::is_uppercase) { + match s { + "NOT" => { + newnode.fun = Mode::Not; + newnode.a = String::from(arg.remove(0)); + }, + _ => (), + } + } else if s.contains(char::is_lowercase) { + newnode.a = String::from(s); + if arg.get(0).unwrap().contains(char::is_uppercase) { + match arg.remove(0) { + "AND" => { + newnode.fun = Mode::And; + newnode.b = String::from(arg.remove(0)); + }, + "OR" => { + newnode.fun = Mode::Or; + newnode.b = String::from(arg.remove(0)); + }, + "LSHIFT" => { + newnode.fun = Mode::Lshift; + newnode.value = arg.remove(0).parse::().unwrap(); + }, + "RSHIFT" => { + newnode.fun = Mode::Rshift; + newnode.value = arg.remove(0).parse::().unwrap(); + }, + _ => (), + } + } else { + newnode.fun = Mode::Equal; + } + } else if s.contains(char::is_numeric) { + newnode.value = s.parse::().unwrap(); + if arg.get(0).unwrap().contains(char::is_uppercase) { + match arg.remove(0) { + "AND" => { + newnode.fun = Mode::Andconst; + newnode.a = String::from(arg.remove(0)); + }, + "OR" => { + newnode.fun = Mode::Orconst; + newnode.a = String::from(arg.remove(0)); + }, + _ => (), + } + } else { + newnode.fun = Mode::Const; + } + } + } + if arg.remove(0).eq("->") { + newnode.name = String::from(arg.remove(0)); + } + newnode + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 6cd0163..a03dba9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod day3; mod day4; mod day5; mod day6; +mod day7; mod tests; @@ -100,4 +101,23 @@ fn main() { } Err(msg) => println!("{}",msg), }; + + match File::open("day7.txt") { + Ok(mut f) => { + let mut input = String::new(); + match f.read_to_string(&mut input) { + Ok(_) => (), + Err(msg) => println!("{}",msg), + } + let mut d7 = day7::Data::new(); + d7.parse(input); + let res = match d7.execute(String::from("a")) { + Some(val) => val, + None => 0, + }; + println!("day7 execute: {}", res); + println!("day7 execute2: {}", d7.execute2(String::from("a")).unwrap()); + } + Err(msg) => println!("{}",msg), + }; } diff --git a/src/tests.rs b/src/tests.rs index 809b10b..8fedf60 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -309,3 +309,33 @@ fn day6_5() { assert_eq!(res, 2000000); } +#[test] +fn day7_1() { + let input = String::from("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"); + let mut day7 = day7::Data::new(); + day7.parse(input); + let mut res = day7.execute(String::from("d")).unwrap(); + assert_eq!(res, 72); + res = day7.execute(String::from("e")).unwrap(); + assert_eq!(res, 507); + res = day7.execute(String::from("f")).unwrap(); + assert_eq!(res, 492); + res = day7.execute(String::from("g")).unwrap(); + assert_eq!(res, 114); + res = day7.execute(String::from("h")).unwrap(); + assert_eq!(res, 65412); + res = day7.execute(String::from("i")).unwrap(); + assert_eq!(res, 65079); + res = day7.execute(String::from("x")).unwrap(); + assert_eq!(res, 123); + res = day7.execute(String::from("y")).unwrap(); + assert_eq!(res, 456); +} +