Skip to content

Instantly share code, notes, and snippets.

@kayhadrin
Last active October 30, 2025 09:42
Show Gist options
  • Save kayhadrin/00facd28be727262560a546e766de6e4 to your computer and use it in GitHub Desktop.
Save kayhadrin/00facd28be727262560a546e766de6e4 to your computer and use it in GitHub Desktop.
Keyboard spell test

Keyboard spell test

Write a function spell() that takes a keyboard layout as a 2D array and an input string. The function will output a list of instructions that will traverse the keyboard to print the input string.

The instructions are:

  • U: up
  • D: down
  • L: left
  • R: right
  • P: print character

Assume the starting key is the first element in the first row (q in the example below) E.g.

spell(
  [
    ['q','w','e','r','t','y','u','i','o','p'],
    ['a','s','d','f','g','h','j','k','l'],
    ['z','x','c','v','b','n','m']
  ],
  "hello"
);

Should output: DRRRRRPULLLPDRRRRRRPPUP

/*
Write a function spell() that takes a keyboard layout as a 2D array and an input string. The function will output a list of instructions that will traverse the keyboard to print the input the string.
The instructions are up, down, left, right and print. i.e. U, D, L, R and P
Assume the starting key is the first element in the first row ('q' in the example below) e.g.
spell(
[
['q','w','e','r','t','y','u','i','o','p'],
['a','s','d','f','g','h','j','k','l'],
['z','x','c','v','b','n','m']
],
"hello"
);
Should output: "DRRRRRPULLLPDRRRRRRPPUP"
*/
/**
* Generates instructions to spell a given string on a provided keyboard layout.
* @param {Array} layout - The keyboard layout as a 2D array.
* @param {string} s - The string to spell on the keyboard.
* @returns {string} - The instructions to spell the string on the keyboard.
*/
function spell(layout, s) {
/*
Remap keyboard layout to unique character codes
[
['q','w','e','r','t','y','u','i','o','p'],
['a','s','d','f','g','h','j','k','l'],
['z','x','c','v','b','n','m']
]
=>
[
[0,1,2,...,9],
[10,11,...,18],
[19,20,...,25]
]
*/
let charI = 0;
const charMap = {};
const rowSets = [];
const charLayout = layout.map((row) => {
const mappedRow = row.map((char) => {
charMap[char] = charI;
return charI++;
});
rowSets.push(new Set(mappedRow));
return mappedRow;
});
let curRowIndex = 0;
let curColIndex = 0;
let seq = '';
// for each given character
for (let sIndex = 0; sIndex < s.length; sIndex++) {
const charCode = charMap[s.charAt(sIndex)];
// find row
const targetRowIndex = rowSets.findIndex((rowSet) => rowSet.has(charCode));
if (targetRowIndex === -1) {
throw new Error(`Character "${s.charAt(sIndex)}" not found in layout`);
}
seq += new Array(Math.abs(targetRowIndex - curRowIndex))
.fill(targetRowIndex - curRowIndex > 0 ? 'D' : 'U')
.join('');
curRowIndex = targetRowIndex;
// find col
const curCode = charLayout[curRowIndex]?.[curColIndex];
if (curCode == undefined) {
throw new Error(`Invalid current position at row ${curRowIndex}, col ${curColIndex}`);
}
const colDistance = Math.abs(charCode - curCode);
seq += new Array(colDistance).fill(charCode - curCode > 0 ? 'R' : 'L').join('');
curColIndex += colDistance * (charCode - curCode > 0 ? 1 : -1);
seq += 'P';
// request char print
}
// console.log('seq = ', seq);
return seq;
// solution: 'DRRRRRPULLLPDRRRRRRPPUP';
}
// UNIT TESTS
console.assert(
spell(
[
['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'],
['z', 'x', 'c', 'v', 'b', 'n', 'm'],
],
'hello'
) === 'DRRRRRPULLLPDRRRRRRPPUP',
'Failed unit test'
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment