File size: 5,328 Bytes
494c9e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
 * findSplitPoint ๅ•ๅ…ƒๆต‹่ฏ•
 * ่ฟ่กŒ: cd client/src && npx tsx ts/utils/findSplitPoint.test.ts
 *
 * SEPARATOR_GROUPS๏ผˆๅ†…้ƒจๅธธ้‡๏ผŒๆต‹่ฏ•ไพ่ต–ๅ…ถ้ป˜่ฎคๅ€ผ๏ผ‰:
 *   Group 0๏ผˆๅฅๅญ็บง๏ผ‰: ใ€‚๏ผ๏ผŸ.!?
 *   Group 1๏ผˆๅญๅฅ็บง๏ผ‰: ๏ผ›;๏ผŒ, ๏ผˆ็ฉบๆ ผ๏ผ‰
 */
import { findSplitPoint } from "./semanticUtils";

let passed = 0;
let failed = 0;

function assert(desc: string, actual: number, expected: number) {
    if (actual === expected) {
        console.log(`  โœ“ ${desc}`);
        passed++;
    } else {
        console.error(`  โœ— ${desc} โ€” expected ${expected}, got ${actual}`);
        failed++;
    }
}

// โ”€โ”€ 1. ๆ— ไปปไฝ•ๅˆ†้š”็ฌฆ โ†’ ๅ›ž้€€ๅˆฐ maxEnd โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("1. ๆ— ๅˆ†้š”็ฌฆ๏ผŒๅ›ž้€€ maxEnd");
assert("็บฏๅญ—ๆฏๆ— ๅˆ†้š”็ฌฆ",        findSplitPoint("abcdef", 0, 6), 6);
assert("start=2๏ผŒไปๆ— ๅˆ†้š”็ฌฆ",   findSplitPoint("abcdef", 2, 5), 5);
assert("CJK ๆ— ๅˆ†้š”็ฌฆ",          findSplitPoint("ไฝ ๅฅฝไธ–็•Œ", 0, 4), 4);

// โ”€โ”€ 2. ไผ˜ๅ…ˆ็บง๏ผšๅฅๅญ็บงไผ˜ๅ…ˆไบŽๅญๅฅ็บง โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("2. ๅฅๅญ็บง vs ๅญๅฅ็บงไผ˜ๅ…ˆ็บง");
// "ไฝ ๅฅฝ๏ผŒไธ–็•Œใ€‚ๅ†่ง" โ†’ ๅฅๅทๅœจๅŽ๏ผŒ้€—ๅทๅœจๅ‰๏ผ›ๅบ”้€‰ๅฅๅท
assert("ๅฅๅทไผ˜ๅ…ˆไบŽ้€—ๅท",
    findSplitPoint("ไฝ ๅฅฝ๏ผŒไธ–็•Œใ€‚ๅ†่ง", 0, 7), 6); // "ไธ–็•Œใ€‚" ็ป“ๆŸไฝ็ฝฎ = idx 6
// "Hello, world! foo" โ†’ ๆ„Ÿๅนๅทไผ˜ๅ…ˆไบŽ้€—ๅท
assert("ๆ„Ÿๅนๅทไผ˜ๅ…ˆไบŽ้€—ๅท",
    findSplitPoint("Hello, world! foo", 0, 14), 13); // "world!" ็ป“ๆŸ idx=13

// โ”€โ”€ 3. ๅŒ็ป„ๅ†…ๅ–ๆœ€้ ๅณ็š„ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("3. ๅŒ็ป„ๅ†…ๆœ€้ ๅณ");
// "A.B?C" โ†’ .ๅœจidx1๏ผŒ?ๅœจidx3๏ผŒๅŒๅฑžๅฅๅญ็บง๏ผŒๅ– ? ็ป“ๅฐพ(idx=4)
assert("ๅŒ็ป„ๅ–ๆœ€้ ๅณ(. vs ?)",
    findSplitPoint("A.B?C", 0, 5), 4);
// "x๏ผŒyใ€‚z๏ผŒw"๏ผˆๅ…จ JS ๅ•ๅญ—็ฌฆ๏ผ‰โ†’ ใ€‚ๅœจ idx=3๏ผŒ่พน็•Œ=4๏ผ›ๅŽ้ข็š„ ๏ผŒๅœจ idx=5๏ผˆgroup1๏ผ‰๏ผ›group0 ไผ˜ๅ…ˆ โ†’ ่ฟ”ๅ›ž 4
assert("ๅฅๅญ็บง ใ€‚ ไผ˜ๅ…ˆไบŽๅŽ้ข็š„ ๏ผŒ",
    findSplitPoint("x๏ผŒyใ€‚z๏ผŒw", 0, 8), 4);

// โ”€โ”€ 4. start ๅ็งป โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("4. start ๅ็งป");
// "abcde.fg" start=4 โ†’ window="e.fg"๏ผŒ. ๅœจ window[1] โ†’ ่ฟ”ๅ›ž start+2=6
assert("start ๅ็งปๅŽๆ‰พๅˆฐๅฅ็‚น",
    findSplitPoint("abcde.fg", 4, 8), 6);
