hp41programs

Sudoku

Sudoku for the HP-41


Overview
 

 1°)  2 Focal Programs
 2°)  M-Code Routine
 3°)  Creating a Grid

 
Latest Update:   A small improvement of the M-Code routine §2°)

-A sudoku is a 81-cell grid with 9 rows, 9 columns and 9 regions of 3 x 3 cells.
-Each row, each column and each region must contain all the integers from 1 to 9 exactly once, for instance:

  4  6  1  |  3  7  2  |  8  5  9
  9  3  5  |  4  8  6  |  1  7  2
  2  7  8  |  9  1  5  |  3  6  4
  ---------------------------
  7  9  4  |  2  3  1  |  5  8  6
  5  1  2  |  8  6  9  |  4  3  7
  6  8  3  |  5  4  7  |  9  2  1
  --------------------------
  8  4  6  |  7  9  3  |  2  1  5
  1  2  9  |  6  5  8  |  7  4  3
  3  5  7  |  1  2  4  |  6  9  8

-Given a partially empty grid, the puzzle consists in finding the missing numbers.
-The sudoku above is the solution of the problem below, where the empty cells are replaced by zeros:

  0  0  0  |  3  0  0  |  0  5  0
  0  0  5  |  4  0  6  |  0  0  2
  2  7  0  |  0  1  0  |  3  6  0
  ---------------------------
  7  0  4  |  2  3  0  |  0  0  0
  5  1  0  |  0  0  0  |  0  3  7
  0  0  0  |  0  4  7  |  9  0  1
  --------------------------
  0  4  6  |  0  9  0  |  0  1  5
  1  0  0  |  6  0  8  |  7  0  0
  0  5  0  |  0  0  4  |  0  0  0
 

1°)  2 Focal Programs
 

-"SDK"  solves a sudoku by backtracking.
-Though it could theoretically solve any - solvable - sudoku,  only a few can be solved, due to prohibitive execution times !
 

Data Registers:         R00 & R82 to R94:  temp           ( Registers R01 thru R81 are to be initialized before executing "SDK" )

                                •  R01 to •  R81 = the elements of the sudoku grid, in column order ( or row order ) with 0 in the empty cells.

Flags: /
Subroutines: /

-Lines 99-102-119 are 3-byte GTOs
 
 

  01  LBL "SDK"
  02  3
  03  STO 86
  04  6.009
  05  STO 87
  06  9
  07  STO 88
  08  7
  09  STO 89
  10  73.00009
  11  STO 90
  12  82
  13  STO 91
  14  STO 00
  15   E3
  16  STO 92
  17  SIGN
  18  STO 94
  19  LBL 01
  20  DSE 00
  21  X=0?
  22  RTN
  23  RCL IND 00
  24  X#0?
  25  GTO 01 
  26  VIEW 00
  27  RCL 88
  28  STO 82
  29  LBL 02
  30  RCL 00
  31  RCL 94
  32  -
  33  STO 85
  34  RCL 88
  35  ST/ 85
  36  MOD
  37  STO 83
  38  RCL 90
  39  +
  40  X<> 85
  41  INT
  42  STO 84
  43  RCL 94 
  44  +
  45  RCL 88
  46  *
  47  STO 93
  48  LBL 03
  49  RCL IND 93
  50  ABS
  51  RCL 82
  52  X=Y?
  53  GTO 05
  54  RCL IND 85
  55  ABS
  56  X=Y?
  57  GTO 05
  58  DSE 93
  59  CLX
  60  DSE 85
  61  GTO 03
  62  RCL 86
  63  X<> 83
  64  RCL 86
  65  /
  66  INT
  67  RCL 84
  68  RCL 86 
  69  /
  70  INT
  71  RCL 88
  72  *
  73  +
  74  RCL 89
  75  +
  76  RCL 86
  77  *
  78  STO 85
  79  RCL 86
  80  -
  81  RCL 92
  82  /
  83  ST+ 85
  84  LBL 04
  85  RCL IND 85
  86  ABS
  87  RCL 82
  88  X=Y?
  89  GTO 05
  90  DSE 85
  91  GTO 04
  92  RCL 87
  93  ST- 85
  94  DSE 83
  95  GTO 04
  96  X<>Y
  97  CHS
  98  STO IND 00
  99  GTO 01
