Пошук симетрій у квадратах


14

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

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

Квадрати - це різні символи, просто їх можна розрізнити. Тільки форма, зроблена об'єднанням усіх квадратів, повинна бути симетричною. Ви можете припустити, що список не буде містити більше 94 елементів (оскільки це 94 символи).

Наприклад, якщо вхід був [2, 1, 2, 2, 2], можливий вихід:

DD--
DD--
Z
FFPP
FFPP

Ця форма має горизонтальну лінію відбивної симетрії; її верхня і нижня половинки - дзеркальні зображення. Ось деякі інші можливості: (Зверніть увагу, що квадрати не потрібно чіпати, і будь-які символи можуть бути використані до тих пір, поки два квадрати не створені з одного символу.)

  55
  55
  %%
  %%
@
  HH
  HH
  ((
  ((
       G

     11 33
     11 33

    22   44
    22   44

Лінія симетрії також може бути межею між символами, наприклад для [2, 4]:

!!!!
!!!!  ++
!!!!  ++
!!!!

Деякі набори квадратів неможливо розташовувати симетрично, наприклад [1, 2, 3]:

AAA BB C
AAA BB         (these can't be vertically or horizontally symmetric => no output)
AAA

І пам’ятайте, що загальна форма може бути симетричною, навіть якщо квадратні межі не є. наприклад, дійсний вихід для [2, 1, 1, 1, 1, 4]:

AA----
AA----
BC----
DE----

Аналогічно, дійсний вихід для [1, 1, 2, 3, 5]:

44444
44444
44444
44444
44444
33301
33322
33322

Примітки

  • У вхідному списку завжди буде від 1 до 94 елементів.
  • Введіть будь-який розумний спосіб: stdin, командний рядок, текстовий файл, аргумент функції. Він може бути злегка відформатований відповідно до ваших потреб, наприклад, {1, 2, 3, 4}або [1 2 3 4].
  • Вихід у stdout або подібне. Будь-яка кількість провідних / кінцевих пробілів або нових рядків є тонкою, якщо отримана форма має лінію симетрії.
  • Діагональна лінія симетрії не враховується (інакше це було б дуже просто). Крім того, вона повинна бути відбивною симетрією, а не обертальною чи перехідною.
  • Я чесно не впевнений, наскільки обчислювально складно це завдання. Ви можете розмістити часткові відповіді, які вирішують певну частину проблеми (особливо якщо ви хочете показати особливо розумний алгоритм). Вони не мають права виграти.
    • Наприклад, ви можете припустити, що вхід завжди має принаймні одне симетричне розташування (тому такі списки як [1, 2, 3]ніколи не вводяться).
    • Або, наприклад, ви можете розглянути лише розташування, де межі квадрата, а також загальна форма є симетричними. У цьому випадку не [1, 1, 2, 3, 5]було б результату.
    • Якщо ви хочете зійти з розуму, ви можете поширити ідею на прямокутники або навіть поліоміно .

Оцінка балів

Ваш бал - це розмір вашої програми в байтах . Виграє найнижчий бал. Tiebreaker отримує відповідь, розміщену першою.


2
Бонусні бали за рішення [2, 4, 6, 7, 8, 9, 11, 15, 16, 17, 18, 19, 24, 25, 27, 29, 33, 35, 37, 42, 50, 112], хоча, оскільки питання дає набагато більше свободи, мабуть, інші рішення.
Sp3000

Відповіді:


4

Python 2, 460 452 437 байт

exec"""def f(L):
 if[]==L:
  X{2}[map(" ".__lt__,q)for q in G]);Z{2}zip(*X));C=Z==Z[::-1]or X==X[::-1]
  if C:print"\\n".join(map("".join,G))
  return C
 x=L[-1];T=S-x+1;R=range(x)
 for n in range(T*T):
  i=n%T;j=n/T
  if all({1}=" "{0}):
{0}:{1}chr(32+len(L))
   r=f(L[:-1])
{0}:{1}" "
   if r:return r""".format("   for a,b in[(a,b)for a in R for b in R]","G[i+a][j+b]=","=filter(sum,")
L=input()
S=sum(L)
G=[S*[" "]for _ in[0]*S]
f(L)

Поки що м'яко гольфуйте, але ось дещо почати. Я намагався використовувати execдля рядків 10 і 12, але мені чомусь це не дозволило.

Введіть список Lчерез STDIN, наприклад [2, 1, 2, 2, 2]. Програма просто намагається використовувати всі можливості розміщення квадратів у sum(L) x sum(L)сітці.

Вибірка зразка (порожні рядки видалено для компактності):

[2, 1, 2, 2, 2]

%%       
%%       
$$       
$$       
"        
##       
##       
!!       
!!      

[2, 4]

""""  
""""  
""""  
""""  
 !!   
 !!   

[2, 1, 1, 1]

$!!  
#!!  
 "   

[1, 1, 2, 3, 5]

%%%%%       
%%%%%       
%%%%%       
%%%%%       
%%%%%       
$$$##       
$$$##       
$$$"!       

[1, 4, 1, 8]

$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
$$$$$$$$      
# """" !      
  """"        
  """"        
  """"        

[8, 1, 4, 1]

$   !!!!!!!!  
    !!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
####!!!!!!!!  
    !!!!!!!!  
"   !!!!!!!!  

(The algorithm starts placing from the last square first, prioritising left then up)

Трохи менш заплутана версія (452 ​​байти):

def f(L):
 if[]==L:
  X=filter(sum,[map(" ".__lt__,q)for q in G]);Z=filter(sum,zip(*X));C=Z==Z[::-1]or X==X[::-1]
  if C:print"\n".join(map("".join,G))
  return C
 x=L[-1];T=S-x+1;R=range(x);V=[(a,b)for a in R for b in R]
 for n in range(T*T):
  i=n%T;j=n/T
  if all(G[i+a][j+b]<"!"for a,b in V):
   for a,b in V:G[i+a][j+b]=chr(32+len(L))
   r=f(L[:-1])
   for a,b in V:G[i+a][j+b]=" "
   if r:return r
L=input()
S=sum(L)
G=[S*[" "]for _ in[0]*S]
f(L)

@ Calvin'sHobbies Я щойно зрозумів, що забув викреслити порожні рядки та стовпці (це означало б, що конфігурація повинна бути симетричною і щодо дошки ). [1, 1, 2, 3, 5]зараз працює нормально.
Sp3000

Ага. Я думав, що груба сила просто приймає назавжди.
Захоплення Кальвіна

@ Calvin'sHobbies Це для більшої дошки, але додавання додаткових обмежень просто погіршує: P
Sp3000

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