Zbuduj Killer Sudoku Solver


9

Myślałeś, że zwykłe sudoku jest trudne, teraz wypróbuj Killer Sudoku !

W grze Killer Sudoku nie otrzymujesz żadnych liczb. Zamiast tego otrzymujesz regiony, o których mówi się, że sumują się do określonej liczby. Rozważ następujący przykład z Wikipedii:

zabójcza sudoku

I jego rozwiązanie:

zabójcze sudoku puzzle

Program, który napiszesz, przyjmie format składający się z sekwencji 81 liter reprezentujących regiony, a następnie sekwencji cyfr. Następnie każda liczba w sekwencji reprezentuje sumę liczb w każdym obszarze literowym, zaczynając od „A”, „B” itp.

Następnie wyświetli sekwencję 81 cyfr reprezentujących rozwiązanie.

Na przykład powyższa łamigłówka zawiera następujące dane wejściowe:

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

Wynikowy wynik to:

215647398368952174794381652586274931142593867973816425821739546659428713437165289

Możesz założyć, że dane wejściowe są prawidłowe i że regiony zawsze będą wyświetlane w kolejności według A, B, ..., Y, Z, a, b, ..., z.

(Wygrywa najkrótszy działający kod).


Jak wygrać konkurs? Najkrótszy kod? Najszybszy kod?
beary605

Najkrótszy kod. [przekroczył limit znaków o 1 znak.]
Joe Z.

A jeśli jest więcej niż 52 regiony, to co?
Pan Lister,

Możesz założyć, że nie będzie więcej niż 45 regionów.
Joe Z.

1
Czy liczba może się powtarzać w obrębie klatki?
Peter Taylor

Odpowiedzi:


4

R - 378 znaków

Zarozumiały

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 znaków:

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

na moim skromnym komputerze zajmuje około godziny, aby osiągnąć oczekiwane rozwiązanie po 2 964 690 iteracjach.


Gra w golfa:

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

4

GolfScript, 138 znaków

n%~[~]:N;1/:P.&:L;9..*?{(.[{.9%)\9/}81*;]:§;L{.`{\~@@=*}+[P§]zip%{+}*\L?N==}%§9/..zip+\3/{{3/}%zip{{+}*}%}%{+}*+{.&,9=}%+1-,!{§puts}*.}do;

To jest solver zabójcy sudoku w GolfScript. Oczekuje danych wejściowych STDIN w dwóch wierszach, jak podano w powyższym przykładzie.

Uwaga: Ponieważ opis łamigłówki nie nakłada żadnych ograniczeń na czas wykonania, wolałem mały rozmiar kodu niż szybkość. Kod testuje wszystkie konfiguracje siatki 9 ^ 81 pod kątem rozwiązania, które może zająć trochę czasu na wolnym komputerze ;-)


Czy możesz to zweryfikować? : P
Joe Z.

@JoeZeng, dostrojenie go do 4x4 wygląda na łatwe. Oto przypadek testowy:AABBCADEFFDDGGGG 6 7 4 8 2 3 10
Peter Taylor

@PeterTaylor Twój przypadek testowy ma cztery różne prawidłowe rozwiązania.
Joe Z.

4

Ruby, 970 znaków

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]

Powyższy kod ruby ​​jest przeciwny do mojej subskrypcji GolfScript. Jest dość długi (i jeszcze nie w pełni golfowy), ale zoptymalizowany pod kątem prędkości. Podane powyżej zabójcze sudoku zostało rozwiązane w niecałą sekundę (w mojej oryginalnej wersji Java było to zaledwie kilka milisekund). Sam solver jest podstawową implementacją algorytmu Knuth DLX.

Dane wejściowe muszą być podane jako dwa wiersze na STDIN. Przykład ( 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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.