@@ -48,54 +48,94 @@ function calcComplexities(lines: string[]) {
48
48
}
49
49
50
50
function calcComplexities2 ( lines : string [ ] ) {
51
- let complexityCount = 0 ;
52
-
53
- for ( const line of lines ) {
54
- let minLength = Infinity ;
55
- const num = Number . parseInt ( line . replace ( 'A' , '' ) ) ;
56
-
57
- const level3List : string [ ] = [ ] ;
58
- const level1 = encodeFirstLevel ( line ) ;
59
- for ( const l1 of level1 ) {
60
- const level2 = encodeSecondLevel ( l1 ) ;
51
+ const memo : { [ key : string ] : number } = { } ;
61
52
62
- for ( const l2 of level2 ) {
63
- const level3 = encodeSecondLevel ( l2 ) ;
53
+ return lines . reduce ( ( sum , code ) => {
54
+ const numerical = parseInt ( ( code . split ( '' ) . filter ( character => character . match ( / \d / ) ) . join ( '' ) ) ) ;
55
+ return sum + numerical * getKeyPresses ( KEYPAD , code , 25 , memo ) ;
56
+ } , 0 ) ;
57
+ }
64
58
65
- for ( const l3 of level3 ) {
66
- for ( const l4 of encodeSecondLevel ( l3 ) ) {
67
- for ( const l5 of encodeSecondLevel ( l4 ) ) {
68
- for ( const l6 of encodeSecondLevel ( l5 ) ) {
69
- for ( const l7 of encodeSecondLevel ( l6 ) ) {
70
- for ( const l8 of encodeSecondLevel ( l7 ) ) {
71
- for ( const l9 of encodeSecondLevel ( l8 ) ) {
72
- for ( const l10 of encodeSecondLevel ( l9 ) ) {
73
- if ( l10 . length < minLength ) {
74
- level3List . push ( l10 ) ;
75
- minLength = l10 . length ;
76
- }
77
- }
78
- }
79
- }
80
- }
81
- }
82
- }
83
- }
59
+ const BFS_DIRECTIONS = {
60
+ '^' : new Coord ( 0 , - 1 ) ,
61
+ '>' : new Coord ( 1 , 0 ) ,
62
+ 'v' : new Coord ( 0 , 1 ) ,
63
+ '<' : new Coord ( - 1 , 0 )
64
+ } ;
65
+
66
+ const KEYPAD : { [ key : string ] : Coord } = {
67
+ 7 : new Coord ( 0 , 0 ) ,
68
+ 8 : new Coord ( 1 , 0 ) ,
69
+ 9 : new Coord ( 2 , 0 ) ,
70
+ 4 : new Coord ( 0 , 1 ) ,
71
+ 5 : new Coord ( 1 , 1 ) ,
72
+ 6 : new Coord ( 2 , 1 ) ,
73
+ 1 : new Coord ( 0 , 2 ) ,
74
+ 2 : new Coord ( 1 , 2 ) ,
75
+ 3 : new Coord ( 2 , 2 ) ,
76
+ X : new Coord ( 0 , 3 ) ,
77
+ 0 : new Coord ( 1 , 3 ) ,
78
+ A : new Coord ( 2 , 3 )
79
+ } ;
80
+
81
+ const DIRECTIONS : { [ key : string ] : Coord } = {
82
+ X : new Coord ( 0 , 0 ) ,
83
+ '^' : new Coord ( 1 , 0 ) ,
84
+ A : new Coord ( 2 , 0 ) ,
85
+ '<' : new Coord ( 0 , 1 ) ,
86
+ 'v' : new Coord ( 1 , 1 ) ,
87
+ '>' : new Coord ( 2 , 1 )
88
+ } ;
89
+
90
+ const getCommand = ( input : { [ key : string ] : Coord } , start : string , end : string ) => {
91
+ const queue = [ { ...input [ start ] , path : '' } ] ;
92
+ const distances : { [ key : string ] : number } = { } ;
93
+
94
+ if ( start === end ) return [ 'A' ] ;
95
+
96
+ let allPaths : string [ ] = [ ] ;
97
+ while ( queue . length ) {
98
+ const current = queue . shift ( ) ;
99
+ if ( current === undefined ) break ;
100
+
101
+ if ( current . x === input [ end ] . x && current . y === input [ end ] . y ) allPaths . push ( current . path + 'A' ) ;
102
+ if ( distances [ `${ current . x } ,${ current . y } ` ] !== undefined && distances [ `${ current . x } ,${ current . y } ` ] < current . path . length ) continue ;
103
+
104
+ Object . entries ( BFS_DIRECTIONS ) . forEach ( ( [ direction , vector ] ) => {
105
+ const position = { x : current . x + vector . x , y : current . y + vector . y } ;
106
+
107
+ if ( input . X . x === position . x && input . X . y === position . y ) return ;
108
+
109
+ const button = Object . values ( input ) . find ( button => button . x === position . x && button . y === position . y ) ;
110
+ if ( button !== undefined ) {
111
+ const newPath = current . path + direction ;
112
+ if ( distances [ `${ position . x } ,${ position . y } ` ] === undefined || distances [ `${ position . x } ,${ position . y } ` ] >= newPath . length ) {
113
+ queue . push ( { ...position , path : newPath } ) ;
114
+ distances [ `${ position . x } ,${ position . y } ` ] = newPath . length ;
84
115
}
85
116
}
86
- }
87
-
88
- level3List . sort ( ( a , b ) => a . length - b . length ) ;
89
- complexityCount += num * level3List [ 0 ] . length ;
117
+ } ) ;
90
118
}
91
- return complexityCount ;
92
- }
93
119
94
- function uniqueLengths ( arr : string [ ] ) : number [ ] {
95
- const lengths = arr . map ( str => str . length ) ; // Get lengths of all strings
96
- return [ ...new Set ( lengths ) ] ; // Use Set to get unique lengths and convert back to array
120
+ return allPaths . sort ( ( a , b ) => a . length - b . length ) ;
97
121
}
98
122
123
+ const getKeyPresses = ( input : { [ key : string ] : Coord } , code : string , robot : number , memo : { [ key : string ] : number } ) : number => {
124
+ const key = `${ code } ,${ robot } ` ;
125
+ if ( memo [ key ] !== undefined ) return memo [ key ] ;
126
+
127
+ let current = 'A' ;
128
+ let length = 0 ;
129
+ for ( let i = 0 ; i < code . length ; i ++ ) {
130
+ const moves = getCommand ( input , current , code [ i ] ) ;
131
+ if ( robot === 0 ) length += moves [ 0 ] . length ;
132
+ else length += Math . min ( ...moves . map ( move => getKeyPresses ( DIRECTIONS , move , robot - 1 , memo ) ) ) ;
133
+ current = code [ i ] ;
134
+ }
135
+
136
+ memo [ key ] = length ;
137
+ return length ;
138
+ }
99
139
100
140
// +---+---+---+
101
141
// | 7 | 8 | 9 | 0,0 1,0 2,0
0 commit comments