{
  "id": "P079",
  "slug": "n-queens",
  "key": "P079-n-queens",
  "title": "N-queens",
  "summary": "Queens on an n x n board with none attacking another: place them yourself and see which pairs attack; backtracking finds a first solution or all of them, with the squares it tried; and the solutions that are really different once the 8 turned and mirrored views count as one.",
  "entry": "main.eml",
  "ui": "terminal",
  "readme": "# P079 - N-queens\n\nn queens on an n x n board with none attacking another. You can place\nthem yourself and see which pairs attack. Backtracking finds a first\nsolution, or all of them, and counts the squares it tried. The program\nalso counts how many solutions are really different once turned and\nmirrored boards count as one.\n\n- `main.eml` - the menu, reading boards, and drawing them\n- `queens.eml` - attacks, conflicts, the backtracking search, and the\n  symmetries\n\nHow each part works:\n\n- As in the corpus case `n-queens`, a board is one column per row, so two\n  queens can never share a row. Only columns and diagonals need checking:\n  queens in rows r1, r2 at columns c1, c2 share a diagonal exactly when\n  |r1 - r2| = |c1 - c2|.\n- Backtracking goes row by row. It tries each column in turn; a column no\n  queen above attacks is taken, and the search goes on to the next row.\n  When a row has none, it steps back. Every square tried is counted:\n  876 before the first solution for 8 queens, and 15,720 to find all 92.\n- Symmetries: a quarter turn takes the queen at row r, column c to row c,\n  column n + 1 - r, and a mirror takes column c to n + 1 - c. Four turns,\n  each with and without the mirror, make the 8 views of a board. Taking\n  the smallest view as its name, solutions with the same name are one\n  solution seen another way: 92 for 8 queens, but 12 different.\n- 2 and 3 queens have no solution. The search says so after trying every\n  square it can.\n\nWhat is checked: menu choices 1 to 4; a board of 4 to 12 to place by\nhand, 1 to 12 for a first solution, 1 to 9 for all of them; exactly n\ncolumn numbers from 1 to n. An empty answer cancels.\n\nSessions: `sessions/basic.in` gives:\n- solutions placed by hand for 8, 4, 6 and 5 queens;\n- the first solution for 8 queens, none for 3, and the single queen;\n- all solutions for 8 (92, 12 different), 6 (4, 1 different) and 4 (2,\n  1 different).\n\n`sessions/bad-input.in` gives:\n- menu choices 0 and x;\n- board sizes 3 and 13; boards of 3 numbers, with a 9, and of letters;\n- eight queens in one column: all 28 pairs attack;\n- sizes 0 and 13 for a first solution, and 10 for all of them, each then\n  cancelled.\n\nBuilt on the verified corpus case `n-queens` (one column per row, and\nbacktracking on the column and diagonal tests).\n",
  "modules": [
    {
      "name": "main.eml",
      "eml": "# P079 N-queens: place queens yourself and see which attack each other;\n# let backtracking find a first solution, or all of them, with how many\n# squares it tried; and how many are really different once turned and\n# mirrored boards count as one.\nimport queens\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 number(s):\n    if len(s) == 0 or len(s) > 2:\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 words(s):\n    [] => out\n    \"\" => w\n    for c in s + \" \":\n        if c == \" \" or c == \",\":\n            if w != \"\":\n                out + [w] => out\n            \"\" => w\n        else:\n            w + c => w\n    return out\n\ndef ask(prompt, low, high):\n    while True:\n        trim(input(prompt + \" (\" + str(low) + \" to \" + str(high) + \")> \")) => a\n        if a == \"\":\n            return -1\n        number(a) => 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 draw(cols):\n    len(cols) => n\n    for r in [0:n - 1]:\n        \"\" => line\n        for c in [1:n]:\n            if c == cols[r]:\n                line + \" Q\" => line\n            else:\n                line + \" .\" => line\n        line ^0\n\ndef squares(k):\n    if k == 1:\n        return \"1 square\"\n    return str(k) + \" squares\"\n\ndef queens_of(n):\n    if n == 1:\n        return \"1 queen\"\n    return str(n) + \" queens\"\n\ndef text(cols):\n    \"\" => s\n    for c in cols:\n        if s != \"\":\n            s + \" \" => s\n        s + str(c) => s\n    return s\n\ndef yours():\n    ask(\"board size\", 4, 12) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    while True:\n        trim(input(\"the column of the queen in each row, top to bottom (\" + str(n) + \" numbers from 1 to \" + str(n) + \")> \")) => s\n        if s == \"\":\n            \"Cancelled.\" ^0\n            return\n        words(s) => ws\n        True => ok\n        [] => cols\n        for w in ws:\n            number(w) => c\n            if c < 1 or c > n:\n                False => ok\n            cols + [c] => cols\n        if ok and len(cols) == n:\n            draw(cols)\n            queens.conflicts(cols) => bad\n            if len(bad) == 0:\n                \"No two queens attack each other: a solution.\" ^0\n            else:\n                for b in bad:\n                    (\"  rows \" + str(b[0]) + \" and \" + str(b[1]) + \" attack along a \" + b[2]) ^0\n                if len(bad) == 1:\n                    \"1 pair attacks.\" ^0\n                else:\n                    (str(len(bad)) + \" pairs attack.\") ^0\n            return\n        (\"Type \" + str(n) + \" numbers from 1 to \" + str(n) + \", separated by spaces.\") ^0\n\ndef first():\n    ask(\"board size\", 1, 12) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    queens.search(n, False) => r\n    if len(r[0]) == 0:\n        (\"No way to place \" + queens_of(n) + \": backtracking tried \" + squares(r[1]) + \" and ran out.\") ^0\n        return\n    draw(r[0][0])\n    (\"Columns \" + text(r[0][0]) + \" - found after trying \" + squares(r[1]) + \".\") ^0\n\ndef every():\n    ask(\"board size\", 1, 9) => n\n    if n == -1:\n        \"Cancelled.\" ^0\n        return\n    queens.search(n, True) => r\n    len(r[0]) => k\n    if k == 0:\n        (\"No solutions for \" + queens_of(n) + \"; backtracking tried \" + squares(r[1]) + \".\") ^0\n        return\n    queens.distinct(r[0]) => d\n    \"solutions\" => word\n    if k == 1:\n        \"solution\" => word\n    (str(k) + \" \" + word + \" for \" + queens_of(n) + \"; backtracking tried \" + squares(r[1]) + \".\") ^0\n    if d == 1 and k > 1:\n        \"Counting the 8 turned and mirrored views of a board as one, there is only 1 different solution.\" ^0\n    elif d == 1:\n        \"Turned or mirrored, it is still the only one.\" ^0\n    else:\n        (\"Counting the 8 turned and mirrored views of a board as one, \" + str(d) + \" are different.\") ^0\n\n\"== N-queens ==\" ^0\n\"Queens on a board, none attacking another: by hand, and by backtracking.\" ^0\nTrue => running\nwhile running:\n    \"\" ^0\n    \"1) place them yourself  2) a first solution  3) all solutions  4) quit\" ^0\n    trim(input(\"choice> \")) => choice\n    if choice == \"1\":\n        yours()\n    elif choice == \"2\":\n        first()\n    elif choice == \"3\":\n        every()\n    elif choice == \"4\":\n        False => running\n    else:\n        \"Pick a number from 1 to 4.\" ^0\n\"Bye.\" ^0\n",
      "python": "import queens\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 number(s):\n    if len(s) == 0 or len(s) > 2:\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 words(s):\n    out = []\n    w = \"\"\n    for c in s + \" \":\n        if c == \" \" or c == \",\":\n            if w != \"\":\n                out = out + [w]\n            w = \"\"\n        else:\n            w = w + c\n    return out\n\ndef ask(prompt, low, high):\n    while True:\n        a = trim(input(prompt + \" (\" + str(low) + \" to \" + str(high) + \")> \"))\n        if a == \"\":\n            return -1\n        n = number(a)\n        if n >= low and n <= high:\n            return n\n        print(\"Type a whole number from \" + str(low) + \" to \" + str(high) + \".\")\n\ndef draw(cols):\n    n = len(cols)\n    for r in range(0, n):\n        line = \"\"\n        for c in range(1, n+1):\n            if c == cols[r]:\n                line = line + \" Q\"\n            else:\n                line = line + \" .\"\n        print(line)\n\ndef squares(k):\n    if k == 1:\n        return \"1 square\"\n    return str(k) + \" squares\"\n\ndef queens_of(n):\n    if n == 1:\n        return \"1 queen\"\n    return str(n) + \" queens\"\n\ndef text(cols):\n    s = \"\"\n    for c in cols:\n        if s != \"\":\n            s = s + \" \"\n        s = s + str(c)\n    return s\n\ndef yours():\n    n = ask(\"board size\", 4, 12)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    while True:\n        s = trim(input(\"the column of the queen in each row, top to bottom (\" + str(n) + \" numbers from 1 to \" + str(n) + \")> \"))\n        if s == \"\":\n            print(\"Cancelled.\")\n            return\n        ws = words(s)\n        ok = True\n        cols = []\n        for w in ws:\n            c = number(w)\n            if c < 1 or c > n:\n                ok = False\n            cols = cols + [c]\n        if ok and len(cols) == n:\n            draw(cols)\n            bad = queens.conflicts(cols)\n            if len(bad) == 0:\n                print(\"No two queens attack each other: a solution.\")\n            else:\n                for b in bad:\n                    print(\"  rows \" + str(b[0]) + \" and \" + str(b[1]) + \" attack along a \" + b[2])\n                if len(bad) == 1:\n                    print(\"1 pair attacks.\")\n                else:\n                    print(str(len(bad)) + \" pairs attack.\")\n            return\n        print(\"Type \" + str(n) + \" numbers from 1 to \" + str(n) + \", separated by spaces.\")\n\ndef first():\n    n = ask(\"board size\", 1, 12)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    r = queens.search(n, False)\n    if len(r[0]) == 0:\n        print(\"No way to place \" + queens_of(n) + \": backtracking tried \" + squares(r[1]) + \" and ran out.\")\n        return\n    draw(r[0][0])\n    print(\"Columns \" + text(r[0][0]) + \" - found after trying \" + squares(r[1]) + \".\")\n\ndef every():\n    n = ask(\"board size\", 1, 9)\n    if n == -1:\n        print(\"Cancelled.\")\n        return\n    r = queens.search(n, True)\n    k = len(r[0])\n    if k == 0:\n        print(\"No solutions for \" + queens_of(n) + \"; backtracking tried \" + squares(r[1]) + \".\")\n        return\n    d = queens.distinct(r[0])\n    word = \"solutions\"\n    if k == 1:\n        word = \"solution\"\n    print(str(k) + \" \" + word + \" for \" + queens_of(n) + \"; backtracking tried \" + squares(r[1]) + \".\")\n    if d == 1 and k > 1:\n        print(\"Counting the 8 turned and mirrored views of a board as one, there is only 1 different solution.\")\n    elif d == 1:\n        print(\"Turned or mirrored, it is still the only one.\")\n    else:\n        print(\"Counting the 8 turned and mirrored views of a board as one, \" + str(d) + \" are different.\")\n\nprint(\"== N-queens ==\")\nprint(\"Queens on a board, none attacking another: by hand, and by backtracking.\")\nrunning = True\nwhile running:\n    print(\"\")\n    print(\"1) place them yourself  2) a first solution  3) all solutions  4) quit\")\n    choice = trim(input(\"choice> \"))\n    if choice == \"1\":\n        yours()\n    elif choice == \"2\":\n        first()\n    elif choice == \"3\":\n        every()\n    elif choice == \"4\":\n        running = False\n    else:\n        print(\"Pick a number from 1 to 4.\")\nprint(\"Bye.\")\n"
    },
    {
      "name": "queens.eml",
      "eml": "# P079 N-queens - n queens on an n x n board with none attacking another.\n# As in the corpus case n-queens, a board is one column per row (columns\n# numbered 1 to n), so two queens can never share a row; only columns and\n# diagonals need checking: queens in rows r1, r2 at columns c1, c2 attack\n# along a diagonal exactly when |r1 - r2| = |c1 - c2|.\n\ndef attacks(r1, c1, r2, c2):\n    # \"\" if they do not attack, else how: \"column\" or \"diagonal\".\n    if c1 == c2:\n        return \"column\"\n    if r1 - r2 == c1 - c2 or r1 - r2 == c2 - c1:\n        return \"diagonal\"\n    return \"\"\n\ndef conflicts(cols):\n    # Every attacking pair as [row, row, how], rows numbered from 1.\n    [] => out\n    for i in [0:len(cols) - 1]:\n        for j in [i + 1:len(cols) - 1]:\n            attacks(i, cols[i], j, cols[j]) => how\n            if how != \"\":\n                out + [[i + 1, j + 1, how]] => out\n    return out\n\ndef safe(cols, row, col):\n    for r in [0:row - 1]:\n        if attacks(r, cols[r], row, col) != \"\":\n            return False\n    return True\n\ndef search(n, want_all):\n    # Backtracking, row by row: try each column that no queen above\n    # attacks, go on to the next row, and step back when a row has none.\n    # Returns [solutions found (just the first unless want_all), squares\n    # tried]. The tries are counted in a one-element list so the recursion\n    # can add to it.\n    [0] * n => cols\n    [0] => tried\n    [] => found\n    place(n, 0, cols, tried, found, want_all) => found\n    return [found, tried[0]]\n\ndef place(n, row, cols, tried, found, want_all):\n    if row == n:\n        [0] * n => copy\n        for i in [0:n - 1]:\n            cols[i] => copy[i]\n        return found + [copy]\n    for c in [1:n]:\n        if want_all or len(found) == 0:\n            tried[0] + 1 => tried[0]\n            if safe(cols, row, c):\n                c => cols[row]\n                place(n, row + 1, cols, tried, found, want_all) => found\n    return found\n\ndef turned(cols):\n    # The board a quarter turn clockwise: the queen at (row r, column c)\n    # moves to (row c, column n + 1 - r) - rows and columns from 1.\n    len(cols) => n\n    [0] * n => out\n    for r in [0:n - 1]:\n        n - r => out[cols[r] - 1]\n    return out\n\ndef mirrored(cols):\n    len(cols) => n\n    [0] * n => out\n    for r in [0:n - 1]:\n        n + 1 - cols[r] => out[r]\n    return out\n\ndef smaller(a, b):\n    # Whether a comes before b, reading the columns left to right.\n    for i in [0:len(a) - 1]:\n        if a[i] != b[i]:\n            return a[i] < b[i]\n    return False\n\ndef canonical(cols):\n    # The smallest of the 8 boards a solution becomes when turned and\n    # mirrored: solutions with the same canonical form are the same\n    # solution seen another way.\n    cols => best\n    cols => x\n    for k in [1:4]:\n        mirrored(x) => m\n        if smaller(m, best):\n            m => best\n        turned(x) => x\n        if k < 4 and smaller(x, best):\n            x => best\n    return best\n\ndef distinct(solutions):\n    # How many solutions are left when the 8 symmetric views count as one.\n    [] => seen\n    for s in solutions:\n        canonical(s) => c\n        True => fresh\n        for t in seen:\n            if t == c:\n                False => fresh\n        if fresh:\n            seen + [c] => seen\n    return len(seen)\n",
      "python": "def attacks(r1, c1, r2, c2):\n    if c1 == c2:\n        return \"column\"\n    if r1 - r2 == c1 - c2 or r1 - r2 == c2 - c1:\n        return \"diagonal\"\n    return \"\"\n\ndef conflicts(cols):\n    out = []\n    for i in range(0, len(cols)):\n        for j in range(i + 1, len(cols)):\n            how = attacks(i, cols[i], j, cols[j])\n            if how != \"\":\n                out = out + [[i + 1, j + 1, how]]\n    return out\n\ndef safe(cols, row, col):\n    for r in range(0, row):\n        if attacks(r, cols[r], row, col) != \"\":\n            return False\n    return True\n\ndef search(n, want_all):\n    cols = [0] * n\n    tried = [0]\n    found = []\n    found = place(n, 0, cols, tried, found, want_all)\n    return [found, tried[0]]\n\ndef place(n, row, cols, tried, found, want_all):\n    if row == n:\n        copy = [0] * n\n        for i in range(0, n):\n            copy[i] = cols[i]\n        return found + [copy]\n    for c in range(1, n+1):\n        if want_all or len(found) == 0:\n            tried[0] = tried[0] + 1\n            if safe(cols, row, c):\n                cols[row] = c\n                found = place(n, row + 1, cols, tried, found, want_all)\n    return found\n\ndef turned(cols):\n    n = len(cols)\n    out = [0] * n\n    for r in range(0, n):\n        out[cols[r] - 1] = n - r\n    return out\n\ndef mirrored(cols):\n    n = len(cols)\n    out = [0] * n\n    for r in range(0, n):\n        out[r] = n + 1 - cols[r]\n    return out\n\ndef smaller(a, b):\n    for i in range(0, len(a)):\n        if a[i] != b[i]:\n            return a[i] < b[i]\n    return False\n\ndef canonical(cols):\n    best = cols\n    x = cols\n    for k in range(1, 5):\n        m = mirrored(x)\n        if smaller(m, best):\n            best = m\n        x = turned(x)\n        if k < 4 and smaller(x, best):\n            best = x\n    return best\n\ndef distinct(solutions):\n    seen = []\n    for s in solutions:\n        c = canonical(s)\n        fresh = True\n        for t in seen:\n            if t == c:\n                fresh = False\n        if fresh:\n            seen = seen + [c]\n    return len(seen)\n"
    }
  ],
  "sessions": [
    {
      "name": "bad-input",
      "input": "0\nx\n1\n3\n13\n8\n1 2 3\n1 2 3 4 5 6 7 9\na b c d e f g h\n1 1 1 1 1 1 1 1\n2\n0\n13\n\n3\n10\n\n4\n",
      "screen": "== N-queens ==\nQueens on a board, none attacking another: by hand, and by backtracking.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 0\nPick a number from 1 to 4.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> x\nPick a number from 1 to 4.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 1\nboard size (4 to 12)> 3\nType a whole number from 4 to 12.\nboard size (4 to 12)> 13\nType a whole number from 4 to 12.\nboard size (4 to 12)> 8\nthe column of the queen in each row, top to bottom (8 numbers from 1 to 8)> 1 2 3\nType 8 numbers from 1 to 8, separated by spaces.\nthe column of the queen in each row, top to bottom (8 numbers from 1 to 8)> 1 2 3 4 5 6 7 9\nType 8 numbers from 1 to 8, separated by spaces.\nthe column of the queen in each row, top to bottom (8 numbers from 1 to 8)> a b c d e f g h\nType 8 numbers from 1 to 8, separated by spaces.\nthe column of the queen in each row, top to bottom (8 numbers from 1 to 8)> 1 1 1 1 1 1 1 1\n Q . . . . . . .\n Q . . . . . . .\n Q . . . . . . .\n Q . . . . . . .\n Q . . . . . . .\n Q . . . . . . .\n Q . . . . . . .\n Q . . . . . . .\n  rows 1 and 2 attack along a column\n  rows 1 and 3 attack along a column\n  rows 1 and 4 attack along a column\n  rows 1 and 5 attack along a column\n  rows 1 and 6 attack along a column\n  rows 1 and 7 attack along a column\n  rows 1 and 8 attack along a column\n  rows 2 and 3 attack along a column\n  rows 2 and 4 attack along a column\n  rows 2 and 5 attack along a column\n  rows 2 and 6 attack along a column\n  rows 2 and 7 attack along a column\n  rows 2 and 8 attack along a column\n  rows 3 and 4 attack along a column\n  rows 3 and 5 attack along a column\n  rows 3 and 6 attack along a column\n  rows 3 and 7 attack along a column\n  rows 3 and 8 attack along a column\n  rows 4 and 5 attack along a column\n  rows 4 and 6 attack along a column\n  rows 4 and 7 attack along a column\n  rows 4 and 8 attack along a column\n  rows 5 and 6 attack along a column\n  rows 5 and 7 attack along a column\n  rows 5 and 8 attack along a column\n  rows 6 and 7 attack along a column\n  rows 6 and 8 attack along a column\n  rows 7 and 8 attack along a column\n28 pairs attack.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 2\nboard size (1 to 12)> 0\nType a whole number from 1 to 12.\nboard size (1 to 12)> 13\nType a whole number from 1 to 12.\nboard size (1 to 12)> \nCancelled.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 3\nboard size (1 to 9)> 10\nType a whole number from 1 to 9.\nboard size (1 to 9)> \nCancelled.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 4\nBye.\n",
      "interpreter": "equal"
    },
    {
      "name": "basic",
      "input": "1\n8\n1 5 8 6 3 7 2 4\n1\n4\n2 4 1 3\n1\n6\n2 4 6 1 3 5\n1\n5\n1 3 5 2 4\n2\n8\n2\n3\n2\n1\n3\n8\n3\n6\n3\n4\n4\n",
      "screen": "== N-queens ==\nQueens on a board, none attacking another: by hand, and by backtracking.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 1\nboard size (4 to 12)> 8\nthe column of the queen in each row, top to bottom (8 numbers from 1 to 8)> 1 5 8 6 3 7 2 4\n Q . . . . . . .\n . . . . Q . . .\n . . . . . . . Q\n . . . . . Q . .\n . . Q . . . . .\n . . . . . . Q .\n . Q . . . . . .\n . . . Q . . . .\nNo two queens attack each other: a solution.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 1\nboard size (4 to 12)> 4\nthe column of the queen in each row, top to bottom (4 numbers from 1 to 4)> 2 4 1 3\n . Q . .\n . . . Q\n Q . . .\n . . Q .\nNo two queens attack each other: a solution.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 1\nboard size (4 to 12)> 6\nthe column of the queen in each row, top to bottom (6 numbers from 1 to 6)> 2 4 6 1 3 5\n . Q . . . .\n . . . Q . .\n . . . . . Q\n Q . . . . .\n . . Q . . .\n . . . . Q .\nNo two queens attack each other: a solution.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 1\nboard size (4 to 12)> 5\nthe column of the queen in each row, top to bottom (5 numbers from 1 to 5)> 1 3 5 2 4\n Q . . . .\n . . Q . .\n . . . . Q\n . Q . . .\n . . . Q .\nNo two queens attack each other: a solution.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 2\nboard size (1 to 12)> 8\n Q . . . . . . .\n . . . . Q . . .\n . . . . . . . Q\n . . . . . Q . .\n . . Q . . . . .\n . . . . . . Q .\n . Q . . . . . .\n . . . Q . . . .\nColumns 1 5 8 6 3 7 2 4 - found after trying 876 squares.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 2\nboard size (1 to 12)> 3\nNo way to place 3 queens: backtracking tried 18 squares and ran out.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 2\nboard size (1 to 12)> 1\n Q\nColumns 1 - found after trying 1 square.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 3\nboard size (1 to 9)> 8\n92 solutions for 8 queens; backtracking tried 15720 squares.\nCounting the 8 turned and mirrored views of a board as one, 12 are different.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 3\nboard size (1 to 9)> 6\n4 solutions for 6 queens; backtracking tried 894 squares.\nCounting the 8 turned and mirrored views of a board as one, there is only 1 different solution.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 3\nboard size (1 to 9)> 4\n2 solutions for 4 queens; backtracking tried 60 squares.\nCounting the 8 turned and mirrored views of a board as one, there is only 1 different solution.\n\n1) place them yourself  2) a first solution  3) all solutions  4) quit\nchoice> 4\nBye.\n",
      "interpreter": "equal"
    }
  ],
  "builtOn": [
    {
      "slug": "n-queens",
      "caseId": "119-n-queens",
      "title": "N-Queens"
    }
  ],
  "updated": "2026-10-14"
}
