1
- use std:: collections:: { HashMap , HashSet , VecDeque } ;
1
+ use std:: collections:: { HashMap , VecDeque } ;
2
2
use std:: env;
3
3
use std:: fs:: File ;
4
4
use std:: io:: { BufRead , BufReader } ;
@@ -9,11 +9,92 @@ type Circuit = HashMap<(String, usize), (String, String, String)>;
9
9
fn main ( ) {
10
10
let args = env:: args ( ) . collect :: < Vec < String > > ( ) ;
11
11
if let Ok ( ( state, circuit) ) = get_init_state_and_circuit ( & args[ 1 ] ) {
12
- println ! ( "{:?}" , solve( state, circuit) )
12
+ println ! ( "{:?}" , solve1( state, & circuit) ) ;
13
+ println ! ( "{:?}" , solve2( circuit) ) ;
13
14
}
14
15
}
15
16
16
- fn solve ( mut state : State , circuit : Circuit ) -> i64 {
17
+ fn solve2 ( circuit : Circuit ) -> String {
18
+ let mut swapped_wires = circuit
19
+ . iter ( )
20
+ . filter_map (
21
+ |( ( gate_type, _) , ( in1, in2, out) ) | match gate_type. as_str ( ) {
22
+ "AND" => is_invalid_and ( in1, in2, out, & circuit) ,
23
+ "OR" => is_invalid_or ( out, & circuit) ,
24
+ "XOR" => is_invalid_xor ( in1, in2, out, & circuit) ,
25
+ _ => panic ! ( "How?" ) ,
26
+ } ,
27
+ )
28
+ . collect :: < Vec < String > > ( ) ;
29
+ swapped_wires. sort ( ) ;
30
+ swapped_wires. join ( "," )
31
+ }
32
+
33
+ fn is_invalid_xor ( in1 : & String , in2 : & String , out : & String , circuit : & Circuit ) -> Option < String > {
34
+ if in1. starts_with ( "x" ) && in2. starts_with ( "y" ) || in1. starts_with ( "y" ) && in2. starts_with ( "x" )
35
+ {
36
+ let bit_position = & in1[ 1 ..] ;
37
+ let z = format ! ( "z{}" , bit_position) ;
38
+ let flag1 = bit_position == "00" && & z == out;
39
+ let flag2 =
40
+ find_ins ( & z, String :: from ( "XOR" ) , & circuit) . filter ( |e| & e. 0 == out || & e. 1 == out) ;
41
+ let flag3 = find_gate_with_in ( String :: from ( "AND" ) , out, & circuit) ;
42
+ if flag1 || flag2. is_some ( ) || flag3. is_some ( ) {
43
+ None
44
+ } else {
45
+ Some ( out. to_string ( ) )
46
+ }
47
+ } else if !out. starts_with ( "z" ) {
48
+ Some ( out. to_string ( ) )
49
+ } else {
50
+ None
51
+ }
52
+ }
53
+
54
+ fn is_invalid_or ( out : & String , circuit : & Circuit ) -> Option < String > {
55
+ let max_z = circuit
56
+ . values ( )
57
+ . filter ( |e| e. 2 . starts_with ( "z" ) )
58
+ . max_by_key ( |e| & e. 2 )
59
+ . unwrap ( ) ;
60
+ let flag1 = * out == max_z. 2 ;
61
+ let flag2 = find_gate_with_in ( String :: from ( "XOR" ) , out, circuit) . is_some ( )
62
+ && find_gate_with_in ( String :: from ( "AND" ) , out, circuit) . is_some ( ) ;
63
+ if flag1 || flag2 {
64
+ None
65
+ } else {
66
+ Some ( out. to_string ( ) )
67
+ }
68
+ }
69
+ fn is_invalid_and ( in1 : & String , in2 : & String , out : & String , circuit : & Circuit ) -> Option < String > {
70
+ let flag1 = in1 == "x00" && in2 == "y00" || in1 == "y00" && in2 == "x00" ;
71
+ let flag2 = find_gate_with_in ( String :: from ( "OR" ) , out, circuit) . is_some ( ) ;
72
+ if flag1 || flag2 {
73
+ None
74
+ } else {
75
+ Some ( out. to_string ( ) )
76
+ }
77
+ }
78
+
79
+ fn find_gate_with_in (
80
+ gate_type : String ,
81
+ input : & String ,
82
+ circuit : & Circuit ,
83
+ ) -> Option < ( String , String , String ) > {
84
+ circuit
85
+ . iter ( )
86
+ . find ( |( k, v) | k. 0 == * gate_type && ( v. 0 == * input || v. 1 == * input) )
87
+ . map ( |( _, v) | v. clone ( ) )
88
+ }
89
+
90
+ fn find_ins ( z : & String , gate_type : String , circuit : & Circuit ) -> Option < ( String , String ) > {
91
+ circuit
92
+ . iter ( )
93
+ . find ( |( k, v) | k. 0 == * gate_type && ( v. 2 == * z) )
94
+ . map ( |e| ( e. 1 . 0 . clone ( ) , e. 1 . 1 . clone ( ) ) )
95
+ }
96
+
97
+ fn solve1 ( mut state : State , circuit : & Circuit ) -> i64 {
17
98
let mut gates: VecDeque < & ( String , usize ) > =
18
99
VecDeque :: < & ( String , usize ) > :: from ( circuit. keys ( ) . collect :: < Vec < & ( String , usize ) > > ( ) ) ;
19
100
while !gates. is_empty ( ) {
0 commit comments