@@ -48,54 +48,94 @@ function calcComplexities(lines: string[]) {
4848} 
4949
5050function  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  }  =  { } ; 
6152
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+ } 
6458
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 ; 
84115                } 
85116            } 
86-         } 
87- 
88-         level3List . sort ( ( a ,  b )  =>  a . length  -  b . length ) ; 
89-         complexityCount  +=  num  *  level3List [ 0 ] . length ; 
117+         } ) ; 
90118    } 
91-     return  complexityCount ; 
92- } 
93119
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 ) ; 
97121} 
98122
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+ } 
99139
100140// +---+---+---+ 
101141// | 7 | 8 | 9 |    0,0  1,0  2,0 
0 commit comments