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 } Number of steps.
19+ */
20+ parse ( input ) {
21+ let consoleLine = this . solConsole . addLine ( "Parsing..." ) ;
22+
23+ input = input . trim ( ) ;
24+ if ( ! / ^ \d + $ / . test ( input ) )
25+ throw new Error ( "Invalid input data" ) ;
26+ let numberOfSteps = parseInt ( input ) ;
27+
28+ consoleLine . innerHTML += " done." ;
29+ return numberOfSteps ;
30+ }
31+
32+ /**
33+ * Finds the value after 2017 in the buffer after 2017th insert (part 1) or the value after 0 in the buffer after 50000000th insert (part 2).
34+ * @param {number } part Puzzle part.
35+ * @param {string } input Puzzle input.
36+ * @param {boolean } visualization Enable visualization.
37+ * @returns {string } Value after 2017 in the buffer after 2017th insert (part 1) or the value after 0 in the buffer after 50000000th insert (part 2).
38+ */
39+ async solve ( part , input , visualization ) {
40+ try {
41+ this . isSolving = true ;
42+
43+ let numberOfSteps = this . parse ( input ) ;
44+ let numberOfInserts = part == 1 ? 2017 : 50000000 ;
45+
46+ let visConsole = new Console ( ) ;
47+ if ( visualization )
48+ this . visContainer . append ( visConsole . container ) ;
49+
50+ let position = 0 ;
51+
52+ if ( part == 1 ) {
53+ let buffer = [ 0 ] ;
54+ for ( let i = 1 ; i <= numberOfInserts ; i ++ ) {
55+ position = ( position + numberOfSteps ) % i ;
56+ buffer . splice ( position ++ , 0 , i ) ;
57+ }
58+
59+ if ( visualization ) {
60+ for ( let value of buffer )
61+ visConsole . addLine ( value ) ;
62+ }
63+
64+ visConsole . lines [ buffer . indexOf ( 2017 ) ] . classList . add ( "highlighted" ) ;
65+ visConsole . lines [ ( buffer . indexOf ( 2017 ) + 1 ) % buffer . length ] . classList . add ( "strongly-highlighted" ) ;
66+ visConsole . container . scrollTop = visConsole . lines [ ( buffer . indexOf ( 2017 ) + 1 ) % buffer . length ] . offsetTop - visConsole . container . offsetHeight / 2 ;
67+
68+ return buffer [ ( buffer . indexOf ( 2017 ) + 1 ) % buffer . length ] ;
69+ }
70+ else {
71+ let valueInsertedAfterZero ;
72+ for ( let i = 1 ; i <= numberOfInserts ; i ++ ) {
73+ position = ( position + numberOfSteps ) % i ;
74+ if ( ( position ++ ) == 0 ) {
75+ valueInsertedAfterZero = i ;
76+ if ( visualization )
77+ visConsole . addLine ( `${ i } is inserted after 0.` )
78+ }
79+ }
80+
81+ if ( visualization ) {
82+ visConsole . lines [ visConsole . lines . length - 1 ] . innerHTML = `<span class="highlighted">${ valueInsertedAfterZero } </span> is inserted after 0.` ;
83+ visConsole . container . scrollTop = visConsole . lines [ visConsole . lines . length - 1 ] . offsetTop - visConsole . container . offsetHeight / 2 ;
84+ }
85+
86+ return valueInsertedAfterZero ;
87+ }
88+ }
89+
90+ finally {
91+ this . isSolving = false ;
92+ }
93+ }
94+
95+ /**
96+ * Stops solving the puzzle.
97+ */
98+ async stopSolving ( ) {
99+ this . isStopping = true ;
100+ while ( this . isSolving )
101+ await ( delay ( 10 ) ) ;
102+ this . isStopping = false ;
103+ }
104+ }
0 commit comments