Створіть головоломку без програми


24

Nonogram є двовимірним логічна головоломка , яка виглядає приблизно так (скріншоти з гри Pixelo , моя улюблена Nonogram гри):

Порожня дошка з нонограмами

Мета гри - з'ясувати, яке зображення кодують ці числа. Правила прості: число в стовпці чи рядку означає, що десь у цьому стовпчику чи рядку багато рядків заповнено підряд. Наприклад, нижній рядок на наведеному вище зображенні не повинен заповнювати поля, тоді як у верхньому ряді повинні бути заповнені всі його поля. Третій ряд знизу має 8 заповнених коробок, і всі вони будуть в ряд.

Дві або більше цифр для одного стовпця або рядка означають, що є кілька "прогонів" заповнених полів, принаймні один пробіл між ними, з цими довжинами. Порядок збережений. Наприклад, у правій колонці вищезазначеного зображення є три заповнені поля, принаймні одне пробіл під ними, а потім ще одне заповнене поле.

Ось та сама головоломка, майже завершена:

Майже закінчена дошка з програмою нонограм

(Сиси не важливі, вони просто натяк, який гравець залишає для себе, щоб сказати "Цей квадрат точно не заповнений". Подумайте прапори в "Мінерувальнику". У них немає правил, що означають.)

Сподіваємось, ви можете побачити, що, наприклад, середні стовпці з підказками, що говорять про "2 2", мають два заповнення в полях 2-х завдовжки.

Якщо ви вирішите прийняти це, ваша місія полягає в тому, щоб написати програму або функцію, яка створить такий пазл. Вам надається розмір дошки як одне ціле число (5 <= n <= 50) на stdin або як аргумент (немає причини, щоб головоломка з нонограмою повинна бути квадратною, але для цього завдання це буде). Після цього вам буде надано ряд з 1 і 0, що представляють заповнені та незаповнені квадрати на зображенні відповідно. Перший n з них - це верхній рядок, потім наступний рядок і т. Д. Ви повернетесь або роздрукуєте для складання дошки з 2 * 1 комірок (адже вони виглядають краще, і це дає місце для двозначних підказок для стовпчика ), всі вони порожні, з підказками, що відповідають вхідним даним.

Формат виводу

Формат виводу

Зразок

Вхід:

./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для рядка чи стовпця, які не заповнюють поля, є обов'язковим. Я не говорю це словами ніде, але це є у вибіркових даних.

Я щойно закінчила зі своїм рішенням. Чи можемо ми припустити, що у рядку чи стовпці не буде тризначної кількості полів?
невдалий

2
@voidpigeon: 5<=n<=50це специфікація, тому не може бути жодних 3-значних цифр
Kyle Kanos

Опублікувавши це питання, я сам почав працювати над рішенням. Я поки не публікую його (відповідно до цього метавідповіді), але я опублікую свій підрахунок байтів, щоб ви, хлопці, мали до чого прагнути: 404 байти в Python 2.7
undergroundmonorail

Невже ваш перший приклад не містить одного більше, -ніж слід?
Вентеро

@Ventro Ви праві! Я знав, як я напишу програму для цього, але насправді цього не робив дотепер, тому мої вибіркові виходи були вручну. На жаль! (Я також викрутив другий вихідний зразок, але виправив його, перш ніж були відповіді.)
підземниймонорельс

Відповіді:


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 приємно, я дізнався чимало хороших хитрощів з цієї публікації
Крістіан Лупаску

Мені вдалося переграти його до 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символів, не потрібно мене дискваліфікувати. :)
Вентеро

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 1на 2x2
невдалий

Це хороша відповідь, але ви не друкуєте 0четвертий останній стовпець у другому прикладі.
підземниймонорельс

Я щойно помітив, що +------... рядок також відступає один занадто багато пробілів.
підземний

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збереження ще однієї символи

Демонстрації в Інтернеті

Дещо помічена версія коду

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

Безумовно

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 Видалений регулярний вираз використовується для пошуку стовпців. Oververill
2 Простіше, тим краще. Виведення в рядок, а не в масив. Вилучена функція помічника FILL (F)
3 Ще простіше. Я не можу зробити краще, ніж це. Ще не можна порівняти з Golfscript :(


Приємно. Я також спробував версію Javascript, але закінчився приблизно 500 байтами і вирішив, що я занадто великий, щоб розмістити його тут. Було б добре розмістити версію, що не має волі з оригінальними іменами змінних (якщо вона все ще є). Також, як ви це запускаєте? Якщо я скопіюю вставити його у вікно хромованої консолі, я отримаю "ReferenceError: Неприпустимий лівий бік у призначенні". Чи потрібно щось змінити або додати перед запуском?
tigrou

@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

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

Минуло кілька днів, і ніхто не відповідав пітоном, тож ось моя (напевно, досить бідна) спроба:

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

Невдовзі я опублікую невмілену версію, але наразі я думаю, що це досить легко читається. :)

Редагувати: Під час написання версії, що не має волі, я помітив деякі вдосконалення, які я міг би зробити, що додане було досить значним! З якоїсь причини, яку я не можу пояснити, у неї є додаткові нові рядки вгорі та пробіли зліва (хоча я не думаю, що я змінив щось функціональне), але він все ще відповідає специфікації.Незрозуміла версія виходить!

Безголівки:

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

@dor Aha! Спробуйте зробити свій код помилки HTTP зараз! : P
підземниймонорельс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.