1- import { memoize } from "../utils/memoize.js" ;
21import { powerSet } from "combinatorial-generators" ;
32
43function parse ( input ) {
@@ -17,41 +16,43 @@ function producePatterns(buttons, length) {
1716 let lights = Array ( length ) . fill ( 0 ) ;
1817 for ( let button of pressed ) for ( let i of button ) lights [ i ] ++ ;
1918 let key = lights . map ( x => x % 2 ) . join ( "" ) ;
20- patterns [ key ] = [ ... ( patterns [ key ] || [ ] ) , pressed ] ;
19+ patterns [ key ] = ( patterns [ key ] || [ ] ) . concat ( [ pressed ] ) ;
2120 }
2221 return patterns ;
2322}
2423
2524export function part1 ( input ) {
2625 let machines = parse ( input ) ;
27- let p1 = 0 ;
26+ let result = 0 ;
2827 for ( let { indicator, buttons } of machines ) {
2928 let patterns = producePatterns ( buttons , indicator . length ) ;
30- p1 += Math . min ( ...patterns [ indicator ] . map ( x => x . length ) ) ;
29+ result += Math . min ( ...patterns [ indicator ] . map ( x => x . length ) ) ;
3130 }
32- return p1 ;
31+ return result ;
32+ }
33+
34+ function minimumPresses ( target , patterns ) {
35+ if ( target . every ( x => x === 0 ) ) return 0 ;
36+ if ( target . some ( x => x < 0 ) ) return Infinity ;
37+ let totals = [ ] ;
38+ // find minimum presses to make all jolt counters even numbers
39+ let options = patterns [ target . map ( x => x % 2 ) . join ( "" ) ] || [ ] ;
40+ for ( let pressed of options ) {
41+ let next = target . slice ( 0 ) ;
42+ for ( let button of pressed ) for ( let i of button ) next [ i ] -- ;
43+ // find the minimum presses to get jolts half way and multiply by 2
44+ next = next . map ( x => x / 2 ) ;
45+ totals . push ( pressed . length + 2 * minimumPresses ( next , patterns ) ) ;
46+ }
47+ return Math . min ( ...totals ) ;
3348}
3449
3550export function part2 ( input ) {
3651 let machines = parse ( input ) ;
37- let p2 = 0 ;
52+ let result = 0 ;
3853 for ( let { buttons, jolts } of machines ) {
3954 let patterns = producePatterns ( buttons , jolts . length ) ;
40- let presses = memoize ( target => {
41- if ( target . every ( x => x === 0 ) ) return 0 ;
42- if ( target . some ( x => x < 0 ) ) return Infinity ;
43-
44- let total = Infinity ;
45- let options = patterns [ target . map ( x => x % 2 ) . join ( "" ) ] || [ ] ;
46- for ( let pressed of options ) {
47- let jolt = Array ( target . length ) . fill ( 0 ) ;
48- for ( let button of pressed ) for ( let i of button ) jolt [ i ] ++ ;
49- let newTarget = jolt . map ( ( a , i ) => ( target [ i ] - a ) / 2 ) ;
50- total = Math . min ( total , pressed . length + 2 * presses ( newTarget ) ) ;
51- }
52- return total ;
53- } ) ;
54- p2 += presses ( jolts ) ;
55+ result += minimumPresses ( jolts , patterns ) ;
5556 }
56- return p2 ;
57+ return result ;
5758}
0 commit comments