100  LBL 05
101  DSE 82
102  GTO 02
103  LBL 06
104  RCL 00
105  RCL 94
106  +
107  STO 00
108  RCL 91
109  X=Y?
110  SF 41
111  RCL IND 00
112  X>0?
113  GTO 06
114  CHS
115  ST+ IND 00
116  STO 82
117  VIEW 00
118  DSE 82
119  GTO 02
120  GTO 06
121  END

 
     ( 214 bytes / SIZE 095 )
 
 

      STACK        INPUTS      OUTPUTS
           X             /             /

 
Example1:   Solve the following sudoku:

  0  0  0  |  3  0  0  |  0  5  0
  0  0  5  |  4  0  6  |  0  0  2
  2  7  0  |  0  1  0  |  3  6  0
  ---------------------------
  7  0  4  |  2  3  0  |  0  0  0
  5  1  0  |  0  0  0  |  0  3  7
  0  0  0  |  0  4  7  |  9  0  1
  --------------------------
  0  4  6  |  0  9  0  |  0  1  5
  1  0  0  |  6  0  8  |  7  0  0
  0  5  0  |  0  0  4  |  0  0  0

-Store the 81 elements into R01 to R81 in column order ( 0  STO 01  STO 02  2  STO 03  .......................  0  STO 81 )

  XEQ "SDK"  >>>>  the solution hereunder is returned in about 1h02mn (!)

  4  6  1  |  3  7  2  |  8  5  9
  9  3  5  |  4  8  6  |  1  7  2
  2  7  8  |  9  1  5  |  3  6  4
  ---------------------------
  7  9  4  |  2  3  1  |  5  8  6
  5  1  2  |  8  6  9  |  4  3  7       Actually, the digits found by the HP-41 are preceded by a "minus" sign
  6  8  3  |  5  4  7  |  9  2  1
  --------------------------
  8  4  6  |  7  9  3  |  2  1  5
  1  2  9  |  6  5  8  |  7  4  3
  3  5  7  |  1  2  4  |  6  9  8
 

Example2:    With the empty grid - which is not a "proper" sudoku - "SDK" gives the following solution:

  XEQ "CLRG"
  XEQ "SDK"   >>>>    ( in about 2h30mn )

  8  9  2  |  5  6  3  |  4  7  1
  6  7  3  |  4  9  1  |  5  8  2
  4  5  1  |  7  8  2  |  6  9  3
  ---------------------------
  9  2  8  |  6  3  5  |  7  1  4
  7  3  6  |  9  1  4  |  8  2  5
  5  1  4  |  8  2  7  |  9  3  6
  --------------------------
  2  8  9  |  3  5  6  |  1  4  7
  3  6  7  |  1  4  9  |  2  5  8
  1  4  5  |  2  7  8  |  3  6  9

Notes:

-Obviously, this program is very slow, all the more that these examples belong to the easy puzzles.
-However, if you are using a good emulator in turbo mode, the execution times become about 6 seconds and 15 seconds respectively.

-The address of the current register is displayed ( 81 80 .... )
-If line 110 is executed, displaying "NONEXISTENT", the puzzle has no solution. 

-We can add a few lines to store the puzzle and read the solution more easily:

