{
  "id": "P069",
  "slug": "sequence-explorer",
  "key": "P069-sequence-explorer",
  "title": "Sequence explorer",
  "summary": "Collatz paths from starts up to a trillion, worked in exact whole numbers, and the start below a limit with the longest path; exact Fibonacci numbers with Cassini's identity checked and the ratio closing in on the golden ratio; and Pascal's triangle, as numbers and as the pattern its odd entries make.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P069 - Sequence explorer\n\nThree famous sequences, in whole numbers of any size. The Collatz path of a\nstart up to 10^12, and the start below a limit whose path is longest.\nFibonacci numbers up to F(2000), each checked with Cassini's identity. And\nPascal's triangle, either as numbers or as the pattern its odd numbers\nmake.\n\n- `main.eml` - the menu, reading numbers, and laying out the output\n- `sequences.eml` - exact halving, Collatz paths and step counts,\n  Fibonacci numbers, Cassini's identity and Pascal's rows\n\nHow each part works:\n\n- Collatz: as in the corpus case `collatz-sequence`, halve an even number\n  and take 3n + 1 for an odd one until 1 is reached. The corpus case halves\n  with int(n / 2), which goes through a float and is exact only below\n  2^53. A path from a start below 10^12 can climb past that:\n  1,410,123,943 climbs to 7,125,885,122,794,452,160 on its 770 steps. So\n  the halving here is exact long division.\n- Longest path: the step counts for every start up to the limit, each\n  using the ones before it. A path is followed only until it drops below\n  its start, and the count already known for that number is added. The\n  first start with the most steps is reported: 6171, with 261, up to 10,000.\n- Fibonacci: each number the sum of the two before, in whole numbers, so\n  F(1000) has all 209 of its digits. Cassini's identity\n  F(n-1) x F(n+1) - F(n)^2 = (-1)^n is checked every time. As the corpus\n  case `fibonacci-cassini-exact` shows, those two products are huge and\n  differ by exactly 1, a check that floats cannot pass. F(n+1) / F(n) is\n  shown to 12 places by long division, closing in on the golden ratio.\n- Pascal: each number the sum of the two above it, built row by row as in\n  the corpus case `pascals-triangle`, and centred. Marking only the odd\n  ones, with 16 or 32 rows, draws Sierpinski's triangle.\n\nWhat is checked: menu choices 1 to 6; a Collatz start from 1 to\n1,000,000,000,000; a limit from 2 to 100,000 for the longest path; n from\n1 to 2000 for Fibonacci; 1 to 15 rows of numbers, or 1 to 32 rows of the\nodd pattern. An empty answer cancels. A path of more than 40 numbers shows\nits first 20 and last 10; a Fibonacci number over 60 digits shows its\nfirst and last 25.\n\nSessions: `sessions/basic.in` gives:\n- the paths of 27 (111 steps, up to 9232) and 1,410,123,943;\n- the longest path up to 10,000, and the step counts of the starts 1 to 20;\n- F(10) and F(1000), with Cassini's identity and the ratio to the next;\n- 7 rows of Pascal's triangle, and 16 rows of its odd numbers.\n\n`sessions/bad-input.in` gives:\n- menu choices 0 and x;\n- Collatz starts 0 and abc, then a cancel;\n- longest-path limits 1 and 100001, then a cancel;\n- n = 2001 for Fibonacci, 16 rows of numbers and 33 rows of the pattern,\n  each then cancelled.\n\nBuilt on the verified corpus cases `collatz-sequence` (the halve-or-3n+1\nstep), `fibonacci-cassini-exact` (Fibonacci numbers checked with an\nidentity floats cannot fake) and `pascals-triangle` (each row from the one\nbefore).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P069 sequence explorer: Collatz paths and the longest one below a limit,\n# exact Fibonacci numbers with Cassini's identity and the golden ratio, and\n# Pascal's triangle - as numbers and as the pattern its odd entries make.\nimport sequences\n\ndef trim(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 steps_text(k):\n    if k == 1:\n        return \"1 step\"\n    return str(k) + \" steps\"\n\ndef number(s):\n    if s == \"\" or len(s) > 13:\n        return -1\n    0 => n\n    for c in s:\n        if not (c >= \"0\" and c <= \"9\"):\n            return -1\n        n * 10 + int(c) => n\n    return n\n\ndef ask(prompt, low, high):\n    while True:\n        trim(input(prompt + \" (\" + str(low) + \" to \" + str(high) + \")> \")) => answer\n        if answer == \"\":\n            return -1\n        number(answer) => n\n        if n >= low and n <= high:\n            return n\n        (\"Type a whole number from \" + str(low) + \" to \" + str(high) + \".\") ^0\n\ndef joined(xs):\n    \"\" => s\n    for x in xs:\n        if s != \"\":\n            s + \" \" => s\n        s + str(x) => s\n    return s\n\ndef collatz():\n    ask(\"start\", 1, 1000000000000) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    sequences.collatz(n) => r\n    r[0] => path\n    len(path) - 1 => steps\n    if len(path) <= 40:\n        joined(path) ^0\n    else:\n        (joined(path[0:20]) + \" ... \" + joined(path[len(path) - 10:len(path)])) ^0\n    (str(n) + \" reaches 1 in \" + steps_text(steps) + \", climbing as high as \" + str(r[1]) + \".\") ^0\n\ndef longest():\n    ask(\"up to\", 2, 100000) => limit\n    if limit == -1:\n        \"Cancelled.\" ^0\n        return\n    sequences.steps_up_to(limit) => st\n    1 => best\n    for k in [2:limit]:\n        if st[k] > st[best]:\n            k => best\n    (\"Up to \" + str(limit) + \", the start that takes longest is \" + str(best) + \": \" + steps_text(st[best]) + \".\") ^0\n    \"Steps for each start up to 20:\" ^0\n    [] => xs\n    for k in [1:20]:\n        if k <= limit:\n            xs + [st[k]] => xs\n    (\"  \" + joined(xs)) ^0\n\ndef fib():\n    ask(\"n\", 1, 2000) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    sequences.fibonacci(n) => f\n    str(f[1]) => s\n    if len(s) <= 60:\n        (\"F(\" + str(n) + \") = \" + s) ^0\n    else:\n        (\"F(\" + str(n) + \") = \" + s[0:25] + \"...\" + s[len(s) - 25:len(s)] + \", \" + str(len(s)) + \" digits\") ^0\n    sequences.cassini(n) => c\n    (\"Cassini: F(\" + str(n - 1) + \") x F(\" + str(n + 1) + \") - F(\" + str(n) + \")^2 = \" + str(c) + \", as (-1)^\" + str(n) + \" says.\") ^0\n    # F(n+1) / F(n) to 12 places, exactly rounded down\n    f[2] => a\n    f[1] => b\n    long_div(a, b, 12) => q\n    (\"F(\" + str(n + 1) + \") / F(\" + str(n) + \") = \" + q + \"... - the golden ratio is 1.618033988749...\") ^0\n\ndef long_div(a, b, places):\n    # a / b to `places` decimals, rounded down, by long division - for a\n    # quotient below 10, as F(n+1) / F(n) always is.\n    0 => q\n    a => r\n    while r >= b:\n        r - b => r\n        q + 1 => q\n    str(q) + \".\" => s\n    for k in [1:places]:\n        r * 10 => r\n        0 => d\n        while r >= b:\n            r - b => r\n            d + 1 => d\n        s + str(d) => s\n    return s\n\ndef pascal():\n    ask(\"rows\", 1, 15) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    sequences.pascal_rows(n) => rows\n    len(joined(rows[n - 1])) => width\n    for row in rows:\n        joined(row) => s\n        \"\" => pad\n        while len(pad) * 2 + len(s) < width:\n            pad + \" \" => pad\n        (pad + s) ^0\n\ndef pascal_odd():\n    ask(\"rows\", 1, 32) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    sequences.pascal_rows(n) => rows\n    for r in [0:n - 1]:\n        \"\" => line\n        while len(line) < n - 1 - r:\n            line + \" \" => line\n        for k in [0:r]:\n            if k > 0:\n                line + \" \" => line\n            if rows[r][k] % 2 == 1:\n                line + \"*\" => line\n            else:\n                line + \" \" => line\n        trim_right(line) ^0\n    \"Each * is an odd number; the even ones are left blank.\" ^0\n\ndef trim_right(s):\n    len(s) => j\n    while j > 0 and s[j - 1] == \" \":\n        j - 1 => j\n    return s[0:j]\n\n\"== Sequence explorer ==\" ^0\n\"Collatz paths, exact Fibonacci numbers and Pascal's triangle.\" ^0\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\" ^0\n    trim(input(\"choice> \")) => choice\n    if choice == \"1\":\n        collatz()\n    elif choice == \"2\":\n        longest()\n    elif choice == \"3\":\n        fib()\n    elif choice == \"4\":\n        pascal()\n    elif choice == \"5\":\n        pascal_odd()\n    elif choice == \"6\":\n        False => running\n    else:\n        \"Pick a number from 1 to 6.\" ^0\n\"Bye.\" ^0\n",
      "python": "import sequences\n\ndef trim(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 steps_text(k):\n    if k == 1:\n        return \"1 step\"\n    return str(k) + \" steps\"\n\ndef number(s):\n    if s == \"\" or len(s) > 13:\n        return -1\n    n = 0\n    for c in s:\n        if not (c >= \"0\" and c <= \"9\"):\n            return -1\n        n = n * 10 + int(c)\n    return n\n\ndef ask(prompt, low, high):\n    while True:\n        answer = trim(input(prompt + \" (\" + str(low) + \" to \" + str(high) + \")> \"))\n        if answer == \"\":\n            return -1\n        n = number(answer)\n        if n >= low and n <= high:\n            return n\n        print(\"Type a whole number from \" + str(low) + \" to \" + str(high) + \".\")\n\ndef joined(xs):\n    s = \"\"\n    for x in xs:\n        if s != \"\":\n            s = s + \" \"\n        s = s + str(x)\n    return s\n\ndef collatz():\n    n = ask(\"start\", 1, 1000000000000)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    r = sequences.collatz(n)\n    path = r[0]\n    steps = len(path) - 1\n    if len(path) <= 40:\n        print(joined(path))\n    else:\n        print(joined(path[0:20]) + \" ... \" + joined(path[len(path) - 10:len(path)]))\n    print(str(n) + \" reaches 1 in \" + steps_text(steps) + \", climbing as high as \" + str(r[1]) + \".\")\n\ndef longest():\n    limit = ask(\"up to\", 2, 100000)\n    if limit == -1:\n        print(\"Cancelled.\")\n        return\n    st = sequences.steps_up_to(limit)\n    best = 1\n    for k in range(2, limit+1):\n        if st[k] > st[best]:\n            best = k\n    print(\"Up to \" + str(limit) + \", the start that takes longest is \" + str(best) + \": \" + steps_text(st[best]) + \".\")\n    print(\"Steps for each start up to 20:\")\n    xs = []\n    for k in range(1, 21):\n        if k <= limit:\n            xs = xs + [st[k]]\n    print(\"  \" + joined(xs))\n\ndef fib():\n    n = ask(\"n\", 1, 2000)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    f = sequences.fibonacci(n)\n    s = str(f[1])\n    if len(s) <= 60:\n        print(\"F(\" + str(n) + \") = \" + s)\n    else:\n        print(\"F(\" + str(n) + \") = \" + s[0:25] + \"...\" + s[len(s) - 25:len(s)] + \", \" + str(len(s)) + \" digits\")\n    c = sequences.cassini(n)\n    print(\"Cassini: F(\" + str(n - 1) + \") x F(\" + str(n + 1) + \") - F(\" + str(n) + \")^2 = \" + str(c) + \", as (-1)^\" + str(n) + \" says.\")\n    a = f[2]\n    b = f[1]\n    q = long_div(a, b, 12)\n    print(\"F(\" + str(n + 1) + \") / F(\" + str(n) + \") = \" + q + \"... - the golden ratio is 1.618033988749...\")\n\ndef long_div(a, b, places):\n    q = 0\n    r = a\n    while r >= b:\n        r = r - b\n        q = q + 1\n    s = str(q) + \".\"\n    for k in range(1, places+1):\n        r = r * 10\n        d = 0\n        while r >= b:\n            r = r - b\n            d = d + 1\n        s = s + str(d)\n    return s\n\ndef pascal():\n    n = ask(\"rows\", 1, 15)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    rows = sequences.pascal_rows(n)\n    width = len(joined(rows[n - 1]))\n    for row in rows:\n        s = joined(row)\n        pad = \"\"\n        while len(pad) * 2 + len(s) < width:\n            pad = pad + \" \"\n        print(pad + s)\n\ndef pascal_odd():\n    n = ask(\"rows\", 1, 32)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    rows = sequences.pascal_rows(n)\n    for r in range(0, n):\n        line = \"\"\n        while len(line) < n - 1 - r:\n            line = line + \" \"\n        for k in range(0, r+1):\n            if k > 0:\n                line = line + \" \"\n            if rows[r][k] % 2 == 1:\n                line = line + \"*\"\n            else:\n                line = line + \" \"\n        print(trim_right(line))\n    print(\"Each * is an odd number; the even ones are left blank.\")\n\ndef trim_right(s):\n    j = len(s)\n    while j > 0 and s[j - 1] == \" \":\n        j = j - 1\n    return s[0:j]\n\nprint(\"== Sequence explorer ==\")\nprint(\"Collatz paths, exact Fibonacci numbers and Pascal's triangle.\")\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\")\n    choice = trim(input(\"choice> \"))\n    if choice == \"1\":\n        collatz()\n    elif choice == \"2\":\n        longest()\n    elif choice == \"3\":\n        fib()\n    elif choice == \"4\":\n        pascal()\n    elif choice == \"5\":\n        pascal_odd()\n    elif choice == \"6\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 6.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "sequences.eml",
      "eml": "# P069 sequence explorer - Collatz, Fibonacci and Pascal, in whole numbers\n# of any size.\n\ndef half(n):\n    # n // 2 for an even n >= 0, exactly. The corpus case collatz-sequence\n    # writes int(n / 2), which goes through a float and is exact only below\n    # 2^53; a Collatz path from a start below 10^12 can climb past that, so\n    # the halving is done by long division instead.\n    0 => q\n    n => a\n    while a >= 2:\n        2 => m\n        1 => k\n        while m + m <= a:\n            m + m => m\n            k + k => k\n        a - m => a\n        q + k => q\n    return q\n\ndef collatz(n):\n    # The path from n down to 1: halve an even number, and take 3n + 1 for\n    # an odd one. Returns [path, highest value].\n    [n] => path\n    n => top\n    while n != 1:\n        if n % 2 == 0:\n            half(n) => n\n        else:\n            3 * n + 1 => n\n        path + [n] => path\n        if n > top:\n            n => top\n    return [path, top]\n\ndef steps_up_to(limit):\n    # How many steps each start from 1 to limit takes to reach 1, using the\n    # answers already found: a path is followed only until it drops below\n    # its start. Returns the list of step counts, index = start.\n    [0] * (limit + 1) => steps\n    for start in [2:limit]:\n        start => n\n        0 => k\n        while n >= start:\n            if n % 2 == 0:\n                half(n) => n\n            else:\n                3 * n + 1 => n\n            k + 1 => k\n        k + steps[n] => steps[start]\n    return steps\n\ndef fibonacci(n):\n    # F(0) = 0, F(1) = 1, each the sum of the two before: [F(n-1), F(n), F(n+1)].\n    0 => a\n    1 => b\n    for i in [1:n]:\n        a + b => c\n        b => a\n        c => b\n    return [b - a, a, b]\n\ndef cassini(n):\n    # F(n-1) F(n+1) - F(n)^2, which Cassini (1680) showed is (-1)^n: the two\n    # products are huge and differ by exactly one, which floats cannot see\n    # (the corpus case fibonacci-cassini-exact).\n    fibonacci(n) => f\n    return f[0] * f[2] - f[1] * f[1]\n\ndef pascal_rows(count):\n    # The first `count` rows: each number the sum of the two above it.\n    [[1]] => rows\n    for r in [1:count - 1]:\n        rows[r - 1] => prev\n        [1] => row\n        for k in [1:r - 1]:\n            row + [prev[k - 1] + prev[k]] => row\n        rows + [row + [1]] => rows\n    return rows\n",
      "python": "def half(n):\n    q = 0\n    a = n\n    while a >= 2:\n        m = 2\n        k = 1\n        while m + m <= a:\n            m = m + m\n            k = k + k\n        a = a - m\n        q = q + k\n    return q\n\ndef collatz(n):\n    path = [n]\n    top = n\n    while n != 1:\n        if n % 2 == 0:\n            n = half(n)\n        else:\n            n = 3 * n + 1\n        path = path + [n]\n        if n > top:\n            top = n\n    return [path, top]\n\ndef steps_up_to(limit):\n    steps = [0] * (limit + 1)\n    for start in range(2, limit+1):\n        n = start\n        k = 0\n        while n >= start:\n            if n % 2 == 0:\n                n = half(n)\n            else:\n                n = 3 * n + 1\n            k = k + 1\n        steps[start] = k + steps[n]\n    return steps\n\ndef fibonacci(n):\n    a = 0\n    b = 1\n    for i in range(1, n+1):\n        c = a + b\n        a = b\n        b = c\n    return [b - a, a, b]\n\ndef cassini(n):\n    f = fibonacci(n)\n    return f[0] * f[2] - f[1] * f[1]\n\ndef pascal_rows(count):\n    rows = [[1]]\n    for r in range(1, count):\n        prev = rows[r - 1]\n        row = [1]\n        for k in range(1, r):\n            row = row + [prev[k - 1] + prev[k]]\n        rows = rows + [row + [1]]\n    return rows\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n1\n0\nabc\n\n2\n1\n100001\n\n3\n2001\n\n4\n16\n\n5\n33\n\n6\n",
      "screen": "== Sequence explorer ==\nCollatz paths, exact Fibonacci numbers and Pascal's triangle.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 0\nPick a number from 1 to 6.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> x\nPick a number from 1 to 6.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 1\nstart (1 to 1000000000000)> 0\nType a whole number from 1 to 1000000000000.\nstart (1 to 1000000000000)> abc\nType a whole number from 1 to 1000000000000.\nstart (1 to 1000000000000)> \nCancelled.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 2\nup to (2 to 100000)> 1\nType a whole number from 2 to 100000.\nup to (2 to 100000)> 100001\nType a whole number from 2 to 100000.\nup to (2 to 100000)> \nCancelled.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 3\nn (1 to 2000)> 2001\nType a whole number from 1 to 2000.\nn (1 to 2000)> \nCancelled.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 4\nrows (1 to 15)> 16\nType a whole number from 1 to 15.\nrows (1 to 15)> \nCancelled.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 5\nrows (1 to 32)> 33\nType a whole number from 1 to 32.\nrows (1 to 32)> \nCancelled.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\n27\n1\n1410123943\n2\n10000\n3\n10\n3\n1000\n4\n7\n5\n16\n6\n",
      "screen": "== Sequence explorer ==\nCollatz paths, exact Fibonacci numbers and Pascal's triangle.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 1\nstart (1 to 1000000000000)> 27\n27 82 41 124 62 31 94 47 142 71 214 107 322 161 484 242 121 364 182 91 ... 80 40 20 10 5 16 8 4 2 1\n27 reaches 1 in 111 steps, climbing as high as 9232.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 1\nstart (1 to 1000000000000)> 1410123943\n1410123943 4230371830 2115185915 6345557746 3172778873 9518336620 4759168310 2379584155 7138752466 3569376233 10708128700 5354064350 2677032175 8031096526 4015548263 12046644790 6023322395 18069967186 9034983593 27104950780 ... 13 40 20 10 5 16 8 4 2 1\n1410123943 reaches 1 in 770 steps, climbing as high as 7125885122794452160.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 2\nup to (2 to 100000)> 10000\nUp to 10000, the start that takes longest is 6171: 261 steps.\nSteps for each start up to 20:\n  0 1 7 2 5 8 16 3 19 6 14 9 9 17 17 4 12 20 20 7\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 3\nn (1 to 2000)> 10\nF(10) = 55\nCassini: F(9) x F(11) - F(10)^2 = 1, as (-1)^10 says.\nF(11) / F(10) = 1.618181818181... - the golden ratio is 1.618033988749...\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 3\nn (1 to 2000)> 1000\nF(1000) = 4346655768693745643568852...3704476137795166849228875, 209 digits\nCassini: F(999) x F(1001) - F(1000)^2 = 1, as (-1)^1000 says.\nF(1001) / F(1000) = 1.618033988749... - the golden ratio is 1.618033988749...\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 4\nrows (1 to 15)> 7\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\n1 6 15 20 15 6 1\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 5\nrows (1 to 32)> 16\n               *\n              * *\n             *   *\n            * * * *\n           *       *\n          * *     * *\n         *   *   *   *\n        * * * * * * * *\n       *               *\n      * *             * *\n     *   *           *   *\n    * * * *         * * * *\n   *       *       *       *\n  * *     * *     * *     * *\n *   *   *   *   *   *   *   *\n* * * * * * * * * * * * * * * *\nEach * is an odd number; the even ones are left blank.\n\n1) Collatz path  2) longest Collatz  3) Fibonacci  4) Pascal  5) Pascal's odd numbers  6) quit\nchoice> 6\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "collatz-sequence",
      "caseId": "016-collatz-sequence",
      "title": "Collatz sequence"
    },
    {
      "slug": "fibonacci-cassini-exact",
      "caseId": "189-fibonacci-cassini-exact",
      "title": "Fibonacci to F(200), checked with Cassini"
    },
    {
      "slug": "pascals-triangle",
      "caseId": "057-pascals-triangle",
      "title": "Pascal's triangle"
    }
  ],
  "updated": "2026-10-14"
}
