Bộ giải Fillomino


20

Fillomino là một câu đố, nơi bạn điền vào một mạng lưới với polyominoes . Mỗi polyomino là một khu vực của các tế bào tiếp giáp. Biểu diễn lưới cho thấy kích thước polyomino bao phủ trên mỗi ô. Ví dụ, một pentomino (5) sẽ được hiển thị như 5trong mỗi năm ô liền kề (xem bên dưới). Hai đa giác có cùng kích thước không thể chia sẻ một đường viền, nhưng có thể viền theo đường chéo.

Đối với mỗi câu đố, bạn bắt đầu với một số quà tặng và phải điền vào các ô còn lại. Một ví dụ dễ giải đố và giải pháp:

mẫu câu đố fillomino

Nhiệm vụ của bạn: Đưa ra một câu đố vuông, giải nó và đưa ra câu trả lời. Đầu vào có thể thông qua stdin, một đối số dòng lệnh hoặc tệp văn bản. Đầu vào sẽ được cung cấp dưới dạng một số nguyên n, theo sau là mỗi ndòng nchữ số. Các ô trống sẽ được cung cấp dưới dạng period ( .). Đối với câu đố mẫu ở trên, nó sẽ là:

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

Đầu ra là câu đố đã giải, được đưa ra trên ncác dòng nchữ số, cho bàn điều khiển hoặc tệp văn bản:

33366
55446
55466
51462
33312

Nếu câu đố không hợp lệ, đầu ra 0. Một câu đố có thể không hợp lệ nếu đầu vào không đúng định dạng hoặc không có giải pháp. Nếu có nhiều giải pháp, bạn có thể xuất bất kỳ một hoặc tất cả chúng.

Vì mỗi ô được biểu thị bằng một chữ số duy nhất, tất cả các câu đố sẽ chỉ bao gồm kích thước đa giác 9và dưới. Nếu không thể giải quyết mà không có đa giác lớn hơn, hãy xem xét nó không hợp lệ.

Câu trả lời hợp lệ sẽ giải quyết bất kỳ câu đố nào, không chỉ đơn giản là giải pháp đầu ra cho các trường hợp thử nghiệm. Không có tài nguyên bên ngoài, có thể là trực tuyến hoặc địa phương. Nếu có xảy ra là một ngôn ngữ với một built-in chức năng giải quyết fillomino, bạn không thể sử dụng nó. Tóm lại, chơi sòng phẳng .

Trường hợp thử nghiệm:

Đầu vào:

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....

Đầu ra (một giải pháp khả thi):

322133315
355445555
315443334
235531444
233135551
141535515
344553155
324553553
321223133

Hãy nhớ rằng một số đa giác không có số đã cho và một số có nhiều hơn một. Có không một mối quan hệ một-một giữa số Givens và số lượng polyominoes.

Điểm là mã golf tiêu chuẩn, kích thước của chương trình tính bằng byte.


Là một cách tiếp cận đệ quy là một câu trả lời hợp lệ nếu nó hoạt động cho một bảng 9x9 nhưng sẽ hết bộ nhớ cho một số bảng kích thước lớn hơn?
trichoplax 04/07/2015

1
Có. Tôi không hy vọng bạn có thể chạy 31x31 một cách khả thi . Để bạn thực sự có thể chạy cả 5x5 và 9x9 ở trên (để cung cấp đầu ra cho các trường hợp thử nghiệm) và về mặt lý thuyết sẽ hoạt động với quy mô lớn hơn với cùng một thuật toán (được cung cấp một tài nguyên tào lao).
Geobits

Câu trả lời:


4

4882 ký tự - Java

Không phải là một giải pháp rất được đánh gôn (ví dụ 4800 ký tự là một lotttttttttttt) Có thể được đánh gôn thêm một chút trong đó 1 hoặc 2 bản in gỡ lỗi vẫn còn ở đó. Tôi nghĩ rằng tôi có thể giảm một chút công bằng về mã vô dụng / tối ưu hóa.

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("");}}}

Chưa bao giờ nhìn thấy Polyominoes trước đó, tôi đọc về chúng là gì và không cần nhìn vào việc giải quyết các thuật toán chỉ tạo nên của riêng tôi (khá chậm).

Về cơ bản, sử dụng đệ quy rất nhiều ... Tìm một Polyomino chưa hoàn chỉnh, cố gắng hoàn thành nó. Tìm một khoảng trống, Vòng lặp 1-9 qua tất cả các ô vuông trong túi, đặt túi đó vào giá trị đó. Nếu túi hoàn thành, nó cố gắng tìm túi khác, sau đó lặp lại cho đến khi hoàn thành. Tôi không thể làm cho nó hoạt động cho một lưới có kích thước 9 ... Tôi có ít nhất một tối ưu hóa có thể khiến nó hoạt động trong khoảng thời gian hợp lý cho 9. Có thể cố gắng đưa nó vào vị trí sớm.


1
Làm thế nào bạn biên dịch này? Tôi đang nhận được lỗi trùng lặp ở một vài nơi.
Geobits 13/03/2015
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.