83 lines
1.8 KiB
Text
83 lines
1.8 KiB
Text
# patterns.ludic - a msgid with holes ("Day {1}"): its literal pieces, how much English they pin
|
|
# down, and a chain by its first (else last) four bytes so a lookup tries only its own kind
|
|
function holes(s: string) -> int {
|
|
let n = len(s)
|
|
var h = 0
|
|
var i = 0
|
|
while i < n {
|
|
if hole_at(s, i) >= 0 {
|
|
h += 1
|
|
i = hole_end(s, i)
|
|
continue
|
|
}
|
|
i += 1
|
|
}
|
|
return h
|
|
}
|
|
|
|
function add_pattern(id: string, tr: string) -> void {
|
|
let p = pat_n
|
|
pat_n += 1
|
|
let l0 = len(lits)
|
|
let n = len(id)
|
|
var seg = 0
|
|
var i = 0
|
|
var nl = 0
|
|
var score = 0
|
|
while i < n {
|
|
let num = hole_at(id, i)
|
|
if num >= 0 {
|
|
push(lits, id[seg..i])
|
|
score += i - seg
|
|
pat_ph[l0 + nl] = num
|
|
nl += 1
|
|
i = hole_end(id, i)
|
|
seg = i
|
|
continue
|
|
}
|
|
i += 1
|
|
}
|
|
push(lits, id[seg..n])
|
|
score += n - seg
|
|
nl += 1
|
|
pat_l0[p] = l0
|
|
pat_nl[p] = nl
|
|
pat_sc[p] = score
|
|
push(pat_out, tr)
|
|
chain(p, lits[l0], lits[l0 + nl - 1])
|
|
}
|
|
|
|
function chain(p: int, first: string, last: string) -> void {
|
|
if len(first) >= 4 {
|
|
let key: string = first[0..4]
|
|
nx_p[p] = Dict.get_or(pfx, key, 0)
|
|
Dict.set(pfx, key, p + 1)
|
|
} else if len(last) >= 4 {
|
|
let key: string = last[len(last) - 4..len(last)]
|
|
nx_s[p] = Dict.get_or(sfx, key, 0)
|
|
Dict.set(sfx, key, p + 1)
|
|
} else {
|
|
nx_g[p] = gen_head
|
|
gen_head = p + 1
|
|
}
|
|
}
|
|
|
|
# a translation with its holes filled from caps, by number: a translation may reorder or drop them
|
|
function fill_holes(t: string, l0: int, nl: int, cs: []string) -> string {
|
|
let n = len(t)
|
|
var r = ""
|
|
var seg = 0
|
|
var i = 0
|
|
while i < n {
|
|
let num = hole_at(t, i)
|
|
if num >= 0 {
|
|
r = r + t[seg..i]
|
|
for g in 0 .. nl - 1 { if pat_ph[l0 + g] == num { r = r + cs[g] } }
|
|
i = hole_end(t, i)
|
|
seg = i
|
|
continue
|
|
}
|
|
i += 1
|
|
}
|
|
return r + t[seg..n]
|
|
}
|