const fs = require('fs')

let input = fs.readFileSync('./input2.txt', 'utf8').trim()
let instructions = input.split('\n').map(x => x.trim().toUpperCase().split(''))

function solve(keypad, instructions, start) {
    let directions = {'U': [0, -1], 'L': [-1, 0], 'D': [0, 1], 'R': [1, 0]}
    let valid = ([x, y]) => y in keypad && keypad[y][x] != null

    if (!valid(start)) return ''

    let [passcode, ] = instructions.reduce(([passcode, position], chunk) => {
        [x, y] = chunk.reduce((position, uldr) => {
            let newPosition = directions[uldr].map((x, i) => position[i] + x)
            return valid(newPosition) ? newPosition : position
        }, position)

        return [passcode + keypad[y][x], [x, y]]
    }, ['', start])

    return passcode
}

let normalKeypad = [
    ['1', '2', '3'],
    ['4', '5', '6'],
    ['7', '8', '9']
]

console.log('Part 1:\t', solve(normalKeypad, instructions, [1, 1]))

let weirdKeypad = [
    [null, null, '1', null, null],
    [null,  '2', '3',  '4', null],
    [ '5',  '6', '7',  '8',  '9'],
    [null,  'A', 'B',  'C', null],
    [null, null, 'D', null, null]
]

console.log('Part 2:\t', solve(weirdKeypad, instructions, [0, 2]))

@@ -163,60 +163,12 @@
 ))%0A%0A
-function solve(keypad, instructions, start) %7B%0A    le
+cons
 t di
@@ -233,20 +233,17 @@
 %5B1, 0%5D%7D%0A
-    
+%0A
 let vali
@@ -247,16 +247,20 @@
 alid = (
+kp, 
 %5Bx, y%5D) 
@@ -272,167 +272,213 @@
 in k
-eypad && keypad%5By%5D%5Bx%5D != null%0A%0A    if (!valid(start)) return ''%0A%0A    let %5Bpasscode, %5D = instructions.reduce((%5Bpasscode, position%5D, c
+p && kp%5By%5D%5Bx%5D != null%0Alet add = (a, b) =%3E a.map((x, i) =%3E x + b%5Bi%5D)%0Alet goDirection = (kp, p, uldr) =%3E valid(kp, add(p, directions%5Buldr%5D)) ? add(p, directions%5Buldr%5D) : p%0Alet followC
 hunk
-)
  =
-%3E %7B%0A        %5Bx, y%5D
+ (kp, s, chunk)
  =
+%3E
  chu
@@ -492,160 +492,199 @@
 ce((
-position, uldr) =%3E %7B%0A            let newPosition = directions%5Buldr%5D.map((x, i) =%3E position%5Bi%5D + x)%0A            return valid(newPosition) ? newP
+...pd) =%3E goDirection(kp, ...pd), s)%0Alet followInstr = (kp, s, instr) =%3E instr.reduce((acc, chunk) =%3E %5B...acc, followChunk(kp, acc.slice(-1)%5B0%5D, chunk)%5D, %5Bs%5D)%0Alet getCode = (kp, p
 osition
- :
+s) =%3E
  pos
@@ -692,122 +692,122 @@
 tion
-%0A        %7D, position)%0A%0A        return %5Bpasscode + keypad%5By%5D%5Bx%5D, %5Bx, y%5D%5D%0A    %7D, %5B'', start%5D)%0A%0A    return passcode%0A%7D
+s.map((%5Bx, y%5D) =%3E kp%5By%5D%5Bx%5D).join('')%0Alet solve = (kp, s, instr) =%3E getCode(kp, followInstr(kp, s, instr).slice(1))
 %0A%0Ale
@@ -930,24 +930,32 @@
 ormalKeypad,
+ %5B1, 1%5D,
  instruction
@@ -955,24 +955,16 @@
 ructions
-, %5B1, 1%5D
 ))%0A%0Alet 
@@ -1199,16 +1199,24 @@
 dKeypad,
+ %5B0, 2%5D,
  instruc
@@ -1220,19 +1220,11 @@
 ructions
-, %5B0, 2%5D
 ))%0A

Rewrite using composition of small functions