1+ class Transformation {
2+ constructor ( matcher , result ) {
3+ this . matcher = matcher ;
4+ this . result = result ;
5+ }
6+ }
7+
8+ class State {
9+ constructor ( initialState , firstIndex = - 2 ) {
10+ //TODO - optimise and only add if nothing at the end
11+ this . current = initialState ;
12+ this . firstIndex = firstIndex + 2 ;
13+ if ( ! this . current . startsWith ( '....' ) ) {
14+ this . current = '....' + this . current ;
15+ this . firstIndex = this . firstIndex - 4 ;
16+ }
17+
18+ if ( ! this . current . endsWith ( '....' ) ) {
19+ this . current = this . current + '....' ;
20+ }
21+ }
22+
23+ evolve ( transformations ) {
24+ let nextString = '' ;
25+ //console.log('currLEngth:',this.current.length - 4);
26+ for ( let i = 0 ; i < this . current . length - 4 ; i ++ ) {
27+ let replacementChar = '.' ;
28+ transformations . forEach ( ( transformation ) => {
29+ if ( this . current . substring ( i , i + 5 ) === transformation . matcher ) {
30+ //console.log(this.current.substring(i,i+5),'matches',transformation.matcher);
31+ replacementChar = transformation . result ;
32+ }
33+ } ) ;
34+ //console.log(i,'replacementChar',replacementChar);
35+ nextString = nextString + replacementChar ;
36+ }
37+ //console.log('next String',nextString);
38+ return new State ( nextString , this . firstIndex ) ;
39+ }
40+
41+ calculateSum ( ) {
42+ let sum = 0 ;
43+ for ( let i = 0 ; i < this . current . length ; i ++ ) {
44+ if ( this . current . charAt ( i ) == '#' ) {
45+ //console.log('Adding',i+this.firstIndex);
46+ sum += i + this . firstIndex ;
47+ }
48+ }
49+ return sum ;
50+ }
51+ }
52+
53+ function calculateSum ( input , iterations = 20 ) {
54+ let inputLines = input . split ( / \r ? \n / ) ;
55+ let state = parseInitialState ( inputLines . shift ( ) ) ;
56+ inputLines . shift ( ) ;
57+
58+ let transformations = [ ] ;
59+ inputLines
60+ . map ( ( line ) => {
61+ let result = line . trim ( ) . match ( / ( .+ ) = > ( .+ ) / ) ;
62+ transformations . push ( new Transformation ( result [ 1 ] , result [ 2 ] ) ) ;
63+ } ) ;
64+
65+ let actualIt = iterations ;
66+ if ( iterations > 1000 ) {
67+ iterations = 1000 ;
68+ }
69+ for ( let i = 0 ; i < iterations ; i ++ ) {
70+ state = state . evolve ( transformations ) ;
71+ }
72+
73+ if ( actualIt > 1000 ) {
74+ let currSum = state . calculateSum ( ) ;
75+ let diff = state . evolve ( transformations ) . calculateSum ( ) - currSum ;
76+ return ( actualIt - iterations ) * diff + currSum ;
77+ }
78+
79+ return state . calculateSum ( ) ;
80+ }
81+
82+ function parseInitialState ( input ) {
83+ return new State ( input . replace ( 'initial state: ' , '' ) ) ;
84+ }
85+
86+ module . exports . calculateSum = calculateSum ;
0 commit comments