Valider les solutions Loopy

9

Ceci est un défi supplémentaire au défi de génération d'énigmes Loopy . Vous voudrez peut-être résoudre ce défi avant de tenter le défi le plus difficile du lien précédent.

Le but de ce défi est de valider la solution d'un puzzle en boucle. Veuillez prendre toute la documentation sur ce qu'est un puzzle en boucle du lien précédent. Un puzzle en boucle résolu est formaté de manière très similaire à la sortie d'une soumission valide au défi «générer des puzzles en boucle» et peut ressembler à ceci:

+-+-+ +-+ +-+ +
|   | | |2|3|  
+-+ + + + + +-+
 2| | | |2|  3|
+ + +-+ + + +-+
 2|  2 1|3| |  
+-+ +-+ +-+ +-+
|2  | |    1 2|
+ +-+ +-+ +-+ +
| |2 1 2|3|3| |
+ + +-+ +-+ +-+
| | |3|2   1   
+ +-+ +-+-+-+-+
|        2 2  |
+-+-+-+-+-+-+-+

Le chemin qui compose la solution est marqué par |et des -caractères entre les +caractères.

Spécification d'entrée

Votre programme recevra un puzzle en boucle avec une solution formatée comme l'exemple ci-dessus en entrée. Votre programme doit déduire la taille du puzzle à partir de l'entrée. Vous pouvez faire les hypothèses suivantes sur l'entrée:

  • Le puzzle n'a pas moins de 2 et pas plus de 99 cellules dans les deux sens
  • Ainsi, chaque ligne a une longueur maximale de 199 caractères n'incluant pas le (s) caractère (s) de nouvelle ligne
  • Ainsi, l'entrée contient un maximum de 99 lignes
  • chaque ligne peut se terminer après le dernier caractère imprimable ou peut être complétée par des caractères blancs afin qu'elle ait une longueur allant jusqu'à 2 · y + 1 caractères où y est le nombre de cellules dans le sens horizontal
  • chaque position avec les coordonnées x et y contient même un +caractère
  • les positions adjacentes horizontalement ou verticalement aux positions contenant des +caractères contiennent soit un espace, sont derrière la fin de la ligne ou contiennent un -caractère si elles sont adjacentes horizontalement ou un |caractère si elles sont adjacentes verticalement
  • toutes les autres positions sont soit derrière l'extrémité de la ligne ou contenir l' un des caractères , 0, 1, 2, ou3
  • toutes les lignes se terminent par le ou les caractères de nouvelle ligne par défaut de votre plate-forme
  • il y a exactement un saut de ligne

Les contributions doivent être reçues de l'une des manières suivantes:

  • De l'entrée standard
  • Comme la valeur d'un paramètre nommé pdans une requête HTTP POST
  • En tant que contenu d'un formulaire HTML
  • En tant que contenu d'un fichier nommé pdans un répertoire défini par l'implémentation
  • D'une manière définie par l'implémentation lors de l'exécution si les quatre anciens ne sont pas disponibles
  • Codé en dur si votre langue ne fournit aucun moyen de recevoir des données

Spécifications de sortie

