Tạo một câu đố Nonogram


24

Một nonogram là một câu đố logic hai chiều trông giống như thế này (ảnh chụp màn hình từ trò chơi Pixelo , trò chơi phi hình yêu thích của tôi):

Một bảng phi hình trống

Mục tiêu của trò chơi là tìm ra những hình ảnh mà những con số đó được mã hóa. Các quy tắc rất đơn giản: Một số trên một cột hoặc hàng có nghĩa là ở đâu đó trong cột hoặc hàng đó, có nhiều hộp được điền vào một hàng. Ví dụ, hàng dưới cùng trong hình trên phải không có ô nào được điền vào, trong khi hàng bên trên phải có tất cả các ô của nó được điền. Hàng thứ ba từ dưới lên có 8 ô đầy, và tất cả chúng sẽ nằm trong một hàng.

Hai hoặc nhiều số cho cùng một cột hoặc hàng có nghĩa là có nhiều "lần chạy" của các hộp được lấp đầy, với ít nhất một khoảng trống ở giữa, với các độ dài đó. Trật tự được bảo tồn. Ví dụ, có ba ô được điền vào cột bên phải của hình trên, ít nhất một khoảng trắng bên dưới chúng, và sau đó thêm một ô nữa.

Đây là câu đố tương tự, gần như đã hoàn thành:

Một bảng nonogram gần hoàn thành

(Các chữ X không quan trọng, chúng chỉ là một gợi ý mà người chơi để họ tự nói "Quảng trường này chắc chắn không được điền vào". Hãy nghĩ những lá cờ trong Minesweeper. Chúng không có ý nghĩa quy tắc nào.)

Hy vọng rằng bạn có thể thấy rằng, ví dụ, các cột ở giữa với các gợi ý có nội dung "2 2" có hai lần chạy dài 2 ô.

Nhiệm vụ của bạn, nếu bạn chọn chấp nhận nó, là viết một chương trình hoặc chức năng sẽ tạo ra một câu đố như thế này. Bạn được cung cấp kích thước của bảng dưới dạng một số nguyên duy nhất (5 <= n <= 50) trên stdin hoặc làm đối số (không có lý do tại sao câu đố không phải là hình vuông, nhưng đối với thử thách này sẽ là). Sau đó, bạn sẽ được cung cấp một loạt các số 1 và 0 tương ứng với các ô vuông được lấp đầy và không được lấp đầy trong hình ảnh. N đầu tiên trong số chúng là hàng trên cùng, sau đó là hàng tiếp theo, v.v. Bạn sẽ quay lại hoặc in để xuất bản bảng 2 * 1 ô (vì chúng trông đẹp hơn và nó cung cấp cho bạn chỗ cho các gợi ý 2 chữ số cho một cột ), tất cả đều trống, với các gợi ý tương ứng với dữ liệu đầu vào.

Định dạng đầu ra

Định dạng đầu ra

Mẫu vật

Đầu vào:

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

Hình:

Hình ảnh ví dụ đầu tiên

Đầu ra:

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

Đầu vào:

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

Hình:

Hình ảnh ví dụ thứ hai

Đầu ra:

                   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|

Làm rõ

  • Đầu ra của bạn không cần phải là một câu đố có thể giải được. Không phải tất cả các biểu đồ đều có thể giải được, nhưng đó không phải là mối quan tâm của bạn. Chỉ cần đưa ra các gợi ý tương ứng với đầu vào, cho dù chúng có tạo ra một câu đố hay hay không.
  • Một chương trình lấy các đối số trên dòng lệnh được cho phép. Đây là loại đã nêu ở trên, nhưng có thể hiểu sai. Đó là những gì làm rõ là cho.
  • In một 0hàng hoặc cột không có hộp điền là bắt buộc. Tôi không nói điều này với các từ ở bất cứ đâu nhưng nó có trong dữ liệu mẫu.

Tôi vừa mới thực hiện với giải pháp của mình. Chúng ta có thể cho rằng sẽ không có số lượng hộp gồm 3 chữ số trong một hàng hoặc cột không?
ngày

2
@voidpigeon: 5<=n<=50là thông số kỹ thuật, vì vậy không thể có bất kỳ số có 3 chữ số nào
Kyle Kanos

