Erstellen Sie ein Nonogram-Puzzle

24

Ein Nonogramm ist ein zweidimensionales Logik-Puzzle, das ungefähr so aussieht (Screenshots aus dem Spiel Pixelo , meinem Lieblings-Nonogramm-Spiel):

Eine leere Nonogram-Tafel

Das Ziel des Spiels ist es herauszufinden, welches Bild diese Zahlen codieren. Die Regeln sind einfach: Eine Zahl in einer Spalte oder Zeile bedeutet, dass irgendwo in dieser Spalte oder Zeile viele Felder in einer Zeile ausgefüllt sind. Beispielsweise darf in der unteren Zeile des obigen Bildes kein Kästchen ausgefüllt sein, während in der oberen Zeile alle Kästchen ausgefüllt sein müssen. Die dritte Reihe von unten hat 8 gefüllte Kisten, und sie werden alle in einer Reihe sein.

Zwei oder mehr Zahlen für dieselbe Spalte oder Zeile bedeuten, dass mehrere "Durchläufe" von gefüllten Feldern mit mindestens einem Leerzeichen dazwischen mit diesen Längen vorhanden sind. Die Reihenfolge bleibt erhalten. Beispielsweise befinden sich drei ausgefüllte Kästchen in der rechten Spalte des obigen Bildes, mindestens ein Leerzeichen darunter, und ein weiteres ausgefülltes Kästchen.

Hier ist dasselbe Puzzle, fast fertig:

Eine fast fertige Nonogram-Tafel

(Die Xs sind nicht wichtig, sie sind nur ein Hinweis, den der Spieler für sich selbst hinterlässt, um zu sagen, "Dieses Feld ist definitiv nicht ausgefüllt". Denken Sie an Flags in Minesweeper. Sie haben keine Regelbedeutung.)

Hoffentlich können Sie sehen, dass beispielsweise die mittleren Spalten mit Hinweisen, die "2 2" sagen, zwei Reihen von ausgefüllten Feldern mit zwei Längen aufweisen.

Ihre Mission ist es, ein Programm oder eine Funktion zu schreiben, mit der Sie ein solches Puzzle erstellen können. Sie erhalten die Größe der Tafel als einzelne Ganzzahl (5 <= n <= 50) auf stdin oder als Argument (es gibt keinen Grund, warum ein Nonogramm-Puzzle quadratisch sein muss, aber für diese Herausforderung wird es sein). Danach erhalten Sie eine Reihe von Einsen und Nullen, die jeweils gefüllte und ungefüllte Quadrate im Bild darstellen. Die ersten n von ihnen sind die oberste Reihe, dann die nächste Reihe usw. Sie kehren zurück oder drucken auf eine Tafel mit 2 * 1-Zellen (weil sie besser aussehen und Sie Platz für zweistellige Hinweise für eine Spalte haben) ), alle leer, mit Hinweisen, die den Eingabedaten entsprechen.

Ausgabeformat

Ausgabeformat

Probe

Eingang:

./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])

Bild:

Erstes Beispielbild

Ausgabe:

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

Eingang:

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

Bild:

Zweites Beispielbild

Ausgabe:

                   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|

Klarstellungen

  • Ihre Ausgabe muss kein lösbares Rätsel sein. Nicht alle Nonogramme sind lösbar, aber das geht Sie nichts an. Gib einfach die Hinweise aus, die der Eingabe entsprechen, ob sie ein gutes Puzzle ergeben oder nicht.
  • Ein Programm, das Argumente in der Befehlszeile akzeptiert, ist zulässig. Dies ist eine Art oben angegeben, aber es ist möglich, die falsche Idee zu bekommen. Dafür gibt es Klarstellungen.
  • Das Drucken von a 0für eine Zeile oder Spalte, in der keine Felder ausgefüllt sind, ist obligatorisch. Ich sage das nirgendwo mit Worten, aber es ist in den Beispieldaten.
