Fillomino Solver


20

Fillomino è un puzzle in cui riempi una griglia di poliomino . Ogni poliomino è un'area di cellule contigue. La rappresentazione della griglia mostra le dimensioni del poliomino che copre ogni cella. Ad esempio, un pentomino (5) verrebbe mostrato come 5in ciascuna delle cinque celle contigue (vedi sotto). Due poliomino della stessa dimensione non possono condividere un bordo, ma possono bordare in diagonale.

Per ogni puzzle, hai iniziato con un numero di dati e devi riempire le celle rimanenti. Un semplice esempio di puzzle e soluzione:

esempio di fillomino puzzle

Il tuo compito: dato un puzzle quadrato, risolvilo e genera la risposta. L'input può essere tramite stdin, un singolo argomento della riga di comando o un file di testo. L'input verrà dato come un numero intero n, seguito da nrighe di ncifre ciascuna. Le celle vuote verranno indicate come punti ( .). Per il puzzle di esempio sopra, sarebbe:

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

L'output è il puzzle risolto, dato su nrighe di ncifre, per console o file di testo:

33366
55446
55466
51462
33312

Se il puzzle non è valido, output 0. Un puzzle potrebbe non essere valido se l'input non è corretto o non esiste una soluzione. Se esistono più soluzioni, è possibile produrre una o tutte le soluzioni.

Poiché ogni cella è rappresentata da una singola cifra, tutti i puzzle saranno costituiti da dimensioni di poliomino 9e solo sotto. Se non è possibile risolvere senza poliomino più grandi, considerarlo non valido.

Le risposte valide risolveranno qualsiasi enigma dato, non semplicemente le soluzioni di output per i casi di test. Nessuna risorsa esterna, sia online che locale. Se ci capita di essere una lingua con un built-in funzione di fillomino solving, non è possibile utilizzarlo. In breve, gioca bene .

Caso di prova:

Ingresso:

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 (una possibile soluzione):

322133315
355445555
315443334
235531444
233135551
141535515
344553155
324553553
321223133

Ricorda che alcuni poliomino non hanno numeri dati e alcuni ne hanno più di uno. C'è non è una relazione uno-a-uno tra il numero di Givens e il numero di poliomini.

Il punteggio è un codice-golf standard, la dimensione del programma in byte.


Un approccio ricorsivo è una risposta valida se funziona per una scheda 9x9 ma esaurisce la memoria per una scheda di dimensioni maggiori?
trichoplax,

1
Yes.I non si aspettano che tu sia in grado di tenerne eseguire un qualcosa di 31x31 o. Solo così puoi effettivamente eseguire sia il 5x5 che il 9x9 sopra (per fornire un output per i casi di test), e teoricamente funzionerebbe per dimensioni maggiori con lo stesso algoritmo (dato un sacco di risorse).
Geobits il

Risposte:


4

4882 caratteri - Java

Non è una soluzione molto golf (ovvero 4800 caratteri è un lotttttttttttt) Potrebbe essere giocato un po 'più a golf in quanto 1 o 2 linee di debug sono ancora lì. Penso di poter ridurre ancora un po 'in termini di codice inutile / ottimizzato.

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

Non avendo mai visto prima i Polyominoes, ho letto cosa sono e senza guardare alla risoluzione degli alrogitmi ho inventato il mio (abbastanza lentamente).

Fondamentalmente, usa molto la ricorsione ... Trova un Polyomino incompleto, cerca di completarlo. Trova uno spazio vuoto, passa da 1 a 9 attraverso tutti i quadrati della tasca, imposta quella tasca su quel valore. Se la tasca è completa, prova a trovare un'altra tasca, quindi si ripete fino al termine. Non sono riuscito a farlo funzionare per una griglia di dimensioni 9 ... Ho in mente almeno un'ottimizzazione che potrebbe farlo funzionare entro un tempo ragionevole per 9. Potrebbe provare a metterlo in atto presto.


1
Come stai compilando questo? Ricevo errori variabili duplicati in alcuni punti.
Geobits,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.