Чи можу я зробити цю форму за допомогою блоків, плит та сходів?


13

Розглянемо прямокутну двовимірну сітку, де кожна комірка може бути порожньою ( .) або повною ( 0).

напр

..00....
0000....
.00000..
000...00
..000000
000.00..

Сітка вважається нескінченною, усі комірки поза зображеною областю порожні.

Мета - накрити заповнені простори та залишити порожні простори відкритими, використовуючи набір із 7 чітко зафіксованих цеглин, кожен з яких займає 4 комірки (2 × 2) сітки.

Це 7 цеглинок:

  • Блоки - 1 варіант

    11
    11
    
  • Плити - 2 варіанти

    ..
    22
    33
    ..
  • Сходи - 4 варіанти

    .4
    44
    5.
    55
    66
    .6
    77
    7.

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

Отож, один із способів прикрити (він також вирішив) наведений вище приклад:

..11....
2211....
.47733..
447...22
..771133
227.11..

(Ідентичний сусідній цегла все ще може викликати неоднозначність, але ретельне виявлення більшої сітки вирішує це.)

недійсним рішення

000000
000000

є

566774
556744

тому що цеглини не всі вирівнюються до більшої сітки і не займають лише одну клітинку її.

Тут дійсне рішення - 3 блоки поспіль:

111111
111111

І ще одне дійсне рішення передбачає 6 плит:

......
222222
333333
......

Тому зауважте, що деякі вхідні сітки мають декілька рішень .

недійсним рішення

00.00
00...

є

11.33
11...

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

Виклик

Напишіть програму, яка містить (через stdin / командний рядок) прямокутний блок тексту .'s і 0', що являє собою сітку, яку слід охопити.

Якщо є правильне рішення покриття, друк (через стандартний висновок) будь одне рішення таким же чином , як зазначено вище, замінивши всі 0«S з відповідним 1через 7цеглу.

Якщо рішення немає, програма не повинна нічого виводити, а тихо закінчується нормально.

Примітки

  • Вхід і вихід не повинні мати однакові прямокутні розміри. У вашому висновку можуть бути сторонні рядки та / або стовпці всіх .(до тих пір, поки вони не скасують рішення).

  • Також добре обрізати рядки та стовпці всіх ., якщо це не вплине на заповнені пробіли. напр

    222222
    333333
    

    є правильним рішенням для

    000000
    000000
    

    І навпаки, два порожні стовпці в 00..00не вдалося видалити, оскільки це призведе до розстановки заповнених пробілів.

  • Ви можете припустити, що вхід має один зворотний рядок. Однократне затримка нового рядка на виході також добре, навіть якщо немає рішення.

  • Сітки, які повністю порожні (усі .) та тривіальна сітка 0 × 0, не є вхідними випадками, про які потрібно турбуватися. Але 0сітка 1 × 1 є, як і всі інші сітки, що містять принаймні одну 0. (Ви можете не вважати, що ширина або висота вхідної сітки є рівною!)

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

  • Ви можете використовувати будь-які 9 різних символів для друку ASCII замість . 0 1 2 3 4 5 6 7. Просто не забудьте сказати, якими були ваші заміни! Нові лінії повинні залишатися такими, як є.

Оцінка балів

Виграє найкоротший код у байтах. Tierereaker - це найвище оцінений пост.

Цей виклик був натхненний блоками , плитами та сходами в Minecraft , які дотримуються тих же правил, що описані тут. Якщо ви любите PPCG та Minecraft, ви можете перевірити сервер Minecraft PPCG .


3
Здається, сервер Minecraft не реалізований у сценарії Golf - нудно :-)
Томас Веллер

5
@ThomasWeller Це було повторно додано в CJam, щоб зберегти кілька байт.
Олексій А.

Відповіді:


6

Python - 525 491 478 430 байт

r=range
def t(s):
 m=s.find("\n")+1
 for q in r(4):
  try:
   for i in r(-q%2,m-1,2):
    for j in r(-q/2,len(s)/m,2):
     k,g=j*m+i,""
     b=[k,k+1,k+m,k+m+1]
     for z in b:g+=a(s,z)
     for z in b:
      if a(s,z)!="d":s=s[:z]+`dict(dddd=0,zzdd=3,ddzz=2,zzzd=7,zzdz=6,zdzz=5,dzzz=4,zzzz=1)[g]`+s[z+1:]
   return s
  except:d
def a(v,i):
 try:
  if v[i]!="\n":return v[i]
  return "d"
 except:return "d"

Пояснення: Це мій перший гольф з кодом, тому він може бути не оптимальним, але ось як це працює. Функція t (s) дає результат для переданого рядка. Спочатку він знаходить кількість стовпців, потім проходить чотири можливі чіткі переклади на 1 (жоден, лівий, вгору, вгору вліво) і намагається вирішити його для кожного. Він переглядає кожен блок 2x2 і відображає його на дійсний номер блоку, заданий словником, і змінює нулі на число.

Якщо він не знайдеться в словнику, він відмовляється від конкретного зміщення і починається з наступного. Якщо він проходить через усі 4 компенсації, не знайшовши дійсного рішення, він закінчується, не виводячи нічого. a (v, i) допускає значення за замовчуванням поза рядком і ігнорує символи нового рядка. Хоча він може закінчитися частковими рішеннями протягом тривалості пробігу, він завжди перекриє їх остаточним правильним, якщо він існує.

Редагувати: Використовується інше відображення символів:. -> d, 0 -> z, всі інші числа йдуть самі собі. Це стосується і вводу, і виходу.


1
Ласкаво просимо до PPCG! У нас є кілька порад щодо гольфу в Python ; я думаю, ви можете зберегти кілька байт.
lirtosiast
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.