Créer un puzzle sans programme

24

Un nonogramme est un puzzle logique bidimensionnel qui ressemble à ceci (captures d'écran du jeu Pixelo , mon jeu de nonogramme préféré):

Un plateau de nonogramme vide

Le but du jeu est de comprendre quelle image ces nombres encodent. Les règles sont simples: un nombre sur une colonne ou une ligne signifie que quelque part dans cette colonne ou cette ligne, de nombreuses cases sont remplies dans une ligne. Par exemple, la ligne du bas de l'image ci-dessus ne doit contenir aucune case, tandis que celle du dessus doit contenir toutes ses cases. La troisième rangée à partir du bas a 8 cases remplies, et elles seront toutes consécutives.

Deux nombres ou plus pour la même colonne ou ligne signifient qu'il y a plusieurs "séries" de cases remplies, avec au moins un espace entre elles, avec ces longueurs. L'ordre est conservé. Par exemple, il y a trois cases remplies dans la colonne de droite de l'image ci-dessus, au moins un espace en dessous, puis une autre case remplie.

Voici ce même puzzle, presque terminé:

Un panneau de nonogramme presque fini

(Les X ne sont pas importants, ils sont juste un indice que le joueur se laisse à lui-même pour dire "Cette case n'est certainement pas remplie". Pensez aux drapeaux dans Démineur. Ils n'ont pas de sens pour les règles.)

J'espère que vous pouvez voir que, par exemple, les colonnes du milieu avec des indices qui disent "2 2" ont deux séries de 2 cases remplies.

Votre mission, si vous l'acceptez, est d'écrire un programme ou une fonction qui créera un puzzle comme celui-ci. La taille de la carte vous est donnée sous la forme d'un entier unique (5 <= n <= 50) sur stdin ou comme argument (il n'y a aucune raison pour qu'un casse-tête non graphique doive être carré, mais pour ce défi, il le sera). Après cela, vous recevrez une série de 1 et de 0 représentant respectivement les carrés remplis et non remplis dans l'image. Les premiers n d'entre eux sont la ligne du haut, puis la ligne suivante, etc. Vous retournerez ou imprimerez pour afficher un tableau de 2 * 1 cellules (car elles sont plus belles et cela vous donne de la place pour des indices à 2 chiffres pour une colonne). ), tous vides, avec des indices correspondant aux données d'entrée.

Format de sortie

Format de sortie

Échantillon

Contribution:

./nonogram <<< '5 0 1 1 1 0 1 1 0 1 1 1 0 1 0 1 1 1 0 1 1 0 1 1 1 0'
                                 OR
      n(5,[0,1,1,1,0,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,0,1,1,1,0])

Image:

Premier exemple d'image

Sortie:

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

Contribution:

./nonogram <<< '15 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 0 1 1 1 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1'

Image:

Deuxième exemple d'image

Sortie:

                   1                       1
                 1 1 3       3 5   5 3   3 1
                 7 2 3 2 4 2 3 210 2 3 0 4 215
               +------------------------------
              2|
              1|
              1|
              1|
              1|
            1 1|
        3 3 1 1|
        1 5 1 1|
          3 5 3|
          1 5 1|
          1 3 1|
      1 1 1 1 1|
1 1 1 1 1 1 1 1|
           11 3|
           11 3|

Clarifications

  • Votre sortie n'a pas besoin d'être un puzzle résoluble. Tous les nonogrammes ne sont pas résolubles, mais ce n'est pas votre problème. Sortez simplement les indices qui correspondent à l'entrée, qu'ils constituent ou non un bon casse-tête.
  • Un programme qui prend des arguments sur la ligne de commande est autorisé. C'est un peu indiqué ci-dessus, mais il est possible de se tromper. C'est à cela que servent les clarifications.
  • L'impression d'un 0pour une ligne ou une colonne qui n'a pas de cases remplies est obligatoire. Je ne dis cela avec des mots nulle part, mais c'est dans les exemples de données.
métro monorail
la source
J'ai à peu près fini avec ma solution. Peut-on supposer qu'il n'y aura pas de nombre à 3 chiffres de cases dans une ligne ou une colonne?
afuous
2
@voidpigeon: 5<=n<=50est la spécification, donc il ne peut pas y avoir de nombres à 3 chiffres
Kyle Kanos
Après avoir posté cette question, j'ai commencé à travailler sur une solution moi-même. Je ne le publierai pas encore (selon cette méta-réponse), mais je publierai mon nombre d'octets afin que vous ayez quelque chose à rechercher: 404 octets en Python 2.7
undergroundmonorail
Votre premier exemple de sortie n'en contient-il pas un de plus -qu'il ne devrait?
Ventero
@Ventro Vous avez raison! Je savais comment j'écrirais un programme pour le faire, mais je ne l'ai pas fait jusqu'à maintenant, donc mes sorties d'échantillons étaient à la main. Oops! (J'ai également foiré le deuxième exemple de sortie, mais je l'ai corrigé avant qu'il n'y ait de réponses.)
undergroundmonorail

Réponses:

9

GolfScript, 128 caractères

~](:k/.{{1,%{,}%.!,+}%}:^~{' ':s*}%.{,}%$-1=:9{s*\+9~)>'|'n}+%\zip^.{,~}%$0=){.~[s]*@+>{s\+-2>}%}+%zip{9)s*\n}%\[9s*'+''--'k*n]\