untergrundbahn
quelle
Ich bin fast fertig mit meiner Lösung. Können wir davon ausgehen, dass eine Reihe oder Spalte keine dreistellige Anzahl von Kästchen enthält?
ängstlich
2
@voidpigeon: 5<=n<=50ist die Spezifikation, daher kann es keine 3-stelligen Zahlen geben
Kyle Kanos
Nachdem ich diese Frage gestellt hatte, fing ich an, selbst an einer Lösung zu arbeiten. Ich werde es noch nicht veröffentlichen (gemäß dieser Meta-Antwort), aber ich werde meine Byteanzahl veröffentlichen, damit ihr nach etwas streben könnt: 404 Bytes in Python 2.7
undergroundmonorail
Enthält Ihre erste Beispielausgabe nicht mehr -als sie sollte?
Ventero
@Ventro Sie sind richtig! Ich wusste, wie ich ein Programm schreiben würde, aber ich tat es erst jetzt, also waren meine Beispielausgaben von Hand. Hoppla! (Ich habe auch die Ausgabe des zweiten Beispiels vermasselt, aber ich habe sie behoben, bevor es irgendwelche Antworten gab.)
undergroundmonorail

Antworten:

9

GolfScript, 128 Zeichen

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

Die Eingabe muss in STDIN als durch Leerzeichen getrennte Zahl erfolgen.

Sie können das Beispiel testen hier .

Kommentierter Code:

# 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
quelle
1
+1 schön, ich habe einige gute Tricks aus diesem Beitrag gelernt
Cristian Lupascu
Ich habe es geschafft, auf 123 Zeichen zu ~](:k/.zip\]{{1,%{,}%.!,+}%}/{' ':^*}%{.{,}%$-1=}:f~:r{^*\+r~)>'|'n}+%\f{.~)\[^]*@+>{^\+-2>}%}+%zip{r)^*\n}%r^*'+''--'k*n](golfen : (aus irgendeinem Grund sagt lettercount.com 125 Zeichen, wenn Sie es kopieren, aber ich versichere Ihnen, es sind 123 Zeichen). Einige Teile des Algorithmus wurden geändert, aber die Mehrheit bleibt gleich. Ich habe auch einige Variablennamen geändert (9 als Variable ist klug, aber auch verwirrend), aber Sie können sie zurücksetzen, wenn Sie möchten.
Volatility
7

Rubin, 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*""+?|}

Dies führt zwar nicht zu der in der Frage angegebenen exakten Beispielausgabe, entspricht jedoch den Spezifikationen. Der einzige Unterschied zu den Beispielen besteht darin, dass ich ein paar führende Leerzeichen / Zeilenumbrüche drucke.

Beispiel:

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

Änderungsprotokoll:

  • 240 -> 231: Das Eingabeformat wurde geändert, um Befehlszeilenargumente anstelle von stdin zu verwenden.
  • 231 -> 230: Ein Leerzeichen wurde entfernt, indem die Wertüberprüfung von chunknach verschoben wurdemap .
  • 230 -> 226: Subtrahieren [nil]statt aufrufen Array#compact.
  • 226 -> 216: Vereinfachen Sie die Erzeugung von Hinweisen.
Ventero
quelle
Sie drucken zwar einige zusätzliche Zeilenumbrüche und Leerzeichen, aber bisher haben sie in allen meinen Tests der Spezifikation "0 oder mehr" entsprochen, sodass Sie gut sind. Ich warne Sie jetzt, aber wenn ich Zahlen sehe, die links neben meinem Monitor in der Luft schweben, muss ich diese Antwort disqualifizieren :)
undergroundmonorail
1
@undergroundmonorail: Die Ausgabe wird so gedruckt, dass length(leading spaces + numbers to the left) == 2*nund height(leading newlines + numbers at the top) == n... Solange Ihr Monitor groß genug für 3*n+1 × 2*n+2Zeichen ist, sollten Sie mich nicht disqualifizieren müssen. :)
Ventero
4

Ruby, 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]}*""+?|}
ängstlich
quelle
Wie läuft das ab? Ich versuchte es ruby $yourprogram <<< $inputaber bekam ruby_nanograms:7:in '<main>': undefined method '+' for nil:NilClass (NoMethodError).
Undergroundmonorail
@undergroundmonorail ruby nonogram.rb 2 1 0 0 1für eine 2x2
ängstliche
Dies ist eine gute Antwort, aber 0im zweiten Beispiel wird die viertletzte Spalte nicht gedruckt .
Undergroundmonorail
Mir ist gerade aufgefallen, dass die +------... -Zeile auch von einem zu vielen Leerzeichen eingerückt wird.
Undergroundmonorail
1
@undergroundmonorail Beides behoben.
ängstlich
4

