Winner the cyclist (CT 1)

Finish 2005-11-09 09:00:00 UTC

SHsudo18

by Stijn Helsen

Status: Failed
Results:

Based on: SHsudo16 (diff)

Comments
Stijn Helsen
09 Nov 2005
you never know
Please login or create a profile.
Code
function solution = solver(puzzle,list)

rand('seed',1);

list=list(:,end:-1:1);
global h iX iN col_selection blockmap rowmap colmap;
h =  [1    4    7   28   31   34   55   58   61
    2    5    8   29   32   35   56   59   62
    3    6    9   30   33   36   57   60   63
   10   13   16   37   40   43   64   67   70
   11   14   17   38   41   44   65   68   71
   12   15   18   39   42   45   66   69   72
   19   22   25   46   49   52   73   76   79
   20   23   26   47   50   53   74   77   80
   21   24   27   48   51   54   75   78   81];
  h1 =[ 1    10    19    28    37    46    55    64    73
     2    11    20    29    38    47    56    65    74
     3    12    21    30    39    48    57    66    75
     4    13    22    31    40    49    58    67    76
     5    14    23    32    41    50    59    68    77
     6    15    24    33    42    51    60    69    78
     7    16    25    34    43    52    61    70    79
     8    17    26    35    44    53    62    71    80
     9    18    27    36    45    54    63    72    81]; 