Sau khi đăng câu hỏi này, tôi bắt đầu tự mình giải quyết một giải pháp. Tôi sẽ không đăng nó chưa (theo này câu trả lời meta), nhưng tôi sẽ gửi số byte của tôi để các bạn có cái gì đó để phấn đấu: 404 byte trong Python 2.7
undergroundmonorail

Không phải đầu ra ví dụ đầu tiên của bạn có chứa nhiều -hơn mức cần thiết không?
Ventero

@Ventro Bạn đúng rồi! Tôi biết làm thế nào tôi sẽ viết một chương trình để làm điều này, nhưng tôi thực sự đã không làm nó cho đến bây giờ, vì vậy đầu ra mẫu của tôi là bằng tay. Rất tiếc! (Tôi cũng hơi say lên đầu ra mẫu thứ hai, nhưng tôi cố định nó trước khi có bất kỳ câu trả lời.)
undergroundmonorail

Câu trả lời:


9

GolfScript, 128 ký tự

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

Đầu vào phải được cung cấp trên STDIN dưới dạng các số được phân tách bằng dấu cách.

Bạn có thể kiểm tra ví dụ ở đây .

Mã nhận xét:

# 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
]\

1
+1 tuyệt vời, tôi đã học được khá nhiều thủ thuật hay từ bài đăng này
Cristian Lupascu

Tôi đã quản lý để chơi nó tới 123 ký tự: ~](:k/.zip\]{{1,%{,}%.!,+}%}/{' ':^*}%{.{,}%$-1=}:f~:r{^*\+r~)>'|'n}+%\f{.~)\[^]*@+>{^\+-2>}%}+%zip{r)^*\n}%r^*'+''--'k*n]((vì một số lý do, lettercount.com nói 125 ký tự nếu bạn sao chép nó, nhưng tôi đảm bảo với bạn, đó là 123 ký tự). Một số phần của thuật toán đã được thay đổi, nhưng phần lớn vẫn giống nhau. Tôi cũng đã thay đổi một số tên biến (có 9 là một biến là thông minh, nhưng cũng khó hiểu), nhưng bạn có thể thay đổi chúng trở lại nếu bạn muốn.
Biến động

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

Mặc dù điều này không tạo ra đầu ra mẫu chính xác được đưa ra trong câu hỏi, nhưng nó không tuân theo thông số kỹ thuật. Sự khác biệt duy nhất với các ví dụ là tôi in một vài khoảng trắng / dòng mới.

Thí dụ:

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

Thay đổi:

  • 240 -> 231: Thay đổi định dạng đầu vào để sử dụng đối số dòng lệnh thay vì stdin.
  • 231 -> 230: Loại bỏ khoảng trắng bằng cách di chuyển kiểm tra giá trị từ chunkđến map.
  • 230 -> 226: Trừ [nil]thay vì gọi Array#compact.
  • 226 -> 216: Đơn giản hóa việc tạo gợi ý.

Bạn in thêm một số dòng mới và khoảng trắng, nhưng cho đến nay trong tất cả các thử nghiệm của tôi, chúng đều phù hợp với thông số "0 trở lên", vì vậy bạn rất tốt. Tôi cảnh báo bạn bây giờ, tuy nhiên, nếu tôi bắt đầu thấy số trôi nổi trong không khí sang trái màn hình của tôi, tôi sẽ phải loại ra câu trả lời này :)
undergroundmonorail

1
@undergroundmonorail: Đầu ra được in theo cách như vậy length(leading spaces + numbers to the left) == 2*nheight(leading newlines + numbers at the top) == n... miễn là màn hình của bạn đủ lớn cho các 3*n+1 × 2*n+2ký tự, bạn không cần phải loại tôi. :)
Ventero

4

Hồng ngọc, 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]}*""+?|}

Làm thế nào để bạn chạy này? Tôi đã thử ruby $yourprogram <<< $inputnhưng có ruby_nanograms:7:in '<main>': undefined method '+' for nil:NilClass (NoMethodError).
undergroundmonorail

@undergroundmonorail ruby nonogram.rb 2 1 0 0 1cho 2x2
ngày