Votre programme doit se terminer pour toutes les entrées correspondant à la spécification d'entrée et doit calculer si la solution au puzzle est correcte. Votre programme doit afficher le résultat du calcul sous forme de valeur booléenne de l'une des manières suivantes:

  • En tant qu'état de sortie de zéro (la solution est valide) ou non nulle (la solution n'est pas valide)
  • Comme le caractère y(la solution est valide) ou n(la solution n'est pas valide) suivi de zéro ou plusieurs caractères arbitraires sortis d'une manière définie par l'implémentation

Le comportement de votre programme n'est pas spécifié lorsque vous rencontrez une entrée non formatée conformément à la spécification d'entrée.

Notation

Le score de votre programme est le nombre de caractères dans sa source, à l'exception des caractères d'espacement et des commentaires omittables. Nous vous encourageons à mettre en retrait votre soumission afin qu'elle soit plus facile à lire pour les autres et à commenter votre solution afin qu'elle soit plus facile à suivre.

Les soumissions qui ne respectent pas les spécifications d'entrée ou de sortie ou qui génèrent des résultats incorrects ne sont pas valides.

FUZxxl
la source
Comment gérer les entrées? Lire à partir d'un fichier? STDIN? Puis-je écrire une fonction?
Martin Ender
@ MartinBüttner "votre programme recevra ...". Je ne sais pas pourquoi vous souhaitez lire un fichier.
John Dvorak
@ MartinBüttner Vous devez écrire un programme complet. Je pense que le langage "votre programme", "doit se terminer", "état de sortie" est assez clair.
FUZxxl
1
Notez également que dans la plupart des puzzles 0est également un numéro valide pour une cellule.
Howard
@Howard Désolé, j'ai raté ça.
FUZxxl

Réponses:

2

GolfScript, 133 caractères

'|':^4,{48+.(}%+^*1>.^/'-'*+2/:F;4{{~@@/*}2F//n%zip-1%n*}:X*.'+-'?.3+@/(-2<' 9'+\+'9-+  99|+  9'3/:F;.,4*{X}*.9`?@=\' +09
'-!&'ny'1/=

Attend l'entrée de STDIN et imprime yune solution valide et nnon valide. Effectue la tâche en utilisant principalement le remplacement de chaîne sur la grille ou avec des versions pivotées de la grille.

Code annoté:

# construct the string "|0|/|1|0|2|1|3|2-0-/-1-0-2-1-3-2"
# split into pieces of two and save to variable F
'|':^4,{48+.(}%+^*1>.^/'-'*+
2/:F;

# run the code block X 4 times
# with X: string-replace 1st item in F with 2nd, 3rd with 4th, ...
# i.e. '|0' with '|/', '|1' with '|0'
# and then rotate grid by 90 degrees
4{{~@@/*}2F//n%zip-1%n*}:X*

# for a valid grid all digits are now reduced to exactly '0'
# (i.e. no '1' or '2' or '3' or '/')

# now follow the loop along and remove it
# start: find the first occurence of '+-+' and replace with '+ 9'
# note: '9' is the marker for the current position
.'+-'?
.3+@/(-2<' 9'+\+

# string-replace '9-+' or '9|+' by '  9' (i.e. go one step along the loop)
# using block X enough times
'9-+  99|+  9'3/:F;
.,4*{X}*

# look for the marker '9' in the result and check if it is at the original
# position again
.9`?
@=

# the remaining grid must not contain any digits besides 0 and 9
# esp. no '|' or '-' may remain
\' +09
'-!

# check if both conditions are fulfilled and output corresponding character
&'ny'1/=
Howard
la source
2

C # 803 579 octets

Le programme complet, lu à partir de STDIN, devrait faire face à tout schéma de nouvelle ligne commun tant qu'il a des sauts de ligne. Merci à HackerCow d'avoir souligné que je n'ai pas à ajouter une nouvelle ligne dans une question différente, m'invitant à la supprimer ici et à économiser 4 octets

Code golf:

using C=System.Console;class P{static void Main(){var D=C.In.ReadToEnd().Replace("\r","").Split('\n');int w=D[0].Length+2,h=D.Length+1,i=0,j,c,T=0,O=1,o,z,R=0;var B=new int[w,h];var S=new int[w*h*9];for(;i++<w-2;)for(j=0;j<h-2;B[i,j]=c)if((c=(D[j++][i-1]-8)%10)>5){c=5;T++;S[0]=i+j*w;}for(i=0;++i<w-1;)for(j=0;++j<h-1;)R=(i%2+j%2>1&(o=B[i,j-1]%2+B[i-1,j]%2+B[i+1,j]%2+B[i,j+1]%2)>0&o!=2)|((c=B[i,j])<4&c!=o)?7:R;for(o=h=0;o<O;B[i,j]=0)if(B[i=(c=S[o++])%w,j=c/w]>4){h++;S[O++]=(S[O++]=c-w-1)+2;S[O++]=(S[O++]=c+w-1)+2;z=j%2<1?w*2:2;S[O++]=c-z;S[O++]=c+z;}C.Write(h-R<T?"n":"y");}}

Le code effectue 3 vérifications, vérifiant d'abord le nombre de lignes autour de chaque numéro et que chaque jonction a 0 ou 2 lignes qui en découlent, puis que toutes les lignes sont jointes.

Code formaté:

using C=System.Console;

class P
{
    static void Main()
    {
        var D=C.In.ReadToEnd().Replace("\r","").Split('\n');
        int w=D[0].Length+2,h=D.Length+1,i=0,j,c,T=0,O=1,o,z,R=0;
        var B=new int[w,h]; // this is the grid
        var S=new int[w*h*9]; // this is a list of joined up lines (stored as x+y*w)

        for(;i++<w-2;)
            for(j=0;j<h-2;B[i,j]=c)
                if((c=(D[j++][i-1]-8)%10)>5)
                { // we are a line
                    c=5;
                    T++; // increment line counter
                    S[0]=i+j*w; // set start of loop
                }

        for(i=0;++i<w-1;) // this loop checks the numbers and that every + has 0 or 2 lines leading from it
            for(j=0;++j<h-1;)
                R=(i%2+j%2>1&(o=B[i,j-1]%2+B[i-1,j]%2+B[i+1,j]%2+B[i,j+1]%2)>0&o!=2)|((c=B[i,j])<4&c!=o)?7:R; // set R to 7 (no significance) if check fails

        for(o=h=0;o<O;B[i,j]=0) // this loops through the list of joined lines adding more until the whole loop has been seen
            if(B[i=(c=S[o++])%w,j=c/w]>4)
            {
                h++; // increment "seen" counter
                S[O++]=(S[O++]=c-w-1)+2;
                S[O++]=(S[O++]=c+w-1)+2;
                z=j%2<1?w*2:2; // special for | and -
                S[O++]=c-z;
                S[O++]=c+z;
            }

        C.Write(h-R<T?"n":"y"); // check if R is greater than 0 or h is less than T and output appropriately
    }
}
VisualMelon
la source
Merci @ edc65, aucune idée de comment j'ai raté ça!
VisualMelon
1

Cobra - 514

class P
    def main
        t,m,g=[[1]][:0],nil,File.readAllLines('p')
        u,i=g[0].length,1
        for l in g.length,for c in u,if g[l][c]in'0123'
            n=0
            for j in-1:2:2,for r in[g[l+j][c],g[l][c+j]],if r in'-|',n+=1
            if'[n]'<>g[l][c],m?='n'
        else if g[l][c]in'-|',x,y,t,d=c,l,t+[[c,l]],g[l][c]
        while i
            i=z=6
            for f,b in[[-1,1],[1,1],[0,2],[-1,-1],[+1,-1],[0,-2]]
                if'-'==d,f,b=b,f
                for w in t.count,if z and t[w]==[x+f,y+b],t,x,y,d,z=t[:w]+t[w+1:],x+=f,y+=b,g[y][x],0
                i-=z//6
        print if(t.count,'n',m?'y')

Vérifie si chaque numéro a le bon nombre de lignes à côté, puis parcourt un chemin autour des lignes et vérifie s'il en a manqué.

Οurous
la source