노노 그램 퍼즐 만들기


24

노노 그램은 이 (게임의 스크린 샷과 같이 보이는 두 개의 차원 논리 퍼즐입니다 Pixelo , 내가 좋아하는 노노 그램 게임) :

빈 노노 그램 보드

이 게임의 목표는 해당 숫자가 어떤 이미지를 인코딩하는지 파악하는 것입니다. 규칙은 간단합니다. 열 또는 행의 숫자는 해당 열 또는 행의 어딘가에 많은 상자가 한 행에 채워져 있음을 의미합니다. 예를 들어, 위 이미지의 맨 아래 행에는 상자가 채워져 있지 않아야하고, 위의 행에는 모든 상자가 채워져 있어야합니다. 아래에서 세 번째 줄에는 8 개의 채워진 상자가 있으며 모두 한 줄에 있습니다.

동일한 열 또는 행에 대해 두 개 이상의 숫자는 채워진 상자에 여러 개의 "실행"이 있으며, 그 사이에 최소한 하나의 공백이 있습니다. 순서가 유지됩니다. 예를 들어, 위 이미지의 맨 오른쪽 열에 3 개의 채워진 상자가 있고 그 아래에 최소 1 개의 공백이 있고 상자가 하나 더 채워져 있습니다.

거의 같은 퍼즐이 거의 완성되었습니다.

거의 완성 된 노노 그램 보드

(X는 중요하지 않습니다. 플레이어가 "이 사각형은 확실히 채워져 있지 않습니다"라고 말하는 힌트 일뿐입니다. 지뢰 찾기에서 플래그를 생각하십시오. 규칙 의미는 없습니다.)

예를 들어, "2 2"라는 힌트가있는 가운데 열에는 2 개의 2 길이 길이의 상자가 채워져 있음을 알 수 있습니다.

당신의 임무는 당신이 그것을 받아들이기로 선택한다면, 이와 같은 퍼즐을 만들 프로그램이나 기능을 작성하는 것입니다. 보드의 크기는 stdin에서 단일 정수 (5 <= n <= 50) 또는 인수로 제공됩니다 (비노 그램 퍼즐이 정사각형이어야하는 이유는 없지만이 문제는 그럴 것입니다). 그 후에는 이미지에서 채워진 사각형과 채워지지 않은 사각형을 나타내는 일련의 1과 0이 각각 주어집니다. 그중 첫 번째 n은 맨 위 행이고 다음 행은 다음과 같습니다. 2 * 1 셀 보드를 반환하거나 인쇄합니다 (더 좋아 보이기 때문에 열에 대한 2 자리 힌트를위한 공간을 제공합니다) ), 입력 데이터에 해당하는 힌트가 모두 비어 있습니다.

출력 형식

출력 형식

견본

입력:

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

영상:

첫 번째 예 이미지

산출:

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

입력:

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

영상:

두 번째 예 이미지

산출:

                   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|

설명

  • 당신의 산출물이 풀릴 수있는 퍼즐 일 필요는 없습니다. 모든 비노 그램을 해결할 수있는 것은 아니지만 걱정할 필요는 없습니다. 좋은 퍼즐인지 아닌지에 상관없이 입력에 해당하는 힌트를 출력하십시오.
  • 명령 행에서 인수를 취하는 프로그램이 허용됩니다. 이것은 위에서 언급 한 내용이지만 잘못된 생각을 가질 수 있습니다. 그것이 설명을위한 것입니다.
  • 0상자를 채우지 않은 행이나 열에 대해 인쇄 는 필수입니다. 나는 어디에서나 단어로 이것을 말하지 않지만 샘플 데이터에 있습니다.

나는 단지 나의 해결책으로 끝났다. 행이나 열에 3 자리 숫자의 상자가 없다고 가정 할 수 있습니까?
어리석은

2
@voidpigeon : 5<=n<=50은 스펙이므로 3 자리 숫자를 사용할 수 없습니다
Kyle Kanos

이 질문을 게시 한 후 솔루션을 직접 연구하기 시작했습니다. 메타 답변에 따라 아직 게시 하지는 않지만 바이트 수를 게시하여 다음과 같은 노력을 기울일 것입니다. Python 2.7의 404 바이트
undergroundmonorail

첫 번째 예제 출력에 필요한 것 이상 -이 포함되어 있지 않습니까?
Ventero

@ 벤트로 당신이 맞습니다! 이 작업을 수행하는 프로그램을 작성하는 방법을 알고 있었지만 지금까지 실제로는 수행하지 않았으므로 샘플 출력은 직접 작성했습니다. 죄송합니다! (또한 두 번째 샘플 출력을 망 쳤지 만 답이 나오기 전에 수정했습니다.)
undergroundmonorail

답변:


9

GolfScript, 128 자

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

입력은 공백으로 구분 된 숫자로 STDIN에 제공되어야합니다.

여기서 예제를 테스트 할 수 있습니다 .

주석이 달린 코드 :

# 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 nice, 저는이 포스트에서 꽤 좋은 트릭을 배웠습니다
Cristian Lupascu