Đây là một câu trả lời hay, nhưng bạn không in 0cột thứ tư cuối cùng trong ví dụ thứ hai.
undergroundmonorail

Tôi chỉ nhận thấy rằng +------... dòng được thụt vào bởi quá nhiều khoảng trắng.
undergroundmonorail

1
@undergroundmonorail Đã sửa cả hai.
xa xôi

4

GolfScript 149 147

Mật mã

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

Chỉnh sửa:

  • loại bỏ không gian vô dụng
  • đã định nghĩa một hàm char có thể tái sử dụng putsđể lưu thêm một char

Bản demo trực tuyến

Một phiên bản có phần chú thích của mã

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

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}

Bị đánh cắp

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
}

Sử dụng

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

Chỉnh sửa lịch sử

1 Loại bỏ regex được sử dụng để tìm cột.Overkill
2 Đơn giản hơn. Xuất ra một chuỗi, không phải là một mảng. Chức năng trợ giúp bị xóa FILL (F)
3 Thậm chí đơn giản hơn. Tôi không thể làm tốt hơn thế này. Vẫn không thể so sánh với Golfscript :(


Tốt đẹp. Tôi cũng đã thử một phiên bản Javascript nhưng kết thúc với khoảng 500 byte và quyết định tôi quá lớn để đặt nó ở đây. Sẽ rất tốt để đăng phiên bản không có tên với các tên biến ban đầu (nếu bạn vẫn có nó). Ngoài ra, làm thế nào để bạn chạy này? Nếu tôi sao chép, dán nó vào cửa sổ giao diện điều khiển chrome, tôi nhận được "ReferenceError: bên trái không hợp lệ trong bài tập". Có một cái gì đó để thay đổi hoặc thêm trước khi chạy?
tigrou

@tigrou xin lỗi, sintax "=>" chỉ hoạt động trong firefox. Các biến: c gợi ý colunns, kích thước d, danh sách l đầu vào, đầu ra o, biến vòng lặp i, temp q và z
edc65


@nderscore loay hoay với mã, tôi đã nhận được 326. Trong mã của bạn R không được khởi tạo (lỗi dễ dàng khi bạn thử lại lần nữa ...)
edc65

1

R, 384 ký tự

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

Với những vết lõm và một số giải thích:

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

Sử dụng:

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

1

C - 511

C chắc chắn không được thực hiện để định dạng đầu ra độc đáo. Số lượng ký tự chỉ bao gồm các khoảng trắng cần thiết / dòng mới.

Đầu vào là từ STDIN, các số được phân tách bằng dấu cách.

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

1

Đã vài ngày và không có ai trả lời bằng trăn, vì vậy đây là nỗ lực của tôi (có lẽ khá nghèo):

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

Tôi sẽ sớm đăng một phiên bản không có bản quyền, nhưng hiện tại tôi nghĩ nó khá dễ đọc. :)

EDIT: Trong khi viết phiên bản không có bản quyền, tôi nhận thấy một số cải tiến tôi có thể làm cho phần bổ sung đó trở nên khá quan trọng! Vì một số lý do mà tôi không thể giải thích, giờ đây nó có thêm các dòng mới ở trên cùng và khoảng trắng ở bên trái (mặc dù tôi không nghĩ rằng tôi đã thay đổi bất cứ điều gì chức năng), nhưng nó vẫn đáp ứng thông số kỹ thuật.Phiên bản Ungolfed đang đến!

Ung dung:

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

Một vài thay đổi đã được thực hiện vì mục đích dễ đọc ( gđược chia thành ba chức năng được đặt tên, việc hiểu danh sách phức tạp được thực hiện thành forcác vòng lặp) nhưng về mặt logic thì nó hoạt động chính xác theo cùng một cách.

Đó là lý do tại sao điều này gây nhầm lẫn rằng cái này không in thêm không gian và dòng mới, trong khi cái được đánh golf thì có. ¯ \ _ (ツ) _ /


1
Umm, tôi không thể tìm thấy giải pháp của bạn. (xin lỗi, chỉ là một trò đùa kinh khủng liên quan đến số lượng nhân vật, đừng
bận

@dor Aha! Hãy thử làm cho mã lỗi HTTP của bạn đùa ngay bây giờ! : P
undergroundmonorail
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.