Skip to main content

Grade your first puzzle

In ten minutes you will install pencilmark, grade one classic sudoku and read what the result means. You need Python 3.10 or newer.

1. Install​

pip install pencilmark

The package includes its C++ engine, so there is nothing else to build.

2. Grade a puzzle from the command line​

A classic puzzle can be written as one line of 81 characters, row by row, with . for an empty cell:

$ echo '....4.8.3.6...8..29.86.5..1235.........7..2.........96..2......8.12..7...9.......' | pencilmark rate -
Hard 5.9 10.7 X-Wing

The four columns are the band, the difficulty, the time in minutes and the hardest technique the solve needs. - means "read puzzles from standard input"; you can also pass a file with one puzzle per line.

3. Read the card​

--report gives the same result as readable text:

$ echo '....4.8.3.6...8..29.86.5..1235.........7..2.........96..2......8.12..7...9.......' | pencilmark rate - --report
#1 Hard - difficulty 5.9 - time 10.7 min
contains: Naked Pair (or Hidden Pair), X-Wing (or 2-String Kite / Simple Colouring / Short chain in the head)
  • Hard is the band: what you need to know. Hard means the puzzle needs a pattern most people learn after the basics; here an X-Wing.
  • 5.9 is the difficulty: how hard the steps are, on a scale with no ceiling. A typical newspaper medium is about 5.
  • 10.7 min is the predicted median solve time; the median classic takes about 12 minutes.
  • contains lists the techniques the solve needs, easiest first (the report leaves out the singles). "X-Wing (or 2-String Kite / …)" means any one of those does the job at that point.

4. See the steps​

Add -v to list every step in solvers' notation (-vv gives plain sentences). The two steps that set the band are:

$ echo '....4.8.3.6...8..29.86.5..1235.........7..2.........96..2......8.12..7...9.......' | pencilmark rate - --report -v
...
25. Naked Pair: 4,8 in r4c48 => r4c5<>8, r4c6<>4
26. X-Wing: 3 r58 c68 => r679c6<>3
...

r4c48 means row 4, columns 4 and 8; r4c5<>8 means "8 is removed from row 4, column 5".

5. The same in Python​

import pencilmark

card = pencilmark.rate("....4.8.3.6...8..29.86.5..1235.........7..2.........96..2......8.12..7...9.......")
print(card["band"], card["difficulty"], card["time"]) # Hard 5.9 10.7
print([c["chip"] for c in card["contains"]]) # ['HSI', 'NSI', 'NPR/HPR', 'XWG/KTE/SCL/MCH']

The card is a plain dictionary; Grade card lists every key. The contains entries carry short codes (XWG is X-Wing); Techniques lists them.

6. When a puzzle has no single answer​

pencilmark grades only puzzles with exactly one solution. pencilmark solve tells you which case you have; the second puzzle below is the first with one given removed:

$ printf '%s\n' '....4.8.3.6...8..29.86.5..1235.........7..2.........96..2......8.12..7...9.......' \
'....4.8.3.6...8..29.86.5..1235.........7..2.........96..2......8.12..7...........' | pencilmark solve -
157942863463178952928635471235469187619783245784521396572394618841256739396817524
not unique

From Python, pencilmark.solve raises pencilmark.NotUnique or pencilmark.NoSolution instead.