Pengisi Fillomino


20

Fillomino adalah teka-teki di mana Anda mengisi kotak dengan polyomino . Setiap polyomino adalah area sel yang berdekatan. Representasi grid menunjukkan ukuran polyomino yang menutupi setiap sel. Sebagai contoh, sebuah pentomino (5) akan ditampilkan sebagai 5masing-masing dari lima sel yang berdekatan (lihat di bawah). Dua polyomino dengan ukuran yang sama tidak dapat berbagi batas, tetapi dapat berbatasan secara diagonal.

Untuk setiap puzzle, Anda mulai dengan sejumlah givens dan harus mengisi sel yang tersisa. Contoh teka-teki dan solusi mudah:

contoh puzzle fillomino

Tugas Anda: Diberikan puzzle persegi, pecahkan dan keluarkan jawabannya. Input dapat melalui stdin, argumen baris perintah tunggal, atau file teks. Input akan diberikan sebagai integer n, diikuti oleh masing-masing nbaris ndigit. Sel kosong akan diberikan sebagai titik ( .). Untuk contoh puzzle di atas, itu akan menjadi:

5
3..66
5.4.6
.54.6
.1.6.
..312

Output adalah teka-teki yang dipecahkan, diberikan pada ngaris ndigit, ke konsol atau file teks:

33366
55446
55466
51462
33312

Jika puzzle tidak valid, hasilkan 0. Teka-teki bisa tidak valid jika inputnya salah atau tidak ada solusi. Jika ada beberapa solusi, Anda dapat mengeluarkan salah satu atau semuanya.

Karena setiap sel diwakili oleh satu digit, semua teka-teki akan terdiri dari ukuran poliomino 9dan di bawahnya saja. Jika tidak mungkin diselesaikan tanpa poliomino yang lebih besar, anggap itu tidak valid.

Jawaban yang valid akan memecahkan setiap teka-teki yang diberikan, bukan hanya menghasilkan solusi untuk menguji kasus. Tidak ada sumber daya eksternal, baik online maupun lokal. Jika kebetulan ada bahasa dengan fungsi penyelesaian fillomino bawaan, Anda tidak dapat menggunakannya. Singkatnya, bermain adil .

Kasus cobaan:

Memasukkan:

9
..21.3..5
.5...5..5
.1.44.334
...53.4..
2.3.3..5.
1.15.5.15
..45..1..
.24.53.53
....2....

Output (kemungkinan solusi):

322133315
355445555
315443334
235531444
233135551
141535515
344553155
324553553
321223133

Ingatlah bahwa beberapa polyomino tidak memiliki angka, dan beberapa memiliki lebih dari satu. Ada tidak hubungan satu-ke-satu antara jumlah kodrat dan jumlah polyominoes.

Skor adalah kode-golf standar, ukuran program dalam byte.


Apakah pendekatan rekursif merupakan jawaban yang valid jika berhasil untuk papan 9x9 tetapi akan kehabisan memori untuk beberapa papan ukuran yang lebih besar?
trichoplax

1
Ya. Saya tidak berharap Anda dapat menjalankan 31x31 secara layak atau apa pun. Hanya agar Anda benar - benar dapat menjalankan kedua 5x5 dan 9x9 di atas (untuk memberikan output untuk kasus uji), dan secara teoritis akan bekerja untuk yang lebih besar dengan algoritma yang sama (diberi sumber daya omong kosong-ton).
Geobits

Jawaban:


4

4882 karakter - Jawa

Bukan solusi yang sangat golf (yaitu 4800 karakter adalah lotttttttttttt). Bisa lebih sedikit golf karena 1 atau 2 debug printlines masih ada di sana. Saya pikir saya dapat mengurangi sedikit masih adil dalam hal kode tidak berguna / dioptimalkan.

