Skip to content

Commit bfb4d82

Browse files
committed
feat: adds stretch assignment with test cases
1 parent 305f7d8 commit bfb4d82

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
export function isValidAlphaAbbreviation(word: string, abbr: string): boolean {
2+
let i = 0; // position in word
3+
let j = 0; // position in abbreviation
4+
5+
while (j < abbr.length) {
6+
const ch = abbr[j];
7+
8+
if (ch >= "0" && ch <= "9") {
9+
// Leading zero check
10+
if (ch === "0") return false;
11+
12+
// Parse complete number
13+
let num = 0;
14+
while (j < abbr.length && abbr[j] >= "0" && abbr[j] <= "9") {
15+
num = num * 10 + (abbr[j].charCodeAt(0) - "0".charCodeAt(0));
16+
j++;
17+
}
18+
19+
// Apply skip
20+
i += num;
21+
22+
// Bounds check
23+
if (i > word.length) return false;
24+
} else {
25+
// Literal character match
26+
if (i >= word.length || word[i] !== ch) {
27+
return false;
28+
}
29+
i++;
30+
j++;
31+
}
32+
}
33+
34+
// Must consume entire word
35+
return i === word.length;
36+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { isValidAlphaAbbreviation } from "./alpha_abbreviation.js";
2+
3+
function test(word: string, abbr: string, expected: boolean) {
4+
const result = isValidAlphaAbbreviation(word, abbr);
5+
const status = result === expected ? "✅ PASS" : "❌ FAIL";
6+
console.log(
7+
`${status} | Word: "${word}" | Abbr: "${abbr}" → Expected: ${expected}, Got: ${result}`,
8+
);
9+
}
10+
11+
// === Basic valid cases ===
12+
test("internationalization", "i18n", true);
13+
test("substitution", "s10n", true);
14+
test("hello", "4o", true); // skip "e", "l", "l", "o"
15+
test("abcde", "4e", true); // skip "b", "c", "d", arrive at "e"
16+
17+
// === Literal-only match ===
18+
test("dog", "dog", true);
19+
test("cat", "cut", false); // mismatch at "a" vs "u"
20+
21+
// === Skip everything ===
22+
test("abcdef", "6", true); // skip entire word
23+
test("abcdef", "7", false); // skip past word length
24+
test("abcdef", "5g", true); // skip to last letter and match
25+
26+
// === Mixed skip + literal ===
27+
test("compression", "c9n", true);
28+
test("transformation", "t12n", true);
29+
test("transformation", "t13n", false); // too much skip
30+
31+
// === Zero padding (invalid) ===
32+
test("test", "01st", false);
33+
test("skiptest", "s00t", false);
34+
35+
// === Leading and trailing skips ===
36+
test("abcdef", "1bcdef", false); // can't skip and expect literal 'b' immediately
37+
test("abcdef", "a5", true); // literal 'a', skip 5 to end
38+
test("abcdef", "a6", false); // skip past end
39+
40+
// === Multiple number segments ===
41+
test("abcdefg", "1b1d1f1g", true); // skips then matches
42+
test("abcdefg", "1b2e1g", true);
43+
test("abcdefg", "1b3f1g", false); // overshoots
44+
45+
// === Full numeric — skips entire word
46+
test("skipped", "7", true);
47+
test("skipped", "8", false); // overshoot
48+
49+
// === Empty abbreviation or word ===
50+
test("word", "", false); // must match full
51+
test("", "", true); // both empty is valid
52+
test("", "1", false); // can't skip into empty
53+
test("nonempty", "", false); // abbreviation is empty
54+
55+
// === Misc edge junk ===
56+
test("abc", "a01c", false); // invalid leading 0
57+
test("abc", "a0b", false); // zero is illegal
58+
test("abc", "a1b", true); // skip one

0 commit comments

Comments
 (0)