Fillomino Solver


20

Fillominoเป็นปริศนาที่คุณกรอกตารางกับที่polyominoes โพลีโนมิโนแต่ละตัวเป็นพื้นที่ของเซลล์ที่ต่อเนื่องกัน การแทนกริดแสดงให้เห็นว่าโพลีโนมีนขนาดใดครอบคลุมแต่ละเซลล์ ตัวอย่างเช่น pentomino (5) จะปรากฏ5ในเซลล์ที่ต่อเนื่องกันห้าเซลล์ (ดูด้านล่าง) สอง polyominoes ที่มีขนาดเดียวกันไม่สามารถแบ่งปันเส้นขอบ แต่อาจเส้นขอบตามแนวทแยงมุม

สำหรับปริศนาแต่ละอันคุณเริ่มต้นด้วยจำนวนของgivensและต้องกรอกข้อมูลลงในเซลล์ที่เหลือ ตัวอย่างปริศนาและทางออกที่ง่าย:

ตัวอย่างปริศนา Fillomino

งานของคุณ: รับตัวต่อปริศนาแก้มันและออกคำตอบ อินพุตอาจมาจาก stdin อาร์กิวเมนต์บรรทัดคำสั่งเดียวหรือไฟล์ข้อความ อินพุตจะได้รับเป็นจำนวนเต็มnตามด้วยตัวเลขแต่ละnบรรทัด nเซลล์ว่างจะถูกกำหนดเป็นจุด ( .) สำหรับตัวอย่างปริศนาด้านบนมันจะเป็น:

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

เอาท์พุทเป็นปริศนาที่ได้รับการแก้ไขที่กำหนดบนnบรรทัดของnตัวเลขไปยังคอนโซลหรือไฟล์ข้อความ:

33366
55446
55466
51462
33312

หากปริศนาไม่ถูกต้อง, 0เอาท์พุท ตัวต่ออาจไม่ถูกต้องหากอินพุตมีรูปแบบไม่ถูกต้องหรือไม่มีวิธีแก้ไข หากมีหลายวิธีคุณสามารถส่งออกหนึ่งหรือทั้งหมดของพวกเขา

เนื่องจากแต่ละเซลล์จะแสดงเป็นตัวเลขหนึ่งตัวปริศนาทั้งหมดจึงประกอบด้วยขนาดโพลิโม่โน9และใต้เท่านั้น ถ้ามันเป็นไปไม่ได้ที่จะแก้ปัญหาโดยไม่ต้องมีโพลีเมียนขนาดใหญ่ให้พิจารณาว่ามันไม่ถูกต้อง

คำตอบที่ถูกต้องจะช่วยไขปริศนาที่ให้ไม่ใช่เพียงแค่เอาท์พุทโซลูชันเพื่อทดสอบเคส ไม่มีทรัพยากรภายนอกไม่ว่าจะเป็นออนไลน์หรือท้องถิ่น หากเกิดขึ้นเป็นภาษาที่มีฟังก์ชั่นการแก้ปัญหา fillomino ในตัวคุณไม่สามารถใช้งานได้ ในระยะสั้นยุติธรรมเล่น

กรณีทดสอบ:

การป้อนข้อมูล:

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

เอาท์พุท (ทางออกที่เป็นไปได้):

322133315
355445555
315443334
235531444
233135551
141535515
344553155
324553553
321223133

จำไว้ว่าโพลีโอโน่บางตัวไม่มีตัวเลขที่กำหนดและบางอันมีมากกว่าหนึ่งตัว นอกจากนี้ไม่ได้มีความสัมพันธ์แบบหนึ่งต่อหนึ่งระหว่างจำนวน Givens และจำนวน polyominoes ที่

คะแนนเป็นรหัสมาตรฐานกอล์ฟขนาดของโปรแกรมเป็นไบต์


การเรียกซ้ำเป็นคำตอบที่ถูกต้องหรือไม่หากใช้กับบอร์ด 9x9 แต่หน่วยความจำหมดสำหรับบอร์ดขนาดใหญ่กว่า
trichoplax

1
Yes.I ไม่คาดหวังว่าคุณจะสามารถfeasiblyทำงานอะไรหรือ 31x31 เพียงเพื่อให้คุณสามารถจริงทำงานทั้ง 5x5 และ 9x9 ข้างต้น (เพื่อให้การส่งออกสำหรับกรณีการทดสอบ) และจะในทางทฤษฎีการทำงานขนาดใหญ่ที่มีขั้นตอนวิธีการเดียวกัน (รับอึตันของทรัพยากร)
Geobits

คำตอบ:


4

อักขระ 4882 ตัว - Java

ไม่ใช่วิธีการแก้ปัญหาที่ยากมาก (เช่นตัวอักษร 4800 ตัวเป็น lotttttttttttt) อาจมีจำนวนเล็กน้อยในการพิมพ์ debug 1 หรือ 2 ที่ยังอยู่ในนั้น ฉันคิดว่าฉันสามารถลดความเป็นธรรมในแง่ของรหัสที่ไร้ประโยชน์ / ได้รับการปรับปรุงให้ดีขึ้นได้

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

ก่อนหน้านี้ฉันไม่เคยเห็น Polyominoes มาก่อนฉันอ่านสิ่งที่พวกเขาเป็นและไม่ได้มองหาวิธีแก้ปัญหา alrogithms แค่สร้างขึ้นมาเอง (ค่อนข้างช้า)

โดยทั่วไปใช้การเรียกซ้ำบ่อยครั้งมาก ... ค้นหา Polyomino ที่ไม่สมบูรณ์พยายามที่จะทำให้เสร็จ ค้นหาพื้นที่ว่างเปล่าลูป 1-9 ผ่านช่องสี่เหลี่ยมทั้งหมดในกระเป๋าตั้งค่ากระเป๋านั้นเป็นค่านั้น หากกระเป๋าเสร็จสมบูรณ์ก็จะพยายามหากระเป๋าอีกใบจากนั้นทำซ้ำจนกว่าจะเสร็จ ฉันไม่สามารถใช้งานกับกริดที่มีขนาด 9 ได้ ... ฉันมีการเพิ่มประสิทธิภาพอย่างน้อยหนึ่งครั้งที่สามารถทำให้มันทำงานได้ภายในเวลาที่เหมาะสมสำหรับ 9. อาจลองใส่มันในไม่ช้า


1
คุณรวบรวมสิ่งนี้อย่างไร ฉันได้รับข้อผิดพลาดของตัวแปรที่ซ้ำกันในไม่กี่แห่ง
Geobits
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.