Fillomino Solver


20

Fillomino est un puzzle où vous remplissez une grille de polyominos . Chaque polyomino est une zone de cellules contiguës. La représentation de la grille montre quelle taille polyomino recouvre chaque cellule. Par exemple, un pentomino (5) serait représenté comme 5dans chacune des cinq cellules contiguës (voir ci-dessous). Deux polyominos de même taille ne peuvent pas partager une frontière, mais peuvent être bordés en diagonale.

Pour chaque puzzle, vous commencez avec un certain nombre de données et devez remplir les cellules restantes. Un exemple simple de puzzle et de solution:

exemple de puzzle fillomino

Votre tâche: étant donné un puzzle carré, résolvez-le et sortez la réponse. L'entrée peut se faire via stdin, un seul argument de ligne de commande ou un fichier texte. L'entrée sera donnée sous forme d'entier n, suivie de nlignes de nchiffres chacune. Les cellules vides seront données sous forme de points ( .). Pour l'exemple de puzzle ci-dessus, ce serait:

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

La sortie est le puzzle résolu, donné sur des nlignes de nchiffres, à la console ou au fichier texte:

33366
55446
55466
51462
33312

Si le puzzle n'est pas valide, sortez 0. Un casse-tête peut être invalide si l'entrée est mal formée ou s'il n'y a pas de solution. S'il existe plusieurs solutions, vous pouvez en générer une ou toutes.

Étant donné que chaque cellule est représentée par un seul chiffre, tous les puzzles seront constitués de taille de polyominos 9et inférieurs uniquement. S'il n'est pas possible de résoudre sans polyominos plus gros, considérez-le comme invalide.

Des réponses valides résoudront n'importe quel casse-tête donné, pas seulement des solutions de sortie pour les cas de test. Pas de ressources externes, que ce soit en ligne ou local. S'il se trouve qu'il existe un langage avec une fonction de résolution de fillomino intégrée, vous ne pouvez pas l'utiliser. Bref, jouez juste .

Cas de test:

Contribution:

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

Sortie (une solution possible):

322133315
355445555
315443334
235531444
233135551
141535515
344553155
324553553
321223133

Rappelez-vous que certains polyominos n'ont pas de numéro donné et certains en ont plus d'un. Il n'y a pas de relation biunivoque entre le nombre de données et le nombre de polyominos.

Le score est un code-golf standard, la taille du programme en octets.


Une approche récursive est-elle une réponse valide si elle fonctionne pour une carte 9x9 mais manque de mémoire pour une carte de plus grande taille?
trichoplax

1
Yes.I ne vous attendez pas à être en mesure de réalistement exécuter un 31x31 ou quoi que ce soit. Juste pour que vous puissiez réellement exécuter à la fois les 5x5 et 9x9 ci-dessus (pour donner une sortie pour les cas de test), et fonctionneriez théoriquement pour plus grand avec le même algorithme (compte tenu d'une tonne de ressources).
Geobits

Réponses:


4

4882 caractères - Java

Pas une solution très golfée (c.-à-d. 4800 caractères est un lotttttttttttt) Pourrait être joué un peu plus dans la mesure où 1 ou 2 lignes d'impression de débogage sont toujours là. Je pense que je peux réduire encore un peu en termes de code inutile / optimisé.

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

N'ayant jamais vu de polyominos avant cela, j'ai lu ce qu'ils sont et sans chercher à résoudre des alrogithmes, je viens de les inventer (assez lentement).

Fondamentalement, utilise beaucoup la récursivité ... Trouve un Polyomino incomplet, essaie de le terminer. Trouve un espace vide, Boucles 1-9 à travers tous les carrés de la poche, définit cette poche à cette valeur. Si la poche est complète, il essaie de trouver une autre poche, puis se répète jusqu'à la fin. Je ne pouvais pas le faire fonctionner pour une grille de taille 9 ... J'ai au moins une optimisation en tête qui pourrait le faire fonctionner dans un délai raisonnable pour 9. Je pourrais essayer de mettre cela en place bientôt.


1
Comment compilez-vous cela? Je reçois des erreurs de variables en double à quelques endroits.
Geobits
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.