Buat Puzzle Nonogram

24

Sebuah Nonogram adalah dimensi dua teka-teki logika yang terlihat seperti ini (screenshot dari game Pixelo , permainan Nonogram favorit saya):

Papan nonogram kosong

Tujuan permainan ini adalah untuk mengetahui gambar apa yang dikodekan oleh angka-angka tersebut. Aturannya sederhana: Angka pada kolom atau baris berarti bahwa di suatu tempat di kolom atau baris itu, bahwa banyak kotak diisi dalam satu baris. Misalnya, baris bawah pada gambar di atas harus tidak memiliki kotak diisi, sedangkan yang di atasnya harus memiliki semua kotaknya diisi. Baris ketiga dari bawah memiliki 8 kotak yang terisi, dan semuanya akan berturut-turut.

Dua atau lebih angka untuk kolom atau baris yang sama berarti ada beberapa "run" dari kotak yang diisi, dengan setidaknya satu spasi di antaranya, dengan panjangnya. Pesanan dipertahankan. Misalnya, ada tiga kotak yang diisi di kolom paling kanan dari gambar di atas, setidaknya satu ruang di bawahnya, dan kemudian satu lagi yang diisi kotak.

Inilah teka-teki yang sama, hampir selesai:

Papan nonogram yang hampir selesai

(The Xs tidak penting, mereka hanya petunjuk pemain meninggalkannya untuk mengatakan "Alun-alun ini jelas tidak diisi". Pikirkan bendera di Minesweeper. Mereka tidak memiliki arti aturan.)

Mudah-mudahan Anda dapat melihat bahwa, misalnya, kolom tengah dengan petunjuk yang mengatakan "2 2" memiliki dua run 2-panjang dari kotak yang diisi.

Misi Anda, jika Anda memilih untuk menerimanya, adalah menulis program atau fungsi yang akan membuat teka-teki seperti ini. Anda diberi ukuran papan sebagai bilangan bulat tunggal (5 <= n <= 50) pada stdin atau sebagai argumen (tidak ada alasan mengapa teka-teki nonogram harus persegi, tetapi untuk tantangan ini akan menjadi). Setelah itu, Anda akan diberi serangkaian 1s dan 0s yang mewakili kotak diisi dan tidak terisi dalam gambar, masing-masing. N pertama dari mereka adalah baris atas, kemudian baris berikutnya, dll. Anda akan kembali atau mencetak ke stdout papan 2 * 1 sel (karena mereka terlihat lebih baik, dan itu memberi Anda ruang untuk petunjuk 2 digit untuk kolom ), semuanya kosong, dengan petunjuk yang sesuai dengan data input.

Format output

Format output

Mencicipi

Memasukkan:

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

Gambar:

Contoh gambar pertama

Keluaran:

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

Memasukkan:

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

Gambar:

Contoh gambar kedua

Keluaran:

                   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|

Klarifikasi

  • Output Anda tidak perlu menjadi teka-teki yang dapat dipecahkan. Tidak semua nonogram dapat dipecahkan, tetapi itu bukan urusan Anda. Keluarkan petunjuk yang sesuai dengan input, apakah itu membuat puzzle yang baik atau tidak.
  • Program yang mengambil argumen pada baris perintah diizinkan. Ini adalah jenis yang disebutkan di atas, tetapi mungkin untuk mendapatkan ide yang salah. Untuk itulah klarifikasi.
  • Mencetak 0untuk baris atau kolom yang tidak memiliki kotak diisi adalah wajib. Saya tidak mengatakan ini dengan kata-kata di mana pun tetapi dalam data sampel.