// start=0 maxEnd=4 โ†’ window="abcd"๏ผŒๆ— ๅˆ†้š”็ฌฆ โ†’ 4
assert("ๅ็งปๅŽ window ๆ— ๅˆ†้š”็ฌฆๅ›ž้€€",
    findSplitPoint("abcde.fg", 0, 4), 4);

// โ”€โ”€ 5. ๅˆ†้š”็ฌฆๆฐๅœจ maxEnd ่พน็•Œ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("5. ๅˆ†้š”็ฌฆ็ดง่ดด maxEnd");
// "abc." maxEnd=4 โ†’ window ๅŒ…ๅซ . โ†’ ่ฟ”ๅ›ž 4
assert("ๅฅ็‚นๆฐๅœจ maxEnd ๅค„",
    findSplitPoint("abc.", 0, 4), 4);
// "abc." maxEnd=3 โ†’ window="abc"๏ผŒๆ— ๅˆ†้š”็ฌฆ โ†’ 3
assert("ๅฅ็‚นๅˆšๅฅฝๅœจ maxEnd ไน‹ๅค–",
    findSplitPoint("abc.", 0, 3), 3);

// โ”€โ”€ 6. ็ฉบๆ ผ๏ผˆๅญๅฅ็บงๆœ€ไฝŽไผ˜ๅ…ˆ๏ผ‰โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("6. ็ฉบๆ ผ๏ผˆๆœ€ไฝŽไผ˜ๅ…ˆ็บง๏ผ‰");
assert("ๅชๆœ‰็ฉบๆ ผๆ—ถ้€‰็ฉบๆ ผ",
    findSplitPoint("hello world", 0, 11), 6); // "hello " ็ป“ๆŸ idx=6
// ็ฉบๆ ผ + ้€—ๅท โ†’ ้€—ๅทไผ˜ๅ…ˆ๏ผˆๅŒๅฑž group1๏ผŒๅ–ๆœ€้ ๅณ็š„๏ผ‰
// "hello, world test" โ†’ "๏ผŒ" ไธๅญ˜ๅœจ๏ผŒ"," ๅœจ idx=5๏ผŒ็ฉบๆ ผๅœจ idx=12๏ผŒๅŒ็ป„ๅ–้ ๅณ โ†’ 13๏ผˆ็ฉบๆ ผๅŽ๏ผ‰
assert("็ฉบๆ ผไธŽ้€—ๅทๅŒ็ป„๏ผŒๅ–ๆœ€้ ๅณ",
    findSplitPoint("hello, world test", 0, 17), 13);

// โ”€โ”€ 7. ่ฟž็ปญๅˆ†้š”็ฌฆ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("7. ่ฟž็ปญๅˆ†้š”็ฌฆ");
// "a..b" โ†’ ไธคไธช . ้ƒฝๅœจ group0๏ผŒlastIndexOf ๆ‰พๅˆฐ้ ๅณ็š„้‚ฃไธช(idx=2) โ†’ ่ฟ”ๅ›ž 3
assert("่ฟž็ปญๅฅ็‚นๅ–้ ๅณ",
    findSplitPoint("a..b", 0, 4), 3);

// โ”€โ”€ 8. ไธญๆ–‡ๆ ‡็‚น โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log("8. ไธญๆ–‡ๆ ‡็‚น");
// "่ฟ™ๆ˜ฏๅฅๅญใ€‚ไธ‹ไธ€ๅฅ" โ†’ ใ€‚ๅœจidx4 โ†’ ่ฟ”ๅ›ž 5
assert("ไธญๆ–‡ๅฅๅท",
    findSplitPoint("่ฟ™ๆ˜ฏๅฅๅญใ€‚ไธ‹ไธ€ๅฅ", 0, 8), 5);
// "่ฟ™ๆ˜ฏ๏ผŒๅญๅฅ๏ผ›ๅฆไธ€" โ†’ ๏ผ›ๅœจgroup0?ไธๅฏน๏ผŒ๏ผ›ๅœจgroup1๏ผ›๏ผŒไนŸๅœจgroup1๏ผŒ๏ผ›ๅœจidx4๏ผŒ๏ผŒๅœจidx2๏ผŒๅ–้ ๅณ โ†’ idx=5
assert("ไธญๆ–‡ๅˆ†ๅทไผ˜ๅ…ˆไบŽ้€—ๅท๏ผˆๅŒ็ป„้ ๅณ๏ผ‰",
    findSplitPoint("่ฟ™ๆ˜ฏ๏ผŒๅญๅฅ๏ผ›ๅฆไธ€", 0, 8), 6);

// โ”€โ”€ ็ป“ๆžœๆฑ‡ๆ€ป โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
console.log(`\n็ป“ๆžœ: ${passed} ้€š่ฟ‡ / ${failed} ๅคฑ่ดฅ`);
if (failed > 0) process.exit(1);