L'entrée doit être fournie sur STDIN sous forme de nombres séparés par des espaces.

Vous pouvez tester l'exemple ici .

Code commenté:

# Parse the input into an 2D array of digits. The width is saved to variable k
~](:k/

# Apply the code block ^ to a copy of this array
.
{                # begin on code block
  {              # for each line
   1,%           #   split at 0s (1, => [0]) (leading, trailing, multiple 0s are 
                 #   removed because of operator % instead of /)
   {,}%          #   calculate the length of each run of 1s                 
   .!,+          #   special case: only zeros, i.e. []
                 #   in this case the ! operator yiels 1, thus [0], else []
  }%             # end for
}:^              # end of code block
~                # apply

# Format row headers
{' ':s*}%        # join numbers with spaces
.{,}%$-1=:9      # calulate the length of the longest row header
                 # and save it to variable <9>
{                # for each row
  s*\+           #   prepend padding spaces
  9~)>           #   and cut at length <9> from the right
  '|'n           #   append '|' and newline
}+%              # end for

# Format column headers
\zip^            # transpose input array and apply the code block ^
                 # i.e. calculate length of runs
.{,~}%$0=)       # determine (negative) length of the longest column header
{                # for each column
  .~[s]*@+       #   prepend enough spaces
  >              #   and cut at common length (from right)
  {s\+-2>}%      #   format each number/empty to 2 chars width
}+%              # end for
zip              # transpose column header into output lines
{9)s*\n}%        # prepend spaces to each line and append newline

# Inject separator line
\[
9s*              # spaces
'+'              # a plus sign
'--'k*           # k (width) number of '--'
n                # newline
]\
Howard
la source
1
+1 sympa, j'ai appris pas mal de bonnes astuces de ce post
Cristian Lupascu
J'ai réussi à le ~](:k/.zip\]{{1,%{,}%.!,+}%}/{' ':^*}%{.{,}%$-1=}:f~:r{^*\+r~)>'|'n}+%\f{.~)\[^]*@+>{^\+-2>}%}+%zip{r)^*\n}%r^*'+''--'k*n](jouer à 123 caractères: (pour une raison quelconque, lettercount.com dit 125 caractères si vous le copiez, mais je vous assure que c'est 123 caractères). Certaines parties de l'algorithme ont été modifiées, mais la majorité est toujours la même. J'ai également changé certains noms de variable (avoir 9 comme variable est intelligent, mais aussi déroutant), mais vous pouvez les changer si vous le souhaitez.
Volatilité
7

Rubis, 216 255

n=$*.shift.to_i;k=*$*.each_slice(n)
u=->k{k.map{|i|r=i.join.scan(/1+/).map{|i|"%2d"%i.size}
[*["  "]*n,*r[0]?r:" 0"][-n,n]}}
puts u[k.transpose].transpose.map{|i|" "*(n-~n)+i*""},"  "*n+?++"--"*n,u[k].map{|i|i*""+?|}

Bien que cela ne produise pas la sortie d'échantillon exacte donnée dans la question, elle suit les spécifications. La seule différence avec les exemples est que j'imprime quelques espaces / sauts de ligne.

Exemple:

