@@ -4,6 +4,7 @@ function read(wiresMap, prefix) {
4
4
return out . map ( x => wiresMap . get ( x ) ) . join ( "" ) ;
5
5
}
6
6
7
+ const ops = { AND : ( a , b ) => a & b , OR : ( a , b ) => a | b , XOR : ( a , b ) => a ^ b } ;
7
8
function run ( gates , wiresMap ) {
8
9
let done = false ;
9
10
while ( ! done ) {
@@ -14,9 +15,7 @@ function run(gates, wiresMap) {
14
15
let c = wiresMap . get ( wire ) ;
15
16
if ( a !== undefined && b !== undefined && c === undefined ) {
16
17
done = false ;
17
- if ( op === "AND" ) wiresMap . set ( wire , a & b ) ;
18
- if ( op === "OR" ) wiresMap . set ( wire , a | b ) ;
19
- if ( op === "XOR" ) wiresMap . set ( wire , a ^ b ) ;
18
+ wiresMap . set ( wire , ops [ op ] ( a , b ) ) ;
20
19
}
21
20
} ) ;
22
21
}
@@ -46,55 +45,45 @@ export function part1(input) {
46
45
function extractUnit ( gates , i ) {
47
46
let num = i . toString ( ) . padStart ( 2 , "0" ) ;
48
47
let next = ( i + 1 ) . toString ( ) . padStart ( 2 , "0" ) ;
49
- let unit = gates . filter ( x => x . a === `x${ num } ` && x . b === `y${ num } ` ) ;
50
- let not = gates
51
- . filter ( x => x . a === `x${ next } ` && x . b === `y${ next } ` )
52
- . map ( x => x . wire ) ;
53
- let done = false ;
54
- while ( ! done ) {
55
- done = true ;
56
- let wires = unit . map ( x => x . wire ) ;
57
- let more = gates . filter ( x => wires . includes ( x . a ) || wires . includes ( x . b ) ) ;
58
- more = more . filter ( x => ! unit . includes ( x ) ) ;
48
+ let more = gates . filter ( x => x . a === `x${ num } ` && x . b === `y${ num } ` ) ;
49
+ let not = gates . filter ( x => x . a === `x${ next } ` && x . b === `y${ next } ` ) ;
50
+ not = not . map ( x => x . wire ) ;
51
+
52
+ let unit = [ ] ;
53
+ while ( more . length ) {
54
+ let wires = more . map ( x => x . wire ) ;
55
+ unit . push ( ...more ) ;
56
+ more = gates . filter ( x => wires . includes ( x . a ) || wires . includes ( x . b ) ) ;
59
57
more = more . filter ( x => ! not . includes ( x . a ) && ! not . includes ( x . b ) ) ;
60
- if ( more . length ) {
61
- done = false ;
62
- unit . push ( ...more ) ;
63
- }
64
58
}
65
59
return unit ;
66
60
}
67
61
68
62
function unitTest ( gates ) {
69
- let inp = new Set ( gates . flatMap ( x => [ x . a , x . b ] ) ) ;
70
- let out = new Set ( gates . map ( x => x . wire ) ) ;
71
- let inputs = [ ...inp . difference ( out ) ] . sort ( ) ;
72
- let outputs = [ ...out . difference ( inp ) ] . sort ( ) ;
63
+ let intoGates = new Set ( gates . flatMap ( x => [ x . a , x . b ] ) ) ;
64
+ let outOfGates = new Set ( gates . map ( x => x . wire ) ) ;
65
+ let inputs = [ ...intoGates . difference ( outOfGates ) ] . sort ( ) ;
66
+ let outputs = [ ...outOfGates . difference ( intoGates ) ] . sort ( ) ;
73
67
if ( outputs . every ( x => x . startsWith ( "z" ) ) ) outputs . reverse ( ) ;
74
68
for ( let i = 0 ; i < 2 ** inputs . length ; i ++ ) {
75
69
let wiresMap = new Map ( ) ;
76
- let bin = i . toString ( 2 ) ;
77
- inputs . forEach ( ( x , j ) => wiresMap . set ( x , + bin [ j ] ) ) ;
70
+ let binary = i . toString ( 2 ) ;
71
+ inputs . forEach ( ( x , j ) => wiresMap . set ( x , + binary [ j ] ) ) ;
78
72
run ( gates , wiresMap ) ;
79
73
let result = parseInt ( outputs . map ( x => wiresMap . get ( x ) ) . join ( "" ) , 2 ) ;
80
- let expect = bin . split ( "" ) . reduce ( ( a , b ) => + a + + b , 0 ) ;
74
+ let expect = binary . split ( "" ) . reduce ( ( a , b ) => + a + + b , 0 ) ;
81
75
if ( result !== expect ) return false ;
82
76
}
83
77
return true ;
84
78
}
85
79
86
- function getSwamps ( gates ) {
80
+ function getSwamps ( unit ) {
87
81
let options = [ ] ;
88
- let out = gates . map ( x => x . wire ) ;
89
- for ( let i = 0 ; i < out . length ; i ++ ) {
90
- for ( let j = i + 1 ; j < out . length ; j ++ ) {
91
- let option = gates . map ( x => {
92
- let next = { ...x } ;
93
- if ( x . wire === out [ i ] ) next . wire = out [ j ] ;
94
- if ( x . wire === out [ j ] ) next . wire = out [ i ] ;
95
- return next ;
96
- } ) ;
97
- options . push ( { swap : [ out [ i ] , out [ j ] ] , gates : option } ) ;
82
+ for ( let i = 0 ; i < unit . length ; i ++ ) {
83
+ for ( let j = i + 1 ; j < unit . length ; j ++ ) {
84
+ let gates = unit . map ( x => ( { ...x } ) ) ;
85
+ [ gates [ i ] . wire , gates [ j ] . wire ] = [ gates [ j ] . wire , gates [ i ] . wire ] ;
86
+ options . push ( { swap : [ gates [ i ] . wire , gates [ j ] . wire ] , gates } ) ;
98
87
}
99
88
}
100
89
return options ;
@@ -106,8 +95,7 @@ export function part2(input) {
106
95
let swapped = [ ] ;
107
96
for ( let i = 0 ; i < length ; i ++ ) {
108
97
let unit = extractUnit ( gates , i ) ;
109
- let pass = unitTest ( unit ) ;
110
- if ( ! pass ) {
98
+ if ( ! unitTest ( unit ) ) {
111
99
let { swap } = getSwamps ( unit ) . find ( x => unitTest ( x . gates ) ) ;
112
100
swapped . push ( ...swap ) ;
113
101
}
0 commit comments