-Lines 45-122-125-142 are 3-byte GTOs


 01 LBL "SDK"
 02 81
 03 STO 82
 04 LBL 00
 05 9
 06 STO 83          
 07 LBL 07
 08 9
 09 STO 84
 10 RCL IND 83
 11 LBL 08
 12 STO Y
 13 10
 14 MOD
 15 STO IND 82
 16 -
 17 10
 18 /
 19 DSE 82
 20 ENTER
 21 DSE 84
 22 GTO 08
 23 DSE 83
 24 GTO 07
 25 3
 26 STO 86
 27 6.009
 28 STO 87          
 29 9
 30 STO 88
 31 7
 32 STO 89
 33 73.00009
 34 STO 90
 35 82
 36 STO 91
 37 STO 00
 38  E3
 39 STO 92
 40 SIGN
 41 STO 94
 42 LBL 01
 43 DSE 00
 44 X=0?
 45 GTO 09
 46 RCL IND 00
 47 X#0?
 48 GTO 01
 49 VIEW 00
 50 RCL 88
 51 STO 82          
 52 LBL 02
 53 RCL 00
 54 RCL 94
 55 -
 56 STO 85
 57 RCL 88
 58 ST/ 85
 59 MOD
 60 STO 83
 61 RCL 90
 62 +
 63 X<> 85
 64 INT
 65 STO 84
 66 RCL 94
 67 +
 68 RCL 88
 69 *
 70 STO 93
 71 LBL 03
 72 RCL IND 93
 73 ABS
 74 RCL 82
 75 X=Y?
 76 GTO 05
 77 RCL IND 85
 78 ABS
 79 X=Y?
 80 GTO 05
 81 DSE 93
 82 CLX
 83 DSE 85
 84 GTO 03
 85 RCL 86          
 86 X<> 83
 87 RCL 86
 88 /
 89 INT
 90 RCL 84
 91 RCL 86
 92 /
 93 INT
 94 RCL 88
 95 *
 96 +
 97 RCL 89          
 98 +
 99 RCL 86
100 *
101 STO 85
102 RCL 86
103 -
104 RCL 92
105 /
106 ST+ 85
107 LBL 04
108 RCL IND 85
109 ABS
110 RCL 82
111 X=Y?
112 GTO 05
113 DSE 85
114 GTO 04
115 RCL 87
116 ST- 85
117 DSE 83
118 GTO 04
119 X<>Y
120 CHS
121 STO IND 00
122 GTO 01
123 LBL 05
124 DSE 82
125 GTO 02
126 LBL 06
127 RCL 00
128 RCL 94        
129 +
130 STO 00
131 RCL 91
132 X=Y?
133 SF 41
134 RCL IND 00
135 X>0?
136 GTO 06
137 CHS
138 ST+ IND 00
139 STO 82
140 VIEW 00
141 DSE 82
142 GTO 02
143 GTO 06
144 LBL 09
145 1.009
146 STO 82
147 STO 83        
148 CLX
149 LBL 10
150 10
151 *
152 RCL IND 83
153 ABS
154 +
155 ISG 83
156 GTO 10
157 STO IND 82
158 .009
159 ST+ 83
160 CLX
161 ISG 82
162 GTO 10
163 END


     ( 289 bytes / SIZE 095 )

-Simply store the rows ( or the columns ) into R01 thru R09

Example:   With

  0  0  0  |  3  0  0  |  0  5  0
  0  0  5  |  4  0  6  |  0  0  2
  2  7  0  |  0  1  0  |  3  6  0
  ---------------------------
  7  0  4  |  2  3  0  |  0  0  0
  5  1  0  |  0  0  0  |  0  3  7
  0  0  0  |  0  4  7  |  9  0  1
  --------------------------
  0  4  6  |  0  9  0  |  0  1  5
  1  0  0  |  6  0  8  |  7  0  0
  0  5  0  |  0  0  4  |  0  0  0

      300050  STO 01
    5406002  STO 02
270010360  STO 03
704230000  STO 04
510000037  STO 05
        47901  STO 06
  46090015  STO 07
100608700  STO 08
  50004000  STO 09

    XEQ "SDK"    and we have the solution in R01 to R09:

 461372859
 935486172
 278915364
 794231586
 512869437
 683547921
 846793215
 129658743
 357124698
 

2°)  M-Code Routine
 
 

-This M-Code routine uses a similar scheme to solve a sudoku.
-It is almost 200 times as fast as the focal program.
-So, much more puzzles can be solved in a "raisonnable" time.
 
   

