Semudah ABC Solver

11

Easy As ABC, juga dikenal sebagai "End View", adalah teka-teki di mana Anda diberi kotak kosong dengan huruf di sekitarnya; Anda harus mengisi sebagian kisi sehingga tepat satu dari setiap huruf ada di setiap baris dan kolom; selain itu, huruf di akhir baris (atau kolom) harus huruf pertama yang terlihat di baris (atau kolom) dari arah itu. Tujuan Anda dalam golf kode ini adalah memecahkan teka-teki Easy As ABC.

Sebagai contoh, berikut adalah teka-teki Easy As ABC dari MIT Mystery Hunt tahun ini menggunakan huruf MIC:

membingungkan

Solusinya adalah:

larutan

(Maaf tentang artefak di Cs; saya mencoba mengedit informasi yang tidak relevan dari sisa teka-teki.)

I / O

Input akan berupa array string atau string yang mungkin dengan pembatas. Itu akan mulai di sudut kiri atas dan pergi searah jarum jam. Misalnya, teka-teki di atas bisa menjadi input seperti ini:

".CMM.M|....IM|.....I|C.ICI."

Output harus berupa grid yang dipecahkan, dengan atau tanpa batas. Itu bisa sebagai array karakter, array string, atau format lain yang nyaman. Karakter "kosong" yang sama harus diterima sebagai input dan ditampilkan sebagai keluaran, tetapi karakter kosong itu bisa apa saja. Jika mereka adalah string tunggal, input dan output harus memiliki pemisah yang sama (antara sisi untuk input dan baris untuk output) atau tanpa pemisah sama sekali.

Untuk teka-teki yang tidak dapat dipecahkan, Anda harus mengeluarkan sesuatu yang tidak salah untuk solusi. Anda dapat berasumsi bahwa tidak ada puzzle yang memiliki lebih dari satu solusi.

Anda harus mengizinkan sejumlah huruf dan ukuran kisi apa pun; semua huruf yang digunakan akan muncul di perbatasan kisi.

Ini : seperti biasa, kode terpendek menang!

Uji Kasus

"T.AA..|.T.TSS|..TST.|A...SS"
"R.RU..|B.B..B|.UR.UB|UR..B."
"N...NK|E.NK.K|..KK..|....EK"
"CA..DBD|.B..CC.|.D.DEB.|DB.A..A"
"...DDEBE|DC..EBBD|BA..ABF.|E..FECDE"
Deusovi
sumber
2
menjadi jelas: seluruh alfabet diberikan di perbatasan? (yaitu tidak ada surat akan muncul yang tidak di perbatasan?)
quintopia
@quintopia: Ya. Perbatasan akan berisi setiap huruf yang digunakan.
Deusovi
Teka
Sp3000

Jawaban:

1

PHP, 1111 Bytes

minus Bytes menghapus baris baru

Versi Online hanya berfungsi dengan Testcases dengan panjang 6

solusi singkat

buat semua permutasi

isi 2 array dengan permutasi $ x $ y

berubah di antara dua fungsi begitu lama hingga hanya 1 solusi dalam x array untuk setiap baris yang ada

fungsi i: menemukan persimpangan di grid dan drop permutasi

fungsi c: periksa kolom di setiap array karakter unik dan hapus permutasi di baris lain untuk array $ x dan $ y

$p=[];p(array_pad(($s="str_split")(substr(count_chars($a=$argn,3),1,-1)),$l=(strlen($a)-3)/4," "));
$e=explode("|",$a);$e[3]=strrev($e[3]);$e[2]=strrev($e[2]);
$x=$y=array_fill(0,$l,$p);$g="preg_grep";$c="array_column";$o="join";
foreach($q=range(0,$l-1)as$i){
$e[0][$i]=="."?:$y[$i]=$g("#^\s*{$e[0][$i]}#",$y[$i]);
$e[2][$i]=="."?:$y[$i]=$g("#{$e[2][$i]}\s*$#",$y[$i]);
$e[3][$i]=="."?:$x[$i]=$g("#^\s*{$e[3][$i]}#",$x[$i]);
$e[1][$i]=="."?:$x[$i]=$g("#{$e[1][$i]}\s*$#",$x[$i]);}
for(;array_sum(($m="array_map")("count",$x))>$l;){
foreach($q as$i)foreach($q as$j){
$k=array_intersect($c($m($s,$x[$i]),$j),$c($m($s,$y[$j]),$i));
$y[$j]=$g("#^.{{$i}}(".$o("|",$k).")#",$y[$j]);
$x[$i]=$g("#^.{{$j}}(".$o("|",$k).")#",$x[$i]);
foreach(["x","y"]as$z){
$u=array_unique($c($m($s,${"$z"}[$i]),$j));
if(count($u)==1&&end($u)!=" "){$w=end($u);
foreach($q as$h){
if($i!=$h)${"$z"}[$h]=$g("#^.{{$j}}{$w}#",${"$z"}[$h],1);}}
}}}
echo$o("\n",$m($o,$x));
function p($c,$b=[]){global$p;
if(($c)){$n=[];while($c){
$e=array_pop($c);
p(($m="array_merge")($c,$n),$m($b,[$e]));
$n[]=$e;
}}else in_array($b=join($b),$p)?:$p[]=$b;}
Jörg Hülsermann
sumber