Warning: session_start(): open(/var/lib/php/sessions/sess_5a256vlo34e4pin1em3meljdbp, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
cmodule AModule {
switchable S input = "STATICALAFLATTENLISTOFPAIRSLPAIRALLAOUTEMPTYLISTLLFORPAIRAPUNNULLLOUTADDPAOUTADDPBRETOUT";
switchable S words = "ret ll ls static out list pair pairs flatten null of if else while for";
// basically immutable (we make a new copy for every step)
// to allow evaluating states in parallel and in any order
class GreedySplitIntoWordsCI_Multi implements IF0, LS>> {
S s; // the input to be split
TreeSet wordsSet;
Map longestMatchMap;
int i = 0, last = 0;
ReverseChain out;
*() {}
*(S *s, Cl words) {
wordsSet = asCISet(words);
longestMatchMap = new AutoMap(i -> print("longest match at " + i + ": ", lengthOfLongestPrefixInCISet(substring(s, i), wordsSet)));
}
Cl wordsAtPosition(int i) {
int longestMatch = longestMatchMap.get(i);
ret mapNonNulls(countBackwardsTo1(longestMatch), matchLength -> {
S word = substring(s, i, i+matchLength);
ret contains(wordsSet, word) ? word : null;
});
}
// either we return some choices or a final result
Either, LS> get() {
if (i >= l(s)) ret done(); // done with input
ret eitherA(listPlus(map(wordsAtPosition(i), wordMatched -> {
GreedySplitIntoWordsCI_Multi clone = shallowClone(this, new GreedySplitIntoWordsCI_Multi);
clone.flush();
clone.i = clone.last = i+l(wordMatched);
clone.out = revChainPlus(clone.out, substring(s, i, clone.i));
ret clone;
}), getVar(() -> {
GreedySplitIntoWordsCI_Multi clone = shallowClone(this, new GreedySplitIntoWordsCI_Multi);
clone.i++;
ret clone;
})));
}
Either, LS> done() {
flush();
ret eitherB(asList(out));
}
void flush {
if (i > last) {
// modifying this object in spite of convention
out = revChainPlus(out, substring(s, last, i));
last = i;
}
}
toString { ret asList(out) + prependIfNempty("|", substring(s, last, i)) + ", " + i + "/" + l(s); }
}
GreedySplitIntoWordsCI_Multi root() {
ret new GreedySplitIntoWordsCI_Multi(input, splitAtSpace(words));
}
/*visual jDynamicTree(
root()!,
x -> getVars(eitherAOpt(x)));*/
visual jDynamicTree(
(Either) (Either) eitherA(root()),
x -> {
if (!isEitherA(x)) null; // leaves have no children
Either, LS> result = eitherAOpt(x)!;
ret (Cl>)
(isEitherA(result) ? map eitherA(eitherGetA(result)) : ll(eitherBOpt(result)));
});
start-thread {
dm_reloadOnFieldChange('words, 'input);
time {
print("First result: " + getFirstResultOfEitherTree(root()!));
}
GreedySplitIntoWordsCI_Multi root = root();
new TreeMap combinationsFromPosition;
for (int i = l(input)-1; i >= 0; i--) {
long combinations = 1; // skipping a character is one combination
for (S word : root.wordsAtPosition(i))
combinations += or(combinationsFromPosition.get(i+l(word)), 1L);
print("Combinations from " + i + ": " + combinations);
combinationsFromPosition.put(i, combinations);
}
}
}