@@ -4,6 +4,7 @@ function read(wiresMap, prefix) {
44 return out . map ( x => wiresMap . get ( x ) ) . join ( "" ) ;
55}
66
7+ const ops = { AND : ( a , b ) => a & b , OR : ( a , b ) => a | b , XOR : ( a , b ) => a ^ b } ;
78function run ( gates , wiresMap ) {
89 let done = false ;
910 while ( ! done ) {
@@ -14,9 +15,7 @@ function run(gates, wiresMap) {
1415 let c = wiresMap . get ( wire ) ;
1516 if ( a !== undefined && b !== undefined && c === undefined ) {
1617 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 ) ) ;
2019 }
2120 } ) ;
2221 }
@@ -46,55 +45,45 @@ export function part1(input) {
4645function extractUnit ( gates , i ) {
4746 let num = i . toString ( ) . padStart ( 2 , "0" ) ;
4847 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 ) ) ;
5957 more = more . filter ( x => ! not . includes ( x . a ) && ! not . includes ( x . b ) ) ;
60- if ( more . length ) {
61- done = false ;
62- unit . push ( ...more ) ;
63- }
6458 }
6559 return unit ;
6660}
6761
6862function 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 ( ) ;
7367 if ( outputs . every ( x => x . startsWith ( "z" ) ) ) outputs . reverse ( ) ;
7468 for ( let i = 0 ; i < 2 ** inputs . length ; i ++ ) {
7569 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 ] ) ) ;
7872 run ( gates , wiresMap ) ;
7973 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 ) ;
8175 if ( result !== expect ) return false ;
8276 }
8377 return true ;
8478}
8579
86- function getSwamps ( gates ) {
80+ function getSwamps ( unit ) {
8781 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 } ) ;
9887 }
9988 }
10089 return options ;
@@ -106,8 +95,7 @@ export function part2(input) {
10695 let swapped = [ ] ;
10796 for ( let i = 0 ; i < length ; i ++ ) {
10897 let unit = extractUnit ( gates , i ) ;
109- let pass = unitTest ( unit ) ;
110- if ( ! pass ) {
98+ if ( ! unitTest ( unit ) ) {
11199 let { swap } = getSwamps ( unit ) . find ( x => unitTest ( x . gates ) ) ;
112100 swapped . push ( ...swap ) ;
113101 }
0 commit comments