나는 그것을 123 문자로 골프를 ~](:k/.zip\]{{1,%{,}%.!,+}%}/{' ':^*}%{.{,}%$-1=}:f~:r{^*\+r~)>'|'n}+%\f{.~)\[^]*@+>{^\+-2>}%}+%zip{r)^*\n}%r^*'+''--'k*n](쳤다 . (어떤 이유로 lettercount.com은 복사하면 125 문자를 말하지만 123 문자라고 확신합니다). 알고리즘의 일부가 변경되었지만 대부분은 여전히 ​​동일합니다. 또한 일부 변수 이름을 변경했지만 (9는 변수가 똑똑하지만 혼란 스러우므로) 원하는 경우 다시 변경할 수 있습니다.
변동성

7

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

이것은 질문에 주어진 정확한 샘플 출력을 생성하지는 않지만 사양을 따릅니다. 예제와의 유일한 차이점은 몇 가지 선행 공백 / 줄 바꿈을 인쇄한다는 것입니다.

예:

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

변경 로그:

  • 240-> 231 : stdin 대신 명령 행 인수를 사용하도록 입력 형식이 변경되었습니다.
  • 231-> 230 : 값 확인을에서 chunk로 이동하여 공백을 제거했습니다 map.
  • 230-> 226 : [nil]을 호출하는 대신 빼기 Array#compact.
  • 226-> 216 : 힌트 생성을 단순화합니다.

줄 바꿈과 공백을 추가로 인쇄하지만 지금까지의 모든 테스트에서 "0 이상"사양에 맞았으므로 좋습니다. 나는 지금 당신에게 경고하고 있습니다. 만약 모니터 왼쪽에 공중에 떠있는 숫자가 보이기 시작하면,이 답을 실격해야합니다. :)
undergroundmonorail

1
@undergroundmonorail : 출력이 다음과 같은 방식으로 인쇄됩니다 ... length(leading spaces + numbers to the left) == 2*n그리고 height(leading newlines + numbers at the top) == n모니터가 3*n+1 × 2*n+2문자에 비해 충분히 큰 한 , 나를 실격시킬 필요는 없습니다. :)
Ventero

4

루비, 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]}*""+?|}

이것을 어떻게 실행합니까? 나는 시도 ruby $yourprogram <<< $input했지만 얻었다 ruby_nanograms:7:in '<main>': undefined method '+' for nil:NilClass (NoMethodError).
undergroundmonorail

ruby nonogram.rb 2 1 0 0 12x2를위한 @undergroundmonorail
어리석은

이것은 좋은 대답이지만 0두 번째 예에서 네 번째 마지막 열에 대해서는 인쇄하지 않습니다 .
undergroundmonorail

방금 +------... 줄이 너무 많은 공백으로 들여 쓰기 된 것을 알았 습니다.
undergroundmonorail

1
@undergroundmonorail 둘 다 수정했습니다.
어리석은

4

GolfScript 149 147

코드

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

편집 :

  • 쓸모없는 공간을 제거
  • puts하나 이상의 문자를 저장하기 위해 재사용 가능한 1 문자 함수 정의

온라인 데모

다소 주석이 달린 코드

# 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

자바 (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}

언 골프

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
}

용법

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

기록 편집

1 열을 찾는 데 사용 된 정규 표현식을 제거했습니다
. 배열이 아닌 문자열로 출력합니다. 헬퍼 기능 제거 FILL (F)
3 더 간단합니다. 나는 이것보다 더 잘할 수 없다. 여전히 Golfscript와 비교할 수 없습니다 :(


좋은. Javascript 버전도 시도했지만 약 500 바이트로 끝나고 여기에 넣기가 너무 컸습니다. 원래 변수 이름으로 아직 ungolfed 버전을 게시하는 것이 좋습니다. 또한 어떻게 실행합니까? 크롬 콘솔 창에 붙여 넣으면 "ReferenceError : Assignment in invalid 왼쪽"이 나타납니다. 실행하기 전에 변경하거나 추가해야 할 것이 있습니까?
tigrou 2016 년

@tigrou 죄송합니다 "=>"sintax는 firefox에서만 작동합니다. 변수 : c colunns 힌트, d 차원, l 입력 목록, o 출력, i 루프 변수, q 및 z temp
edc65


@nderscore는 코드를 다루면서 326을 얻었습니다. 코드에서 R이 초기화되지 않았습니다 (다시 시도해도 쉬운 실수 ...)
edc65

1

R, 384 자

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

들여 쓰기와 설명이 있습니다 :

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

용법:

> 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는 출력 형식을 멋지게 만들기 위해 확실히 만들어지지 않았습니다. 문자 수에는 필요한 공백 / 줄 바꾸기 만 포함됩니다.

입력은 STDIN에서 시작하며 숫자는 공백으로 구분됩니다.

#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

며칠이 지났고 파이썬으로 아무도 대답하지 않았으므로 여기에 (아마도 가난한) 시도가 있습니다.

파이썬 2.7- 404 397 380 바이트

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

곧 ungolfed 버전을 게시 할 것이지만, 현재는 꽤 읽기 쉽다고 생각합니다. :)

편집 : 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

가독성을 위해 몇 가지 변경 사항 ( g세 개의 명명 된 함수, for루프 로 작성된 복잡한 목록 이해로 분할 됨 )이 논리적으로 동일하게 작동합니다.

이것이 골프 공간이 추가 공간과 줄 바꿈을 인쇄하지 않는 반면 혼란스러워하는 이유는 혼란 스럽습니다. ¯ \ _ (ツ) _ / ¯


1
음, 해결책을 찾을 수 없습니다. (죄송합니다, 캐릭터 수에 관한 끔찍한 농담은 신경 쓰지 마세요 :))
Doorknob

@ 도어 아하! HTTP 오류 코드 농담을 지금 시도하십시오! : P
undergroundmonorail
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.