08B  "K"   
004  "D"
013  "S"
3C8  CLRKEY
378   C=c
03C   RCR 3
106   A=C S&X
130   LDI S&X
012   012h=018d
146   A=A+C S&X
130   LDI S&X
200   200h=512d
306   ?A<C S&X
381   ?NCGO
00A   NONEXISTENT
378   C=c
0A6  A<>C S&X
106   A=C S&X
1BC  RCR 11
130   LDI S&X
009   009
246   C=A-C S&X
106   A=C S&X
27C  RCR 9
0A6  A<>C S&X
0BC  RCR 5
070   N=C ALL               here N contains  the addresses of  R09  R00  R18  R09  in nybbles   11-10-9  8-7-6  5-4-3  2-1-0  respectively
04E   C=0 ALL
19C   PT=11
050    LD@PT- 1
050    LD@PT- 1
050    LD@PT- 1
050    LD@PT- 1
050    LD@PT- 1            C = 111111111   in nybbles  11 to 3
050    LD@PT- 1
050    LD@PT- 1
050    LD@PT- 1
050    LD@PT- 1
268    Q=C
10E   A=C ALL
1EE   C=C+C  ALL
1EE   C=C+C  ALL
1EE   C=C+C   ALL
20E   C=A+C ALL
228   P=C                      P = 999999999   in nybbles  11 to 3
0A0  SLCT P
21C  PT=2                     loop 0
3DC  PT=PT+1             LOOP1
0B0   C= N ALL
354   ?PT=12
063   JNC+12d
266   C=C-1 S&X
27A  C=C-1 M
070   N=C ALL
106   A=C S&X
17C  RCR 6
366   ?A#C S&X
3AF   JC-11d                goto loop 0
04E   C=0 ALL
270   RAMSLCT
228   P=C
3E0   RTN                     the routine stops here if a solution is found
270   RAMSLCT
038   READATA
2E2   ?C#0@PT
377   JC-18d                 goto loop 1
10E   A=C ALL
046   C=0 S&X
270   RAMSLCT
238   C=P
158   M=C ALL           LOOP2 
0E0   SLCT Q
01C   PT=3
362   ?A#C@PT                 we test if the digit is different from all the other digits in the same column
07B   JNC+15d
3DC  PT=PT+1
354   ?PT=12
3E3   JNC-04
0A0   SLCT P
130   LDI S&X
008   008
10E   A=C ALL
0B0   C=N ALL
17C   RCR 6
226    C=C+1 S&X
270   RAMSLCT
0E6   B<>C S&X
038   READATA
362   ?A#C@PT                   we test if the digit is different from all the other digits in the same row
1BB   JNC+55d
0E6   B<>C S&X
1A6   A=A-1 S&X
3C3   JNC-08
0B0   C=N ALL
10E   A=C ALL
1A6   A=A-1 S&X
17C   RCR 6
226   C=C+1 S&X
226   C=C+1 S&X
226   C=C+1 S&X
306   ?A<C S&X
057   JC+10d
226   C=C+1 S&X
226   C=C+1 S&X
226   C=C+1 S&X
306   ?A<C S&X
02F   JC+05
03C  RCR 3
01B  JNC+03
213  JNC-62d                       goto loop1
2C3 JNC-40d                       goto loop2
0E6   B<>C S&X                  here, B S&X contains the address of the register in the right lower corner of the 3x3 region ( R09 or R06 or R03 )
0E0   SLCT Q
01C  PT=3
0A0  SLCT P
014  ?PT=3
087  JC+16d
054  ?PT=4
077  JC+14d
094  ?PT=5
067   JC+12d
0E0  SLCT Q
15C  PT=6
0A0  SLCT P
154  ?PT=6
03F  JC+07
294  ?PT=7
02F  JC+05
114  ?PT=8
01F  JC+03
0E0  SLCT Q
25C  PT=9
0E0  SLCT Q               now, pointer Q points to the right lower corner of the 3x3 region ( 9 or 6 or 3 )
198  C=M
23E  C=C+1 MS
23E  C=C+1 MS
10E  A=C ALL
0C6  C=B S&X
270  RAMSLCT
038  READATA
362  ?A#C@PT              we test if the digit is different from all the other digits in the same 3x3 region
0B3  JNC+22d
3DC  PT=PT+1
362  ?A#C@PT
09B  JNC+19d
3DC  PT=PT+1
362  ?A#C@PT
083  JNC+16d
3D4  PT=PT-1
3D4  PT=PT-1
0E6  B<>C S&X
266  C=C-1 S&X
0E6  B<>C S&X
1BE  A=A-1 MS
37B  JNC-17d
0A0  SELCT P
0B0  C=N ALL                 if the candidate number has successfully passed all the tests, it replaces the zero in the empty cell
270   RAMSLCT
038   READATA
0A2  A<>C@PT
2F0  WRITDATA
263  JNC-52d                   goto loop1
263  JNC-52d                   goto loop2
0A0  SLCT P                    the execution jumps here if the digit has been rejected
198  C=M ALL
10E  A=C ALL
046  C=0 S&X
270  RAMSLCT
278  C=Q
1CE  A=A-C ALL           we started with 999999999 in M, then we try 888888888 in M , ...etc...
0B0  C=N ALL
270  RAMSLCT
038  READATA
0AE  A<>C ALL
2EE  ?C#0 ALL               ...  until we arrive at  000000000
39F  JC-13d                    goto loop2
3D4  PT=PT-1                if all the digits are rejected for this cell, we go to the previous cell ( backtracking )
214  ?PT=2
107  JC+32d                  we must also move to the previous register if we were at the left of a register
0B0  C=N ALL
03C  RCR 3
270   RAMSLCT            otherwise, we check in a register between R10 and R18 if the cell was empty or not
038   READATA
2E2  ?C#0@PT
3C7  JC-08                     If the cell was not empty, we go to the previous cell again
0B0  C=N ALL
270  RAMSLCT
038  READATA
10E  A=C ALL
04E  C=0 ALL
0A2  A<>C@PT
0AE  A<>C ALL
2F0   WRITDATA          the number in the non-fixed cell is replaced by 0
1A2  A=A-1@PT
342   ?A#0@PT
36B  JNC-19d                if the last tested digit was 1, we again go to the previous non-fixed cell
046  C=0 S&X
270  RAMSLCT
278  C=Q
08E  B=A ALL
10E  A=C ALL
322  ?A<B@PT
01B  JNC+03                  if the digit in the previous cell was, say 8, we must recreate 777777777 which will be stored in CPU register M ( loop2 )
14E  A=A+C ALL
3EB  JNC-03
0B0  C=N ALL
270  RAMSLCT
038  READATA
0AE  A<>C ALL
28B  JNC-47d                 goto loop2
19C  PT=11                     we arrive here if we must go to the "previous" register ( R01->R02->R03 ... )
0B0  C=N ALL
226  C=C+1 S&X
23A  C=C+1 M
070  N=C ALL
27C  RCR 9
106  A=C S&X
0BC  RCR 5
160  ?LOWBAT                 the 4 instructions written in blue
360  ?C RTN                      will stop the routine if the batteries are low
3CC  ?KEY                        or if you press any key
360   ?CRTN                      They may be deleted if you have a "newest" HP-41:  simply press  ENTER^  ON   to stop the program
306  ?A<C S&X
2A3  JNC-44d                    Replace this line by    2C3  JNC-40d    if you don't key in the blue instructions ( in this case, the 4th word: 3C8  CLRKEY may also be deleted )
0B5  ?NCGO
0A2  DATA ERROR         if the "previous" register is R10, the sudoku cannot be solved !
 