iX = uint8([h h1 h1']);
iN = [3 1 1 2 2 2 2 2 2 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3
 1 3 1 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3
 1 1 3 2 2 2 2 2 2 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3
 2 2 2 3 1 1 2 2 2 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3
 2 2 2 1 3 1 2 2 2 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3
 2 2 2 1 1 3 2 2 2 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3
 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3
 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3
 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2
 1 2 2 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3
 2 1 2 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3
 2 2 1 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3
 3 3 3 1 2 2 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3
 3 3 3 2 1 2 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3
 3 3 3 2 2 1 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3
 3 3 3 3 3 3 1 2 2 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3
 3 3 3 3 3 3 2 1 2 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3
 3 3 3 3 3 3 2 2 1 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2
 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3
 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3
 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3
 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3
 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3
 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3
 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3
 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3
 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2
 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3
 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3
 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3
 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3
 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3
 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3
 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3
 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3
 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2
 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3
 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3
 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3
 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3
 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3
 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3
 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3
 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3
 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2
 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3
 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3
 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3
 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3
 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3
 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3
 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3
 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3
 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2
 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3
 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3
 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3
 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3
 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3
 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3
 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2
 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2
 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1
 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2 1 2 2 3 3 3 3 3 3
 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2 2 1 2 3 3 3 3 3 3
 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2 2 2 1 3 3 3 3 3 3
 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 2 2 2 3 1 1 2 2 2 3 3 3 1 2 2 3 3 3
 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 2 2 2 1 3 1 2 2 2 3 3 3 2 1 2 3 3 3
 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 2 2 2 1 1 3 2 2 2 3 3 3 2 2 1 3 3 3
 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 2 2 2 2 2 2 3 1 1 3 3 3 3 3 3 1 2 2
 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 2 2 2 2 2 2 1 3 1 3 3 3 3 3 3 2 1 2
 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 2 2 2 2 2 2 1 1 3 3 3 3 3 3 3 2 2 1
 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 3 1 1 2 2 2 2 2 2
 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 1 3 1 2 2 2 2 2 2
 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 1 1 3 2 2 2 2 2 2
 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 3 3 3 2 2 2 3 1 1 2 2 2
 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 3 3 3 2 2 2 1 3 1 2 2 2
 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 3 3 3 2 2 2 1 1 3 2 2 2
 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 1 2 2 3 3 3 3 3 3 1 2 2 2 2 2 2 2 2 3 1 1
 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 2 1 2 3 3 3 3 3 3 2 1 2 2 2 2 2 2 2 1 3 1
 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 2 2 1 3 3 3 3 3 3 2 2 1 2 2 2 2 2 2 1 1 3];

col_selection = [[4 5 6 7 8 9];[7 8 9 7 8 9]];
blockmap=[1     1     1     4     4     4     7     7     7
     1     1     1     4     4     4     7     7     7
     1     1     1     4     4     4     7     7     7
     2     2     2     5     5     5     8     8     8
     2     2     2     5     5     5     8     8     8
     2     2     2     5     5     5     8     8     8
     3     3     3     6     6     6     9     9     9
     3     3     3     6     6     6     9     9     9
     3     3     3     6     6     6     9     9     9];
rowmap = [1     1     1     1     1     1     1     1     1
     2     2     2     2     2     2     2     2     2
     3     3     3     3     3     3     3     3     3
     4     4     4     4     4     4     4     4     4
     5     5     5     5     5     5     5     5     5
     6     6     6     6     6     6     6     6     6
     7     7     7     7     7     7     7     7     7
     8     8     8     8     8     8     8     8     8
     9     9     9     9     9     9     9     9     9];
colmap = [1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9
     1     2     3     4     5     6     7     8     9];


[solution,s]    =solverC(puzzle,list);                                                            
if floor(s) == 19
        [sol2,s2]       =solverC(puzzle(:,end:-1:1),list);
        if s2<s
                solution=sol2(:,end:-1:1);
                s=s2;
        end
end 
if s > 200
        [sol2,s2]       =solverC(puzzle(end:-1:1,:),list);
        if s2<s
                solution=sol2(end:-1:1,:);
                s=s2;
        end
end

idx=find(puzzle==0);
[solution1,s2]  =improver3(list,solution,idx);
if s2<s
        solution=solution1;
        s=s2;
end     
if s>100
	[solution1,s2]  =improver3(list,solution,idx);
        if s2<s
                solution=solution1;
        end
end

flag=1;
while flag
  [solution,flag]=improver4(solution,list,idx);
end;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [solution,s] = solverC(puzzle,list)
NUMREPS = 25000;
NUMTRIES1 = 200;
NUMTRIES2 = 200;
NUMTRIES3 = 300;

global h iX iN col_selection blockmap rowmap colmap;

free = puzzle==0;
q = uint8(find(free)');
missing = numel(q);
lq = missing;
list_count = numel(list);
listO=list;
NUMRUNS = (list_count / 10)+10;
% Calculate the average of all values available
total_puzzle = sum(sum(puzzle));
total_all = sum(list) + total_puzzle;
total_count = (81 - missing) + list_count;
average = total_all / total_count;
target = average*9;
bestscore2 = 1e10;
bestscore = 1e10;
reruns=0;

index1v = ceil(rand(1,NUMREPS)*lq);
index1v = q(index1v);
index2v = mod((index1v+uint8(floor(rand(1,NUMREPS)*(lq-1)))),lq)+1;
index2v = q(index2v);

id=1:9;

if target>600
    idT=sum(free);
    [tempT,id]=sort(idT,'descend');
end

while reruns<3
        for run = 1:NUMRUNS
                % Fill in values to optimize the rows
                list = listO;
                list_left = list_count;
                solution = puzzle;
                % Fill in values to optimize the rows
                for r=id
        %for r = 1:9
                        % Fill in values for all empty spaces in this row
                        for c = 1:9
                                if free(r,c)
                                        list_index = ceil(rand*list_left);
                                        solution(r,c) = list(list_index);
                                        list(list_index)=[];
                                        list_left = list_left-1;
                                end
                        end
                        list(end+1:list_count) = 1e10;
                        if list_left
                                %  Get row as close as possible to
                                %  target value
                                row_total = sum(solution(r,:)) - target;
                                est_error = abs(row_total);
                                tq = r + 9*(find(free(r,:))-1);
                                indv = tq(ceil(rand(NUMTRIES1,1)*numel(tq)));
rt = rand(NUMTRIES1,1);
                                for tries = 1:NUMTRIES1
                                        ind = indv(tries);
                                        list_index = ceil(rt(tries)*list_left);
                                        list_value = list(list_index);
                                        delta = list_value - solution(ind);
                                        new_est_error = abs(row_total + delta);
                                        if (new_est_error < est_error)
                                                row_total = row_total + delta;
                                                est_error = new_est_error;
                                                list(list_index) = solution(ind);
                                                solution(ind) = list_value;
                                        end
                                end
                        end
                end
        
                target = sum(sum(solution)) *0.11111111111111111111111;
                
                        % Go about optimizing blocks without changing rows
        
                                cols_all_outside = 4:9;
                                block = sum(sum(solution(1:3,1:3)));
                for tries = 1:NUMTRIES2         
                  row        = ceil(rand*3);
                  col_inside = ceil(rand*3);
                  if free(row,col_inside)
                    col_outside = cols_all_outside(ceil(rand*6));
                    if free(row,col_outside)
                      val_inside  = solution(row, col_inside);
                      val_outside = solution(row, col_outside);
                      new_block   = block - val_inside + val_outside;
                      if abs(new_block - target) < abs(block - target)
                        solution(row,col_outside) = val_inside;
                        solution(row,col_inside)  = val_outside;
                        block                     = new_block;
                      end    
                    end
                  end
                end
                
                                cols_all_outside = [7 8 9 7 8 9];
                                block = sum(sum(solution(1:3,4:6)));
                for tries = 1:NUMTRIES2         
                  row        = ceil(rand*3);
                  col_inside = 3 + ceil(rand*3);
                  if free(row,col_inside)
                    col_outside = cols_all_outside(ceil(rand*6));
                    if free(row,col_outside)
                      val_inside  = solution(row, col_inside);
                      val_outside = solution(row, col_outside);
                      new_block   = block - val_inside + val_outside;
                      if abs(new_block - target) < abs(block - target)
                        solution(row,col_outside) = val_inside;
                        solution(row,col_inside)  = val_outside;
                        block                     = new_block;
                      end    
                    end
                  end
                end



        
        
        

                                cols_all_outside = 4:9;
                                block = sum(sum(solution(4:6,1:3)));
                for tries = 1:NUMTRIES2         
                  row        = 3 + ceil(rand*3);
                  col_inside = ceil(rand*3);
                  if free(row,col_inside)
                    col_outside = cols_all_outside(ceil(rand*6));
                    if free(row,col_outside)
                      val_inside  = solution(row, col_inside);
                      val_outside = solution(row, col_outside);
                      new_block   = block - val_inside + val_outside;
                      if abs(new_block - target) < abs(block - target)
                        solution(row,col_outside) = val_inside;
                        solution(row,col_inside)  = val_outside;
                        block                     = new_block;
                      end    
                    end
                  end
                end
                                cols_all_outside = [7 8 9 7 8 9];
                                block = sum(sum(solution(4:6,4:6)));
                                
                for tries = 1:NUMTRIES2         
                  row        = 3 + ceil(rand*3);
                  col_inside = 3 + ceil(rand*3);
                  if free(row,col_inside)
                    col_outside = cols_all_outside(ceil(rand*6));
                    if free(row,col_outside)
                      val_inside  = solution(row, col_inside);
                      val_outside = solution(row, col_outside);
                      new_block   = block - val_inside + val_outside;
                      if abs(new_block - target) < abs(block - target)
                        solution(row,col_outside) = val_inside;
                        solution(row,col_inside)  = val_outside;
                        block                     = new_block;
                      end    
                    end
                  end
                end

        
                
                

                                cols_all_outside = 4:9;
                                block = sum(sum(solution(7:9,1:3)));
                                
                for tries = 1:NUMTRIES2         
                  row        = 6 + ceil(rand*3);
                  col_inside = ceil(rand*3);
                  if free(row,col_inside)
                    col_outside = cols_all_outside(ceil(rand*6));
                    if free(row,col_outside)
                      val_inside  = solution(row, col_inside);
                      val_outside = solution(row, col_outside);
                      new_block   = block - val_inside + val_outside;
                      if abs(new_block - target) < abs(block - target)
                        solution(row,col_outside) = val_inside;
                        solution(row,col_inside)  = val_outside;
                        block                     = new_block;
                      end    
                    end
                  end
                end
                
                                cols_all_outside = [7 8 9 7 8 9];
                                block = sum(sum(solution(7:9,4:6)));
                for tries = 1:NUMTRIES2         
                  row        = 6 + ceil(rand*3);
                  col_inside = 3 + ceil(rand*3);
                  if free(row,col_inside)
                    col_outside = cols_all_outside(ceil(rand*6));
                    if free(row,col_outside)
                      val_inside  = solution(row, col_inside);
                      val_outside = solution(row, col_outside);
                      new_block   = block - val_inside + val_outside;
                      if abs(new_block - target) < abs(block - target)
                        solution(row,col_outside) = val_inside;
                        solution(row,col_inside)  = val_outside;
                        block                     = new_block;
                      end    
                    end
                  end
                end     
                %Solve the columns without changing rows or blocks
                col_total = sum(solution) - target;
                for tries = 1:NUMTRIES3
                        el = q(ceil(rand*missing));
                        col = colmap(el);
                        row = el - 9*(col-1);
                        col_swap = ceil(rand*3) + (ceil(col/3)-1)*3;
                        if free(row,col_swap)
                                value_swap = solution(row,col_swap);
                                error = abs(col_total(col));
                                value = solution(row,col);
                                col_swap_total = col_total(col_swap);
                                col_total_new = col_total(col) + value_swap - value;
                                col_swap_total_new = col_swap_total + value - value_swap;
                                error_total_new = abs(col_total_new) + abs(col_swap_total_new);
                                if (error_total_new < error + abs(col_swap_total))
                                        solution(el) = value_swap;
                                        solution(row, col_swap) = value;
                                        col_total(col_swap) = col_swap_total_new;
                                        col_total(col) = col_total_new;
                                end
                        end
                end
        
                sums  = sum(solution(iX));
                score = sum(abs(sum(sums)*0.03703703703703703703-sums));
                if score < bestscore
                        bestinit = solution;
                        bestscore = score;
                        bestlist = list;
                        coltotals = col_total + target;
                else
                   solution = bestinit;
                   list = bestlist;
                  sTemp = sum(solution);
                  target = sum(sTemp) *0.11111111111111111111;
                  coltotals = sTemp;
                end             
        
                rowtotals = sum(solution,2)';
                coltotals = sTemp;
                blocktotals = sum(solution(h));
                
                if list_left ~= 0
                        rep = 0;
                        for repl = 1:5000 %  blimey! loop unroll! (drumroll?)
                                target3=target*3; %constant for loop 0-3
                                % ----- loop 0,  do the first thing (loops 0-3 are the same)
                                rep = rep + 1;
                                index1 = index1v(rep);     index2 = index2v(rep);
                                index1r = rowmap(index1);  index2r = rowmap(index2);
                                index1c = colmap(index1);  index2c = colmap(index2);
                                value1 = solution(index1); value2 = solution(index2);
                                block1i = blockmap(index1);block2i = blockmap(index2);
                                valdiff = value1-value2;
                nvd=iN(index1,index2)*valdiff;
                                subtotal1_old = rowtotals(index1r) + coltotals(index1c) + blocktotals(block1i) - target3;
                                subtotal2_old = rowtotals(index2r) + coltotals(index2c) + blocktotals(block2i) - target3;
                                subscoret_old = abs(subtotal1_old) + abs(subtotal2_old);
                                subscoret_new = abs(subtotal1_old-nvd) + abs(subtotal2_old+nvd); 
                                if (subscoret_new - subscoret_old) < (rand*0.1666666667)
                                        solution(index1) = value2;
                                        solution(index2) = value1;
                                        % dont bother to compare if the rows/cols are the same..
                                        rowtotals(index1r) = rowtotals(index1r) - valdiff;
                                        rowtotals(index2r) = rowtotals(index2r) + valdiff;
                                        coltotals(index1c) = coltotals(index1c) - valdiff;
                                        coltotals(index2c) = coltotals(index2c) + valdiff;
                                        blocktotals(block1i) = blocktotals(block1i) - valdiff;
                                        blocktotals(block2i) = blocktotals(block2i) + valdiff;
                                end
                                % ----- loop 1,  do the first thing
                                rep = rep + 1;
                                index1 = index1v(rep);     index2 = index2v(rep);
                                index1r = rowmap(index1);  index2r = rowmap(index2);
                                index1c = colmap(index1);  index2c = colmap(index2);
                                value1 = solution(index1); value2 = solution(index2);
                                block1i = blockmap(index1);block2i = blockmap(index2);
                                valdiff = value1-value2;
                nvd=iN(index1,index2)*valdiff;
                                subtotal1_old = rowtotals(index1r) + coltotals(index1c) + blocktotals(block1i) - target3;
                                subtotal2_old = rowtotals(index2r) + coltotals(index2c) + blocktotals(block2i) - target3;
                                subscoret_old = abs(subtotal1_old) + abs(subtotal2_old);
                                subscoret_new = abs(subtotal1_old-nvd) + abs(subtotal2_old+nvd); 
                                if (subscoret_new - subscoret_old) < (rand*0.1666666667)
                                        solution(index1) = value2;
                                        solution(index2) = value1;
                                        % dont bother to compare if the rows/cols are the same..
                                        rowtotals(index1r) = rowtotals(index1r) - valdiff;
                                        rowtotals(index2r) = rowtotals(index2r) + valdiff;
                                        coltotals(index1c) = coltotals(index1c) - valdiff;
                                        coltotals(index2c) = coltotals(index2c) + valdiff;
                                        blocktotals(block1i) = blocktotals(block1i) - valdiff;
                                        blocktotals(block2i) = blocktotals(block2i) + valdiff;
                                end
                                % ----- loop 2,  do the first thing
                                rep = rep + 1;
                                index1 = index1v(rep);     index2 = index2v(rep);
                                index1r = rowmap(index1);  index2r = rowmap(index2);
                                index1c = colmap(index1);  index2c = colmap(index2);
                                value1 = solution(index1); value2 = solution(index2);
                                block1i = blockmap(index1);block2i = blockmap(index2);
                                valdiff = value1-value2;
                nvd=iN(index1,index2)*valdiff;
                                subtotal1_old = rowtotals(index1r) + coltotals(index1c) + blocktotals(block1i) - target3;
                                subtotal2_old = rowtotals(index2r) + coltotals(index2c) + blocktotals(block2i) - target3;
                                subscoret_old = abs(subtotal1_old) + abs(subtotal2_old);
                                subscoret_new = abs(subtotal1_old-nvd) + abs(subtotal2_old+nvd); 
                                if (subscoret_new - subscoret_old) < (rand*0.166666667)
                                        solution(index1) = value2;
                                        solution(index2) = value1;
                                        % dont bother to compare if the rows/cols are the same..
                                        rowtotals(index1r) = rowtotals(index1r) - valdiff;
                                        rowtotals(index2r) = rowtotals(index2r) + valdiff;
                                        coltotals(index1c) = coltotals(index1c) - valdiff;
                                        coltotals(index2c) = coltotals(index2c) + valdiff;
                                        blocktotals(block1i) = blocktotals(block1i) - valdiff;
                                        blocktotals(block2i) = blocktotals(block2i) + valdiff;
                                end
                                % ----- loop 3,  do the first thing
                                rep = rep + 1;
                                index1 = index1v(rep);     index2 = index2v(rep);
                                index1r = rowmap(index1);  index2r = rowmap(index2);
                                index1c = colmap(index1);  index2c = colmap(index2);
                                value1 = solution(index1); value2 = solution(index2);
                                block1i = blockmap(index1);block2i = blockmap(index2);
                                valdiff = value1-value2;
                nvd=iN(index1,index2)*valdiff;
                                subtotal1_old = rowtotals(index1r) + coltotals(index1c) + blocktotals(block1i) - target3;
                                subtotal2_old = rowtotals(index2r) + coltotals(index2c) + blocktotals(block2i) - target3;
                                subscoret_old = abs(subtotal1_old) + abs(subtotal2_old);
                                subscoret_new = abs(subtotal1_old-nvd) + abs(subtotal2_old+nvd); 
                                if (subscoret_new - subscoret_old) < (rand*0.1666666667)
                                        solution(index1) = value2;
                                        solution(index2) = value1;
                                        % dont bother to compare if the rows/cols are the same..
                                        rowtotals(index1r) = rowtotals(index1r) - valdiff;
                                        rowtotals(index2r) = rowtotals(index2r) + valdiff;
                                        coltotals(index1c) = coltotals(index1c) - valdiff;
                                        coltotals(index2c) = coltotals(index2c) + valdiff;
                                        blocktotals(block1i) = blocktotals(block1i) - valdiff;
                                        blocktotals(block2i) = blocktotals(block2i) + valdiff;
                                end
                                %------ loop 4, do the other thing
                                rep = rep+1;
                                index1 = index1v(rep);
                                index1r = rowmap(index1);
                                index1c = colmap(index1);
                                value1 = solution(index1);
                                block1i = blockmap(index1);
                                list_index = ceil(rand*list_left);
                                replace = list(list_index);
                                subtotal1_old = rowtotals(index1r) + coltotals(index1c) + blocktotals(block1i);
                newtarg = target + (replace-value1) *0.11111111111111111111111;
                                score_diff = abs(subtotal1_old+3*(replace-value1-newtarg)) - abs(subtotal1_old - 3*target);
                                if score_diff < 0.93*rand
                                        solution(index1) = replace;
                                        list(list_index) = value1;
                    delta=replace-value1;
                                        rowtotals(index1r) = rowtotals(index1r) + delta;
                                        coltotals(index1c) = coltotals(index1c) + delta;
                                        blocktotals(block1i) = blocktotals(block1i) + delta;
                                        target = newtarg;
                                end
                                % ---- end loop
                        end
                
                else % (list_left == 0)
        
                        % time for fresh random numbers...
                        index1v = ceil(rand(NUMREPS,1)*lq);
                        index1v = q(index1v);
                        sok=NUMREPS-350;
            target3=target*3;   %constant target
                        for rep = 1:sok
                                % --- this is same as the "first thing" above
                                index1 = index1v(rep);     index2 = index2v(rep);
                                index1r = rowmap(index1);  index2r = rowmap(index2);
                                index1c = colmap(index1);  index2c = colmap(index2);
                                value1 = solution(index1); value2 = solution(index2);
                                block1i = blockmap(index1);block2i = blockmap(index2);
                                
                                valdiff = value1-value2;
                nvd=iN(index1,index2)*valdiff;

                                subtotal1_old = rowtotals(index1r) + coltotals(index1c) + blocktotals(block1i) - target3;
                                subtotal2_old = rowtotals(index2r) + coltotals(index2c) + blocktotals(block2i) - target3;
                                subscoret_old = abs(subtotal1_old) + abs(subtotal2_old);
                                subscoret_new = abs(subtotal1_old-nvd) + abs(subtotal2_old+nvd); 
                                
                                if (subscoret_new - subscoret_old) < (rand*0.1666666667)
                                        solution(index1) = value2;
                                        solution(index2) = value1;
                                        % dont bother to compare if the rows/cols are the same..
                                        rowtotals(index1r) = rowtotals(index1r) - valdiff;
                                        rowtotals(index2r) = rowtotals(index2r) + valdiff;
                                        coltotals(index1c) = coltotals(index1c) - valdiff;
                                        coltotals(index2c) = coltotals(index2c) + valdiff;
                                        blocktotals(block1i) = blocktotals(block1i) - valdiff;
                                        blocktotals(block2i) = blocktotals(block2i) + valdiff;
                                end
                        
                        end
                end
                % --- end the inner loop
                
                sums  = sum(solution(iX));
                score = sum(abs(sum(sums)*0.0370370370370370-sums));
                if score < bestscore2
                        bestsol = solution;
                        bestscore2 = score;
                end
                if bestscore2 < 5
                        break
                end
        end
        if ( reruns==0 && bestscore2>9 )
                reruns=reruns+1;
        elseif ( reruns==1 && bestscore2>25 )
                reruns=reruns+1;
        else
                reruns=1e8;
        end
end
solution = bestsol;
% --- prepare for final improvers
n=ceil(bestscore2);
X = solution(iX);
sX = sum(X);
mX = sum(sX)*0.0370370370370370;
XX=zeros(81,3);
for i=q
        XX(i,:)=find(sum(iX==i));
end

for i=1:n
        bVerb=0;
        for iEl=q
                I=XX(iEl,:);
                s1=sum(sX(I)-mX);
                if (s1>0&&sum(sX(I)>mX)<2)||(s1<0&&sum(sX(I)<mX)<2)
                        continue
                end
                x=solution(iEl);
                dx=solution(q)-x;
                if s1>0
                        j=find(dx<0.8&dx+s1*2>0&dx~=0);
                else
                        j=find(dx>-0.8&dx+s1*2<0&dx~=0);
                end
                if ~isempty(j)
                        S0=sX-mX;
                        s=sum(abs(S0));
                        m=0;
            kozz=numel(j);
                        for k=1:kozz
                                S=S0;
                                S(I)=S(I)+dx(j(k));
                                J=XX(q(j(k)),:);
                                S(J)=S(J)-dx(j(k));
                                T=sum(abs(S));
                                if T<s
                                        m=k;
                                        s=T;
                                end
                        end
                        if m
                                j=q(j(m));
                                solution(iEl)=solution(j);
                                solution(j)=x;
                                X=solution(iX);
                                sX=sum(X);
                                bVerb=1;
                                
                        end
                end
        end
        if ~bVerb
                break
        end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [out,vprev]=improver3(list,solution,idx)
%Initialize
y=ceil(idx*0.111);
x=idx-(y-1)*9;
a=solution(idx);
a=[a ; list(~ismembc(list,sort(a)))];
N1=numel(idx);

% Initialise the square indices
isquare = [ 1     2     3    10    11    12    19    20    21
     4     5     6    13    14    15    22    23    24
     7     8     9    16    17    18    25    26    27
    28    29    30    37    38    39    46    47    48
    31    32    33    40    41    42    49    50    51
    34    35    36    43    44    45    52    53    54
    55    56    57    64    65    66    73    74    75
    58    59    60    67    68    69    76    77    78
    61    62    63    70    71    72    79    80    81];
square=[1     1     1     4     4     4     7     7     7
     1     1     1     4     4     4     7     7     7
     1     1     1     4     4     4     7     7     7
     2     2     2     5     5     5     8     8     8
     2     2     2     5     5     5     8     8     8
     2     2     2     5     5     5     8     8     8
     3     3     3     6     6     6     9     9     9
     3     3     3     6     6     6     9     9     9
     3     3     3     6     6     6     9     9     9];
% Initialise the solution
out=solution;
N=numel(a)-N1;

% Calculate bounds on the block values
rowsum=sum(out,2);
optsum=sum(rowsum)*0.11111111111;
colsum=sum(out,1)';
sqsum=sum(out(isquare),2);
S=[rowsum(x) colsum(y) sqsum(square(idx))]-optsum;
vprev=Inf;
ii=1; cnt=1;
while 1                         
    yy=ii+1;
        tmp=S(zeros(numel(a)-ii,1)+ii,:);
        tmp=tmp+a(yy:end,[1 1 1])-a(ii);
        tmp=sum(abs(tmp),2)-sum(abs(S(ii,:)));
        tmp2=S(yy:end,:)-a(yy:numel(idx),[1 1 1])+a(ii);
        tmp2=[sum(abs(tmp2),2)-sum(abs(S(yy:end,:)),2) ; zeros(N,1)];
        tmp=tmp+tmp2;
        [tmp,idx3]=min(tmp);
        if (tmp<0)                      % Replace one list value by another
        zz = idx3+ii;
                tmp=a(zz); a(zz)=a(ii); a(ii)=tmp;
                out(x(ii),y(ii))=a(ii);
                if (zz<=size(S,1)) % Swaps the two currently used list values
                        out(x(zz),y(zz))=a(zz);
                else                    % Re-calculate the optimal sum
			optsum=optsum+(a(ii)-a(zz)) *0.111111111111111;
                end                             % Re-calculate the various sums
                rowsum=sum(out,2);
                colsum=sum(out,1)';
                sqsum=sum(out(isquare),2);
                S=[rowsum(x) colsum(y) sqsum(square(idx))]-optsum;
        end
        if (ii==1)
                sums  = [rowsum ; colsum ; sqsum];
                v = sum(abs(sum(sums)/numel(sums)-sums));
                if (v>=vprev)
                        break
                end
                vprev=v;
        end
        ii=yy;
        if (ii==size(S,1))
                ii=1;
                cnt=cnt+1;
                if (cnt==4)
                        break
                end
        end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% All of the previous algorithms have focussed on pairwise switching
% of weights. The main loop is a fast random method for choosing the
% blocks to be switched. What follows that (formerly improver2) is a 
% slower method comparing the scores before and after each pair of blocks 
% already in the matrix have been swapped. Then improver3 is a faster 
% method of doing the same thing, but only approximates the change in 
% score, and also allows swaps with unassigned elements in the list. 
% This improver looks at swapping three elements at a time (although 
% not exhaustively), and can trivially be altered for more than three 
% elements (increasing to more than 3 would probably minimally affect 
% the score though).

function [solution,flag]=improver4(solution,list,idx)

global iX

%Initialize

a=solution(idx); N=numel(a);
a=[a ; list(~ismembc(list,sort(a)))];

sums = sum(solution(iX));
bsc  = sum(abs(sum(sums) *0.0370370370370370-sums)); bsc2=bsc;
ba   = a;

[b,idx2]=sort(a);
zok=numel(a)-2;
for ii=1:zok
  tmp=a(idx2(ii:ii+2));

  a=ba;
  a(idx2(ii:ii+2))=[tmp(2:3) ; tmp(1)];

  solution(idx)=a(1:N);
  
  sums  = sum(solution(iX));
  score = sum(abs(sum(sums) *0.037037037037-sums));
  if (score<bsc) bsc=score; ba=a; continue; end;

  tmp=[tmp(2:3) ; tmp(1)];
  a(idx2(ii:ii+2))=[tmp(2:3) ; tmp(1)];
  solution(idx)=a(1:N);

  sums  = sum(solution(iX));
  score = sum(abs(sum(sums) *0.037037037-sums));
  if (score<bsc) bsc=score; ba=a; continue; end;

  a(idx2(ii:ii+2))=tmp([3;1;2]);

end;

flag=(bsc<bsc2);
solution(idx)=ba(1:N);