R-378文字
想定
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文字:
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
2,964,690回の反復の後、私の控えめなPCで期待されるソリューションに到達するのに約1時間かかります。
脱ゴルフ:
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