11package org .ck .adventofcode .year2025 ;
22
33import java .util .*;
4- import java .util .function .ToLongFunction ;
4+ import java .util .function .Function ;
5+ import java .util .stream .IntStream ;
56import org .ck .adventofcode .util .AOCSolution ;
67import org .ck .codechallengelib .annotation .Solution ;
78
@@ -19,111 +20,134 @@ public class Day06 extends AOCSolution {
1920
2021 @ Override
2122 protected void runPartOne (final Scanner in ) {
22- run (in , Day06 :: getPart1Result );
23+ run (in , strings -> Arrays . stream ( strings ). map ( String :: trim ). map ( Long :: valueOf ). toList () );
2324 }
2425
2526 @ Override
2627 protected void runPartTwo (final Scanner in ) {
27- run (in , Day06 ::getPart2Result );
28+ run (in , Day06 ::parseVertical );
2829 }
2930
30- private void run (final Scanner in , final ToLongFunction < List <List < String >>> getResult ) {
31+ private void run (final Scanner in , final Function < String [], List <Long >> numberParser ) {
3132 final List <String > inputs = new ArrayList <>();
3233
3334 while (in .hasNextLine ()) {
3435 inputs .add (in .nextLine ());
3536 }
3637
37- final String operations = inputs .getLast ();
38- final List <List <String >> columns = new ArrayList <>();
39- for (int j = 0 ; j < inputs .size () - 1 ; ++j ) {
40- columns .add (new ArrayList <>());
41- }
38+ final List <Problem > problems = getProblems (inputs , numberParser );
39+ print (problems .stream ().mapToLong (Problem ::solve ).sum ());
40+ }
4241
43- int start = 1 ;
44- while (true ) {
45- final int nextPlus = operations .indexOf ('+' , start );
46- final int nextTimes = operations .indexOf ('*' , start );
47-
48- final int nextNumberStart ;
49- if (nextPlus == -1 && nextTimes == -1 ) {
50- break ;
51- } else if (nextPlus == -1 ) {
52- nextNumberStart = nextTimes ;
53- } else if (nextTimes == -1 ) {
54- nextNumberStart = nextPlus ;
55- } else {
56- nextNumberStart = Math .min (nextPlus , nextTimes );
57- }
42+ private List <Problem > getProblems (
43+ final List <String > inputs , final Function <String [], List <Long >> numberParser ) {
44+ final List <Integer > emptyColumns = getEmptyColumns (inputs );
45+
46+ final String [][] inputArray = new String [emptyColumns .size () + 1 ][inputs .size ()];
47+ for (int inputRow = 0 ; inputRow < inputs .size (); ++inputRow ) {
48+ final String input = inputs .get (inputRow );
5849
59- for (int j = 0 ; j < inputs .size () - 1 ; ++j ) {
60- columns .get (j ).add (inputs .get (j ).substring (start - 1 , nextNumberStart - 1 ));
50+ int previousIndex = 0 ;
51+ for (int column = 0 ; column < emptyColumns .size (); ++column ) {
52+ final int emptyColumnIndex = emptyColumns .get (column );
53+ inputArray [column ][inputRow ] = input .substring (previousIndex , emptyColumnIndex );
54+
55+ previousIndex = emptyColumnIndex + 1 ;
6156 }
6257
63- start = nextNumberStart + 1 ;
64- }
65- for (int j = 0 ; j < inputs .size () - 1 ; ++j ) {
66- columns .get (j ).add (inputs .get (j ).substring (start - 1 ));
58+ inputArray [inputArray .length - 1 ][inputRow ] = input .substring (previousIndex );
6759 }
6860
69- columns .add (new ArrayList <>(Arrays .asList (operations .trim ().split ("\\ s+" ))));
61+ final List <Problem > problems = new ArrayList <>();
62+ for (int problemIndex = 0 ; problemIndex < emptyColumns .size () + 1 ; ++problemIndex ) {
63+ problems .add (
64+ new Problem (
65+ numberParser .apply (
66+ Arrays .copyOfRange (
67+ inputArray [problemIndex ], 0 , inputArray [problemIndex ].length - 1 )),
68+ inputArray [problemIndex ][inputArray [problemIndex ].length - 1 ].startsWith ("+" )
69+ ? new Operation .Addition ()
70+ : new Operation .Multiplication ()));
71+ }
7072
71- print ( getResult . applyAsLong ( columns )) ;
73+ return problems ;
7274 }
7375
74- private static Long getPart1Result ( List <List < String > > inputs ) {
75- long sum = 0 ;
76- for ( int i = 0 ; i < inputs .get ( 0 ). size (); ++ i ) {
77- final String operation = inputs . get ( inputs . size () - 1 ). get ( i );
78- long result = "*" . equals ( operation ) ? 1 : 0 ;
76+ private static List < Integer > getEmptyColumns ( final List <String > inputs ) {
77+ final Set < Integer > emptyIndices =
78+ new HashSet <>( IntStream . range ( 0 , inputs .getFirst (). length ()). boxed (). toList ());
79+ for ( final String input : inputs ) {
80+ final Set < Integer > emptyIndicesOnLine = new HashSet <>() ;
7981
80- for (int j = 0 ; j < inputs .size () - 1 ; ++j ) {
81- switch (operation ) {
82- case "+" -> result += Long .parseLong (inputs .get (j ).get (i ).trim ());
83- case "*" -> result *= Long .parseLong (inputs .get (j ).get (i ).trim ());
82+ for (int i = 0 ; i < input .length (); ++i ) {
83+ if (' ' == input .charAt (i )) {
84+ emptyIndicesOnLine .add (i );
8485 }
8586 }
8687
87- sum += result ;
88+ emptyIndices . retainAll ( emptyIndicesOnLine ) ;
8889 }
8990
90- return sum ;
91+ return emptyIndices . stream (). sorted (). toList () ;
9192 }
9293
93- private static Long getPart2Result (List <List <String >> inputs ) {
94- long sum = 0 ;
95- for (int i = 0 ; i < inputs .get (0 ).size (); ++i ) {
96- int numbersCount = 0 ;
97- for (int j = 0 ; j < inputs .size () - 1 ; ++j ) {
98- numbersCount = Math .max (numbersCount , inputs .get (j ).get (i ).length ());
94+ private static List <Long > parseVertical (final String [] strings ) {
95+ final List <Long > numbers = new ArrayList <>();
96+ for (int numberIndex = 0 ; numberIndex < strings [0 ].length (); ++numberIndex ) {
97+ long number = 0 ;
98+ for (final String string : strings ) {
99+ char current = string .charAt (numberIndex );
100+
101+ if (current != ' ' ) {
102+ number = number * 10 + (current - '0' );
103+ }
99104 }
100105
101- final List <Long > numbers = new ArrayList <>();
102- for (int numberIndex = 0 ; numberIndex < numbersCount ; ++numberIndex ) {
103- long number = 0 ;
104- for (int j = 0 ; j < inputs .size () - 1 ; ++j ) {
105- char current = inputs .get (j ).get (i ).charAt (numberIndex );
106+ numbers .add (number );
107+ }
106108
107- if (current != ' ' ) {
108- number = number * 10 + (current - '0' );
109- }
110- }
109+ return numbers ;
110+ }
111111
112- numbers .add (number );
113- }
112+ private record Problem (List <Long > values , Operation operation ) {
113+ public long solve () {
114+ values .forEach (operation ::apply );
114115
115- final String operation = inputs .get (inputs .size () - 1 ).get (i );
116- long result = "*" .equals (operation ) ? 1 : 0 ;
117- for (Long number : numbers ) {
118- switch (operation ) {
119- case "+" -> result += number ;
120- case "*" -> result *= number ;
121- }
116+ return operation .getResult ();
117+ }
118+ }
119+
120+ private sealed interface Operation {
121+ void apply (Long value );
122+
123+ long getResult ();
124+
125+ final class Multiplication implements Operation {
126+ private long result = 1 ;
127+
128+ @ Override
129+ public void apply (Long value ) {
130+ result *= value ;
122131 }
123132
124- sum += result ;
133+ @ Override
134+ public long getResult () {
135+ return result ;
136+ }
125137 }
126138
127- return sum ;
139+ final class Addition implements Operation {
140+ private long result = 0 ;
141+
142+ @ Override
143+ public void apply (Long value ) {
144+ result += value ;
145+ }
146+
147+ @ Override
148+ public long getResult () {
149+ return result ;
150+ }
151+ }
128152 }
129153}
0 commit comments