$ ruby nonogram.rb 15 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 0 1 1 1 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
# empty lines removed for brevity
                                  1                       1  
                                1 1 3       3 5   5 3   3 1  
                                7 2 3 2 4 2 3 210 2 3 0 4 215
                              +------------------------------
                             2|
                             1|
                             1|
                             1|
                             1|
                           1 1|
                       3 3 1 1|
                       1 5 1 1|
                         3 5 3|
                         1 5 1|
                         1 3 1|
                     1 1 1 1 1|
               1 1 1 1 1 1 1 1|
                          11 3|
                          11 3|

Journal des modifications:

  • 240 -> 231: format d'entrée modifié pour utiliser des arguments de ligne de commande au lieu de stdin.
  • 231 -> 230: Élimination d'un espace en déplaçant le contrôle de valeur de chunkàmap .
  • 230 -> 226: Soustrayez [nil]au lieu d'appeler Array#compact.
  • 226 -> 216: Simplifiez la génération d'indices.
Ventero
la source
Vous imprimez des nouvelles lignes et des espaces supplémentaires, mais jusqu'à présent, dans tous mes tests, ils correspondent à la spécification "0 ou plus", donc vous êtes bon. Je vous préviens maintenant, cependant, si je commence à voir des nombres flottant dans l'air à gauche de mon moniteur, je vais devoir disqualifier cette réponse :)
undergroundmonorail
1
@undergroundmonorail: La sortie est imprimée en manière telle que length(leading spaces + numbers to the left) == 2*net height(leading newlines + numbers at the top) == n... aussi longtemps que votre moniteur est assez grand pour les 3*n+1 × 2*n+2personnages, vous ne devriez pas avoir à me disqualifier. :)
Ventero
4

Rubis, 434

n=$*[i=0].to_i
a,b=[],[]
a.push $*.slice!(1..n)*""while $*.size>1
(b.push a.map{|c|c[i]}*"";i+=1)while i<n
a,b=*[a,b].map{|c|c.map{|d|e=d.split(/[0]+/).map(&:size).select{|f|f>i=0}.map &:to_s;(e.size>0)?e:[?0]}}
m,k=*[a,b].map{|c|c.map(&:size).max}
s="  "*m
k.times{$><<s+"  "+b.map{|c|(" "+((c.size==k-i)?(c.shift):(" ")))[-2..-1]}*"";i+=1;puts}
puts s+" "+?++?-*n*2
a.each{|c|puts"  "*(m-c.size)+" "+c.map{|d|(" "+d)[-2..-1]}*""+?|}
afuous
la source
Comment gérez-vous cela? J'ai essayé ruby $yourprogram <<< $inputmais j'ai réussi ruby_nanograms:7:in '<main>': undefined method '+' for nil:NilClass (NoMethodError).
undergroundmonorail
@undergroundmonorail ruby nonogram.rb 2 1 0 0 1pour un 2x2
afuous
C'est une bonne réponse, mais vous n'imprimez pas la 0pour l'avant-dernière colonne du deuxième exemple.
undergroundmonorail
Je viens de remarquer que la +------ligne ... est également en retrait d'un espace de trop.
undergroundmonorail
1
@undergroundmonorail Correction des deux.
afuous
4

GolfScript 149 147

Le code

~](:s/.zip{{[0]%{,`}%['0']or}%.{,}%$)\;:¶;{.,¶\-[' ']*\+}%}:f~¶:v;\[f~]\zip{{{.,2\-' '*\+}%''*}:d2*)' '*:z\+{puts}:o~}%z(;'+'s'-'2**++o~{d'|'+o}/

Modifications:

  • espace inutile supprimé
  • défini une fonction réutilisable à un caractère pour putsenregistrer un autre caractère

Démos en ligne

Une version quelque peu annotée du code

# split lines
~](:s/

# make transposed copy
.zip

#prepare numbers to show in the header
{{[0]%{,`}%['0']or}%.{,}%$)\;:¶;{.,¶\-[' ']*\+}%}:f~¶:v;

# prepare numbers to show in the left column
\[f~]\zip

#print header (vertical hints)
{  {{.,2\-' '*\+}%''*}:d~  2*)' '*:z\+puts}%

