broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return measure(''.join(ws)) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kerning across spaces', [['Wavy', 'Ta', 'office', 'AT', 'office', 'shelf|life', 'flow'], 140], [['Wavy Ta office', 122], ['AT office', 77], ['shelflife flow', 104]]), ('partial-repair probe', [['LA|VALLE', 'av', 'Ta', 'LA|VALLE', 'dry.', 'wolf|like', 'wolf|like'], 51], [['LAVALLE', 88], ['av Ta', 45], ['LAVALLE', 88], ['dry.', 32], ['wolflike', 62], ['wolflike', 62]]), ('partial-repair probe', [['raffle', 'LA', 'fi', 'fl.', 'Wavy', 'raffle'], 128], [['raffle LA fi fl.', 113], ['Wavy raffle', 96]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['fly.', 'LA|VALLE'], 93], [['fly.', 23], ['LAVALLE', 88]]), ('control layout', [['our', 'Av'], 54], [['our', 30], ['Av', 23]])], [('regression: kerning across spaces', [['LA', 'VIA'], 102], [['LA VIA', 70]]), ('regression: kerning across spaces', [['AT', 'AT', 'office', 'Ta', 'staff.', 'Tofu'], 114], [['AT AT office', 108], ['Ta staff. Tofu', 110]]), ('partial-repair probe', [['shelf|life', 'LA|VALLE', 'raffle', 'y.', 'fl.'], 132], [['shelflife', 64], ['LAVALLE', 88], ['raffle y. fl.', 83]]), ('partial-repair probe', [['Tofu', 'LA'], 126], [['Tofu LA', 68]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['fi', 'dry.', 'wolf|like', 'VIA', 'Tofu'], 45], [['fi', 11], ['dry.', 32], ['wolflike', 62], ['VIA', 39], ['Tofu', 37]]), ('control layout', [['raffle', 'raffle'], 87], [['raffle', 46], ['raffle', 46]])], [('regression: kerning across spaces', [['fi', 'LT', 'office', 'Ta'], 104], [['fi LT office', 90], ['Ta', 21]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kerning across spaces', [['office', 'AT', 'our', 'fly.', 'flow', 'shelf|life'], 129], [['office AT our', 112], ['fly. flow', 63], ['shelflife', 64]]), ('partial-repair probe', [['Tofu', 'our', 'wolf|like', 'y.', 'flow', 'LT'], 91], [['Tofu our', 72], ['wolflike y.', 79], ['flow LT', 63]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['fly.', 'LA|VALLE'], 93], [['fly.', 23], ['LAVALLE', 88]]), ('control layout', [['Vat', 'VIA', 'Tofu', 'office', 'y.'], 62], [['Vat', 27], ['VIA', 39], ['Tofu', 37], ['office', 46], ['y.', 12]])], [('regression: kerning across spaces', [['shelf|life', 'AVAIL', 'Ta'], 103], [['shelflife', 64], ['AVAIL Ta', 85]]), ('regression: kerning across spaces', [['LA|VALLE', 'Wavy', 'fl.', 'AT', 'av', 'our'], 80], [['LAVALLE', 88], ['Wavy fl.', 65], ['AT av', 50], ['our', 30]]), ('partial-repair probe', [['VIA', 'AVAIL', 'VIA', 'raffle', 'raffle', 'wolf|like'], 91], [['VIA', 39], ['AVAIL', 59], ['VIA raffle', 90], ['raffle', 46], ['wolflike', 62]]), ('partial-repair probe', [['flow', 'VIA', 'Tofu', 'Av', 'fly.', 'Vat', 'Yo'], 74], [['flow', 35], ['VIA', 39], ['Tofu Av', 65], ['fly. Vat', 55], ['Yo', 21]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['fi', 'LA|VALLE'], 55], [['fi', 11], ['LAVALLE', 88]]), ('control layout', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]])], [('regression: kerning across spaces', [['flow', 'dry.', 'LA', 'LA', 'LT', 'av'], 77], [['flow dry.', 72], ['LA LA', 57], ['LT av', 47]]), ('regression: kerning across spaces', [['AT', 'LT', 'Tofu', 'LT', 'office', 'Tofu'], 111], [['AT LT Tofu', 96], ['LT office', 74], ['Tofu', 37]]), ('partial-repair probe', [['av', 'Av', 'Av'], 104], [['av Av Av', 75]]), ('partial-repair probe', [['LA|VALLE', 'shelf|life', 'office', 'AT', 'wolf|like'], 116], [['LAVALLE', 88], ['shelflife office', 115], ['AT wolflike', 93]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AVAIL', 'LA|VALLE', 'staff.'], 78], [['AVAIL', 59], ['LAVALLE', 88], ['staff.', 42]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return measure(' '.join(ws))
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kerning across spaces', [['Wavy', 'Ta', 'office', 'AT', 'office', 'shelf|life', 'flow'], 140], [['Wavy Ta office', 122], ['AT office', 77], ['shelflife flow', 104]]), ('partial-repair probe', [['LA|VALLE', 'av', 'Ta', 'LA|VALLE', 'dry.', 'wolf|like', 'wolf|like'], 51], [['LAVALLE', 88], ['av Ta', 45], ['LAVALLE', 88], ['dry.', 32], ['wolflike', 62], ['wolflike', 62]]), ('partial-repair probe', [['raffle', 'LA', 'fi', 'fl.', 'Wavy', 'raffle'], 128], [['raffle LA fi fl.', 113], ['Wavy raffle', 96]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['fly.', 'LA|VALLE'], 93], [['fly.', 23], ['LAVALLE', 88]]), ('control layout', [['our', 'Av'], 54], [['our', 30], ['Av', 23]])], [('regression: kerning across spaces', [['LA', 'VIA'], 102], [['LA VIA', 70]]), ('regression: kerning across spaces', [['AT', 'AT', 'office', 'Ta', 'staff.', 'Tofu'], 114], [['AT AT office', 108], ['Ta staff. Tofu', 110]]), ('partial-repair probe', [['shelf|life', 'LA|VALLE', 'raffle', 'y.', 'fl.'], 132], [['shelflife', 64], ['LAVALLE', 88], ['raffle y. fl.', 83]]), ('partial-repair probe', [['Tofu', 'LA'], 126], [['Tofu LA', 68]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['fi', 'dry.', 'wolf|like', 'VIA', 'Tofu'], 45], [['fi', 11], ['dry.', 32], ['wolflike', 62], ['VIA', 39], ['Tofu', 37]]), ('control layout', [['raffle', 'raffle'], 87], [['raffle', 46], ['raffle', 46]])], [('regression: kerning across spaces', [['fi', 'LT', 'office', 'Ta'], 104], [['fi LT office', 90], ['Ta', 21]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kerning across spaces', [['office', 'AT', 'our', 'fly.', 'flow', 'shelf|life'], 129], [['office AT our', 112], ['fly. flow', 63], ['shelflife', 64]]), ('partial-repair probe', [['Tofu', 'our', 'wolf|like', 'y.', 'flow', 'LT'], 91], [['Tofu our', 72], ['wolflike y.', 79], ['flow LT', 63]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['fly.', 'LA|VALLE'], 93], [['fly.', 23], ['LAVALLE', 88]]), ('control layout', [['Vat', 'VIA', 'Tofu', 'office', 'y.'], 62], [['Vat', 27], ['VIA', 39], ['Tofu', 37], ['office', 46], ['y.', 12]])], [('regression: kerning across spaces', [['shelf|life', 'AVAIL', 'Ta'], 103], [['shelflife', 64], ['AVAIL Ta', 85]]), ('regression: kerning across spaces', [['LA|VALLE', 'Wavy', 'fl.', 'AT', 'av', 'our'], 80], [['LAVALLE', 88], ['Wavy fl.', 65], ['AT av', 50], ['our', 30]]), ('partial-repair probe', [['VIA', 'AVAIL', 'VIA', 'raffle', 'raffle', 'wolf|like'], 91], [['VIA', 39], ['AVAIL', 59], ['VIA raffle', 90], ['raffle', 46], ['wolflike', 62]]), ('partial-repair probe', [['flow', 'VIA', 'Tofu', 'Av', 'fly.', 'Vat', 'Yo'], 74], [['flow', 35], ['VIA', 39], ['Tofu Av', 65], ['fly. Vat', 55], ['Yo', 21]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['fi', 'LA|VALLE'], 55], [['fi', 11], ['LAVALLE', 88]]), ('control layout', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]])], [('regression: kerning across spaces', [['flow', 'dry.', 'LA', 'LA', 'LT', 'av'], 77], [['flow dry.', 72], ['LA LA', 57], ['LT av', 47]]), ('regression: kerning across spaces', [['AT', 'LT', 'Tofu', 'LT', 'office', 'Tofu'], 111], [['AT LT Tofu', 96], ['LT office', 74], ['Tofu', 37]]), ('partial-repair probe', [['av', 'Av', 'Av'], 104], [['av Av Av', 75]]), ('partial-repair probe', [['LA|VALLE', 'shelf|life', 'office', 'AT', 'wolf|like'], 116], [['LAVALLE', 88], ['shelflife office', 115], ['AT wolflike', 93]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AVAIL', 'LA|VALLE', 'staff.'], 78], [['AVAIL', 59], ['LAVALLE', 88], ['staff.', 42]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Lines measure narrower when a word ends and the next begins with a kern pair.

Input [words, width]. Glyph widths: i,l,j,.,, 4; t,f 6; m 15; w 14; M 16; W 18; other lowercase 10; other uppercase 13; space 5. Within a word, fi/fl/ff form ligatures (11/11/12) with no kerning into or out of them; case-sensitive kern pairs apply between adjacent glyphs; "|" is a non-joiner (invisible, blocks ligatures and kerning). No kerning across spaces. Greedy fill. Return [[text, width]].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = w[i + 1]
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('regression: kerning after ligature', [['fi', 'fl.', 'AVAIL', 'fly.', 'Tofu'], 100], [['fi fl. AVAIL', 95], ['fly. Tofu', 65]]), ('regression: kerning after ligature', [['staff.', 'LA|VALLE', 'fl.', 'shelf|life', 'our'], 95], [['staff.', 42], ['LAVALLE', 88], ['fl. shelflife', 84], ['our', 30]]), ('regression: kerning after ligature', [['VIA', 'flow', 'dry.', 'y.', 'AVAIL', 'fl.', 'av'], 42], [['VIA', 39], ['flow', 35], ['dry.', 32], ['y.', 12], ['AVAIL', 59], ['fl. av', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['Av', 'office', 'Ta', 'LA|VALLE', 'AVAIL', 'Wavy', 'Vat'], 99], [['Av office', 74], ['Ta', 21], ['LAVALLE', 88], ['AVAIL', 59], ['Wavy Vat', 77]]), ('control layout', [['fly.', 'office', 'Vat', 'AT', 'Av', 'our'], 57], [['fly.', 23], ['office', 46], ['Vat', 27], ['AT Av', 54], ['our', 30]])], [('regression: kerning after ligature', [['fl.', 'staff.', 'flow', 'Tofu'], 109], [['fl. staff. flow', 102], ['Tofu', 37]]), ('regression: kerning after ligature', [['staff.', 'wolf|like', 'Ta', 'Tofu', 'flow'], 94], [['staff.', 42], ['wolflike Ta', 88], ['Tofu flow', 77]]), ('regression: kerning after ligature', [['LA', 'staff.', 'Av'], 120], [['LA staff. Av', 101]]), ('regression: kerning after ligature', [['fi', 'staff.', 'fi', 'fi'], 118], [['fi staff. fi fi', 90]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['VIA', 'AVAIL', 'office', 'Av'], 112], [['VIA AVAIL', 103], ['office Av', 74]]), ('control layout', [['fi', 'Ta', 'Ta', 'Tofu', 'y.'], 103], [['fi Ta Ta', 63], ['Tofu y.', 54]])], [('regression: kerning after ligature', [['fly.', 'staff.', 'y.', 'raffle', 'av', 'raffle'], 99], [['fly. staff. y.', 87], ['raffle av', 70], ['raffle', 46]]), ('regression: kerning after ligature', [['staff.', 'AVAIL', 'LA', 'LA|VALLE'], 42], [['staff.', 42], ['AVAIL', 59], ['LA', 26], ['LAVALLE', 88]]), ('regression: kerning after ligature', [['fl.', 'Wavy', 'our', 'VIA', 'Tofu', 'staff.', 'staff.'], 58], [['fl.', 15], ['Wavy', 45], ['our', 30], ['VIA', 39], ['Tofu', 37], ['staff.', 42], ['staff.', 42]]), ('regression: kerning after ligature', [['shelf|life', 'raffle', 'av', 'our', 'staff.', 'y.'], 43], [['shelflife', 64], ['raffle', 46], ['av', 19], ['our', 30], ['staff.', 42], ['y.', 12]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['Ta', 'raffle', 'Yo'], 80], [['Ta raffle', 72], ['Yo', 21]]), ('control layout', [['fly.', 'shelf|life', 'AT', 'flow', 'av'], 91], [['fly.', 23], ['shelflife', 64], ['AT flow av', 90]])], [('regression: kerning after ligature', [['our', 'av', 'staff.', 'Av'], 56], [['our av', 54], ['staff.', 42], ['Av', 23]]), ('regression: kerning after ligature', [['av', 'fl.', 'Tofu', 'flow'], 112], [['av fl. Tofu', 81], ['flow', 35]]), ('regression: kerning after ligature', [['fl.', 'wolf|like', 'Wavy', 'Vat'], 50], [['fl.', 15], ['wolflike', 62], ['Wavy', 45], ['Vat', 27]]), ('regression: kerning after ligature', [['flow', 'av', 'av', 'wolf|like', 'fl.', 'Av'], 88], [['flow av av', 83], ['wolflike fl.', 82], ['Av', 23]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['AT', 'flow', 'raffle', 'wolf|like', 'VIA', 'dry.'], 79], [['AT flow', 66], ['raffle', 46], ['wolflike', 62], ['VIA dry.', 76]]), ('control layout', [['flow', 'Yo', 'y.', 'y.'], 102], [['flow Yo y. y.', 95]])], [('regression: kerning after ligature', [['dry.', 'LA', 'shelf|life', 'staff.', 'fi', 'staff.', 'av'], 116], [['dry. LA', 63], ['shelflife staff.', 111], ['fi staff. av', 82]]), ('regression: kerning after ligature', [['fly.', 'office', 'raffle', 'staff.', 'fly.', 'VIA'], 68], [['fly.', 23], ['office', 46], ['raffle', 46], ['staff.', 42], ['fly. VIA', 67]]), ('regression: kerning after ligature', [['fl.', 'wolf|like', 'Wavy', 'Vat'], 50], [['fl.', 15], ['wolflike', 62], ['Wavy', 45], ['Vat', 27]]), ('regression: kerning after ligature', [['Av', 'staff.', 'office'], 55], [['Av', 23], ['staff.', 42], ['office', 46]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['office', 'wolf|like'], 70], [['office', 46], ['wolflike', 62]]), ('control layout', [['our', 'av', 'our', 'Wavy'], 94], [['our av our', 89], ['Wavy', 45]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = w[i]
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('regression: kerning after ligature', [['fi', 'fl.', 'AVAIL', 'fly.', 'Tofu'], 100], [['fi fl. AVAIL', 95], ['fly. Tofu', 65]]), ('regression: kerning after ligature', [['staff.', 'LA|VALLE', 'fl.', 'shelf|life', 'our'], 95], [['staff.', 42], ['LAVALLE', 88], ['fl. shelflife', 84], ['our', 30]]), ('regression: kerning after ligature', [['VIA', 'flow', 'dry.', 'y.', 'AVAIL', 'fl.', 'av'], 42], [['VIA', 39], ['flow', 35], ['dry.', 32], ['y.', 12], ['AVAIL', 59], ['fl. av', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['Av', 'office', 'Ta', 'LA|VALLE', 'AVAIL', 'Wavy', 'Vat'], 99], [['Av office', 74], ['Ta', 21], ['LAVALLE', 88], ['AVAIL', 59], ['Wavy Vat', 77]]), ('control layout', [['fly.', 'office', 'Vat', 'AT', 'Av', 'our'], 57], [['fly.', 23], ['office', 46], ['Vat', 27], ['AT Av', 54], ['our', 30]])], [('regression: kerning after ligature', [['fl.', 'staff.', 'flow', 'Tofu'], 109], [['fl. staff. flow', 102], ['Tofu', 37]]), ('regression: kerning after ligature', [['staff.', 'wolf|like', 'Ta', 'Tofu', 'flow'], 94], [['staff.', 42], ['wolflike Ta', 88], ['Tofu flow', 77]]), ('regression: kerning after ligature', [['LA', 'staff.', 'Av'], 120], [['LA staff. Av', 101]]), ('regression: kerning after ligature', [['fi', 'staff.', 'fi', 'fi'], 118], [['fi staff. fi fi', 90]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['VIA', 'AVAIL', 'office', 'Av'], 112], [['VIA AVAIL', 103], ['office Av', 74]]), ('control layout', [['fi', 'Ta', 'Ta', 'Tofu', 'y.'], 103], [['fi Ta Ta', 63], ['Tofu y.', 54]])], [('regression: kerning after ligature', [['fly.', 'staff.', 'y.', 'raffle', 'av', 'raffle'], 99], [['fly. staff. y.', 87], ['raffle av', 70], ['raffle', 46]]), ('regression: kerning after ligature', [['staff.', 'AVAIL', 'LA', 'LA|VALLE'], 42], [['staff.', 42], ['AVAIL', 59], ['LA', 26], ['LAVALLE', 88]]), ('regression: kerning after ligature', [['fl.', 'Wavy', 'our', 'VIA', 'Tofu', 'staff.', 'staff.'], 58], [['fl.', 15], ['Wavy', 45], ['our', 30], ['VIA', 39], ['Tofu', 37], ['staff.', 42], ['staff.', 42]]), ('regression: kerning after ligature', [['shelf|life', 'raffle', 'av', 'our', 'staff.', 'y.'], 43], [['shelflife', 64], ['raffle', 46], ['av', 19], ['our', 30], ['staff.', 42], ['y.', 12]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['Ta', 'raffle', 'Yo'], 80], [['Ta raffle', 72], ['Yo', 21]]), ('control layout', [['fly.', 'shelf|life', 'AT', 'flow', 'av'], 91], [['fly.', 23], ['shelflife', 64], ['AT flow av', 90]])], [('regression: kerning after ligature', [['our', 'av', 'staff.', 'Av'], 56], [['our av', 54], ['staff.', 42], ['Av', 23]]), ('regression: kerning after ligature', [['av', 'fl.', 'Tofu', 'flow'], 112], [['av fl. Tofu', 81], ['flow', 35]]), ('regression: kerning after ligature', [['fl.', 'wolf|like', 'Wavy', 'Vat'], 50], [['fl.', 15], ['wolflike', 62], ['Wavy', 45], ['Vat', 27]]), ('regression: kerning after ligature', [['flow', 'av', 'av', 'wolf|like', 'fl.', 'Av'], 88], [['flow av av', 83], ['wolflike fl.', 82], ['Av', 23]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['AT', 'flow', 'raffle', 'wolf|like', 'VIA', 'dry.'], 79], [['AT flow', 66], ['raffle', 46], ['wolflike', 62], ['VIA dry.', 76]]), ('control layout', [['flow', 'Yo', 'y.', 'y.'], 102], [['flow Yo y. y.', 95]])], [('regression: kerning after ligature', [['dry.', 'LA', 'shelf|life', 'staff.', 'fi', 'staff.', 'av'], 116], [['dry. LA', 63], ['shelflife staff.', 111], ['fi staff. av', 82]]), ('regression: kerning after ligature', [['fly.', 'office', 'raffle', 'staff.', 'fly.', 'VIA'], 68], [['fly.', 23], ['office', 46], ['raffle', 46], ['staff.', 42], ['fly. VIA', 67]]), ('regression: kerning after ligature', [['fl.', 'wolf|like', 'Wavy', 'Vat'], 50], [['fl.', 15], ['wolflike', 62], ['Wavy', 45], ['Vat', 27]]), ('regression: kerning after ligature', [['Av', 'staff.', 'office'], 55], [['Av', 23], ['staff.', 42], ['office', 46]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['office', 'wolf|like'], 70], [['office', 46], ['wolflike', 62]]), ('control layout', [['our', 'av', 'our', 'Wavy'], 94], [['our av our', 89], ['Wavy', 45]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Punctuation after a ligature is kerned against a hidden component glyph.

Input [words, width]. Glyph widths: i,l,j,.,, 4; t,f 6; m 15; w 14; M 16; W 18; other lowercase 10; other uppercase 13; space 5. Within a word, fi/fl/ff form ligatures (11/11/12) with no kerning into or out of them; case-sensitive kern pairs apply between adjacent glyphs; "|" is a non-joiner (invisible, blocks ligatures and kerning). No kerning across spaces. Greedy fill. Return [[text, width]].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get((prev + g).upper(), 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kern pair case sensitivity', [['y.', 'Yo', 'fi', 'wolf|like'], 47], [['y. Yo', 38], ['fi', 11], ['wolflike', 62]]), ('regression: kern pair case sensitivity', [['Av', 'fly.', 'LA|VALLE', 'y.', 'office', 'raffle', 'VIA'], 77], [['Av fly.', 51], ['LAVALLE', 88], ['y. office', 63], ['raffle', 46], ['VIA', 39]]), ('regression: kern pair case sensitivity', [['Av', 'flow'], 132], [['Av flow', 63]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]]), ('control layout', [['AVAIL', 'shelf|life', 'AT'], 140], [['AVAIL shelflife', 128], ['AT', 26]])], [('regression: kern pair case sensitivity', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: kern pair case sensitivity', [['office', 'wolf|like', 'flow', 'VIA', 'LT', 'Ta'], 45], [['office', 46], ['wolflike', 62], ['flow', 35], ['VIA', 39], ['LT', 23], ['Ta', 21]]), ('regression: kern pair case sensitivity', [['our', 'Av', 'fly.', 'av'], 83], [['our Av', 58], ['fly. av', 47]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AT', 'flow'], 114], [['AT flow', 66]]), ('control layout', [['shelf|life', 'our'], 55], [['shelflife', 64], ['our', 30]])], [('regression: kern pair case sensitivity', [['fly.', 'Yo'], 43], [['fly.', 23], ['Yo', 21]]), ('regression: kern pair case sensitivity', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('regression: kern pair case sensitivity', [['flow', 'Ta', 'Ta', 'Av', 'LA|VALLE'], 115], [['flow Ta Ta Av', 115], ['LAVALLE', 88]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]])], [('regression: kern pair case sensitivity', [['Tofu', 'Av'], 95], [['Tofu Av', 65]]), ('regression: kern pair case sensitivity', [['Wavy', 'VIA', 'y.', 'wolf|like', 'fi'], 95], [['Wavy VIA', 89], ['y. wolflike fi', 95]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('regression: kern pair case sensitivity', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['staff.', 'office'], 111], [['staff. office', 93]]), ('control layout', [['AVAIL', 'raffle', 'raffle', 'LA', 'office', 'VIA', 'AT'], 79], [['AVAIL', 59], ['raffle', 46], ['raffle LA', 77], ['office', 46], ['VIA AT', 70]])], [('regression: kern pair case sensitivity', [['Vat', 'office', 'flow', 'LA', 'staff.', 'AT'], 44], [['Vat', 27], ['office', 46], ['flow', 35], ['LA', 26], ['staff.', 42], ['AT', 26]]), ('regression: kern pair case sensitivity', [['LT', 'staff.', 'LA|VALLE', 'LA|VALLE', 'Vat', 'office'], 95], [['LT staff.', 70], ['LAVALLE', 88], ['LAVALLE', 88], ['Vat office', 78]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('regression: kern pair case sensitivity', [['Av', 'LA|VALLE', 'Ta', 'VIA'], 53], [['Av', 23], ['LAVALLE', 88], ['Ta', 21], ['VIA', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['staff.', 'office'], 118], [['staff. office', 93]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0) or KERN.get((prev + g).lower(), 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: kern pair case sensitivity', [['y.', 'Yo', 'fi', 'wolf|like'], 47], [['y. Yo', 38], ['fi', 11], ['wolflike', 62]]), ('regression: kern pair case sensitivity', [['Av', 'fly.', 'LA|VALLE', 'y.', 'office', 'raffle', 'VIA'], 77], [['Av fly.', 51], ['LAVALLE', 88], ['y. office', 63], ['raffle', 46], ['VIA', 39]]), ('regression: kern pair case sensitivity', [['Av', 'flow'], 132], [['Av flow', 63]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('control layout', [['VIA', 'LA|VALLE', 'Wavy', 'wolf|like'], 72], [['VIA', 39], ['LAVALLE', 88], ['Wavy', 45], ['wolflike', 62]]), ('control layout', [['AVAIL', 'shelf|life', 'AT'], 140], [['AVAIL shelflife', 128], ['AT', 26]])], [('regression: kern pair case sensitivity', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: kern pair case sensitivity', [['office', 'wolf|like', 'flow', 'VIA', 'LT', 'Ta'], 45], [['office', 46], ['wolflike', 62], ['flow', 35], ['VIA', 39], ['LT', 23], ['Ta', 21]]), ('regression: kern pair case sensitivity', [['our', 'Av', 'fly.', 'av'], 83], [['our Av', 58], ['fly. av', 47]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['AT', 'flow'], 114], [['AT flow', 66]]), ('control layout', [['shelf|life', 'our'], 55], [['shelflife', 64], ['our', 30]])], [('regression: kern pair case sensitivity', [['fly.', 'Yo'], 43], [['fly.', 23], ['Yo', 21]]), ('regression: kern pair case sensitivity', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('regression: kern pair case sensitivity', [['flow', 'Ta', 'Ta', 'Av', 'LA|VALLE'], 115], [['flow Ta Ta Av', 115], ['LAVALLE', 88]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]])], [('regression: kern pair case sensitivity', [['Tofu', 'Av'], 95], [['Tofu Av', 65]]), ('regression: kern pair case sensitivity', [['Wavy', 'VIA', 'y.', 'wolf|like', 'fi'], 95], [['Wavy VIA', 89], ['y. wolflike fi', 95]]), ('regression: kern pair case sensitivity', [['Av', 'Tofu'], 41], [['Av', 23], ['Tofu', 37]]), ('regression: kern pair case sensitivity', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['staff.', 'office'], 111], [['staff. office', 93]]), ('control layout', [['AVAIL', 'raffle', 'raffle', 'LA', 'office', 'VIA', 'AT'], 79], [['AVAIL', 59], ['raffle', 46], ['raffle LA', 77], ['office', 46], ['VIA AT', 70]])], [('regression: kern pair case sensitivity', [['Vat', 'office', 'flow', 'LA', 'staff.', 'AT'], 44], [['Vat', 27], ['office', 46], ['flow', 35], ['LA', 26], ['staff.', 42], ['AT', 26]]), ('regression: kern pair case sensitivity', [['LT', 'staff.', 'LA|VALLE', 'LA|VALLE', 'Vat', 'office'], 95], [['LT staff.', 70], ['LAVALLE', 88], ['LAVALLE', 88], ['Vat office', 78]]), ('regression: kern pair case sensitivity', [['LA|VALLE', 'av', 'Av', 'AT'], 122], [['LAVALLE av', 112], ['Av AT', 54]]), ('regression: kern pair case sensitivity', [['Av', 'LA|VALLE', 'Ta', 'VIA'], 53], [['Av', 23], ['LAVALLE', 88], ['Ta', 21], ['VIA', 39]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['office', 'VIA'], 112], [['office VIA', 90]]), ('control layout', [['staff.', 'office'], 118], [['staff. office', 93]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Lowercase pairs receive the tighter uppercase kerning value.

Input [words, width]. Glyph widths: i,l,j,.,, 4; t,f 6; m 15; w 14; M 16; W 18; other lowercase 10; other uppercase 13; space 5. Within a word, fi/fl/ff form ligatures (11/11/12) with no kerning into or out of them; case-sensitive kern pairs apply between adjacent glyphs; "|" is a non-joiner (invisible, blocks ligatures and kerning). No kerning across spaces. Greedy fill. Return [[text, width]].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * len(ws)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: interword space count', [['av', 'Av', 'Av'], 104], [['av Av Av', 75]]), ('regression: interword space count', [['office', 'wolf|like', 'fl.', 'y.', 'fl.'], 72], [['office', 46], ['wolflike', 62], ['fl. y. fl.', 52]]), ('regression: interword space count', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('regression: interword space count', [['fly.', 'Yo'], 126], [['fly. Yo', 49]]), ('regression: interword space count', [['Av', 'av', 'fly.'], 95], [['Av av fly.', 75]])], [('regression: interword space count', [['flow', 'fly.', 'Wavy', 'Ta', 'fly.', 'Vat'], 120], [['flow fly. Wavy', 113], ['Ta fly. Vat', 81]]), ('regression: interword space count', [['staff.', 'LA|VALLE', 'Av', 'Yo'], 106], [['staff.', 42], ['LAVALLE', 88], ['Av Yo', 49]]), ('regression: interword space count', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('regression: interword space count', [['fi', 'fi', 'AVAIL', 'Tofu'], 58], [['fi fi', 27], ['AVAIL', 59], ['Tofu', 37]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: interword space count', [['wolf|like', 'our', 'wolf|like', 'Yo', 'fly.', 'Tofu'], 41], [['wolflike', 62], ['our', 30], ['wolflike', 62], ['Yo', 21], ['fly.', 23], ['Tofu', 37]]), ('regression: interword space count', [['AT', 'staff.', 'raffle', 'fly.'], 77], [['AT staff.', 73], ['raffle fly.', 74]])], [('regression: interword space count', [['office', 'LT', 'VIA', 'Av', 'dry.'], 77], [['office LT', 74], ['VIA Av', 67], ['dry.', 32]]), ('regression: interword space count', [['Yo', 'AVAIL', 'flow'], 53], [['Yo', 21], ['AVAIL', 59], ['flow', 35]]), ('regression: interword space count', [['fi', 'Vat'], 42], [['fi', 11], ['Vat', 27]]), ('regression: interword space count', [['dry.', 'y.', 'Tofu', 'av', 'av', 'LA', 'Vat'], 46], [['dry.', 32], ['y.', 12], ['Tofu', 37], ['av av', 43], ['LA', 26], ['Vat', 27]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: interword space count', [['Ta', 'fi', 'LA|VALLE', 'shelf|life', 'y.', 'Wavy'], 47], [['Ta fi', 37], ['LAVALLE', 88], ['shelflife', 64], ['y.', 12], ['Wavy', 45]]), ('regression: interword space count', [['LT', 'wolf|like'], 126], [['LT wolflike', 90]])], [('regression: interword space count', [['staff.', 'AVAIL', 'LA', 'LA|VALLE'], 42], [['staff.', 42], ['AVAIL', 59], ['LA', 26], ['LAVALLE', 88]]), ('regression: interword space count', [['Tofu', 'fi'], 74], [['Tofu fi', 53]]), ('regression: interword space count', [['LT', 'y.', 'flow', 'dry.'], 58], [['LT y.', 40], ['flow', 35], ['dry.', 32]]), ('regression: interword space count', [['fly.', 'Ta', 'fl.'], 68], [['fly. Ta', 49], ['fl.', 15]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: interword space count', [['Av', 'LA', 'Av', 'LA', 'Av', 'wolf|like'], 128], [['Av LA Av LA', 113], ['Av wolflike', 90]]), ('regression: interword space count', [['Tofu', 'Ta', 'staff.', 'LA|VALLE', 'Vat', 'fi', 'LT'], 88], [['Tofu Ta', 63], ['staff.', 42], ['LAVALLE', 88], ['Vat fi LT', 71]])], [('regression: interword space count', [['av', 'dry.', 'LA|VALLE', 'raffle', 'LA|VALLE', 'av'], 82], [['av dry.', 56], ['LAVALLE', 88], ['raffle', 46], ['LAVALLE', 88], ['av', 19]]), ('regression: interword space count', [['fi', 'dry.', 'fly.', 'flow', 'AT', 'Yo'], 68], [['fi dry.', 48], ['fly. flow', 63], ['AT Yo', 52]]), ('regression: interword space count', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: interword space count', [['LA', 'office', 'fl.', 'VIA', 'LA'], 96], [['LA office', 77], ['fl. VIA LA', 90]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: interword space count', [['staff.', 'y.', 'dry.', 'wolf|like', 'Av'], 136], [['staff. y. dry.', 96], ['wolflike Av', 90]]), ('regression: interword space count', [['our', 'av', 'staff.', 'Av'], 56], [['our av', 54], ['staff.', 42], ['Av', 23]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * max(len(ws) - 2, 0)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: interword space count', [['av', 'Av', 'Av'], 104], [['av Av Av', 75]]), ('regression: interword space count', [['office', 'wolf|like', 'fl.', 'y.', 'fl.'], 72], [['office', 46], ['wolflike', 62], ['fl. y. fl.', 52]]), ('regression: interword space count', [['staff.', 'Av', 'Av', 'Av', 'LT'], 91], [['staff. Av', 70], ['Av Av LT', 79]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('regression: interword space count', [['fly.', 'Yo'], 126], [['fly. Yo', 49]]), ('regression: interword space count', [['Av', 'av', 'fly.'], 95], [['Av av fly.', 75]])], [('regression: interword space count', [['flow', 'fly.', 'Wavy', 'Ta', 'fly.', 'Vat'], 120], [['flow fly. Wavy', 113], ['Ta fly. Vat', 81]]), ('regression: interword space count', [['staff.', 'LA|VALLE', 'Av', 'Yo'], 106], [['staff.', 42], ['LAVALLE', 88], ['Av Yo', 49]]), ('regression: interword space count', [['Av', 'LA', 'Tofu', 'y.'], 125], [['Av LA Tofu y.', 113]]), ('regression: interword space count', [['fi', 'fi', 'AVAIL', 'Tofu'], 58], [['fi fi', 27], ['AVAIL', 59], ['Tofu', 37]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: interword space count', [['wolf|like', 'our', 'wolf|like', 'Yo', 'fly.', 'Tofu'], 41], [['wolflike', 62], ['our', 30], ['wolflike', 62], ['Yo', 21], ['fly.', 23], ['Tofu', 37]]), ('regression: interword space count', [['AT', 'staff.', 'raffle', 'fly.'], 77], [['AT staff.', 73], ['raffle fly.', 74]])], [('regression: interword space count', [['office', 'LT', 'VIA', 'Av', 'dry.'], 77], [['office LT', 74], ['VIA Av', 67], ['dry.', 32]]), ('regression: interword space count', [['Yo', 'AVAIL', 'flow'], 53], [['Yo', 21], ['AVAIL', 59], ['flow', 35]]), ('regression: interword space count', [['fi', 'Vat'], 42], [['fi', 11], ['Vat', 27]]), ('regression: interword space count', [['dry.', 'y.', 'Tofu', 'av', 'av', 'LA', 'Vat'], 46], [['dry.', 32], ['y.', 12], ['Tofu', 37], ['av av', 43], ['LA', 26], ['Vat', 27]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: interword space count', [['Ta', 'fi', 'LA|VALLE', 'shelf|life', 'y.', 'Wavy'], 47], [['Ta fi', 37], ['LAVALLE', 88], ['shelflife', 64], ['y.', 12], ['Wavy', 45]]), ('regression: interword space count', [['LT', 'wolf|like'], 126], [['LT wolflike', 90]])], [('regression: interword space count', [['staff.', 'AVAIL', 'LA', 'LA|VALLE'], 42], [['staff.', 42], ['AVAIL', 59], ['LA', 26], ['LAVALLE', 88]]), ('regression: interword space count', [['Tofu', 'fi'], 74], [['Tofu fi', 53]]), ('regression: interword space count', [['LT', 'y.', 'flow', 'dry.'], 58], [['LT y.', 40], ['flow', 35], ['dry.', 32]]), ('regression: interword space count', [['fly.', 'Ta', 'fl.'], 68], [['fly. Ta', 49], ['fl.', 15]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('regression: interword space count', [['Av', 'LA', 'Av', 'LA', 'Av', 'wolf|like'], 128], [['Av LA Av LA', 113], ['Av wolflike', 90]]), ('regression: interword space count', [['Tofu', 'Ta', 'staff.', 'LA|VALLE', 'Vat', 'fi', 'LT'], 88], [['Tofu Ta', 63], ['staff.', 42], ['LAVALLE', 88], ['Vat fi LT', 71]])], [('regression: interword space count', [['av', 'dry.', 'LA|VALLE', 'raffle', 'LA|VALLE', 'av'], 82], [['av dry.', 56], ['LAVALLE', 88], ['raffle', 46], ['LAVALLE', 88], ['av', 19]]), ('regression: interword space count', [['fi', 'dry.', 'fly.', 'flow', 'AT', 'Yo'], 68], [['fi dry.', 48], ['fly. flow', 63], ['AT Yo', 52]]), ('regression: interword space count', [['LT', 'Vat', 'office', 'LA', 'dry.', 'dry.', 'dry.'], 122], [['LT Vat office', 106], ['LA dry. dry.', 100], ['dry.', 32]]), ('regression: interword space count', [['LA', 'office', 'fl.', 'VIA', 'LA'], 96], [['LA office', 77], ['fl. VIA LA', 90]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: interword space count', [['staff.', 'y.', 'dry.', 'wolf|like', 'Av'], 136], [['staff. y. dry.', 96], ['wolflike Av', 90]]), ('regression: interword space count', [['our', 'av', 'staff.', 'Av'], 56], [['our av', 54], ['staff.', 42], ['Av', 23]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Every line measures one space too wide.

Input [words, width]. Glyph widths: i,l,j,.,, 4; t,f 6; m 15; w 14; M 16; W 18; other lowercase 10; other uppercase 13; space 5. Within a word, fi/fl/ff form ligatures (11/11/12) with no kerning into or out of them; case-sensitive kern pairs apply between adjacent glyphs; "|" is a non-joiner (invisible, blocks ligatures and kerning). No kerning across spaces. Greedy fill. Return [[text, width]].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        w = w.replace('|', '')
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                prev = None
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: non-joiner handling', [['LA', 'fl.', 'av', 'LA|VALLE', 'Vat', 'Wavy'], 112], [['LA fl. av', 70], ['LAVALLE', 88], ['Vat Wavy', 77]]), ('regression: non-joiner handling', [['LA|VALLE', 'LA', 'y.'], 128], [['LAVALLE LA', 119], ['y.', 12]]), ('regression: non-joiner handling', [['Tofu', 'LA|VALLE', 'flow'], 134], [['Tofu LAVALLE', 130], ['flow', 35]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['fly.', 'fi', 'fl.', 'av'], 74], [['fly. fi fl.', 59], ['av', 19]]), ('control layout', [['LA', 'VIA'], 102], [['LA VIA', 70]])], [('regression: non-joiner handling', [['shelf|life', 'AVAIL', 'LA|VALLE', 'Wavy', 'Tofu', 'Vat', 'y.'], 131], [['shelflife AVAIL', 128], ['LAVALLE', 88], ['Wavy Tofu Vat', 119], ['y.', 12]]), ('regression: non-joiner handling', [['office', 'wolf|like', 'fl.', 'y.', 'fl.'], 72], [['office', 46], ['wolflike', 62], ['fl. y. fl.', 52]]), ('regression: non-joiner handling', [['office', 'LT', 'Wavy', 'AT', 'Vat', 'LA|VALLE', 'our'], 65], [['office', 46], ['LT', 23], ['Wavy', 45], ['AT Vat', 58], ['LAVALLE', 88], ['our', 30]]), ('regression: non-joiner handling', [['LA|VALLE', 'VIA', 'raffle', 'dry.'], 97], [['LAVALLE', 88], ['VIA raffle', 90], ['dry.', 32]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['fly.', 'flow', 'Wavy', 'av', 'LT'], 132], [['fly. flow Wavy', 113], ['av LT', 47]]), ('control layout', [['LA', 'office', 'fl.', 'VIA', 'LA'], 96], [['LA office', 77], ['fl. VIA LA', 90]])], [('regression: non-joiner handling', [['LA|VALLE', 'fl.'], 138], [['LAVALLE fl.', 108]]), ('regression: non-joiner handling', [['LA', 'fl.', 'av', 'LA|VALLE', 'Vat', 'Wavy'], 112], [['LA fl. av', 70], ['LAVALLE', 88], ['Vat Wavy', 77]]), ('regression: non-joiner handling', [['LA|VALLE', 'shelf|life', 'office', 'AT', 'wolf|like'], 116], [['LAVALLE', 88], ['shelflife office', 115], ['AT wolflike', 93]]), ('regression: non-joiner handling', [['Yo', 'LA|VALLE', 'Tofu', 'Ta', 'Av'], 56], [['Yo', 21], ['LAVALLE', 88], ['Tofu', 37], ['Ta Av', 49]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['our', 'av', 'AT', 'Yo'], 92], [['our av AT', 85], ['Yo', 21]]), ('control layout', [['fl.', 'Yo', 'Tofu'], 112], [['fl. Yo Tofu', 83]])], [('regression: non-joiner handling', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]]), ('regression: non-joiner handling', [['flow', 'shelf|life', 'Wavy', 'AVAIL', 'dry.'], 88], [['flow', 35], ['shelflife', 64], ['Wavy', 45], ['AVAIL', 59], ['dry.', 32]]), ('regression: non-joiner handling', [['LA|VALLE', 'flow', 'y.', 'dry.', 'AVAIL', 'LA'], 106], [['LAVALLE', 88], ['flow y. dry.', 89], ['AVAIL LA', 90]]), ('regression: non-joiner handling', [['LA|VALLE', 'shelf|life'], 127], [['LAVALLE', 88], ['shelflife', 64]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['AT', 'raffle', 'Wavy', 'Vat', 'AT', 'dry.', 'AVAIL'], 98], [['AT raffle', 77], ['Wavy Vat', 77], ['AT dry.', 63], ['AVAIL', 59]]), ('control layout', [['VIA', 'flow', 'dry.', 'y.', 'AVAIL', 'fl.', 'av'], 42], [['VIA', 39], ['flow', 35], ['dry.', 32], ['y.', 12], ['AVAIL', 59], ['fl. av', 39]])], [('regression: non-joiner handling', [['fi', 'flow', 'shelf|life', 'LA', 'our', 'Yo'], 104], [['fi flow', 51], ['shelflife LA', 95], ['our Yo', 56]]), ('regression: non-joiner handling', [['wolf|like', 'Tofu', 'Yo', 'AVAIL', 'Wavy', 'Av'], 108], [['wolflike Tofu', 104], ['Yo AVAIL', 85], ['Wavy Av', 73]]), ('regression: non-joiner handling', [['fly.', 'LA|VALLE'], 52], [['fly.', 23], ['LAVALLE', 88]]), ('regression: non-joiner handling', [['Ta', 'raffle', 'VIA', 'LA|VALLE'], 66], [['Ta', 21], ['raffle', 46], ['VIA', 39], ['LAVALLE', 88]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['Wavy', 'fi', 'Av', 'LT'], 86], [['Wavy fi', 61], ['Av LT', 51]]), ('control layout', [['fi', 'y.', 'fly.', 'office'], 58], [['fi y. fly.', 56], ['office', 46]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    words, width = x
    W = {'i': 4, 'l': 4, 'j': 4, '.': 4, ',': 4, 't': 6, 'f': 6, 'm': 15, 'w': 14, 'M': 16, 'W': 18}
    LIG = {'fi': 11, 'fl': 11, 'ff': 12}
    KERN = {'AV': -3, 'VA': -3, 'To': -2, 'Ta': -2, 'Yo': -2, 'LT': -3, 'Wa': -2, 'av': -1, 'va': -1, 'y.': -2, 'r.': -2, 'l.': -1, 'f.': -1, 'Va': -2}
    SPACE = 5
    def glyph(c):
        return W.get(c, 13 if c.isupper() else 10)
    def measure(w):
        total, prev, i = 0, None, 0
        while i < len(w):
            if w[i] == '|':
                i += 1
                continue
            pair = w[i:i + 2]
            if pair in LIG:
                total += LIG[pair]
                prev = None
                i += 2
                continue
            g = w[i]
            total += glyph(g)
            if prev is not None:
                total += KERN.get(prev + g, 0)
            prev = g
            i += 1
        return total
    def line_width(ws):
        return sum(measure(t) for t in ws) + SPACE * (len(ws) - 1)
    lines, cur = [], []
    for w in words:
        cand = cur + [w]
        if not cur or line_width(cand) <= width:
            cur = cand
        else:
            lines.append(cur)
            cur = [w]
    if cur:
        lines.append(cur)
    return [[' '.join(t.replace('|', '') for t in ln), line_width(ln)] for ln in lines]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('regression: non-joiner handling', [['LA', 'fl.', 'av', 'LA|VALLE', 'Vat', 'Wavy'], 112], [['LA fl. av', 70], ['LAVALLE', 88], ['Vat Wavy', 77]]), ('regression: non-joiner handling', [['LA|VALLE', 'LA', 'y.'], 128], [['LAVALLE LA', 119], ['y.', 12]]), ('regression: non-joiner handling', [['Tofu', 'LA|VALLE', 'flow'], 134], [['Tofu LAVALLE', 130], ['flow', 35]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['fly.', 'fi', 'fl.', 'av'], 74], [['fly. fi fl.', 59], ['av', 19]]), ('control layout', [['LA', 'VIA'], 102], [['LA VIA', 70]])], [('regression: non-joiner handling', [['shelf|life', 'AVAIL', 'LA|VALLE', 'Wavy', 'Tofu', 'Vat', 'y.'], 131], [['shelflife AVAIL', 128], ['LAVALLE', 88], ['Wavy Tofu Vat', 119], ['y.', 12]]), ('regression: non-joiner handling', [['office', 'wolf|like', 'fl.', 'y.', 'fl.'], 72], [['office', 46], ['wolflike', 62], ['fl. y. fl.', 52]]), ('regression: non-joiner handling', [['office', 'LT', 'Wavy', 'AT', 'Vat', 'LA|VALLE', 'our'], 65], [['office', 46], ['LT', 23], ['Wavy', 45], ['AT Vat', 58], ['LAVALLE', 88], ['our', 30]]), ('regression: non-joiner handling', [['LA|VALLE', 'VIA', 'raffle', 'dry.'], 97], [['LAVALLE', 88], ['VIA raffle', 90], ['dry.', 32]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('control layout', [['fly.', 'flow', 'Wavy', 'av', 'LT'], 132], [['fly. flow Wavy', 113], ['av LT', 47]]), ('control layout', [['LA', 'office', 'fl.', 'VIA', 'LA'], 96], [['LA office', 77], ['fl. VIA LA', 90]])], [('regression: non-joiner handling', [['LA|VALLE', 'fl.'], 138], [['LAVALLE fl.', 108]]), ('regression: non-joiner handling', [['LA', 'fl.', 'av', 'LA|VALLE', 'Vat', 'Wavy'], 112], [['LA fl. av', 70], ['LAVALLE', 88], ['Vat Wavy', 77]]), ('regression: non-joiner handling', [['LA|VALLE', 'shelf|life', 'office', 'AT', 'wolf|like'], 116], [['LAVALLE', 88], ['shelflife office', 115], ['AT wolflike', 93]]), ('regression: non-joiner handling', [['Yo', 'LA|VALLE', 'Tofu', 'Ta', 'Av'], 56], [['Yo', 21], ['LAVALLE', 88], ['Tofu', 37], ['Ta Av', 49]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['our', 'av', 'AT', 'Yo'], 92], [['our av AT', 85], ['Yo', 21]]), ('control layout', [['fl.', 'Yo', 'Tofu'], 112], [['fl. Yo Tofu', 83]])], [('regression: non-joiner handling', [['LA|VALLE', 'office', 'raffle', 'LA', 'staff.'], 129], [['LAVALLE', 88], ['office raffle LA', 128], ['staff.', 42]]), ('regression: non-joiner handling', [['flow', 'shelf|life', 'Wavy', 'AVAIL', 'dry.'], 88], [['flow', 35], ['shelflife', 64], ['Wavy', 45], ['AVAIL', 59], ['dry.', 32]]), ('regression: non-joiner handling', [['LA|VALLE', 'flow', 'y.', 'dry.', 'AVAIL', 'LA'], 106], [['LAVALLE', 88], ['flow y. dry.', 89], ['AVAIL LA', 90]]), ('regression: non-joiner handling', [['LA|VALLE', 'shelf|life'], 127], [['LAVALLE', 88], ['shelflife', 64]]), ('cross-word pair must not kern', [['LA', 'Vat'], 200], [['LA Vat', 58]]), ('ligature then period', [['fl.', 'fi,'], 200], [['fl. fi,', 35]]), ('control layout', [['AT', 'raffle', 'Wavy', 'Vat', 'AT', 'dry.', 'AVAIL'], 98], [['AT raffle', 77], ['Wavy Vat', 77], ['AT dry.', 63], ['AVAIL', 59]]), ('control layout', [['VIA', 'flow', 'dry.', 'y.', 'AVAIL', 'fl.', 'av'], 42], [['VIA', 39], ['flow', 35], ['dry.', 32], ['y.', 12], ['AVAIL', 59], ['fl. av', 39]])], [('regression: non-joiner handling', [['fi', 'flow', 'shelf|life', 'LA', 'our', 'Yo'], 104], [['fi flow', 51], ['shelflife LA', 95], ['our Yo', 56]]), ('regression: non-joiner handling', [['wolf|like', 'Tofu', 'Yo', 'AVAIL', 'Wavy', 'Av'], 108], [['wolflike Tofu', 104], ['Yo AVAIL', 85], ['Wavy Av', 73]]), ('regression: non-joiner handling', [['fly.', 'LA|VALLE'], 52], [['fly.', 23], ['LAVALLE', 88]]), ('regression: non-joiner handling', [['Ta', 'raffle', 'VIA', 'LA|VALLE'], 66], [['Ta', 21], ['raffle', 46], ['VIA', 39], ['LAVALLE', 88]]), ('case-sensitive pair', [['Av', 'av'], 200], [['Av av', 47]]), ('non-joiner blocks ligature', [['shelf|life'], 200], [['shelflife', 64]]), ('control layout', [['Wavy', 'fi', 'Av', 'LT'], 86], [['Wavy fi', 61], ['Av LT', 51]]), ('control layout', [['fi', 'y.', 'fly.', 'office'], 58], [['fi y. fly.', 56], ['office', 46]])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Compound words marked with a non-joiner still form ligatures.

Input [words, width]. Glyph widths: i,l,j,.,, 4; t,f 6; m 15; w 14; M 16; W 18; other lowercase 10; other uppercase 13; space 5. Within a word, fi/fl/ff form ligatures (11/11/12) with no kerning into or out of them; case-sensitive kern pairs apply between adjacent glyphs; "|" is a non-joiner (invisible, blocks ligatures and kerning). No kerning across spaces. Greedy fill. Return [[text, width]].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    src, width = x
    chunks = ['']
    ops = []
    i = 0
    while i < len(src):
        c = src[i]
        if src.startswith('\\-', i):
            ops.append('d')
            chunks.append('')
            i += 2
            continue
        if c in ' ~':
            j = i
            while j < len(src) and src[j] in ' ~':
                j += 1
            ops.append('s')
            chunks.append('')
            i = j
            continue
        if c == '|':
            ops.append('z')
            chunks.append('')
            i += 1
            continue
        chunks[-1] += ' ' if c == '~' else c
        i += 1
    line = chunks[0]
    lines = []
    for op, ch in zip(ops, chunks[1:]):
        sep = ' ' if op == 's' else ''
        if len(line + sep + ch) <= width:
            line = line + sep + ch
        else:
            lines.append(line + ('-' if op == 'd' else ''))
            line = ch
    lines.append(line)
    return lines
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('regression: tie breakability', ['com\\-po\\-si\\-tion word word  ~url|path com\\-po\\-si\\-tion 10~pt', 14], ['composition', 'word word  url', 'path composi-', 'tion 10 pt']), ('regression: tie breakability', ['ink  x Dr.~Knuth ink ink set x word', 7], ['ink x', 'Dr. Knuth', 'ink ink', 'set x', 'word']), ('regression: tie breakability', ['url|path type type com\\-po\\-si\\-tion Dr.~Knuth', 5], ['url', 'path', 'type', 'type', 'compo-', 'si-', 'tion', 'Dr. Knuth']), ('double space collapses', ['type  set', 20], ['type set']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('control layout', ['word  a a set', 7], ['word a', 'a set']), ('control layout', ['url|path com\\-po\\-si\\-tion x a url|path  a', 14], ['urlpath compo-', 'sition x a url', 'path a'])], [('regression: tie breakability', ['com\\-po\\-si\\-tion ~x  com\\-po\\-si\\-tion', 13], ['composition', ' x composi-', 'tion']), ('regression: tie breakability', ['hy\\-phen ~type set ~com\\-po\\-si\\-tion set  type  com\\-po\\-si\\-tion word set', 15], ['hyphen  type', 'set  composi-', 'tion set type', 'composition', 'word set']), ('regression: tie breakability', ['ink 10~pt ink b|c hy\\-phen ~set url|path word', 16], ['ink 10 pt ink bc', 'hyphen  set url', 'path word']), ('regression: tie breakability', ['hy\\-phen ~10~pt b|c hy\\-phen ~x  com\\-po\\-si\\-tion', 5], ['hy-', 'phen', ' 10 pt', 'bc hy-', 'phen', ' x', 'compo-', 'si-', 'tion']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('control layout', ['b|c ink hy\\-phen url|path type com\\-po\\-si\\-tion', 8], ['bc ink', 'hyphen', 'urlpath', 'type com-', 'position']), ('control layout', ['b|c  a ink  ink com\\-po\\-si\\-tion', 11], ['bc a ink', 'ink composi-', 'tion'])], [('regression: tie breakability', ['x com\\-po\\-si\\-tion ink ~type', 14], ['x composition', 'ink  type']), ('regression: tie breakability', ['Dr.~Knuth  hy\\-phen  com\\-po\\-si\\-tion Dr.~Knuth word ink', 6], ['Dr. Knuth', 'hyphen', 'compo-', 'sition', 'Dr. Knuth', 'word', 'ink']), ('regression: tie breakability', ['hy\\-phen type ~word  hy\\-phen ~x', 14], ['hyphen type', ' word hyphen', ' x']), ('partial-repair probe', ['b|c url|path word  Dr.~Knuth', 9], ['bc url', 'path word', 'Dr. Knuth']), ('double space collapses', ['type  set', 20], ['type set']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['word com\\-po\\-si\\-tion a', 15], ['word composi-', 'tion a']), ('control layout', ['type set b|c', 6], ['type', 'set bc'])], [('regression: tie breakability', ['type a hy\\-phen com\\-po\\-si\\-tion ~set set ink  type', 8], ['type a', 'hyphen', 'composi-', 'tion', ' set set', 'ink type']), ('regression: tie breakability', ['ink ~10~pt type  com\\-po\\-si\\-tion url|path  a ~x 10~pt b|c', 9], ['ink', ' 10 pt', 'type com-', 'position', 'urlpath a', ' x 10 pt', 'bc']), ('partial-repair probe', ['ink com\\-po\\-si\\-tion Dr.~Knuth', 16], ['ink composition', 'Dr. Knuth']), ('regression: tie breakability', ['x set  type com\\-po\\-si\\-tion a ~ink b|c hy\\-phen url|path', 13], ['x set type', 'composition a', ' ink bc hy-', 'phen urlpath']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['a type  com\\-po\\-si\\-tion a', 6], ['a type', 'compo-', 'sition', 'a']), ('control layout', ['com\\-po\\-si\\-tion  hy\\-phen com\\-po\\-si\\-tion ink  b|c a', 10], ['composi-', 'tion hy-', 'phen compo-', 'sition ink', 'bc a'])], [('regression: tie breakability', ['Dr.~Knuth ink 10~pt  set x', 16], ['Dr. Knuth ink', '10 pt set x']), ('regression: tie breakability', ['hy\\-phen type ~x ~x hy\\-phen  10~pt  hy\\-phen 10~pt word', 14], ['hyphen type  x', ' x hyphen', '10 pt hyphen', '10 pt word']), ('partial-repair probe', ['url|path type  10~pt  word', 6], ['url', 'path', 'type', '10 pt', 'word']), ('regression: tie breakability', ['url|path type type com\\-po\\-si\\-tion Dr.~Knuth', 5], ['url', 'path', 'type', 'type', 'compo-', 'si-', 'tion', 'Dr. Knuth']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('control layout', ['com\\-po\\-si\\-tion type hy\\-phen hy\\-phen url|path ink', 13], ['composition', 'type hyphen', 'hyphen url', 'path ink']), ('control layout', ['word  a a set', 7], ['word a', 'a set'])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    src, width = x
    chunks = ['']
    ops = []
    i = 0
    while i < len(src):
        c = src[i]
        if src.startswith('\\-', i):
            ops.append('d')
            chunks.append('')
            i += 2
            continue
        if c == ' ':
            j = i
            while j < len(src) and src[j] == ' ':
                j += 1
            ops.append('s')
            chunks.append('')
            i = j
            continue
        if c == '|':
            ops.append('z')
            chunks.append('')
            i += 1
            continue
        chunks[-1] += '' if c == '~' else c
        i += 1
    line = chunks[0]
    lines = []
    for op, ch in zip(ops, chunks[1:]):
        sep = ' ' if op == 's' else ''
        if len(line + sep + ch) <= width:
            line = line + sep + ch
        else:
            lines.append(line + ('-' if op == 'd' else ''))
            line = ch
    lines.append(line)
    return lines
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('regression: tie breakability', ['com\\-po\\-si\\-tion word word  ~url|path com\\-po\\-si\\-tion 10~pt', 14], ['composition', 'word word  url', 'path composi-', 'tion 10 pt']), ('regression: tie breakability', ['ink  x Dr.~Knuth ink ink set x word', 7], ['ink x', 'Dr. Knuth', 'ink ink', 'set x', 'word']), ('regression: tie breakability', ['url|path type type com\\-po\\-si\\-tion Dr.~Knuth', 5], ['url', 'path', 'type', 'type', 'compo-', 'si-', 'tion', 'Dr. Knuth']), ('double space collapses', ['type  set', 20], ['type set']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('control layout', ['word  a a set', 7], ['word a', 'a set']), ('control layout', ['url|path com\\-po\\-si\\-tion x a url|path  a', 14], ['urlpath compo-', 'sition x a url', 'path a'])], [('regression: tie breakability', ['com\\-po\\-si\\-tion ~x  com\\-po\\-si\\-tion', 13], ['composition', ' x composi-', 'tion']), ('regression: tie breakability', ['hy\\-phen ~type set ~com\\-po\\-si\\-tion set  type  com\\-po\\-si\\-tion word set', 15], ['hyphen  type', 'set  composi-', 'tion set type', 'composition', 'word set']), ('regression: tie breakability', ['ink 10~pt ink b|c hy\\-phen ~set url|path word', 16], ['ink 10 pt ink bc', 'hyphen  set url', 'path word']), ('regression: tie breakability', ['hy\\-phen ~10~pt b|c hy\\-phen ~x  com\\-po\\-si\\-tion', 5], ['hy-', 'phen', ' 10 pt', 'bc hy-', 'phen', ' x', 'compo-', 'si-', 'tion']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('control layout', ['b|c ink hy\\-phen url|path type com\\-po\\-si\\-tion', 8], ['bc ink', 'hyphen', 'urlpath', 'type com-', 'position']), ('control layout', ['b|c  a ink  ink com\\-po\\-si\\-tion', 11], ['bc a ink', 'ink composi-', 'tion'])], [('regression: tie breakability', ['x com\\-po\\-si\\-tion ink ~type', 14], ['x composition', 'ink  type']), ('regression: tie breakability', ['Dr.~Knuth  hy\\-phen  com\\-po\\-si\\-tion Dr.~Knuth word ink', 6], ['Dr. Knuth', 'hyphen', 'compo-', 'sition', 'Dr. Knuth', 'word', 'ink']), ('regression: tie breakability', ['hy\\-phen type ~word  hy\\-phen ~x', 14], ['hyphen type', ' word hyphen', ' x']), ('partial-repair probe', ['b|c url|path word  Dr.~Knuth', 9], ['bc url', 'path word', 'Dr. Knuth']), ('double space collapses', ['type  set', 20], ['type set']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['word com\\-po\\-si\\-tion a', 15], ['word composi-', 'tion a']), ('control layout', ['type set b|c', 6], ['type', 'set bc'])], [('regression: tie breakability', ['type a hy\\-phen com\\-po\\-si\\-tion ~set set ink  type', 8], ['type a', 'hyphen', 'composi-', 'tion', ' set set', 'ink type']), ('regression: tie breakability', ['ink ~10~pt type  com\\-po\\-si\\-tion url|path  a ~x 10~pt b|c', 9], ['ink', ' 10 pt', 'type com-', 'position', 'urlpath a', ' x 10 pt', 'bc']), ('partial-repair probe', ['ink com\\-po\\-si\\-tion Dr.~Knuth', 16], ['ink composition', 'Dr. Knuth']), ('regression: tie breakability', ['x set  type com\\-po\\-si\\-tion a ~ink b|c hy\\-phen url|path', 13], ['x set type', 'composition a', ' ink bc hy-', 'phen urlpath']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['a type  com\\-po\\-si\\-tion a', 6], ['a type', 'compo-', 'sition', 'a']), ('control layout', ['com\\-po\\-si\\-tion  hy\\-phen com\\-po\\-si\\-tion ink  b|c a', 10], ['composi-', 'tion hy-', 'phen compo-', 'sition ink', 'bc a'])], [('regression: tie breakability', ['Dr.~Knuth ink 10~pt  set x', 16], ['Dr. Knuth ink', '10 pt set x']), ('regression: tie breakability', ['hy\\-phen type ~x ~x hy\\-phen  10~pt  hy\\-phen 10~pt word', 14], ['hyphen type  x', ' x hyphen', '10 pt hyphen', '10 pt word']), ('partial-repair probe', ['url|path type  10~pt  word', 6], ['url', 'path', 'type', '10 pt', 'word']), ('regression: tie breakability', ['url|path type type com\\-po\\-si\\-tion Dr.~Knuth', 5], ['url', 'path', 'type', 'type', 'compo-', 'si-', 'tion', 'Dr. Knuth']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('control layout', ['com\\-po\\-si\\-tion type hy\\-phen hy\\-phen url|path ink', 13], ['composition', 'type hyphen', 'hyphen url', 'path ink']), ('control layout', ['word  a a set', 7], ['word a', 'a set'])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Lines break inside "Dr.~Knuth" style ties.

Input [source, width]. Runs of spaces are one breakable space; "~" is an unbreakable space rendered " "; "\-" is a discretionary hyphen: invisible unless the line breaks there, then rendered "-"; "|" is an invisible break opportunity. Greedy: append the next chunk if the line (without a potential hyphen) fits, else break at that opportunity. Return rendered lines.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    src, width = x
    chunks = ['']
    ops = []
    i = 0
    while i < len(src):
        c = src[i]
        if src.startswith('\\-', i):
            ops.append('d')
            chunks.append('')
            i += 2
            continue
        if c == ' ':
            j = i
            while j < len(src) and src[j] == ' ':
                j += 1
            ops.append('s')
            chunks.append('')
            i = j
            continue
        if c == '|':
            ops.append('z')
            chunks.append('')
            i += 1
            continue
        chunks[-1] += ' ' if c == '~' else c
        i += 1
    line = chunks[0]
    lines = []
    for op, ch in zip(ops, chunks[1:]):
        sep = ' ' if op == 's' else ('-' if op == 'd' else '')
        if len(line + sep + ch) <= width:
            line = line + sep + ch
        else:
            lines.append(line + ('-' if op == 'd' else ''))
            line = ch
    lines.append(line)
    return lines
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('regression: unbroken discretionary rendering', ['ink a a ~hy\\-phen  x com\\-po\\-si\\-tion x', 6], ['ink a', 'a  hy-', 'phen x', 'compo-', 'sition', 'x']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth  url|path a Dr.~Knuth b|c b|c com\\-po\\-si\\-tion', 15], ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'composition']), ('regression: unbroken discretionary rendering', ['b|c  set  type set Dr.~Knuth com\\-po\\-si\\-tion Dr.~Knuth  x', 15], ['bc set type set', 'Dr. Knuth compo-', 'sition', 'Dr. Knuth x']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('double space collapses', ['type  set', 20], ['type set']), ('control layout', ['word  10~pt 10~pt 10~pt url|path ink', 13], ['word 10 pt', '10 pt 10 pt', 'urlpath ink']), ('control layout', ['type  set Dr.~Knuth word word b|c', 12], ['type set', 'Dr. Knuth', 'word word bc'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~com\\-po\\-si\\-tion  hy\\-phen x  url|path ~a a  com\\-po\\-si\\-tion', 15], ['composition', ' composition hy-', 'phen x urlpath', ' a a composi-', 'tion']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion b|c b|c x x word x', 15], ['composition bc', 'bc x x word x']), ('regression: unbroken discretionary rendering', ['word url|path ~hy\\-phen set a', 14], ['word urlpath', ' hyphen set a']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~ink word url|path x set', 10], ['composi-', 'tion  ink', 'word url', 'path x set']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['b|c b|c  type ~hy\\-phen Dr.~Knuth ~ink x a', 15], ['bc bc type  hy-', 'phen Dr. Knuth', ' ink x a']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth  bc'])], [('regression: unbroken discretionary rendering', ['hy\\-phen  ~a 10~pt  type  type url|path 10~pt  type', 9], ['hyphen  a', '10 pt', 'type type', 'urlpath', '10 pt', 'type']), ('regression: unbroken discretionary rendering', ['ink x hy\\-phen ~x set  type', 12], ['ink x hyphen', ' x set type']), ('regression: unbroken discretionary rendering', ['type 10~pt com\\-po\\-si\\-tion com\\-po\\-si\\-tion type type', 12], ['type 10 pt', 'composition', 'composition', 'type type']), ('regression: unbroken discretionary rendering', ['type x url|path 10~pt hy\\-phen', 14], ['type x urlpath', '10 pt hyphen']), ('double space collapses', ['type  set', 20], ['type set']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth  bc']), ('control layout', ['a x set', 16], ['a x set'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion  x x hy\\-phen  Dr.~Knuth Dr.~Knuth com\\-po\\-si\\-tion type  set', 14], ['composition x', 'x hyphen', 'Dr. Knuth', 'Dr. Knuth com-', 'position type', 'set']), ('regression: unbroken discretionary rendering', ['a set word  hy\\-phen  hy\\-phen word url|path', 15], ['a set word hy-', 'phen hyphen', 'word urlpath']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth  hy\\-phen word  10~pt Dr.~Knuth  word', 11], ['Dr. Knuth', 'hyphen word', '10 pt', 'Dr. Knuth', 'word']), ('regression: unbroken discretionary rendering', ['hy\\-phen ink Dr.~Knuth com\\-po\\-si\\-tion hy\\-phen', 9], ['hyphen', 'ink', 'Dr. Knuth', 'composi-', 'tion hy-', 'phen']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('control layout', ['a  b|c set', 11], ['a bc set']), ('control layout', ['a ink x 10~pt  b|c a', 16], ['a ink x 10 pt bc', 'a'])], [('regression: unbroken discretionary rendering', ['url|path x  ~hy\\-phen word com\\-po\\-si\\-tion com\\-po\\-si\\-tion x', 14], ['urlpath x  hy-', 'phen word com-', 'position compo-', 'sition x']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion  ink ~Dr.~Knuth url|path  url|path  ink b|c  word  10~pt', 5], ['compo-', 'si-', 'tion', 'ink', ' Dr. Knuth', 'url', 'path', 'url', 'path', 'ink b', 'c', 'word', '10 pt']), ('regression: unbroken discretionary rendering', ['ink  hy\\-phen  ~10~pt  url|path word ink  url|path  ~type b|c', 15], ['ink hyphen', ' 10 pt urlpath', 'word ink url', 'path  type bc']), ('regression: unbroken discretionary rendering', ['b|c Dr.~Knuth a hy\\-phen a type ~a Dr.~Knuth', 8], ['bc', 'Dr. Knuth', 'a hyphen', 'a type', ' a', 'Dr. Knuth']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth  bc']), ('control layout', ['Dr.~Knuth ~a url|path', 11], ['Dr. Knuth', ' a urlpath'])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    src, width = x
    chunks = ['']
    ops = []
    i = 0
    while i < len(src):
        c = src[i]
        if src.startswith('\\-', i):
            ops.append('d')
            chunks.append('')
            i += 2
            continue
        if c == ' ':
            j = i
            while j < len(src) and src[j] == ' ':
                j += 1
            ops.append('s')
            chunks.append('')
            i = j
            continue
        if c == '|':
            ops.append('z')
            chunks.append('')
            i += 1
            continue
        chunks[-1] += ' ' if c == '~' else c
        i += 1
    line = chunks[0]
    lines = []
    for op, ch in zip(ops, chunks[1:]):
        sep = ' ' if op != 'z' else ''
        if len(line + sep + ch) <= width:
            line = line + sep + ch
        else:
            lines.append(line + ('-' if op == 'd' else ''))
            line = ch
    lines.append(line)
    return lines
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('regression: unbroken discretionary rendering', ['ink a a ~hy\\-phen  x com\\-po\\-si\\-tion x', 6], ['ink a', 'a  hy-', 'phen x', 'compo-', 'sition', 'x']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth  url|path a Dr.~Knuth b|c b|c com\\-po\\-si\\-tion', 15], ['Dr. Knuth url', 'path a', 'Dr. Knuth bc bc', 'composition']), ('regression: unbroken discretionary rendering', ['b|c  set  type set Dr.~Knuth com\\-po\\-si\\-tion Dr.~Knuth  x', 15], ['bc set type set', 'Dr. Knuth compo-', 'sition', 'Dr. Knuth x']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('double space collapses', ['type  set', 20], ['type set']), ('control layout', ['word  10~pt 10~pt 10~pt url|path ink', 13], ['word 10 pt', '10 pt 10 pt', 'urlpath ink']), ('control layout', ['type  set Dr.~Knuth word word b|c', 12], ['type set', 'Dr. Knuth', 'word word bc'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~com\\-po\\-si\\-tion  hy\\-phen x  url|path ~a a  com\\-po\\-si\\-tion', 15], ['composition', ' composition hy-', 'phen x urlpath', ' a a composi-', 'tion']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion b|c b|c x x word x', 15], ['composition bc', 'bc x x word x']), ('regression: unbroken discretionary rendering', ['word url|path ~hy\\-phen set a', 14], ['word urlpath', ' hyphen set a']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion ~ink word url|path x set', 10], ['composi-', 'tion  ink', 'word url', 'path x set']), ('invisible break', ['url|path|x', 5], ['url', 'pathx']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['b|c b|c  type ~hy\\-phen Dr.~Knuth ~ink x a', 15], ['bc bc type  hy-', 'phen Dr. Knuth', ' ink x a']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth  bc'])], [('regression: unbroken discretionary rendering', ['hy\\-phen  ~a 10~pt  type  type url|path 10~pt  type', 9], ['hyphen  a', '10 pt', 'type type', 'urlpath', '10 pt', 'type']), ('regression: unbroken discretionary rendering', ['ink x hy\\-phen ~x set  type', 12], ['ink x hyphen', ' x set type']), ('regression: unbroken discretionary rendering', ['type 10~pt com\\-po\\-si\\-tion com\\-po\\-si\\-tion type type', 12], ['type 10 pt', 'composition', 'composition', 'type type']), ('regression: unbroken discretionary rendering', ['type x url|path 10~pt hy\\-phen', 14], ['type x urlpath', '10 pt hyphen']), ('double space collapses', ['type  set', 20], ['type set']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth  bc']), ('control layout', ['a x set', 16], ['a x set'])], [('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion  x x hy\\-phen  Dr.~Knuth Dr.~Knuth com\\-po\\-si\\-tion type  set', 14], ['composition x', 'x hyphen', 'Dr. Knuth', 'Dr. Knuth com-', 'position type', 'set']), ('regression: unbroken discretionary rendering', ['a set word  hy\\-phen  hy\\-phen word url|path', 15], ['a set word hy-', 'phen hyphen', 'word urlpath']), ('regression: unbroken discretionary rendering', ['Dr.~Knuth  hy\\-phen word  10~pt Dr.~Knuth  word', 11], ['Dr. Knuth', 'hyphen word', '10 pt', 'Dr. Knuth', 'word']), ('regression: unbroken discretionary rendering', ['hy\\-phen ink Dr.~Knuth com\\-po\\-si\\-tion hy\\-phen', 9], ['hyphen', 'ink', 'Dr. Knuth', 'composi-', 'tion hy-', 'phen']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('control layout', ['a  b|c set', 11], ['a bc set']), ('control layout', ['a ink x 10~pt  b|c a', 16], ['a ink x 10 pt bc', 'a'])], [('regression: unbroken discretionary rendering', ['url|path x  ~hy\\-phen word com\\-po\\-si\\-tion com\\-po\\-si\\-tion x', 14], ['urlpath x  hy-', 'phen word com-', 'position compo-', 'sition x']), ('regression: unbroken discretionary rendering', ['com\\-po\\-si\\-tion  ink ~Dr.~Knuth url|path  url|path  ink b|c  word  10~pt', 5], ['compo-', 'si-', 'tion', 'ink', ' Dr. Knuth', 'url', 'path', 'url', 'path', 'ink b', 'c', 'word', '10 pt']), ('regression: unbroken discretionary rendering', ['ink  hy\\-phen  ~10~pt  url|path word ink  url|path  ~type b|c', 15], ['ink hyphen', ' 10 pt urlpath', 'word ink url', 'path  type bc']), ('regression: unbroken discretionary rendering', ['b|c Dr.~Knuth a hy\\-phen a type ~a Dr.~Knuth', 8], ['bc', 'Dr. Knuth', 'a hyphen', 'a type', ' a', 'Dr. Knuth']), ('discretionary taken', ['the com\\-po\\-si\\-tion', 9], ['the compo-', 'sition']), ('tie keeps title with name', ['see Dr.~Knuth now', 9], ['see', 'Dr. Knuth', 'now']), ('control layout', ['Dr.~Knuth ~Dr.~Knuth ~b|c', 15], ['Dr. Knuth', ' Dr. Knuth  bc']), ('control layout', ['Dr.~Knuth ~a url|path', 11], ['Dr. Knuth', ' a urlpath'])]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Hyphens show inside words that were not broken.

Input [source, width]. Runs of spaces are one breakable space; "~" is an unbreakable space rendered " "; "\-" is a discretionary hyphen: invisible unless the line breaks there, then rendered "-"; "|" is an invisible break opportunity. Greedy: append the next chunk if the line (without a potential hyphen) fits, else break at that opportunity. Return rendered lines.

split: open-access