( 226 words ( or 221 ) / SIZE 019 )
 
 

      STACK        INPUTS      OUTPUTS
           X             /             /

 
-To use the M-Code routine, we must place the cells in nybbles  11 to 3 of registers R01 to R09 and the same data in R10 to R18.
-So the cells of a row must be the fractional part of a real number whose integer part is between 1 and 9

-The short routine hereunder lets the HP-41 deal with the registers R10 to R18.
 
 

 01  LBL "SUD"
 02  1.010009
 03  REGMOVE
 04  SDK
 05  END

 
Examples:    The examples of the 1st paragraph are now solved in 20 seconds and 46 seconds respectively.

A more difficult example:    With the grid:

  0  9  0  |  0  4  2  |  0  1  0
  0  0  5  |  0  0  0  |  0  0  0
  3  0  0  |  0  0  0  |  9  0  4
  ---------------------------
  0  0  0  |  0  0  0  |  1  9  3
  5  2  0  |  7  0  0  |  0  0  6
  0  0  0  |  0  0  1  |  0  0  0
  --------------------------
  9  0  0  |  0  5  0  |  0  6  0
  0  0  0  |  2  0  4  |  0  0  7
  0  0  0  |  0  1  6  |  8  0  0
 

   1.090042010   STO 01
   1.005000000   STO 02
   1.300000904   STO 03
   1.000000193   STO 04
   1.520700006   STO 05
   1.000001000   STO 06
   1.900050060   STO 07
   1.000204007   STO 08
   1.000016800   STO 09     XEQ "SUD"   returns a solution in 23mn38s