#print first line
z(;'+'s'-'2**++puts

#print horizontal hints
~{d'|'+ puts}/
Cristian Lupascu
la source
4

Javascript (E6) 314 334 357 410

N=(d,l)=>{J=a=>a.join(''),M=s=>(s.match(/1+/g)||['']).map(x=>x.length),f=' '.repeat(d+1),c=[n='\n'],o=n+f+'+'+'--'.repeat(d);for(i=-1;++i<d;)c[i]=M(J(l.map((e,p)=>p%d-i?'':e))),o+=n+(f+J(M(J(l).substr(i*d,d)).map(P=n=>n>9?n:n<10?' '+n:'  '))+'|').slice(-d-2);for(;--i;)o=n+f+' '+J(c.map(e=>P(e.pop())))+o;return o}

Non golfé

N=(d,l)=> {
  J = a => a.join(''),
  M = s => (s.match(/1+/g)||['']).map(x=>x.length),
  f=' '.repeat(d+1), c=[n='\n'], o=n+f+'+'+'--'.repeat(d);
  for(i = -1; ++i < d;)
    c[i] = M(J(l.map((e,p)=>p%d-i?'':e))),
    o += n+(f+J(M(J(l).substr(i*d,d)).map(P=n=>n>9?n:n<10?' '+n:'  '))+'|').slice(-d-2);
  for(;--i;)
    o=n+f+' '+J(c.map(e=>P(e.pop())))+o;
  return o
}

Usage

N(5,[0,1,1,1,0,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,0,1,1,1,0])

N(15,[0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,1,1,1,0,1,0,1,1,1,1,0,0,0,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1])

Modifier l'historique

1 Suppression de l'expression rationnelle utilisée pour rechercher les colonnes. Overkill
2 Plus simple est meilleur. Sortie dans une chaîne, pas dans un tableau. Suppression de la fonction d'assistance FILL (F)
3 Encore plus simple. Je ne peux pas faire mieux que ça. Ne peut toujours pas se comparer à Golfscript :(

edc65
la source
Agréable. J'ai aussi essayé une version Javascript mais j'ai fini avec quelque chose autour de 500 octets et j'ai décidé que j'étais trop gros pour la mettre ici. Ce serait bien de publier une version non golfée avec les noms de variables d'origine (si vous l'avez toujours). De plus, comment exécutez-vous cela? Si je le copie, le colle dans la fenêtre de la console Chrome, j'obtiens "ReferenceError: Invalid left-hand side in assignment". Y a-t-il quelque chose à changer ou à ajouter avant de courir?
tigrou
@tigrou désolé, la "=>" sintax ne fonctionne que dans Firefox. Variables: indices c colunns, dimension d, l liste d'entrées, sortie o, variable de boucle i, temp q et z
edc65
-15 octets :)
nderscore
@nderscore tripote le code, j'en ai 326. Dans votre code R n'est pas initialisé (erreur facile quand vous essayez encore et encore ...)
edc65
1

R, 384 caractères

a=scan();p=function(x)paste(x,collapse="");P=paste0;s=sapply;l=length;f=function(i)lapply(apply(matrix(a[-1],nr=a,b=T),i,rle),function(x)if(any(x$v)){x$l[!!x$v]}else{0});g=function(j,i)apply(s(j,function(x)sprintf("%2s",c(rep("",max(s(j,l))-l(x)),x))),i,p);c=P(g(f(1),2),"|");d=g(f(2),1);h=p(rep(" ",nchar(c[1])-1));e=P(h,"+",p(rep("-",nchar(d[1]))));d=P(h," ",d);cat(d,e,c,sep="\n")

Avec des indentations et quelques explications:

a=scan() #Takes input

p=function(x)paste(x,collapse="") #Creates shortcuts
P=paste0
s=sapply
l=length

#This function finds the number of subsequent ones in a line (using rle = run length encoding).
#It takes 1 or 2 as argument (1 being row-wise, 2 column-wise
f=function(i)lapply(apply(matrix(a[-1],nr=a,b=T),i,rle),function(x)if(any(x$v)){x$l[!!x$v]}else{0})

#This function takes the result of the previous and format the strings correctly (depending if they are rows or columns)
g=function(j,i)apply(s(j,function(x)sprintf("%2s",c(rep("",max(s(j,l))-l(x)),x))),i,p)

