@@ -20,8 +20,9 @@ impl Day07 {
2020 fn signal ( & self , input : & str , wire : & str ) -> String {
2121 let instructions = self . parse ( input) ;
2222 let main = instructions. get ( wire) . unwrap ( ) ;
23+ let mut cache = HashMap :: new ( ) ;
2324
24- main. calculate ( & instructions) . to_string ( )
25+ main. calculate ( & instructions, & mut cache ) . to_string ( )
2526 }
2627
2728 fn parse ( & self , input : & str ) -> Wires {
@@ -43,42 +44,52 @@ enum Instruction {
4344 Value ( Value ) ,
4445 And ( Value , Value ) ,
4546 Or ( Value , Value ) ,
46- LShift ( Value , u64 ) ,
47- RShift ( Value , u64 ) ,
47+ LShift ( Value , u16 ) ,
48+ RShift ( Value , u16 ) ,
4849 Not ( Value ) ,
4950}
5051
5152impl Instruction {
52- fn calculate ( & self , wires : & Wires ) -> u16 {
53+ fn calculate ( & self , wires : & Wires , cache : & mut HashMap < String , u16 > ) -> u16 {
5354 match self {
5455 Instruction :: Value ( value) => match value {
5556 Value :: Numeric ( number) => * number,
56- Value :: Variable ( s) => wires. get ( s) . unwrap ( ) . calculate ( wires) ,
57+ Value :: Variable ( s) => {
58+ if let Some ( from_cache) = cache. get ( s) {
59+ return * from_cache;
60+ }
61+
62+ let result = wires. get ( s) . unwrap ( ) . calculate ( wires, cache) ;
63+
64+ cache. insert ( s. clone ( ) , result) ;
65+
66+ result
67+ }
5768 } ,
5869 Instruction :: And ( a, b) => {
59- let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires) ;
60- let right = Instruction :: Value ( b. clone ( ) ) . calculate ( wires) ;
70+ let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires, cache ) ;
71+ let right = Instruction :: Value ( b. clone ( ) ) . calculate ( wires, cache ) ;
6172
6273 left & right
6374 }
6475 Instruction :: Or ( a, b) => {
65- let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires) ;
66- let right = Instruction :: Value ( b. clone ( ) ) . calculate ( wires) ;
76+ let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires, cache ) ;
77+ let right = Instruction :: Value ( b. clone ( ) ) . calculate ( wires, cache ) ;
6778
6879 left | right
6980 }
7081 Instruction :: LShift ( a, b) => {
71- let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires) ;
82+ let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires, cache ) ;
7283
7384 left << b
7485 }
7586 Instruction :: RShift ( a, b) => {
76- let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires) ;
87+ let left = Instruction :: Value ( a. clone ( ) ) . calculate ( wires, cache ) ;
7788
7889 left >> b
7990 }
8091 Instruction :: Not ( a) => {
81- let value = Instruction :: Value ( a. clone ( ) ) . calculate ( wires) ;
92+ let value = Instruction :: Value ( a. clone ( ) ) . calculate ( wires, cache ) ;
8293
8394 !value
8495 }
@@ -156,14 +167,16 @@ x OR y -> e
156167x LSHIFT 2 -> f
157168y RSHIFT 2 -> g
158169NOT x -> h
159- NOT y -> i"# ;
170+ NOT y -> i
171+ 123 AND y -> s"# ;
160172
161173 #[ test]
162174 fn part_one_example_test ( ) {
163175 assert_eq ! ( "123" , Day07 . signal( EXAMPLE , "x" ) ) ;
164176 assert_eq ! ( "456" , Day07 . signal( EXAMPLE , "y" ) ) ;
165177 assert_eq ! ( "456" , Day07 . signal( EXAMPLE , "z" ) ) ;
166178 assert_eq ! ( "72" , Day07 . signal( EXAMPLE , "d" ) ) ;
179+ assert_eq ! ( "72" , Day07 . signal( EXAMPLE , "s" ) ) ;
167180 assert_eq ! ( "507" , Day07 . signal( EXAMPLE , "e" ) ) ;
168181 assert_eq ! ( "492" , Day07 . signal( EXAMPLE , "f" ) ) ;
169182 assert_eq ! ( "114" , Day07 . signal( EXAMPLE , "g" ) ) ;
0 commit comments