-The same solution is returned in 1mn22s (!) if we store the columns instead of the rows.

   ( 1.003050900  STO 01  1.900020000  STO 02  ...............  1.004360070  STO 09 )

-The solution is in registers R01 thru R09:
 

  7  9  8  |  6  4  2  |  3  1  5
  4  1  5  |  9  7  3  |  6  2  8
  3  6  2  |  1  8  5  |  9  7  4
  ---------------------------
  6  7  4  |  5  2  8  |  1  9  3
  5  2  1  |  7  3  9  |  4  8  6
  8  3  9  |  4  6  1  |  7  5  2
  --------------------------
  9  4  3  |  8  5  7  |  2  6  1
  1  8  6  |  2  9  4  |  5  3  7
  2  5  7  |  3  1  6  |  8  4  9

Notes:

-R00 is unused. Synthetic registers P & Q are used. Register P is cleared at the end if a solution has been found.

-Of course, here again, a good emulator like V41 in turbo mode will reduce the execution times by a factor about 600.
-So, many more puzzles can be solved in this case.
-Several minutes may still be required however ( perhaps hours in very difficult cases ... )

-You can also help your HP-41 in many ways:
-For example, if the last row is empty and the 8th row is not, swap them ( R08 <> R09 )
 and swap these registers again when the solution is found.
-Remember that the search starts with the last digit of register R09 then the next to last ( i-e 8th ) digit of R09 and so on ...
 

3°)  Creating a Grid
 

-This program uses a solved sudoku ( lines 08 to 25 ),  then it randomly permutes raws and columns
  and stores this - solved - sudoku in registers R19 to R27 ( lines 127-128 ).
-Finally, cells are replaced by 0 to get a puzzle with N fixed cells, where N is to be specified by the user.

-Line 126 is a three-byte GTO 01.
 
 

  01  LBL "GRID"
  02  STO 00
  03  81
  04  RCL Z
  05  -
  06  INT
  07  STO 18        
  08  1.798642315
  09  STO 01
  10  1.415973628
  11  STO 02
  12  1.362185974
  13  STO 03
  14  1.674528193
  15  STO 04
  16  1.521739486
  17  STO 05
  18  1.839461752
  19  STO 06
  20  1.943857261
  21  STO 07
  22  1.186294537
  23  STO 08
  24  1.257316849
  25  STO 09
  26  7.00003
  27  STO 15
  28  5
  29  STO 16
  30  LBL 01
  31  RCL 15
  32  STO 10
  33  LBL 02
  34  RCL 00
  35  R-D
  36  FRC
  37  STO 00
  38  3
  39  *
  40  INT
  41  LBL 03
  42  RCL 00        
  43  R-D
  44  FRC
  45  STO 00
  46  3
  47  *
  48  INT
  49  X=Y?
  50  GTO 03
  51  RCL 10
  52  ST+ Z
  53  +
  54  RCL IND Y
  55  X<> IND Y
  56  STO IND Z
  57  DSE 10
  58  GTO 02
  59  RCL 15
  60  STO 10
  61  LBL 04
  62  RCL 00
  63  R-D
  64  FRC
  65  STO 00
  66  3
  67  *
  68  INT
  69  LBL 05
  70  RCL 00
  71  R-D
  72  FRC
  73  STO 00        
  74  3
  75  *
  76  INT
  77  X=Y?
  78  GTO 05
  79  RCL 10
  80  +
  81  INT
  82  10^X
  83  STO 11
  84  CLX
  85  RCL 10
  86  +
  87  INT
  88  10^X
  89  STO 12
  90  9
  91  STO 14
  92  LBL 06
  93  RCL IND 14
  94  RCL 11
  95  *
  96  STO Y
  97  10
  98  MOD
  99  INT