c=paste0(g(f(1),2),"|") #Computes the rows
d=g(f(2),1) #Computes the columns
h=p(rep(" ",nchar(c[1])-1)) 
e=paste0(h,"+",p(rep("-",nchar(d[1])))) #Prepare vertical border
d=paste0(h," ",d) #Pad column indices with spaces
cat(d,e,c,sep="\n") #Prints

Usage:

> a=scan();p=function(x)paste(x,collapse="");P=paste0;s=sapply;l=length;f=function(i)lapply(apply(matrix(a[-1],nr=a,b=T),i,rle),function(x)if(any(x$v)){x$l[!!x$v]}else{0});g=function(j,i)apply(s(j,function(x)sprintf("%2s",c(rep("",max(s(j,l))-l(x)),x))),i,p);c=P(g(f(1),2),"|");d=g(f(2),1);h=p(rep(" ",nchar(c[1])-1));e=P(h,"+",p(rep("-",nchar(d[1]))));d=P(h," ",d);cat(d,e,c,sep="\n")
1: 15 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 1 0 1 0 0 1 0 0 0 1 1 1 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 1 1 1 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1
227: 
Read 226 items
                    1                       1  
                  1 1 3       3 5   5 3   3 1  
                  7 2 3 2 4 2 3 210 2 3 0 4 215
                +------------------------------
               2|
               1|
               1|
               1|
               1|
             1 1|
         3 3 1 1|
         1 5 1 1|
           3 5 3|
           1 5 1|
           1 3 1|
       1 1 1 1 1|
 1 1 1 1 1 1 1 1|
            11 3|
            11 3|
plannapus
la source
1

C - 511

C n'a certainement pas été conçu pour formater correctement la sortie. Le nombre de caractères comprend uniquement les espaces / nouvelles lignes nécessaires.

L'entrée provient de STDIN, les nombres sont séparés par des espaces.

#define P printf
#define L(x) for(x=0;x<s/2+1;x++)
#define l(x) for(x=0;x<s;x++)
#define B(x,y) x[i][j]||y==s/2?P("%2d",x[i][j]):P("  ");
a[50][50],i,j,s,h[25][50],v[50][25],H[50],V[50],x[25],y[25];
main(){
    scanf("%d",&s);
    L(j)x[j]=y[j]=s/2+1;
    l(i)l(j)scanf("%d",&a[i][j]);
    for(i=s-1;i>=0;i--)
        for(j=s-1;j>=0;j--)
            a[i][j]?
                !H[j]&&(x[j]--,H[j]=1),
                h[x[j]][j]++,
                !V[i]&&(y[i]--,V[i]=1),
                v[i][y[i]]++:
            (H[j]=V[i]=0);
    L(i){
        L(j)P("  ");
        P(" ");
        l(j)B(h,i);
        P("\n");
    }
    L(i)P("  ");
    P("+");
    l(i)P("--");
    P("\n");
    l(i){
        L(j)B(v,j);
        P("|\n");
    }
}
Allbeert
la source
1

Cela fait quelques jours et personne n'a répondu en python, alors voici ma tentative (probablement assez mauvaise):

Python 2.7 - 404 397 380 octets

def p(n,m):
 k=str.join;l=[];g=lambda y:[['  ']*(max(map(len,y))-len(t))+t for t in[[' '*(a<10)+`a`for a in map(len,k("",c).split('0'))if a]or[' 0']for c in y]]
 while m:l+=[map(str,m[:n])];m=m[n:]
 x=g(l);j=k('\n',['  '*max(map(len,x))+'+'+k("",a)for a in zip(*[list(a)+['--']for a in g(zip(*l))])]);return j.replace('+',' ',j.count('+')-1)+'\n'+k('\n',[k("",a+['|'])for a in x])

Je publierai bientôt une version non golfée, mais pour le moment je pense qu'elle est assez lisible. :)

MODIFIER: Lors de l'écriture de la version non golfée, j'ai remarqué quelques améliorations que je pouvais apporter et qui étaient assez importantes! Pour une raison que je ne peux pas expliquer, il a maintenant des nouvelles lignes supplémentaires en haut et des espaces à gauche (même si je ne pense pas avoir changé quoi que ce soit de fonctionnel), mais il répond toujours aux spécifications.La version non golfée arrive!

Non golfé:

