Заповніть екран Вангом Плитки


24

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

Ван плитки

Кожну плитку ми зобразимо текстуально 3 × 3 сіткою, заповненою пробілами в центрі та кутах, а цифрами від 1 до 5 замість кольорів червоного, зеленого, синього, жовтого, сірого на краях:

 2      2      2      1      1      1      4      3      2      2      4      3      2
1 2    1 3    2 3    2 1    3 1    3 2    4 4    4 4    4 5    4 5    5 5    5 5    5 4
 3      2      3      2      3      2      1      2      1      4      1      2      2

Мета

Ваше завдання - написати програму, яка займає ширину і висоту і виводить дійсну сітку для плитки Ванга з цими розмірами. Дійсною плиткою є та, в якій всі сусідні краї плитки мають однаковий колір (або число). Виграє найменша програма в байтах.

Ваш вхід повинен надходити з аргументів stdin або командного рядка, а вихідний повинен переходити до stdout. Точний формат введення може бути будь-яким досить очевидним, наприклад >>> wangtiler 3 2. Ширина та висота завжди є цілими додатними.

Приклад (ширина = 3, висота = 2)

Зауважте, що коли ми розкладаємо текстові плитки, сусідні краї утворюють необхідні зайві пари цифр:

 1  2  1 
2 11 22 1
 2  3  2 
 2  3  2 
4 55 55 4
 1  2  2 

(Це НЕ належний вихідний формат.)

Ми можемо стиснути їх по горизонталі та вертикалі, щоб отримати:

 1 2 1 
2 1 2 1
 2 3 2 
4 5 5 4
 1 2 2 

Цей стислий формат - це правильний вихідний формат, який ви повинні використовувати. Непарні нумеровані лінії повинні містити їх пробіл.

Графічний бонус

Замість того, щоб мати текстовий вихід, ваша програма може вивести зображення плиткової сітки. Графічна плитка повинна складатися з чотирьох трикутників 45-45-90, розташованих у квадраті, та використовувати п’ять кольорів, що легко відрізняються, як плитки вище. Чорні межі не потрібні. Графічна плитка має бути розміром не менше 32 × 32 пікселів. Ніяке «стиснення» до них не застосовується.

Приклад бонусного зображення: (така ж сітка, як приклад вище)

бонусний приклад

Бонус коштує мінус 150 байт.

Примітки

  • Ви повинні використовувати цей набір з 13 плиток.
  • Плитка може не обертатися.
  • Плитки можуть з’являтися будь-яку кількість разів (навіть не включаючи жодної).
  • Ви можете припустити, що можлива допустима плитка з будь-якими розмірами.

Я думаю, плитку не можна обертати?
Мартін Ендер

@ MartinBüttner Ні. Ви повинні використовувати набір 13 плиток, наданих точно так, як вони є.
Хобі Кальвіна

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

@TeunPronk Nope. Використовуйте їх скільки завгодно разів (звичайно, ви можете змусити їх використовувати більше, щоб правильно відповідати краї).
Хобі Кальвіна

@ Calvin'sHobbies Чи можна припустити, що завжди можливе рішення?
Теун Пронк

Відповіді:


12

GolfScript, 200 символів

~\:W*):R;1,{)\:C"=QCy_~{MTKAis]?OyJE?~WvM"[64 2400]{base}/@{>}+,{:T;[C,W<!{C W~)=T 64/^8/8%}*C,W%0>{C-1=64/T^8%}*]0-!},1<.!!{1,+}*+.,R<}do);W/.0={' '\512/8%`}%n@{.[.0=8%\{' '\64/8%}/n]\{' '\8/8%`}%n}/

Версія ASCII без графічного виводу. Введіть дані про STDIN - спробуйте тут . Код використовує звичайний підхід зворотного відстеження і заповнює пробіл рядком за рядком.

Приклади:

> 3 2
 1 2 1
2 1 2 1
 2 3 2
5 4 4 5
 2 2 1

> 8 5
 1 2 1 2 1 2 1 2
2 1 2 1 2 1 2 1 2
 2 3 2 3 2 3 2 3
5 4 4 5 5 4 4 5 5
 2 2 4 2 2 2 4 2
5 4 5 5 4 5 4 4 5
 2 1 1 2 1 2 1 1
1 3 2 1 2 1 3 2 1
 2 2 2 3 2 2 2 2
5 4 5 4 4 5 4 5 4
 2 1 2 2 1 2 1 2

