Build a Killer Sudoku Solver
GolfScript, 138 characters
n%~[~]:N;1/:P.&:L;9..*?{(.[{.9%)\9/}81*;]:§;L{.`{\~@@=*}+[P§]zip%{+}*\L?N==}%§9/..zip+\3/{{3/}%zip{{+}*}%}%{+}*+{.&,9=}%+1-,!{§puts}*.}do;
This is a killer sudoku solver in GolfScript. It expects input on STDIN in two rows as given in the example above.
Please note: Since the puzzle description does not make any restrictions on execution time I preferred small code size over speed. The code tests all 9^81 grid configurations for a solution which may take some time on a slow computer ;-)
R - 378 characters
Assuming
x="AABBBCDEFGGHHCCDEFGGIICJKKFLMMINJKOFLPPQNJOORSPTQNUVVRSTTQWUUXXSYZWWaaXXSYZWbbbcc"
y="3 15 22 4 16 15 25 17 9 8 20 6 14 17 17 13 20 12 27 6 20 6 10 14 8 16 15 13 17"
378 characters:
z=strsplit
v=sapply
R=rep(1:9,9)
C=rep(1:9,e=9)
N=1+(R-1)%/%3+3*(C-1)%/%3
G=z(x,"")[[1]]
M=as.integer(z(y," ")[[1]])[order(unique(G))]
s=c(1,rep(NA,80))
i=1
repeat if({n=function(g)!any(v(split(s,g),function(x)any(duplicated(x,i=NA))))
S=v(split(s,G),sum)
n(R)&&n(C)&&n(N)&&n(G)&&all(is.na(S)|S==M)}){if(i==81)break;i=i+1;s[i]=1}else{while(s[i]==9){s[i]=NA
i=i-1};s[i]=s[i]+1}
s
takes about an hour on my modest PC to reach the expected solution, after 2,964,690 iterations.
De-golfed:
ROWS <- rep(1:9, 9)
COLS <- rep(1:9, each = 9)
NONETS <- 1 + (ROWS - 1) %/% 3 + 3 * (COLS - 1) %/% 3
CAGES <- strsplit(x, "")[[1]]
SUMS <- as.integer(strsplit(y, " ")[[1]])[order(unique(CAGES))]
is.valid <- function(sol) {
has.no.repeats <- function(sol, grouping) {
!any(vapply(split(sol, grouping),
function(x) any(duplicated(x, incomparables = NA)),
logical(1)))
}
has.exp.sum <- function(sol, grouping, exp.sums) {
sums <- vapply(split(sol, grouping), sum, integer(1))
all(is.na(sums) | sums == exp.sums)
}
has.no.repeats(sol, ROWS ) &&
has.no.repeats(sol, COLS ) &&
has.no.repeats(sol, NONETS) &&
has.no.repeats(sol, CAGES ) &&
has.exp.sum(sol, CAGES, SUMS)
}
sol <- c(1L, rep(NA, 80)) # start by putting a 1
i <- 1L # in the first cell
it <- 0L
repeat {
it <- it + 1L
if (it %% 100L == 0L) print(sol)
if(is.valid(sol)) { # if everything looks good
if (i == 81L) break # we are either done
i <- i + 1L # or we move to the next cell
sol[i] <- 1L # and make it a 1
} else { # otherwise
while (sol[i] == 9L) { # while 9s are found
sol[i] <- NA # replace them with NA
i <- i - 1L # and move back to the previous cell
}
sol[i] <- sol[i] + 1L # when a non-9 is found, increase it
} # repeat
}
sol
Ruby, 970 characters
A,B=gets,gets.split
L=[]
R=[]
U=[]
D=[]
N=[]
C=[]
S=[]
O=[0]*81
z='A'
(0..324).map{|j|U<<j;D<<j;R<<(j+1)%325;L<<(j+324)%325;N<<j;C<<j;S<<0}
X=->s,j,c,cf,n{j<81?(z==A[j]?(0..8).map{|i|X[s-1-i,j+1,c+[i],cf+[1+j,1+81+27*i+j/9,1+81+27*i+9+j%9,1+81+27*i+18+j/3%3+j/27*3],n+[i+1]]}:X[s,j+1,c,cf,n+[0]]if s>=0):(h=U.size;cf.uniq.sort.map{|l|N<<n;L<<(L[h]||h);R<<h;U<<U[l];D<<l;C<<l;S[l]+=1;L[R[-1]]=R[L[-1]]=U[D[-1]]=D[U[-1]]=L.size-1}if s==0)}
Y=->c{L[R[c]]=L[c];R[L[c]]=R[c];i=D[c];(j=R[i];(U[D[j]]=U[j];D[U[j]]=D[j];S[C[j]]-=1;j=R[j])while j!=i;i=D[i])while i!=c}
Z=->c{i=U[c];(j=L[i];(S[C[j]]+=1;U[D[j]]=j;D[U[j]]=j;j=L[j])while j!=i;i=U[i])while i!=c;L[R[c]]=c;R[L[c]]=c}
B.map{|k|X[k.to_i,0,[],[],[]];z=z=='Z'?'a':z.next}
s=->k{c=R[0];c<1?($><<(O[0,k].map{|s|N[s]}.transpose.map &:max)*""):(g=S[b=c];g=S[b=c]if S[c]<g while 0<c=R[c];Y[b];r=D[b];(O[k]=r;j=R[r];(Y[C[j]];j=R[j])while j!=r;s[k+1];r=O[k];c=C[r];j=L[r];(Z[C[j]];j=L[j])while j!=r;r=D[r])while r!=b;Z[b])}
s[0]
The above ruby code is opposite to my GolfScript subscription. It is quite long (and not yet fully golfed), but optimized for speed. The killer sudoku given above is solved in well under a second (with my original java version it was only a few milli seconds). The solver itself is a basic implementation of Knuth's DLX algorithm.
Input must be given as two lines on STDIN. Example (online):
> AABBBCDEFGGHHCCDEFGGIICJKKFLMMINJKOFLPPQNJOORSPTQNUVVRSTTQWUUXXSYZWWaaXXSYZWbbbcc
3 15 22 4 16 15 25 17 9 8 20 6 14 17 17 13 20 12 27 6 20 6 10 14 8 16 15 13 17
215647398368952174794381652586274931142593867973816425821739546659428713437165289