monmon bawah tanah
sumber
Saya hampir selesai dengan solusi saya. Bisakah kita berasumsi bahwa tidak akan ada jumlah kotak 3 digit dalam satu baris atau kolom?
Berlangsung
2
@ voidpigeon: 5<=n<=50adalah specnya, jadi tidak mungkin ada angka 3 digit
Kyle Kanos
Setelah memposting pertanyaan ini, saya mulai mengerjakan solusi sendiri. Saya belum akan mempostingnya (sesuai jawaban meta ini ), tapi saya akan memposting jumlah byte saya sehingga kalian memiliki sesuatu untuk diperjuangkan: 404 byte dalam Python 2.7
undergroundmonorail
Bukankah output contoh pertama Anda mengandung satu lebih -dari yang seharusnya?
Ventero
@Ventro Anda benar! Saya tahu bagaimana saya akan menulis sebuah program untuk melakukan ini, tetapi saya tidak benar-benar melakukannya sampai sekarang, jadi hasil sampel saya dilakukan dengan tangan. Ups! (Saya juga mengacaukan keluaran sampel kedua, tapi saya memperbaikinya sebelum ada jawaban.)
undergroundmonorail

Jawaban:

9

GolfScript, 128 karakter

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

Masukan harus diberikan pada STDIN sebagai angka yang dipisahkan spasi.

Anda dapat menguji contohnya di sini .

Kode yang dikomentari:

# 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
sumber
1
+1 bagus, saya telah belajar beberapa trik bagus dari posting ini
Cristian Lupascu
Saya berhasil memasukkan golf ke 123 karakter: ~](:k/.zip\]{{1,%{,}%.!,+}%}/{' ':^*}%{.{,}%$-1=}:f~:r{^*\+r~)>'|'n}+%\f{.~)\[^]*@+>{^\+-2>}%}+%zip{r)^*\n}%r^*'+''--'k*n]((untuk beberapa alasan lettercount.com mengatakan 125 karakter jika Anda menyalinnya, tapi saya yakinkan Anda, ini 123 karakter). Beberapa bagian dari algoritma telah diubah, tetapi mayoritas masih tetap sama. Saya juga mengubah beberapa nama variabel (memiliki 9 sebagai variabel pintar, tetapi membingungkan juga), tetapi Anda dapat mengubahnya kembali jika Anda mau.
Volatilitas
7

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

Meskipun ini tidak menghasilkan output sampel yang tepat yang diberikan dalam pertanyaan, itu memang mengikuti spesifikasi. Satu-satunya perbedaan dengan contoh adalah bahwa saya mencetak beberapa spasi / baris baru.

Contoh:

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

Changelog:

  • 240 -> 231: Mengubah format input untuk menggunakan argumen baris perintah alih-alih stdin.
  • 231 -> 230: Menghilangkan spasi dengan memindahkan cek nilai dari chunkkemap .
  • 230 -> 226: Kurangi [nil]alih-alih menelepon Array#compact.
  • 226 -> 216: Sederhanakan generasi petunjuk.
Ventero
sumber
Anda memang mencetak beberapa baris dan spasi baru, tetapi sejauh ini dalam semua pengujian saya mereka sudah sesuai dengan spesifikasi "0 atau lebih", jadi Anda baik. Saya memperingatkan Anda sekarang, jika saya mulai melihat angka mengambang di udara di sebelah kiri monitor saya, saya harus mendiskualifikasi jawaban ini :)
undergroundmonorail
1
@undergroundmonorail: Outputnya dicetak sedemikian rupa sehingga length(leading spaces + numbers to the left) == 2*ndan height(leading newlines + numbers at the top) == n... selama monitor Anda cukup besar untuk 3*n+1 × 2*n+2karakter, Anda tidak harus mendiskualifikasi saya. :)
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]}*""+?|}
bersemangat
sumber
Bagaimana Anda menjalankan ini? Saya mencoba ruby $yourprogram <<< $inputtetapi berhasil ruby_nanograms:7:in '<main>': undefined method '+' for nil:NilClass (NoMethodError).
undergroundmonorail
@undergroundmonorail ruby nonogram.rb 2 1 0 0 1untuk 2x2
afair
Ini adalah jawaban yang bagus, tetapi Anda tidak mencetak 0untuk kolom keempat terakhir pada contoh kedua.
undergroundmonorail
Saya hanya memperhatikan bahwa +------... garis diindentasi oleh satu terlalu banyak ruang juga.
undergroundmonorail
1
@undergroundmonorail Memperbaiki keduanya.
Berlangsung
4