Графічний бонус, оцінка 122, 272 символи - 150 бонусів

~\:W*):R;1,{)\:C"=QCy_~{MTKAis]?OyJE?~WvM"[64 2400]{base}/@{>}+,{:T;[C,W<!{C W~)=T 64/^8/8%}*C,W%0>{C-1=64/T^8%}*]0-!},1<.!!{1,+}*+.,R<}do);W["P3\n"32W*" "3$,32*n 1n]\{{:^;512:X;16,{[^8%]1$*[^X/8%]31*@.+>[^64/8%]31*++32<}:F%8:X;16,-1%{F}%+}%zip{{+}*{8+2base(;~}%' '*n}/}/

Той самий базовий код з іншим вихідним форматором. Вихід - це зображення у форматі PPM (тобто просто перенаправити вихід у файл image.ppm). Кольори дещо відрізняються від плиток у питанні, але чітко відрізняються (1-> синій, 2-> зелений, 3-> блакитний, 4-> червоний, 5-> пурпурний).

Приклад 16х12:

Приклад 16х12 ван


16

Пітон (565 - 150 = 415)

До речі ... здається, що ми не можемо наївно просто вирішити наступну плитку лівою та верхньою плиткою. Існує деяка комбінація плиток, яка підійде одна до одної.
Це рішення заповнює ліву-> праву, верхню> нижню грубі сили завдяки всім можливим комбінаціям і зворотній дорозі, якщо плитка не може вміститися.

Для отримання додаткової інформації про доказ 13 плиток: Аперіодичний набір з 13 плиток Ванга

Ширина та висота задаються WтаH

Червоний, зелений, синій, жовтий і Noir визначається R, G, B, YіN

import Image,sys
W,H=map(int,sys.argv[1:])
R=99
G=R<<8
B=G<<8
Y=G+R
N=0
s="RGB";u=32;g=[[0,0]]*W*H;k=f=0
def t(c):i=Image.new(s,(2,2));k=i.load();q=16;k[1,0],k[1,1],k[0,1],k[0,0]=c;return i.resize([64]*2).rotate(45).crop((q,q,q+u,q+u))
while k<H*W:
 z=g[k][1];v=-1;j=k/W;i=k%W
 while z<13:
    l=map(eval,"GGGRRRYBGGYBGGBBRRGYYNNNNYBGBGBGRGRYRGGRRGGBBYYYYNNN"[z::13])
    if(j<1or g[(j-1)*W+i][0][2]==l[0])and(i<1or g[j*W+i-1][0][1]==l[3]):g[k]=[l,z+1];v=1;z=99
    z+=1
 g[k][1]*=(v>0);k+=v
m=Image.new(s,(W*u,H*u))
for e in g:m.paste(t(e[0]),(f%W*u,(f/W)*u));f+=1
m.show()

Вихід. Не власне колірна гамма ... тому що занадто яскраво. Це може зробити цікаві візерунки декору інтер'єру ...:

введіть тут опис зображення


14
Neopolitan Minecraft ...
Захоплення Кальвіна

чи можете ви додати більшу картину? Мені цікаво, як би це виглядало
гордий haskeller

1
@proudhaskeller Більше зображення: Imgur . Виробник шпалер: посилання
Векторизований

1
Це впевнено виглядає періодично - чого мені не вистачає?
гордий haskeller

Майже періодичний .. приклад з більшою контрастністю тут: Imgur
Vectorized

2

Haskell, 208 байт

p x|x<2/3=(3!x)3"3212"3
p x=(0.5!x)1"45423"2
f=floor
(k!x)l s m=do{i<-[0,x..];[' ',s!!(2+f(i+x)-f i)]}:do{i<-[0,l*x..];s!!mod(f i)m:" "}:p(k*x)
t n=take$2*n+1
main=do(w,h)<-readLn;putStr.unlines.t h$t w<$>p 1

Ніякого пошуку, просто математика. Приклад виконання: наведено (8,5)на stdin, виводи

 2 2 2 2 2 2 2 2 
4 5 4 5 4 5 4 5 4
 1 2 1 2 1 2 1 2 
3 2 3 2 3 2 3 2 3
 2 3 2 3 2 3 2 3 
4 5 5 4 4 5 5 4 4
 4 2 2 2 4 2 2 2 
4 4 5 4 5 5 4 5 4
 1 1 2 1 1 2 1 2 
3 2 1 3 2 1 3 2 3
 2 2 2 2 2 2 2 3 

Працюйте в Інтернеті на Ideone

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