Telokis icon

Markov1.ts

Telokis | PRO | 03/05/20 01:57:55 PM UTC | 0 ⭐ | 7149 👁️ | Never ⏰ | []
TypoScript |

2.66 KB

|

None

|

0 👍

/

0 👎

import Random from "./Random";
 
const bow = Symbol("Beginning of word");
const eow = Symbol("Ending of word");
 
export { bow, eow };
 
type StringOrSymbol = symbol | string;
type RawDataForMapping = Array<string>;
 
interface TempMapping {
    // @ts-ignore Waiting for https://github.com/Microsoft/TypeScript/pull/26797
    [key: StringOrSymbol]: {
        // @ts-ignore Waiting for https://github.com/Microsoft/TypeScript/pull/26797
        [key: StringOrSymbol]: number;
    };
}
 
export interface Mapping {
    // @ts-ignore Waiting for https://github.com/Microsoft/TypeScript/pull/26797
    [key: StringOrSymbol]: Array<[number, StringOrSymbol]>;
}
 
interface MarkovOptions {
    minLen: number;
    maxLen: number;
}
 
export const generateMapping = (raw: RawDataForMapping): Mapping => {
    const mapping: TempMapping = {
        [bow]: {
            [eow]: 0,
        },
    };
 
    for (const word of raw) {
        const lowWord = word.toLowerCase();
 
        for (let i = 0; i < lowWord.length; ++i) {
            const char = lowWord[i];
 
            if (i === 0) {
                if (!(char in mapping[bow])) {
                    mapping[bow][char] = 0;
                }
 
                mapping[bow][char] += 1;
            }
 
            if (!(char in mapping)) {
                mapping[char] = {
                    [eow]: 0,
                };
            }
 
            let nextChar: StringOrSymbol = eow;
 
            if (i < lowWord.length - 1) {
                nextChar = lowWord[i + 1];
            }
 
            if (!(nextChar in mapping[char])) {
                mapping[char][nextChar] = 0;
            }
 
            mapping[char][nextChar] += 1;
        }
    }
 
    const keys = (Object.keys(mapping) as Array<StringOrSymbol>).concat([bow]);
 
    for (const key of keys) {
        const entries: Array<[StringOrSymbol, number]> = Object.entries(mapping[key]);
 
        if (eow in mapping[key]) {
            entries.push([eow, mapping[key][eow]]);
        }
 
        mapping[key] = entries.map(entry => entry.reverse());
    }
 
    return mapping;
};
 
export const generateChain = (
    mapping: Mapping,
    random: Random,
    { minLen, maxLen }: MarkovOptions,
) => {
    let word = "";
    let curLetter: StringOrSymbol = bow;
 
    for (let i = 0; i < maxLen; ++i) {
        curLetter = random.weighted(mapping[curLetter]);
 
        if (curLetter === eow) {
            if (i >= minLen) {
                break;
            } else {
                curLetter = random.weighted(mapping[bow]);
            }
        }
 
        word += curLetter as string;
    }
 
    return word;
};

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