100  STO 13
101  -
102  RCL 12
103  RCL 11
104  /
105  STO 17        
106  *
107  STO Y
108  10
109  MOD
110  INT
111  ST- Y
112  X<> 13
113  +
114  RCL 17
115  /
116  RCL 13
117  +
118  RCL 11
119  /
120  STO IND 14
121  DSE 14
122  GTO 06
123  DSE 10
124  GTO 04
125  DSE 16
126  GTO 01
127  1.019009
128  REGMOVE
129  LBL 07
130  9
131  STO 11
132  LBL 08
133  RCL 00
134  R-D
135  FRC
136  STO 00
137  9
138  *
139  INT
140  1
141  +
142  10^X
143  STO 12        
144  RCL IND 11
145  1
146  X=Y?
147  GTO 09
148  RDN
149  *
150  STO Y
151  10
152  MOD
153  INT
154  X=0?
155  GTO 08
156  -
157  RCL 12
158  /
159  STO IND 11
160  DSE 18
161  X=0?
162  GTO 10
163  LBL 09
164  DSE 11
165  GTO 08
166  GTO 07
167  LBL 10
168  END

 
   ( 321 bytes / SIZE 028 )
 
 

      STACK        INPUTS      OUTPUTS
           Y             N             /
           X              r             /

  where   N is an integer between 1 and 81 to get a puzzle with N non-empty cells
   and      r  is a random seed

Example:    You want to get a sudoku with 28 non-empty cells, and you choose 1 as random seed.

     28   ENTER^
      1    XEQ "GRID"   and we get the grid in registers R01 thru R09

  R01 = 1.800600130
  R02 = 1.003050004
  R03 = 1.000900068
  R04 = 1.008016000
  R05 = 1.005003800            ( the integer part doesn't really matter )
  R06 = 1.006500003
  R07 = 1.000361000
  R08 = 1.600000307
  R09 = 1.000005601

-So, the puzzle is

  8  0  0  |  6  0  0  |  1  3  0
  0  0  3  |  0  5  0  |  0  0  4
  0  0  0  |  9  0  0  |  0  6  8
  ---------------------------
  0  0  8  |  0  1  6  |  0  0  0
  0  0  5  |  0  0  3  |  8  0  0
  0  0  6  |  5  0  0  |  0  0  3
  --------------------------
  0  0  0  |  3  6  1  |  0  0  0
  6  0  0  |  0  0  0  |  3  0  7
  0  0  0  |  0  0  5  |  6  0  1

-If you don't solve the grid, one solution is in registers  R19 thru R27
-In this example, "SDK" gives another solution.

Notes:

-Replace line 28 ( 5 )  by a larger integer if you think that the original grid is not enough shuffled.
-This routine does not always return a proper sudoku ( i-e with a unique solution ), especially if N is small.
-If it happens ... it's only by chance !

-If you have a "RAND" M-code function, replace all the  RCL 00   R-D   FRC  STO 00  by  RAND
    replace lines 02-03-04 by    81  X<>Y
    and simply put N in X-register before executing "GRID"