GolfScript 149 147

Kode

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

Suntingan:

  • menghapus ruang yang tidak berguna
  • mendefinisikan fungsi one-char yang dapat digunakan kembali putsuntuk menyimpan satu char lagi

Demo online

Versi kode yang agak beranotasi

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

Tidak disatukan

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
}

Pemakaian

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

Edit riwayat

1 Dihapus regexp digunakan untuk menemukan kolom. Lebih dari
2 Simpler lebih baik. Output ke string, bukan ke array. Fungsi pembantu yang dihapus FILL (F)
3 Lebih sederhana. Saya tidak bisa berbuat lebih baik dari ini. Masih tidak bisa dibandingkan dengan Golfscript :(

edc65
sumber
Bagus. Saya mencoba versi Javascript juga tetapi berakhir dengan sekitar 500 byte dan memutuskan saya terlalu besar untuk meletakkannya di sini. Akan lebih baik untuk memposting versi yang tidak diubah dengan nama variabel asli (jika Anda masih memilikinya). Juga, bagaimana Anda menjalankan ini? Jika saya menyalinnya ke jendela konsol chrome saya mendapatkan "ReferenceError: sisi kiri tidak valid dalam penugasan". Apakah ada sesuatu untuk diubah atau ditambahkan sebelum dijalankan?
tigrou
@tigrou maaf sintaks "=>" hanya berfungsi di firefox. Variabel: c kolom petunjuk, dimensi d, l daftar input, o output, variabel i loop, q dan z temp
edc65
-15 byte :)
nderscore
@nderscore mengutak-atik kode, saya mendapat 326. Dalam kode Anda R tidak diinisialisasi (kesalahan mudah ketika Anda mencoba lagi dan lagi ...)
edc65
1

R, 384 karakter

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

Dengan lekukan dan beberapa penjelasan:

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

Pemakaian:

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

C - 511

C jelas tidak dibuat untuk memformat output dengan baik. Hitungan karakter hanya mencakup spasi yang diperlukan / baris baru.

Input dari STDIN, angka dipisahkan oleh spasi.

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

Sudah beberapa hari dan tidak ada yang menjawab dengan python, jadi inilah upaya saya (mungkin sangat buruk):

Python 2.7 - 404 397 380 byte

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

Saya akan segera memposting versi yang tidak diklik, tetapi saat ini saya pikir itu cukup mudah dibaca. :)

SUNTING : Sambil menulis versi yang tidak di-serigala, saya perhatikan beberapa peningkatan yang bisa saya lakukan sehingga cukup signifikan! Untuk beberapa alasan yang saya tidak bisa jelaskan, sekarang memiliki baris baru tambahan di bagian atas dan spasi di sebelah kiri (meskipun saya tidak berpikir saya mengubah sesuatu yang fungsional), tetapi masih memenuhi spesifikasi.Versi tidak serigala akan datang!

Tidak Disatukan:

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

Beberapa perubahan dibuat demi keterbacaan ( gdibagi menjadi tiga fungsi bernama, pemahaman daftar kompleks dibuat menjadi forloop) tetapi secara logis itu bekerja dengan cara yang persis sama.

Itulah mengapa membingungkan bahwa yang ini tidak mencetak spasi tambahan dan baris baru, sedangkan yang golf melakukannya. ¯ \ _ (ツ) _ / ¯

monmon bawah tanah
sumber
1
Umm, saya tidak dapat menemukan solusi Anda. (maaf, hanya lelucon mengerikan tentang jumlah karakter, jangan pedulikan aku :))
Gagang Pintu
@dor Aha! Coba buat lelucon kode kesalahan HTTP Anda sekarang! : P
undergroundmonorail