GolfScript 149 147

Der Code

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

Bearbeitungen:

  • nutzlosen Raum entfernt
  • hat eine wiederverwendbare Ein-Zeichen-Funktion definiert puts, um ein weiteres Zeichen zu speichern

Online-Demos

Eine etwas kommentierte Version des Codes

# 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
quelle
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}

Ungolfed

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
}

Verwendung

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])

Verlauf bearbeiten

1 Regexp entfernt, um Spalten zu finden. Overkill
2 Einfacher ist besser. Ausgabe in eine Zeichenfolge, nicht in ein Array. Hilfefunktion FÜLLEN (F) entfernt
3 Noch einfacher. Ich kann es nicht besser machen. Kann immer noch nicht mit Golfscript vergleichen :(

edc65
quelle
Nett. Ich habe auch eine Javascript-Version ausprobiert, aber mit etwas um die 500 Bytes geendet und festgestellt, dass ich zu groß war, um es hier abzulegen. Wäre gut, ungolfed version mit originalen Variablennamen zu posten (wenn du es noch hast). Und wie läuft das ab? Wenn ich es kopiere und in das Chrome-Konsolenfenster einfüge, erhalte ich "ReferenceError: Ungültige linke Seite in Zuweisung". Gibt es etwas zu ändern oder vor dem Ausführen hinzuzufügen?
Tigrou
@tigrou sorry das "=>" sintax funktioniert nur in firefox. Variablen: c Spalten Hinweise, d Dimension, l Liste der Eingabe, o Ausgabe, i Schleife Variable, q und z Temp
edc65
-15 bytes :)
nderscore
@nderscore Herumspielen mit dem Code, ich habe 326. In Ihrem Code R ist nicht initialisiert (einfacher Fehler, wenn Sie immer wieder versuchen ...)
edc65
1

R 384 Zeichen

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")

Mit Einrückungen und Erläuterungen:

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

Verwendung:

> 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
quelle
1

C - 511

C war definitiv nicht dafür gemacht, die Ausgabe gut zu formatieren. Die Zeichenanzahl enthält nur die erforderlichen Leerzeichen / neuen Zeilen.

Die Eingabe erfolgt von STDIN, Zahlen durch Leerzeichen getrennt.

#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
quelle
1

Es ist ein paar Tage her und niemand hat in Python geantwortet, also hier ist mein (wahrscheinlich ziemlich schlechter) Versuch:

Python 2.7 - 404 397 380 Bytes

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])

Ich werde bald eine ungolfed Version posten, aber im Moment denke ich, dass sie ziemlich lesbar ist. :)

BEARBEITEN: Während die ungolfed Version zu schreiben, habe ich einige Verbesserungen bemerkte ich könnte das ziemlich bedeutend sein machen aufaddiert! Aus irgendeinem Grund, den ich nicht erklären kann, hat es jetzt zusätzliche Zeilenumbrüche oben und Leerzeichen links (obwohl ich glaube, dass ich nichts an der Funktionalität geändert habe), aber es entspricht immer noch den Spezifikationen.Ungolfed-Version kommt!

Ungolfed:

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

Aus Gründen der Lesbarkeit wurden einige Änderungen vorgenommen ( gAufteilung in drei benannte Funktionen, komplexes Listenverständnis in forSchleifen), aber logischerweise funktioniert es genauso.

Aus diesem Grund ist es verwirrend, dass hier keine zusätzlichen Leerzeichen und Zeilenumbrüche gedruckt werden, während dies beim Golfspieler der Fall ist. ¯ \ _ (ツ) _ / ¯

untergrundbahn
quelle
1
Ähm, ich kann deine Lösung nicht finden. (sorry, nur ein schrecklicher Witz in Bezug auf die Anzahl der Charaktere, stört mich nicht :))
Türklinke
@dor Aha! Versuchen Sie, Ihren HTTP-Fehlercode jetzt zum Scherzen zu bringen! : P
undergroundmonorail