Skip to content

Instantly share code, notes, and snippets.

@joshparkerj
Created June 7, 2021 09:28
Show Gist options
  • Save joshparkerj/b334c0ba95981859d070568f70f49d7f to your computer and use it in GitHub Desktop.
Save joshparkerj/b334c0ba95981859d070568f70f49d7f to your computer and use it in GitHub Desktop.
decode variations puzzle
/* this is the first puzzle I've ever received from pramp.
I admit, I didn't know how to approach the problem until after I'd slept on it.
Here's how the challenge works:
Each letter of the alphabet is encoded as a number
A -> 1
B -> 2
C -> 3
...
Z -> 26
The numbers are mashed together, so they can't be decoded unambiguously.
For example, the string '11' can be decoded as AA or K
How many possible variations can be decoded from the given string?
Input: string S of length at least 1 and no more than 12
Each character in S is a digit.
*/
function decodeVariations(S) {
let first = 0;
let second = 0;
for (let i = S.length - 1; i >= 0; i--) {
if (S[i] === '0') {
first = 0;
} else if (S[i] === '1') {
first = 2 * second;
} else if (S[i] === '2') {
} else {
first = second;
}
second = first;
}
return first;
}
function decodeVariations(S) {
return decodeToLetters(S).length;
}
function decodeToLetters(s) {
if (s.length === 1) {
return [String.fromCodePoint(64 + Number(s))];
}
const mid = Math.floor(s.length / 2);
const leftOutputs = decodeToLetters(s.slice(0, mid));
const rightOutputs = decodeToLetters(s.slice(mid));
return combineDecodedStrings(leftOutputs, rightOutputs);
}
function combineDecodedStrings(leftStrings, rightStrings) {
return leftStrings.reduce((acc, e) => {
acc = acc.concat(rightStrings.map(s => e + s));
const rights = rightStrings.filter(s => s[0] < 'J');
return acc.concat(rights.map(r => combineAffixes(e, r)).filter(e => e));
}, []).filter(w => !w.includes('@'));
}
function combineAffixes(left, right) {
const suffix = 10 * (left.codePointAt(left.length - 1) - 64);
const prefix = right.codePointAt(0) - 64;
const middle = suffix + (prefix === '@' ? 0 : prefix)
if (middle > 26) {
return null;
}
return left.slice(0, left.length - 1) + String.fromCodePoint(64 + middle) + right.slice(1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment