1+ import { delay , Console } from "../../utility.mjs" ;
2+
3+ export default class {
4+ /**
5+ * @param {Console } solConsole Solution console.
6+ * @param {HTMLElement } visContainer Visualization container.
7+ */
8+ constructor ( solConsole , visContainer ) {
9+ this . isSolving = false ;
10+ this . isStopping = false ;
11+ this . solConsole = typeof solConsole !== "undefined" ? solConsole : new Console ( ) ;
12+ this . visContainer = visContainer ;
13+ }
14+
15+ /**
16+ * Parses the puzzle input.
17+ * @param {string } input Puzzle input.
18+ * @returns {number[][] } Spreadsheet.
19+ */
20+ parse ( input ) {
21+ let consoleLine = this . solConsole . addLine ( "Parsing..." ) ;
22+
23+ let spreadsheet = input . trim ( ) . split ( / \r ? \n / ) . map ( ( line , index ) => {
24+ line = line . replaceAll ( / \s + / g, " " ) ;
25+ if ( ! / ^ [ \s \d ] + $ / . test ( line ) )
26+ throw new Error ( `Invalid data in line ${ index + 1 } ` ) ;
27+ return line . split ( " " ) . map ( e => parseInt ( e ) ) ;
28+ } ) ;
29+
30+ consoleLine . innerHTML += " done." ;
31+ return spreadsheet ;
32+ }
33+
34+ /**
35+ * Finds the sum of each row's difference between max and min values (part 1) or sum of each row's result of division of two evenly divisible values (part 2).
36+ * @param {number } part Puzzle part.
37+ * @param {string } input Puzzle input.
38+ * @param {boolean } visualization Enable visualization.
39+ * @returns {number } Sum of each row's difference between max and min values (part 1) or sum of each row's result of division of two evenly divisible values (part 2).
40+ */
41+ async solve ( part , input , visualization ) {
42+ try {
43+ this . isSolving = true ;
44+
45+ let spreadsheet = this . parse ( input ) ;
46+
47+ let visConsole = new Console ( ) ;
48+ if ( visualization )
49+ this . visContainer . append ( visConsole . container ) ;
50+
51+ let sum = 0 ;
52+
53+ for ( let row of spreadsheet ) {
54+ if ( part == 1 ) {
55+ let minValue = Math . min ( ...row ) ;
56+ let maxValue = Math . max ( ...row ) ;
57+ sum += ( maxValue - minValue ) ;
58+
59+ if ( visualization ) {
60+ visConsole . addLine ( row . map ( e => e == minValue ? `<span class="highlighted">${ e } </span>` : ( e == maxValue ? `<span class="strongly-highlighted">${ e } </span>` : e ) ) . join ( " " ) ) ;
61+ visConsole . lines [ visConsole . lines . length - 1 ] . style . whiteSpace = "nowrap" ;
62+ }
63+ }
64+ else {
65+ let valuePair = null ;
66+ for ( let i = 0 ; i < row . length && valuePair == null ; i ++ ) {
67+ for ( let j = 0 ; j < row . length && valuePair == null ; j ++ ) {
68+ if ( i != j && row [ i ] % row [ j ] == 0 )
69+ valuePair = [ row [ i ] , row [ j ] ] ;
70+ }
71+ }
72+
73+ if ( valuePair == null )
74+ throw new Error ( "Solution not found" ) ;
75+
76+ sum += valuePair [ 0 ] / valuePair [ 1 ] ;
77+
78+ if ( visualization ) {
79+ visConsole . addLine ( row . map ( e => e == valuePair [ 1 ] ? `<span class="highlighted">${ e } </span>` : ( e == valuePair [ 0 ] ? `<span class="strongly-highlighted">${ e } </span>` : e ) ) . join ( " " ) ) ;
80+ visConsole . lines [ visConsole . lines . length - 1 ] . style . whiteSpace = "nowrap" ;
81+ }
82+ }
83+ }
84+
85+ return sum ;
86+ }
87+
88+ finally {
89+ this . isSolving = false ;
90+ }
91+ }
92+
93+ /**
94+ * Stops solving the puzzle.
95+ */
96+ async stopSolving ( ) {
97+ this . isStopping = true ;
98+ while ( this . isSolving )
99+ await ( delay ( 10 ) ) ;
100+ this . isStopping = false ;
101+ }
102+ }
0 commit comments