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