{
  "id": "P124",
  "slug": "pascals-triangle",
  "key": "P124-pascals-triangle",
  "title": "Pascal's triangle",
  "summary": "Rows built from the one above by addition, every entry exact however long, checked by symmetry, the sum 2^n, the hockey stick and the count of odd entries; and the float formula's first mistake, in row 55.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P124 - Pascal's triangle\n\nEach row built from the one above by addition, so every entry is exact\nhowever many digits it has.\n\n- `main.eml` - the menu, the triangle, one row with its checks, one entry\n  beside the float formula, the float formula's first mistake, and the\n  odd entries\n- `triangle.eml` - the rows, powers of two, the 1s of a number in binary,\n  the checks, and the float formula\n\nHow each part works:\n\n- As in the corpus cases `pascals-triangle` and `pascal-row-exact`, a row\n  is the row above with neighbours added: no division, so nothing to\n  round. C(80, 40) has 24 digits, C(300, 150) has 89.\n- The checks on a row tie it to things worked out another way:\n  - it is symmetric, C(n, k) = C(n, n - k);\n  - its entries add up to 2^n exactly;\n  - the hockey stick, C(k, k) + ... + C(n, k) = C(n + 1, k + 1), ties it\n    to the next row;\n  - it has 2^(the number of 1s in n in binary) odd entries.\n- The multiplicative formula in floats, C(n, k) = C(n, k - 1) * (n - k +\n  1) / k, is exact up to row 54. In row 55 it gives C(55, 26) as\n  3560597348629859.5 instead of 3560597348629860. That entry is below\n  2^53, but the product before the division is not.\n- The odd entries of rows 0 to 31 make Sierpinski's triangle.\n\nWhat is checked: menu choices 1 to 6; a last row from 0 to 15; a row or\nan n from 0 to 300, and a k from 0 to n. An empty answer cancels.\n\nSessions: `sessions/basic.in` gives:\n- the triangle to row 8;\n- rows 10 and 80, with their checks;\n- C(55, 26), where the float formula is wrong, and C(300, 150);\n- the floats, and the odd entries.\n\n`sessions/bad-input.in` gives:\n- menu choices 0 and x;\n- last rows: a cancel, 16, x and -1;\n- rows 301 and 1000;\n- entries: n 5 with k 6 and a cancel, and C(0, 0).\n\nBuilt on the verified corpus cases `pascals-triangle` (each row grown from\nthe one before) and `pascal-row-exact` (a row far past float precision,\nchecked against global properties).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P124 Pascal's triangle: the triangle, one row exactly, one entry, the\n# checks on a row, the float formula's first mistake, and the odd entries.\nimport triangle\n\ndef plain(s):\n    0 => i\n    len(s) => j\n    while i < j and s[i] == \" \":\n        i + 1 => i\n    while j > i and s[j - 1] == \" \":\n        j - 1 => j\n    return s[i:j]\n\ndef lpad(s, n):\n    s => out\n    while len(out) < n:\n        \" \" + out => out\n    return out\n\ndef spaces(n):\n    \"\" => out\n    for i in [1:n]:\n        out + \" \" => out\n    return out\n\ndef ask_number(prompt, high):\n    plain(input(prompt)) => t\n    if t == \"\":\n        \"Cancelled.\" ^0\n        return 0 - 1\n    if len(t) > 3:\n        (\"Type a whole number from 0 to \" + str(high) + \".\") ^0\n        return 0 - 1\n    for c in t:\n        if c < \"0\" or c > \"9\":\n            (\"Type a whole number from 0 to \" + str(high) + \".\") ^0\n            return 0 - 1\n    if int(t) > high:\n        (\"Type a whole number from 0 to \" + str(high) + \".\") ^0\n        return 0 - 1\n    return int(t)\n\ndef row_text(r):\n    \"\" => out\n    for x in r:\n        if out != \"\":\n            out + \" \" => out\n        out + str(x) => out\n    return out\n\ndef show_triangle():\n    ask_number(\"last row (0 to 15)> \", 15) => n\n    if n < 0:\n        return\n    triangle.rows(n) => rs\n    len(row_text(rs[n])) => w\n    for r in rs:\n        row_text(r) => t\n        (spaces(int((w - len(t)) / 2)) + t) ^0\n\ndef one_row():\n    ask_number(\"row (0 to 300)> \", 300) => n\n    if n < 0:\n        return\n    triangle.row(n) => r\n    if n <= 20:\n        (\"Row \" + str(n) + \": \" + row_text(r)) ^0\n    else:\n        int(n / 2) => m\n        (\"Row \" + str(n) + \" has \" + str(n + 1) + \" entries; it starts \" + str(r[0]) + \", \" + str(r[1]) + \", \" + str(r[2]) + \".\") ^0\n        (\"The middle one, C(\" + str(n) + \", \" + str(m) + \"), has \" + str(triangle.digits(r[m])) + \" digits:\") ^0\n        (\"  \" + str(r[m])) ^0\n    report(n)\n\ndef report(n):\n    triangle.checks(n) => c\n    if c[0]:\n        \"  symmetric: C(n, k) = C(n, n - k) for every k\" ^0\n    else:\n        \"  NOT symmetric\" ^0\n    if c[1]:\n        (\"  the entries add up to 2^\" + str(n) + \" exactly\") ^0\n    else:\n        (\"  the entries do NOT add up to 2^\" + str(n)) ^0\n    if c[2]:\n        (\"  hockey stick: C(k, k) + C(k + 1, k) + ... + C(\" + str(n) + \", k) = C(\" + str(n + 1) + \", k + 1) for every k\") ^0\n    else:\n        \"  the hockey stick does NOT hold\" ^0\n    (\"  \" + str(c[3]) + \" odd entries; \" + str(n) + \" in binary has \" + str(triangle.ones(n)) + \" ones, and 2^\" + str(triangle.ones(n)) + \" = \" + str(c[4])) ^0\n\ndef entry():\n    ask_number(\"n (0 to 300)> \", 300) => n\n    if n < 0:\n        return\n    ask_number(\"k (0 to \" + str(n) + \")> \", n) => k\n    if k < 0:\n        return\n    triangle.row(n)[k] => x\n    if triangle.digits(x) == 1:\n        (\"C(\" + str(n) + \", \" + str(k) + \") = \" + str(x)) ^0\n    else:\n        (\"C(\" + str(n) + \", \" + str(k) + \") = \" + str(x) + \" (\" + str(triangle.digits(x)) + \" digits)\") ^0\n    triangle.float_entry(n, k) => f\n    if f == x:\n        (\"  The float formula gets it exactly: \" + str(f)) ^0\n    else:\n        (\"  The float formula gives \" + str(f) + \".\") ^0\n\ndef floats():\n    triangle.first_float_miss(200) => m\n    \"The multiplicative formula in floats: C(n, k) = C(n, k - 1) * (n - k + 1) / k.\" ^0\n    (\"It is exact up to row \" + str(m[0] - 1) + \", and first goes wrong in row \" + str(m[0]) + \":\") ^0\n    (\"  C(\" + str(m[0]) + \", \" + str(m[1]) + \") comes out \" + str(m[2]) + \", and is \" + str(m[3]) + \".\") ^0\n    (\"  That entry is below 2^53 = \" + str(triangle.power_of_two(53)) + \", but the product before the division,\") ^0\n    (\"  \" + str(m[4]) + \", is not.\") ^0\n    \"Building each row from the one above by addition needs no division, and is exact.\" ^0\n\ndef odd_pattern():\n    \"Rows 0 to 31, # for an odd entry:\" ^0\n    triangle.rows(31) => rs\n    for r in rs:\n        \"\" => t\n        for x in r:\n            if t != \"\":\n                t + \" \" => t\n            if x % 2 == 1:\n                t + \"#\" => t\n            else:\n                t + \".\" => t\n        (spaces(31 - len(r) + 1) + t) ^0\n\n\"== Pascal's triangle ==\" ^0\n\"Each row built from the one above by addition, every entry exact however long.\" ^0\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\" ^0\n    plain(input(\"choice> \")) => choice\n    if choice == \"1\":\n        show_triangle()\n    elif choice == \"2\":\n        one_row()\n    elif choice == \"3\":\n        entry()\n    elif choice == \"4\":\n        floats()\n    elif choice == \"5\":\n        odd_pattern()\n    elif choice == \"6\":\n        False => running\n    else:\n        \"Pick a number from 1 to 6.\" ^0\n\"Bye.\" ^0\n",
      "python": "import triangle\n\ndef plain(s):\n    i = 0\n    j = len(s)\n    while i < j and s[i] == \" \":\n        i = i + 1\n    while j > i and s[j - 1] == \" \":\n        j = j - 1\n    return s[i:j]\n\ndef lpad(s, n):\n    out = s\n    while len(out) < n:\n        out = \" \" + out\n    return out\n\ndef spaces(n):\n    out = \"\"\n    for i in range(1, n+1):\n        out = out + \" \"\n    return out\n\ndef ask_number(prompt, high):\n    t = plain(input(prompt))\n    if t == \"\":\n        print(\"Cancelled.\")\n        return 0 - 1\n    if len(t) > 3:\n        print(\"Type a whole number from 0 to \" + str(high) + \".\")\n        return 0 - 1\n    for c in t:\n        if c < \"0\" or c > \"9\":\n            print(\"Type a whole number from 0 to \" + str(high) + \".\")\n            return 0 - 1\n    if int(t) > high:\n        print(\"Type a whole number from 0 to \" + str(high) + \".\")\n        return 0 - 1\n    return int(t)\n\ndef row_text(r):\n    out = \"\"\n    for x in r:\n        if out != \"\":\n            out = out + \" \"\n        out = out + str(x)\n    return out\n\ndef show_triangle():\n    n = ask_number(\"last row (0 to 15)> \", 15)\n    if n < 0:\n        return\n    rs = triangle.rows(n)\n    w = len(row_text(rs[n]))\n    for r in rs:\n        t = row_text(r)\n        print(spaces(int((w - len(t)) / 2)) + t)\n\ndef one_row():\n    n = ask_number(\"row (0 to 300)> \", 300)\n    if n < 0:\n        return\n    r = triangle.row(n)\n    if n <= 20:\n        print(\"Row \" + str(n) + \": \" + row_text(r))\n    else:\n        m = int(n / 2)\n        print(\"Row \" + str(n) + \" has \" + str(n + 1) + \" entries; it starts \" + str(r[0]) + \", \" + str(r[1]) + \", \" + str(r[2]) + \".\")\n        print(\"The middle one, C(\" + str(n) + \", \" + str(m) + \"), has \" + str(triangle.digits(r[m])) + \" digits:\")\n        print(\"  \" + str(r[m]))\n    report(n)\n\ndef report(n):\n    c = triangle.checks(n)\n    if c[0]:\n        print(\"  symmetric: C(n, k) = C(n, n - k) for every k\")\n    else:\n        print(\"  NOT symmetric\")\n    if c[1]:\n        print(\"  the entries add up to 2^\" + str(n) + \" exactly\")\n    else:\n        print(\"  the entries do NOT add up to 2^\" + str(n))\n    if c[2]:\n        print(\"  hockey stick: C(k, k) + C(k + 1, k) + ... + C(\" + str(n) + \", k) = C(\" + str(n + 1) + \", k + 1) for every k\")\n    else:\n        print(\"  the hockey stick does NOT hold\")\n    print(\"  \" + str(c[3]) + \" odd entries; \" + str(n) + \" in binary has \" + str(triangle.ones(n)) + \" ones, and 2^\" + str(triangle.ones(n)) + \" = \" + str(c[4]))\n\ndef entry():\n    n = ask_number(\"n (0 to 300)> \", 300)\n    if n < 0:\n        return\n    k = ask_number(\"k (0 to \" + str(n) + \")> \", n)\n    if k < 0:\n        return\n    x = triangle.row(n)[k]\n    if triangle.digits(x) == 1:\n        print(\"C(\" + str(n) + \", \" + str(k) + \") = \" + str(x))\n    else:\n        print(\"C(\" + str(n) + \", \" + str(k) + \") = \" + str(x) + \" (\" + str(triangle.digits(x)) + \" digits)\")\n    f = triangle.float_entry(n, k)\n    if f == x:\n        print(\"  The float formula gets it exactly: \" + str(f))\n    else:\n        print(\"  The float formula gives \" + str(f) + \".\")\n\ndef floats():\n    m = triangle.first_float_miss(200)\n    print(\"The multiplicative formula in floats: C(n, k) = C(n, k - 1) * (n - k + 1) / k.\")\n    print(\"It is exact up to row \" + str(m[0] - 1) + \", and first goes wrong in row \" + str(m[0]) + \":\")\n    print(\"  C(\" + str(m[0]) + \", \" + str(m[1]) + \") comes out \" + str(m[2]) + \", and is \" + str(m[3]) + \".\")\n    print(\"  That entry is below 2^53 = \" + str(triangle.power_of_two(53)) + \", but the product before the division,\")\n    print(\"  \" + str(m[4]) + \", is not.\")\n    print(\"Building each row from the one above by addition needs no division, and is exact.\")\n\ndef odd_pattern():\n    print(\"Rows 0 to 31, # for an odd entry:\")\n    rs = triangle.rows(31)\n    for r in rs:\n        t = \"\"\n        for x in r:\n            if t != \"\":\n                t = t + \" \"\n            if x % 2 == 1:\n                t = t + \"#\"\n            else:\n                t = t + \".\"\n        print(spaces(31 - len(r) + 1) + t)\n\nprint(\"== Pascal's triangle ==\")\nprint(\"Each row built from the one above by addition, every entry exact however long.\")\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\")\n    choice = plain(input(\"choice> \"))\n    if choice == \"1\":\n        show_triangle()\n    elif choice == \"2\":\n        one_row()\n    elif choice == \"3\":\n        entry()\n    elif choice == \"4\":\n        floats()\n    elif choice == \"5\":\n        odd_pattern()\n    elif choice == \"6\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 6.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "triangle.eml",
      "eml": "# P124 Pascal's triangle - every row built from the one above by addition,\n# so every entry is exact however many digits it has (the corpus cases\n# pascals-triangle and pascal-row-exact). The checks tie a row to things\n# computed another way: its mirror, its sum 2^n, the hockey stick to the\n# next row, and the count of its odd entries. The multiplicative formula\n# in floats is the comparison that goes wrong.\n\ndef next_row(row):\n    [1] => out\n    for k in [1:len(row) - 1]:\n        out + [row[k - 1] + row[k]] => out\n    return out + [1]\n\ndef row(n):\n    [1] => r\n    for i in [1:n]:\n        next_row(r) => r\n    return r\n\ndef rows(n):\n    # rows 0 to n\n    [[1]] => out\n    [1] => r\n    for i in [1:n]:\n        next_row(r) => r\n        out + [r] => out\n    return out\n\ndef power_of_two(n):\n    1 => p\n    for i in [1:n]:\n        p + p => p\n    return p\n\ndef ones(n):\n    # the 1 bits of n\n    0 => c\n    n => m\n    while m > 0:\n        if m % 2 == 1:\n            c + 1 => c\n            m - 1 => m\n        int(m / 2) => m\n    return c\n\ndef checks(n):\n    # [symmetric, sum is 2^n, hockey stick holds for every k, odd entries,\n    #  2^(1 bits of n)]\n    rows(n + 1) => rs\n    rs[n] => r\n    True => sym\n    0 => total\n    0 => odd\n    for k in [0:n]:\n        if r[k] != r[n - k]:\n            False => sym\n        total + r[k] => total\n        if r[k] % 2 == 1:\n            odd + 1 => odd\n    True => stick\n    for k in [0:n]:\n        0 => s\n        for i in [k:n]:\n            s + rs[i][k] => s\n        if s != rs[n + 1][k + 1]:\n            False => stick\n    return [sym, total == power_of_two(n), stick, odd, power_of_two(ones(n))]\n\ndef float_entry(n, k):\n    # C(n, k) by the multiplicative formula, in floats\n    1.0 => c\n    for i in [1:k]:\n        c * (n - i + 1) / i => c\n    return c\n\ndef first_float_miss(limit):\n    # [n, k, the float, the exact entry, the product before the division]\n    # for the first entry the float formula gets wrong, rows 0 to limit\n    [1] => r\n    for n in [0:limit]:\n        if n > 0:\n            next_row(r) => r\n        1.0 => c\n        for k in [0:n]:\n            if k > 0:\n                c * (n - k + 1) / k => c\n            if c != r[k]:\n                return [n, k, c, r[k], r[k - 1] * (n - k + 1)]\n    return []\n\ndef digits(x):\n    return len(str(x))\n",
      "python": "def next_row(row):\n    out = [1]\n    for k in range(1, len(row)):\n        out = out + [row[k - 1] + row[k]]\n    return out + [1]\n\ndef row(n):\n    r = [1]\n    for i in range(1, n+1):\n        r = next_row(r)\n    return r\n\ndef rows(n):\n    out = [[1]]\n    r = [1]\n    for i in range(1, n+1):\n        r = next_row(r)\n        out = out + [r]\n    return out\n\ndef power_of_two(n):\n    p = 1\n    for i in range(1, n+1):\n        p = p + p\n    return p\n\ndef ones(n):\n    c = 0\n    m = n\n    while m > 0:\n        if m % 2 == 1:\n            c = c + 1\n            m = m - 1\n        m = int(m / 2)\n    return c\n\ndef checks(n):\n    rs = rows(n + 1)\n    r = rs[n]\n    sym = True\n    total = 0\n    odd = 0\n    for k in range(0, n+1):\n        if r[k] != r[n - k]:\n            sym = False\n        total = total + r[k]\n        if r[k] % 2 == 1:\n            odd = odd + 1\n    stick = True\n    for k in range(0, n+1):\n        s = 0\n        for i in range(k, n+1):\n            s = s + rs[i][k]\n        if s != rs[n + 1][k + 1]:\n            stick = False\n    return [sym, total == power_of_two(n), stick, odd, power_of_two(ones(n))]\n\ndef float_entry(n, k):\n    c = 1.0\n    for i in range(1, k+1):\n        c = c * (n - i + 1) / i\n    return c\n\ndef first_float_miss(limit):\n    r = [1]\n    for n in range(0, limit+1):\n        if n > 0:\n            r = next_row(r)\n        c = 1.0\n        for k in range(0, n+1):\n            if k > 0:\n                c = c * (n - k + 1) / k\n            if c != r[k]:\n                return [n, k, c, r[k], r[k - 1] * (n - k + 1)]\n    return []\n\ndef digits(x):\n    return len(str(x))\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n1\n\n1\n16\n1\nx\n1\n-1\n2\n301\n2\n1000\n3\n5\n6\n3\n5\n\n3\n0\n0\n6\n",
      "screen": "== Pascal's triangle ==\nEach row built from the one above by addition, every entry exact however long.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 0\nPick a number from 1 to 6.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> x\nPick a number from 1 to 6.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 1\nlast row (0 to 15)> \nCancelled.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 1\nlast row (0 to 15)> 16\nType a whole number from 0 to 15.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 1\nlast row (0 to 15)> x\nType a whole number from 0 to 15.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 1\nlast row (0 to 15)> -1\nType a whole number from 0 to 15.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 2\nrow (0 to 300)> 301\nType a whole number from 0 to 300.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 2\nrow (0 to 300)> 1000\nType a whole number from 0 to 300.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 3\nn (0 to 300)> 5\nk (0 to 5)> 6\nType a whole number from 0 to 5.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 3\nn (0 to 300)> 5\nk (0 to 5)> \nCancelled.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 3\nn (0 to 300)> 0\nk (0 to 0)> 0\nC(0, 0) = 1\n  The float formula gets it exactly: 1.0\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\n8\n2\n10\n2\n80\n3\n55\n26\n3\n300\n150\n4\n5\n6\n",
      "screen": "== Pascal's triangle ==\nEach row built from the one above by addition, every entry exact however long.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 1\nlast row (0 to 15)> 8\n          1\n         1 1\n        1 2 1\n       1 3 3 1\n      1 4 6 4 1\n    1 5 10 10 5 1\n   1 6 15 20 15 6 1\n 1 7 21 35 35 21 7 1\n1 8 28 56 70 56 28 8 1\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 2\nrow (0 to 300)> 10\nRow 10: 1 10 45 120 210 252 210 120 45 10 1\n  symmetric: C(n, k) = C(n, n - k) for every k\n  the entries add up to 2^10 exactly\n  hockey stick: C(k, k) + C(k + 1, k) + ... + C(10, k) = C(11, k + 1) for every k\n  4 odd entries; 10 in binary has 2 ones, and 2^2 = 4\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 2\nrow (0 to 300)> 80\nRow 80 has 81 entries; it starts 1, 80, 3160.\nThe middle one, C(80, 40), has 24 digits:\n  107507208733336176461620\n  symmetric: C(n, k) = C(n, n - k) for every k\n  the entries add up to 2^80 exactly\n  hockey stick: C(k, k) + C(k + 1, k) + ... + C(80, k) = C(81, k + 1) for every k\n  4 odd entries; 80 in binary has 2 ones, and 2^2 = 4\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 3\nn (0 to 300)> 55\nk (0 to 55)> 26\nC(55, 26) = 3560597348629860 (16 digits)\n  The float formula gives 3560597348629859.5.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 3\nn (0 to 300)> 300\nk (0 to 300)> 150\nC(300, 150) = 93759702772827452793193754439064084879232655700081358920472352712975170021839591675861424 (89 digits)\n  The float formula gives 9.375970277282747e+88.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 4\nThe multiplicative formula in floats: C(n, k) = C(n, k - 1) * (n - k + 1) / k.\nIt is exact up to row 54, and first goes wrong in row 55:\n  C(55, 26) comes out 3560597348629859.5, and is 3560597348629860.\n  That entry is below 2^53 = 9007199254740992, but the product before the division,\n  92575531064376360, is not.\nBuilding each row from the one above by addition needs no division, and is exact.\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 5\nRows 0 to 31, # for an odd entry:\n                               #\n                              # #\n                             # . #\n                            # # # #\n                           # . . . #\n                          # # . . # #\n                         # . # . # . #\n                        # # # # # # # #\n                       # . . . . . . . #\n                      # # . . . . . . # #\n                     # . # . . . . . # . #\n                    # # # # . . . . # # # #\n                   # . . . # . . . # . . . #\n                  # # . . # # . . # # . . # #\n                 # . # . # . # . # . # . # . #\n                # # # # # # # # # # # # # # # #\n               # . . . . . . . . . . . . . . . #\n              # # . . . . . . . . . . . . . . # #\n             # . # . . . . . . . . . . . . . # . #\n            # # # # . . . . . . . . . . . . # # # #\n           # . . . # . . . . . . . . . . . # . . . #\n          # # . . # # . . . . . . . . . . # # . . # #\n         # . # . # . # . . . . . . . . . # . # . # . #\n        # # # # # # # # . . . . . . . . # # # # # # # #\n       # . . . . . . . # . . . . . . . # . . . . . . . #\n      # # . . . . . . # # . . . . . . # # . . . . . . # #\n     # . # . . . . . # . # . . . . . # . # . . . . . # . #\n    # # # # . . . . # # # # . . . . # # # # . . . . # # # #\n   # . . . # . . . # . . . # . . . # . . . # . . . # . . . #\n  # # . . # # . . # # . . # # . . # # . . # # . . # # . . # #\n # . # . # . # . # . # . # . # . # . # . # . # . # . # . # . #\n# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #\n\n1) triangle  2) one row  3) one entry  4) floats  5) odd entries  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "pascals-triangle",
      "caseId": "057-pascals-triangle",
      "title": "Pascal's triangle"
    },
    {
      "slug": "pascal-row-exact",
      "caseId": "193-pascal-row-exact",
      "title": "Row 80 of Pascal’s triangle, exactly"
    }
  ],
  "updated": "2026-10-17"
}