import java.util.*;import java.awt.Point;public class G{public static void main(String[]args){new G();}Scanner z=new Scanner(System.in);public G(){s=z.nextInt();z.nextLine();int g[][]=new int[s][s];for(int i=0;i<s;i++)Arrays.fill(g[i],-1);for(int i=0;i<s;i++){String line=z.nextLine();for(int j=0;j<s;j++)if(line.charAt(j)!='.')g[i][j]=Integer.parseInt(Character.toString(line.charAt(j)));}System.out.println();if(y(g)){for(int i=0;i<s;i++)for(int j=0;j<s;j++)System.out.print(g[i][j]);System.out.println();}else System.out.println(0);}private boolean x(Collection<Point>c,int[][]d){if(c.size()==0)return true;int j=0;for(Iterator<Point>k=c.iterator();k.hasNext();k.next(),j++){for(int sol=9;sol>=0;sol--){int[][]a=new int[s][s];for(int i=0;i<s;i++)a[i]=Arrays.copyOf(d[i],s);List<Point>b=new ArrayList<Point>();for(Point p:c)if(!b.contains(p))b.add(new Point(p));a[b.get(j).x][b.get(j).y]=sol;if(w(a,b.get(j))){if(x(b,a)){for(int i=0;i<s;i++)d[i]=Arrays.copyOf(a[i],s);c.clear();c.addAll(b);return true;}}}}return false;}int s;private boolean y(int[][]d){int[][] a=new int[s][s];for (int i = 0; i<s;i++)a[i]=Arrays.copyOf(d[i],s);List<Point> incomplete=new ArrayList<Point>();if(r(a)&&s(a)){a(a);System.exit(0);}else if(!r(a)){q("INVALID FROM MAIN, ",12);return false;}for(int i=0;i<s;i++)for(int j=0;j<s;j++){if(a[i][j]!=-1)if(t(new Point(i,j),a,null,a[i][j]).size()!=a[i][j]){if(w(a,new Point(i,j))){a(a);if(y(a)){for(int i=0;i<s;i++)d[i]=Arrays.copyOf(a[i],s);return true;}else return false;}else return false;}}for(int i=0;i<s;i++)for(int j=0;j<s;j++)if(a[i][j]==-1){Set<Point>c=t(new Point(i,j),a,null,-1);if(x(c,a)){if(y(a)){for(int i=0;i<s;i++)d[i] = Arrays.copyOf(a[i], s);return true;}else return false;}else return false;}q("How did you get here",1);return false;}private boolean w(int[][]d,Point b){List<Point>c;Set<Point>a;a=t(b,d,null,d[b.x][b.y]);c=new ArrayList<Point>(u(b,d,null,d[b.x][b.y]));int h=d[b.x][b.y];int g=h-a.size();if(c.size()<g){return false;}else if(v(c,h,h,new ArrayList<Point>(a),0,d))return true;else return false;}private boolean v(List<Point>c,int h,int g,List<Point>e,int f,int[][]d){if(e==null)e=new ArrayList<Point>();int[][]a=new int[s][s];for(int i=0;i<s;i++)for(int k=0;k<s;k++)a[i][k]=d[i][k];if(f<g&&e.size()<g){for(int i=0;i<c.size();i++){if(!e.contains(c.get(i))){if(d[c.get(i).x][c.get(i).y]==h){for(Point c:e){a[c.x][c.y]=h;}Set<Point> u=t(e.get(0),a,null,h);Set<Point>v=t(c.get(i),a,null,h);if(!Collections.disjoint(u,v)){u.addAll(v);List<Point>uList=new ArrayList<Point>(u);if(v(c,h,g,uList,f+1,a)){q("this e sucess",2);if(y(d)){e.addAll(uList);return true;}}else;}for(int l=0;l<s;l++)for(int k=0;k<s;k++)a[l][k]=d[l][k];}else if(e.add(c.get(i))){if(v(c,h,g,e,f+1,d)){q("this e sucess",2);if(y(d))return true;}}if(e.contains(c.get(i)))e.remove(c.get(i));}}return false;}else if(f>g||e.size()>g){if(f>g){q("Your over the g. ");return false;}else return false;}else{for(Point c:e){a[c.x][c.y]=h;}if(r(a)){if(y(a)){for(int i=0;i<s;i++)d[i]=Arrays.copyOf(a[i],s);q("complete(a) is true, ",4);return true;}else{return false;}}else{return false;}}}private void q(String out,int i){System.err.println(out+". exit code: "+i);System.exit(i);}private void q(String a){q(a,0);}private boolean r(int[][] d){for(int i=0;i<s;i++)for(int j=0;j<s;j++)if(d[i][j]!=-1){Set<Point>same=t(new Point(i,j),d,null,d[i][j]);if(same.size()>d[i][j]){return false;}Set<Point>fae=u(new Point(i,j),d,null,d[i][j]);if(u(new Point(i,j),d,null,d[i][j]).size()<d[i][j]){return false;}}return true;}private Set<Point> u(Point p,int[][]d,Set<Point>u,int i){u=(u==null)?new HashSet<Point>():u;if(d[p.x][p.y]==i||d[p.x][p.y]==-1)u.add(p);int x=p.x,y=p.y;Point t=new Point();if(x+1<s&&(d[x+1][y]==i||d[x+1][y]==-1)){if(u.add(new Point(x+1,y)))u=u(new Point(x+1,y),d,u,i);}if(y+1<s&&(d[x][y+1]==i||d[x][y+1]==-1)){if(u.add(new Point(x,y+1)))u=u(new Point(x,y+1),d,u,i);}if(x-1>=0&&(d[x-1][y]==i||d[x-1][y]==-1)){if(u.add(new Point(x-1,y)))u=u(new Point(x-1,y),d,u,i);}if(y-1>=0&&(d[x][y-1]==i||d[x][y-1]==-1)){if(u.add(new Point(x,y-1)))u=u(new Point(x,y-1),d,u,i);}return u;}private Set<Point> t(Point p,int[][]d,Set<Point>u,int i){u=(u==null)?new HashSet<Point>():u;if(d[p.x][p.y]==i)u.add(p);int x=p.x,y=p.y;Point t=new Point(p);if(x+1<s&&d[x+1][y]==i){if(u.add(new Point(x+1,y)))u=t(new Point(x+1,y),d,u,i);}if(y+1<s&&d[x][y+1]==i){if(u.add(new Point(x,y+1)))u=t(new Point(x,y+1),d,u,i);}if(x-1>=0&&d[x-1][y]==i){if(u.add(new Point(x-1,y)))u=t(new Point(x-1,y),d,u,i);}if(y-1>=0&&d[x][y-1]==i){if(u.add(new Point(x,y-1)))u=t(new Point(x,y-1),d,u,i);}return u;}private boolean s(int[][]d){for(int i=0;i<s;i++)for(int j=0;j<s;j++)if(t(new Point(i,j),d,null,d[i][j]).size()!=d[i][j])return false;return true;}private void a(int[][]d){for(int i=0;i<s;i++){for(int j=0;j<s;j++){System.out.printf("%1s",d[i][j]==-1?".":Integer.toString(d[i][j]));}System.out.println("");}}}

Belum pernah melihat Polyominoes sebelumnya, saya membaca tentang apa itu dan tanpa melihat pemecahan alrogitma hanya membuat saya sendiri (sangat lambat).

Pada dasarnya, banyak menggunakan rekursi ... Menemukan Polyomino yang tidak lengkap, mencoba untuk menyelesaikannya. Menemukan ruang kosong, Loop 1-9 melalui semua kotak di saku, menetapkan saku ke nilai itu. Jika kantungnya lengkap, ia mencoba mencari kantung lain, lalu ulangi sampai selesai. Saya tidak dapat membuatnya berfungsi untuk kisi ukuran 9 ... Saya memiliki setidaknya satu pengoptimalan yang dapat membuatnya berfungsi dalam waktu yang masuk akal untuk 9. Mungkin mencoba untuk segera menerapkannya.


1
Bagaimana Anda menyusun ini? Saya mendapatkan kesalahan variabel rangkap di beberapa tempat.
Geobits
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.