有效的数独网格填充数字1到9,在9,行或列的每个子块中没有数字出现多次。如果您不熟悉这个流行的谜题,请阅读this article以获取更多详细信息。
挑战在于编写最短的程序来验证可能未满的Sudoku网格。
输入将是一行9行,每行9个字符,代表网格。空单元格将由.
表示。如果网格有效,则输出应为Valid
,否则输出Invalid
。
123...789
...456...
456...123
789...456
...123...
564...897
...231...
897...564
...564...
Valid
123456789
987654321
123456789
123456789
987654321
123456789
123456789
987654321
123456789
Invalid
请以解决此问题的任何语言发布您的最短代码。输入和输出可以通过stdin和stdout或您选择的其他文件来处理。
Winner将是在发布此问题之前存在实现的语言中最短的解决方案(按字节数)。因此,虽然您可以自由地使用您刚刚编写的语言来提交0字节的解决方案,但它不会计算,并且您可能会得到一些支持。
答案 0 :(得分:11)
n%{zip''+9/.{'.'-..&=}%$0=\}:|2*{3/}%|;**"InvV"3/="alid"
答案 1 :(得分:9)
int v[1566],x,y=9,c,b;main(){while(y--)for(x=9;x--+1;)if((c
=getchar()*27)>1242)b|=v[x+c]++|v[y+9+c]++|v[x-x%3+y/3+18+c]
++;puts(b?"Invalid":"Valid");return 0;}
不需要两个换行符。由josefx保存的一个字符:-) ...
答案 2 :(得分:6)
import List
t=take 3
h=[t,t.drop 3,drop 6]
v[]="V"
v _="Inv"
f s=v[1|v<-[s,transpose s,[g=<<f s|f<-h,g<-h]],g<-map(filter(/='.'))v,g/=nub g]++"alid\n"
main=interact$f.lines
答案 3 :(得分:5)
$_=join'',<>;@a=/.../g;print+(/(\d)([^\n]{0,8}|(.{10})*.{9})\1/s
+map"@a[$_,$_+3,$_+6]"=~/(\d).*\1/,0..2,9..11,18..20)?Inv:V,alid
第一个正则表达式检查同一行和列中的重复项;第二个正则表达式处理“相同框”中的重复。
通过将第一个正则表达式中的\n
替换为文字换行符(1个字符)或使用&gt; = Perl 5.12,将[^\n]
替换为\N
(3),可以进一步改进炭)
早些时候,168 char解决方案: 输入来自stdin,输出是 stderr ,因为它使事情变得如此简单。换行是可选的,不计算在内。
$_=join'',<>;$m=alid.$/;$n=Inv.$m;/(\d)(\N{0,8}|(.{10})*.{9})\1/s&&
die$n;@a=/.../g;for$i(0,8,17){for$j($i..$i+2){
$_=$a[$j].$a[$j+3].$a[$j+6];/(\d).*\1/&&die$n}}die"V$m"
答案 4 :(得分:4)
首先是len = 199的可读版本:
import sys
r=range(9)
g=[raw_input()for _ in r]
s=[[]for _ in r*3]
for i in r:
for j in r:
n=g[i][j]
for x in i,9+j,18+i/3*3+j/3:
<T>if n in s[x]:sys.exit('Invalid')
<T>if n>'.':s[x]+=n
print'Valid'
由于SO不显示制表符,我使用<T>
来表示单个制表符。
PS。同样的方法minEvilized低至185个字符:
r=range(9)
g=[raw_input()for _ in r]
s=['']*27
for i in r:
for j in r:
for x in i,9+j,18+i/3*3+j/3:n=g[i][j];s[x]+=n[:n>'.']
print['V','Inv'][any(len(e)>len(set(e))for e in s)]+'alid'
答案 5 :(得分:4)
@B
包含董事会的81个要素。
&E
测试@B
的子集是否包含任何重复数字
主循环验证每个列,“块”和拼图的行
sub E{$V+="@B[@_]"=~/(\d).*\1/}
@B=map/\S/g,<>;
for$d(@b=0..80){
E grep$d==$_%9,@b;
E grep$d==int(($_%9)/3)+3*int$_/27,@b;
E$d*9..$d*9+8}
print$V?Inv:V,alid,$/
答案 6 :(得分:3)
v=[0]*244
for y in range(9):
for x,c in enumerate(raw_input()):
if c>".":
<T>for k in x,y+9,x-x%3+y//3+18:v[k*9+int(c)]+=1
print["Inv","V"][max(v)<2]+"alid"
&LT; T&GT;是单个制表符
答案 7 :(得分:3)
(princ(let((v(make-hash-table))(r "Valid"))(dotimes(y 9)(dotimes(x
10)(let((c(read-char)))(when(>(char-code c)46)(dolist(k(list x(+ 9
y)(+ 18(floor(/ y 3))(- x(mod x 3)))))(when(>(incf(gethash(+(* k
9)(char-code c)-49)v 0))1)(setf r "Invalid")))))))r))
答案 8 :(得分:2)
输入来自stdin,输出到stdout,输入中的换行符可选。
@y=map/\S/g,<>;
sub c{(join'',map$y[$_],@$h)=~/(\d).*\1/|c(@_)if$h=pop}
print(('V','Inv')[c map{$x=$_;[$_*9..$_*9+8],[grep$_%9==$x,0..80],[map$_+3*$b[$x],@b=grep$_%9<3,0..20]}0..8],'alid')
(为“清晰度”添加了换行符。)
c()
是一个函数,它根据作为参数传递的位置编号列表来检查@y
中的输入。如果所有位置列表都有效(不包含多于一次的数字),则返回0,否则返回1,使用递归检查每个列表。底线构建此列表列表,将其传递给c()
并使用结果选择要输出的正确前缀。
我非常喜欢的一点是,此解决方案利用了@b
中“块”位置列表中的“自相似性”(多次重复冗余以避免@b=...
进入@b
一个单独的陈述):通过将# Grab input into an array of individual characters, discarding whitespace
@y = map /\S/g, <>;
# Takes a list of position lists.
# Returns 0 if all position lists are valid, 1 otherwise.
sub c {
# Pop the last list into $h, extract the characters at these positions with
# map, and check the result for multiple occurences of
# any digit using a regex. Note | behaves like || here but is shorter ;)
# If the match fails, try again with the remaining list of position lists.
# Because Perl returns the last expression evaluated, if we are at the
# end of the list, the pop will return undef, and this will be passed back
# which is what we want as it evaluates to false.
(join '', map $y[$_], @$h) =~ /(\d).*\1/ | c(@_) if $h = pop
}
# Make a list of position lists with map and pass it to c().
print(('V','Inv')[c map {
$x=$_; # Save the outer "loop" variable
[$_*9..$_*9+8], # Columns
[grep$_%9==$x,0..80], # Rows
[map$_+3*$b[$x],@b=grep$_%9<3,0..20] # Blocks
} 0..8], # Generates 1 column, row and block each time
'alid')
中的第i个元素乘以3,可以找到整个拼图中第i个块的左上角位置。
更多分散:
{{1}}
答案 9 :(得分:1)
我正在阅读Modern Perl,感觉就像在编写一些东西......(顺便说一下这本书非常酷):
while(<>){$i++;$j=0;for$s(split//){$j++;$l{$i}{$s}++;$c{$j}{$s}++;
$q{(int(($i+2)/3)-1)*3+int(($j+2)/3)}{$s}++}}
$e=V;for$i(1..9){for(1..9){$e=Inv if$l{$i}{$_}>1or$c{$i}{$_}>1or$q{$i}{$_}>1}}
print $e.alid
Count排除不必要的换行符。 这可能需要Perl 5.12.2。
更具可读性:
#use feature qw(say);
#use JSON;
#$json = JSON->new->allow_nonref;
while(<>)
{
$i++;
$j=0;
for $s (split //)
{
$j++;
$l{$i}{$s}++;
$c{$j}{$s}++;
$q{(int(($i+2)/3)-1)*3+int(($j+2)/3)}{$s}++;
}
}
#say "lines: ", $json->pretty->encode( \%l );
#say "columns: ", $json->pretty->encode( \%c );
#say "squares: ", $json->pretty->encode( \%q );
$e = V;
for $i (1..9)
{
for (1..9)
{
#say "checking {$i}{$_}: " . $l{$i}{$_} . " / " . $c{$i}{$_} . " / " . $q{$i}{$_};
$e = Inv if $l{$i}{$_} > 1 or $c{$i}{$_} > 1 or $q{$i}{$_} > 1;
}
}
print $e.alid;
答案 10 :(得分:1)
f=->x{x.any?{|i|(i-[?.]).uniq!}}
a=[*$<].map{|i|i.scan /./}
puts f[a]||f[a.transpose]||f[a.each_slice(3).flat_map{|b|b.transpose.each_slice(3).map &:flatten}]?'Invalid':'Valid'
答案 11 :(得分:1)
Lua,341字节
虽然我知道Lua不是最好的高尔夫语言,但考虑到它的大小,我认为值得张贴它;)。 非高尔夫,评论和错误打印版本,为了额外的乐趣:)
i=io.read("*a"):gsub("\n","") -- Get input, and strip newlines
a={{},{},{}} -- checking array, 1=row, 2=columns, 3=squares
for k=1,3 do for l=1,9 do a[k][l]={0,0,0,0,0,0,0,0,0}end end -- fillup array with 0's (just to have non-nils)
for k=1,81 do -- loop over all numbers
n=tonumber(i:sub(k,k):match'%d') -- get current character, check if it's a digit, and convert to a number
if n then
r={math.floor((k-1)/9)+1,(k-1)%9+1} -- Get row and column number
r[3]=math.floor((r[1]-1)/3)+3*math.floor((r[2]-1)/3)+1 -- Get square number
for l=1,3 do v=a[l][r[l]] -- 1 = row, 2 = column, 3 = square
if v[n] then -- not yet eliminated in this row/column/square
v[n]=nil
else
print("Double "..n.." in "..({"row","column","square"}) [l].." "..r[l]) --error reporting, just for the extra credit :)
q=1 -- Flag indicating invalidity
end
end
end
end
io.write(q and"In"or"","Valid\n")
高尔夫版本,341字节
f=math.floor p=io.write i=io.read("*a"):gsub("\n","")a={{},{},{}}for k=1,3 do for l=1,9 do a[k][l]={0,0,0,0,0,0,0,0,0}end end for k=1,81 do n=tonumber(i:sub(k,k):match'%d')if n then r={f((k-1)/9)+1,(k-1)%9+1}r[3]=f((r[1]-1)/3)+1+3*f((r[2]-1)/3)for l=1,3 do v=a[l][r[l]]if v[n]then v[n]=nil else q=1 end end end end p(q and"In"or"","Valid\n")
答案 12 :(得分:1)
v=[(k,c) for y in range(9) for x,c in enumerate(raw_input()) for k in x,y+9,(x/3,y/3) if c>'.']
print["V","Inv"][len(v)>len(set(v))]+"alid"
答案 13 :(得分:1)
args1["\n"x2I3*x;{;{:=T(T'{:i~{^0}?})}}
{;{;{{,0:e}:;{0:^},u eq}}/`/=}:-C
dc C@;{:|}C&{"Valid"}{"Invalid"}?P
ASL是我制作的Golfscript灵感脚本语言。