def nonogram(board_size, pixels):
    def hints(board):
        output = []
        for row in board:
            # Convert the row to a string of 1s and 0s, then get a list of strings
            # that came between two 0s.
            s = "".join(row).split('0')

            # A list of the length of each string in that list.
            l = map(len, s)

            # We now have our horizontal hints for the board, except that anywhere
            # there were two 0s consecutively we have a useless 0.
            # We can get rid of the 0s easily, but if there were no 1s in the row at
            # all we want exactly one 0.
            # Solution:
            output.append([h for h in l if h != 0] or [0])
            # In this context, `foo or bar` means `foo if foo is a truthy value, bar
            # otherwise`.
            # An empty list is falsey, so if we strip out all the strings we hardcode
            # the 0.
        return output

    def num_format(hints):
        # For both horizontal and vertical hints, we want a space before single-
        # digit numbers and no space otherwise. Convert hints to strings and add
        # spaces as necessary.
        output = []

        for row in hints:
            output.append([' '*(a < 10) + str(a) for a in row])
            # Multiplying a string by n repeats it n times, e.g. 'abc'*3=='abcabcabc'
            # The only numbers that need a space are the ones less than 10.
            # ' '*(a < 10) first evaluates a < 10 to get a True or False value.
            # Python automatically converts True to 1 and False to 0.
            # So, if a is a one digit number, we do `' '*(1) + str(a)`.
            # If it's a two digit number, we do `' '*(0) + str(a)`.
        return output

    def padding(hints):
        output = []
        longest = max(map(len, hints)) # how long is the longest row?
        for row in hints:
            output.append(['  ']*(longest - len(row)) + row)
            # Add '  ' to the beginning of every row until it's the same length
            # as the longest one. Because all hints are two characters wide, this
            # ensures all rows of hints are the same length.
        return output

    board = []

    while pixels: # non-empty list == True
        # Make a list of the first (board_size) pixels converted to strings, then
        # add that list to board. Remove those pixels from the list of pixels.
        # When pixels is empty, board has a seperate list for each row.
        board.append([str(n) for n in pixels[:board_size]])
        pixels = pixels[board_size:]

    horizontal_hints = padding(num_format(hints(board)))

    vertical_hints = padding(num_format(hints(zip(*board))))
    # zip(*l) is a common way to transpose l.
    # zip([1,2,3], [4,5,6], [7,8,9]) == [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
    # the star operator unpacks an iterable so the contents can be used as
    # multiple arguments, so
    # zip(*[[1,2,3],[4,5,6],[7,8,9]]) is the same as what we just did.
    # Transposing the board and getting the horizontal hints gives us the
    # vertical hints of the original, but transposed. We'll transpose it back,
    # but we'll also add '--' to the end of all of them to make up the line
    vertical_hints = zip(*[a + ['--'] for a in vertical_hints])

    # add n spaces, where n is the length of the longest horizontal hint, plus
    # one space to the beginning of each line in the vertical hints, then join
    # with newlines to make it all one string.
    vertical_hints = '\n'.join(['  '*max(map(len, horizontal_hints)) + '+' +
                               ''.join(a) for a in vertical_hints])

    # find the number of plus signs in the string
    # replace the first (that many - 1) plus signs with spaces
    vertical_hints = vertical_hints.replace('+', ' ', vertical_hints.count('+')-1)

    # add a pipe to each row of horizontal hints, then join it with newlines
    horizontal_hints = '\n'.join([''.join(a + ['|']) for a in horizontal_hints])

    # add and return
    return vertical_hints + '\n' + horizontal_hints

Quelques modifications ont été apportées pour des raisons de lisibilité ( gétant divisées en trois fonctions nommées, des compréhensions de listes complexes transformées en forboucles) mais logiquement, cela fonctionne exactement de la même manière.

C'est pourquoi il est déroutant que celui-ci n'imprime pas d'espaces supplémentaires et de nouvelles lignes, tandis que celui qui joue au golf le fait. ¯ \ _ (ツ) _ / ¯

métro monorail
la source
1
Umm, je ne trouve pas votre solution. (désolé, juste une blague terrible concernant le nombre de personnages, ne me dérange pas :))
Poignée de porte
@dor Aha! Essayez de faire vos blagues de code d'erreur HTTP maintenant! : P
undergroundmonorail