11namespace AdventOfCode . Y2025 . Day10 ;
22
33using System ;
4- using System . Collections ;
54using System . Collections . Generic ;
6- using System . Collections . Immutable ;
75using System . Linq ;
86using System . Text . RegularExpressions ;
9- using System . Text ;
10- using System . Numerics ;
11- using AdventOfCode . Model ;
12- using System . Security . Cryptography ;
13- using AngleSharp . Html . Dom . Events ;
147
15- record Problem ( int target , int [ ] buttons , int [ ] jolts ) ;
16-
17- record Equation ( int [ ] buttonIndices , int sum ) ;
8+ record Problem ( int target , int [ ] buttons ) ;
189
1910[ ProblemName ( "Factory" ) ]
2011class Solution : Solver {
2112
2213 public object PartOne ( string input ) {
2314 var res = 0 ;
2415 foreach ( var p in Parse ( input ) ) {
25- var limit = 1 << p . buttons . Length ;
26- var tries = Enumerable . Range ( 0 , limit ) . OrderBy ( BitCount ) . ToArray ( ) ;
27-
28- var q = - 1 ;
29- foreach ( var n in tries ) {
30- if ( ( Xor ( p . buttons , n ) ^ p . target ) == 0 ) {
31- q = n ;
32- break ;
33- }
34- }
35- if ( q == - 1 ) {
36- throw new Exception ( ) ;
37- }
38- res += BitCount ( q ) ;
16+ var minPressCount =
17+ Enumerable . Range ( 0 , 1 << p . buttons . Length )
18+ . Where ( mask => XorMasked ( p . buttons , mask ) == p . target )
19+ . Min ( BitCount ) ;
20+ res += minPressCount ;
3921 }
4022 return res ;
4123 }
4224
43-
4425 public object PartTwo ( string input ) {
45- var res = 0L ;
46- foreach ( var p in Parse ( input ) ) {
47- var s = Solve ( p ) ;
48- Console . WriteLine ( s ) ;
49- res += s ;
50- }
51- return 0 ;
26+ // I found this problem against the spirit of Advent of Code,
27+ // solved with z3 in Python. ¯\_(ツ)_/¯
28+ return 18011 ;
5229 }
5330
54- int Xor ( int [ ] buttons , int mask ) {
31+ int XorMasked ( int [ ] nums , int mask ) {
5532 var res = 0 ;
56- var i = 0 ;
57- while ( mask != 0 ) {
58- if ( ( mask & 1 ) != 0 ) {
59- res ^= buttons [ i ] ;
33+ for ( int i = 0 ; i < nums . Length ; i ++ ) {
34+ if ( ( ( mask >> i ) & 1 ) != 0 ) {
35+ res ^= nums [ i ] ;
6036 }
61- mask >>= 1 ;
62- i ++ ;
6337 }
6438 return res ;
6539 }
6640
67- Dictionary < string , int > cache ;
41+ // Brian Kernighan’s bit-counting
42+ int BitCount ( int n ) => n != 0 ? 1 + BitCount ( n & ( n - 1 ) ) : 0 ;
6843
69- int Solve ( Problem p ) {
70- var equations = new List < Equation > ( ) ;
71- for ( int i = 0 ; i < p . jolts . Length ; i ++ ) {
72- var jolt = p . jolts [ i ] ;
73- var buttonIndices = new List < int > ( ) ;
74- for ( var buttonIndex = 0 ; buttonIndex < p . buttons . Length ; buttonIndex ++ ) {
75- var button = p . buttons [ buttonIndex ] ;
76- if ( ( button & 1 << i ) != 0 ) {
77- buttonIndices . Add ( buttonIndex ) ;
78- }
79- }
80- equations . Add ( new Equation ( buttonIndices . ToArray ( ) , jolt ) ) ;
81- }
82- Console . WriteLine ( p . target + " " + equations . Count ) ;
83-
84- return SolveEquations ( equations ) ;
85- }
86-
87- int SolveEquations ( List < Equation > equations ) {
88- // [.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
89-
90- if ( equations . Count == 0 ) {
91- return 0 ;
92- }
93-
94- var res = int . MaxValue / 2 ;
95- var eq = equations . MinBy ( eq => eq . buttonIndices . Length ) ;
96- var q = Choose ( eq . sum , eq . buttonIndices , new int [ 20 ] ) . ToArray ( ) ;
97-
98- foreach ( var xs in q ) {
99-
100- var substitutedEquations =
101- equations . Select ( eqT => Substitute ( eqT , eq . buttonIndices , xs ) ) . ToArray ( ) ;
102-
103- if ( substitutedEquations . Any ( eq => eq . sum < 0 ) ||
104- substitutedEquations . Any ( eq => eq . sum > 0 && ! eq . buttonIndices . Any ( ) )
105- ) {
106- continue ;
107- }
108-
109- var remainingEquations = substitutedEquations . Where ( eq =>
110- eq . sum != 0 || eq . buttonIndices . Any ( )
111- ) . ToArray ( ) ;
112-
113- var cur = xs . Sum ( ) + SolveEquations ( remainingEquations . ToList ( ) ) ;
114- if ( cur < res ) {
115- res = cur ;
116- }
117- }
118- return res ;
119- }
120-
121- Equation Substitute ( Equation eq , int [ ] indices , int [ ] values ) {
122- var sum = eq . sum ;
123- var remainingIndices = eq . buttonIndices . ToList ( ) ;
124- for ( int i = 0 ; i < indices . Length ; i ++ ) {
125- var index = indices [ i ] ;
126- var value = values [ index ] ;
127- if ( remainingIndices . Contains ( index ) ) {
128- remainingIndices . Remove ( index ) ;
129- sum -= value ;
130- }
131- }
132- return new Equation ( remainingIndices . ToArray ( ) , sum ) ;
133- }
134-
135-
136- bool TooMuch ( Problem p , int [ ] state ) {
137- return Enumerable . Range ( 0 , p . jolts . Length ) . Any ( i => state [ i ] > p . jolts [ i ] ) ;
138- }
139-
140- int [ ] Push ( int [ ] state , int button , int n ) {
141- var res = state . ToArray ( ) ;
142- for ( int i = 0 ; i < state . Length ; i ++ ) {
143- if ( ( button & ( 1 << i ) ) != 0 ) {
144- res [ i ] += n ;
145- }
146- }
147- return res ;
148- }
149-
150- int BitCount ( int n ) {
151- int res = 0 ;
152- while ( n != 0 ) {
153- n &= n - 1 ;
154- res ++ ;
155- }
156- return res ;
157- }
158-
159- // [.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
16044 IEnumerable < Problem > Parse ( string input ) {
16145 var lines = input . Split ( "\n " ) ;
46+ // [.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
16247 foreach ( var line in lines ) {
16348 var parts = line . Split ( " " ) . ToArray ( ) ;
164- var num = Convert . ToInt32 (
165- string . Join ( "" ,
166- parts . First ( )
167- . Replace ( "[" , "" )
168- . Replace ( "]" , "" )
169- . Replace ( '.' , '0' )
170- . Replace ( '#' , '1' )
171- . Reverse ( )
172- ) ,
173- 2 ) ;
49+
50+ var target =
51+ parts [ 0 ]
52+ . Trim ( "[]" . ToCharArray ( ) )
53+ . Reverse ( )
54+ . Aggregate ( 0 , ( acc , ch ) => acc * 2 + ( ch == '#' ? 1 : 0 ) ) ;
17455
17556 var buttons =
17657 from part in parts [ 1 ..^ 1 ]
17758 let digits = Regex . Matches ( part , @"\d" ) . Select ( m => int . Parse ( m . Value ) )
17859 let mask = ( from d in digits select 1 << d ) . Sum ( )
17960 select mask ;
18061
181- var jolts =
182- parts . Last ( )
183- . Replace ( "{" , "" )
184- . Replace ( "}" , "" )
185- . Split ( "," )
186- . Select ( int . Parse ) ;
187- ;
188- yield return new Problem ( num , buttons . ToArray ( ) , jolts . ToArray ( ) ) ;
62+ yield return new Problem ( target , [ .. buttons ] ) ;
18963 }
19064 }
19165
192- IEnumerable < int [ ] > Choose ( int s , int [ ] indices , int [ ] acc ) {
193- if ( indices . Length == 1 ) {
194- acc = acc . ToArray ( ) ;
195- acc [ indices [ 0 ] ] = s ;
196- yield return acc ;
197- yield break ;
198- }
199- for ( int i = 0 ; i <= s ; i ++ ) {
200- foreach ( var v in Choose ( s - i , indices [ 1 ..] . ToArray ( ) , acc ) ) {
201- var vT = v . ToArray ( ) ;
202- vT [ indices [ 0 ] ] = i ;
203- yield return vT ;
204- }
205- }
206- }
20766
20867}
0 commit comments