Давши стіл, покладіть на стільці


41

Виклик

Вам буде надана таблиця як вхідна інформація, намальована ASCII |та _. Ваше завдання - встановити навколо нього стільці.

Приклад

Вхід:

 ____
|    |
|    |
|    |
|    |
|____|

Вихід:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

Ці крісла виготовлені з <>і v^.

Ще один приклад:

У лінійці повинно бути якомога більше стільців.

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

Між кожним стільцем повинні бути пробіли. І >_^_^_<недійсна, так і має бути |_^_^_|.

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

Жодного стільця не може бути на внутрішній стороні "пончика".

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^і vрозставити пріоритети <та >. Жодного крісла немає самостійно (він повинен мати принаймні одне |або _підряд).

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

Це кодовий гольф, тому найкоротший код виграє.


2
Я розгублений, чому стільці вбудовані в стіл з боків?
Оптимізатор

Якщо я пам'ятаю правильно, у вашій оригінальній пісочній пошті був пробіл між вертикальною лінією столу та лінією стільця. Так само, як між горизонтальними лініями столу та стільцями небагато місця.
Оптимізатор

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

1
також я думаю, що в третьому зразку є проблема - є додатковий простір між другим і третім "верхніми" кріслами - а також в останньому прикладі, правому нижньому куті

1
Перший тестовий випадок, здається, зламаний. Вхід всього 4, а вихід 5.
Майстер пшениці

Відповіді:


34

Пітон 2, 1033 1007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 байт

6 байт збережено завдяки Райлі

6 байт збережено завдяки Аднану

Оскільки на це запитання вже більше року, а відповіді досі немає, я подумав, що спробую.

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

Спробуйте в Інтернеті!

Програма читає в таблиці файл з назвою Iта друкує таблицю зі своїми стільцями std::out. Я не був впевнений у купі крайових справ, тому я прийняв найкраще рішення (що б зайняло найменше зусиль), але, здається, пройшов усі тестові справи. Деякі результати не відповідають точно, але всі вони мають однакову кількість стільців.

Пояснення

Перший рядок досить просто встановлює деякі визначення, які врятують нас байтами в майбутньому:

(Я розпакую ці макроси для зручності читання у майбутніх рядках)

n,i,o="\nI ";R=lambda x:range(1,x-1)

Тоді ми відкриємо файл з назвою, Iтому що у нас вже є змінна, коротка для цього, щоб вона економила кілька байт.

b=open("I").read().split("\n")

Ми розділимо нові рядки, щоб створити список рядків (Рядки зображення)

s=b.split(n)

Потім я знаходжу довжину найдовшої лінії, так що я можу прокласти всі рядки до цієї довжини. (Я також додаю 3, тому що нам потрібно трохи додаткової прокладки)

 z=max(map(len,s))+3

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

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

Наступний рядок - це ще одне визначення байтового збереження.

(Я також розпакую цю)

B=R(len(a))

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

for _ in b:

Для кожної ітерації ми хочемо передати кожен символ у двовимірному списку (за винятком самого зовнішнього накладки)

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

Для кожної позиції виконуємо наступний код:

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

Давайте розбимо це.

Ми маємо, якщо з двома умовами, розділеними &(бітовим and)

Перший просто перевіряє, чи є Iв якійсь із сусідніх комірок, а другий просто перевіряє, чи є поточна комірка a " ". Якщо ми переходимо ці умови, ми встановимо, що поточна комірка є an I.


Тепер, коли ми визначили зовнішню і внутрішню форму, ми можемо почати розміщувати стільці навколо столу.

Ще раз перебираємо всі комірки (і встановлюємо ще кілька скорочень)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

Тепер ось моя улюблена частина. Якщо ви до сих пір ходили через мої нудні, здебільшого визначення, гольф, я збираюся нагородити вас чудовим нальотом розумного гольфу (якщо я сам так скажу).

Трохи фону в python:

У Python, якщо ви намагаєтесь призначити ключ словника двічі, він призначає останній. Наприклад

>>> {1:"a",1:"b"}[1]
'b'

Ми зловживатимемо цією властивістю, щоб призначити поточну клітинку конкретному символу.

Перша умова

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

Якщо комірка знаходиться посередині краю з 3 _символів, ми перепризначимо поточну комірку та комірку під нею. Ми призначимо його результатом індексації перевантаженого словника за I. Спочатку ми встановлюємо параметр за замовчуванням за допомогою пари, "I":"_"+a[x+1][y]це означає, що якщо не буде змін, ми присвоїмо їм дві комірки до їх початкових значень. Далі додаємо пару a[x-1][y]:"^ ". Це не буде робити нічого (важливо), якщо клітинка над поточним ( a[x-1][y]) не заповнена символом I. Якщо він має Iв ньому, він скасує за замовчуванням, що говорить нам розмістити стілець у поточній комірці. Далі ми переходимо до клітини нижче поточної комірки, якщо цю клітинку Iми знову переосмислимо, щоб розмістити вгору облицювальний стілець нижче поточного місця.

Наступна умова - це простіше

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

Ми перевіряємо, чи є обидва поточна комірка та комірка над нею |. Якщо так, ми створимо словник.

Перша пара в словнику "I":"|"встановлює за замовчуванням. Оскільки ми збираємось отримати доступ до ключа, Iякщо Iйого не присвоєно, він за замовчуванням повернеться до |(символу, який він уже є) і нічого не зробить.

Ми додаємо дві клавіші A[y+1]:">",A[y-1]:"<"Якщо будь-яка з двох комірок ліворуч і праворуч, Iто вона переставить поточну комірку на стілець, вказуючи у напрямку назовні.


Тепер нам просто потрібно вивести. Однак ми не можемо просто роздрукувати, є кілька речей по господарству, які ми повинні зробити спочатку. Ми повинні перетворити назад у рядок і видалити всі Iстворені нами s. Це робиться в один рядок.

print "\n".join(`y`[2::5]for y in a).replace("I"," ")

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

3
Це може бути найбільш переоцінена відповідь.
Чарівний восьминіг Урна

2
Чи i,o="I "замість i="I";o=" "роботи?
Аднан

1
@ErikGolfer エ リ ッ ク ゴ ル フ ァ ー Затрати в n4 байти і економить мене 6. Хоча я не використовую його часто, він економить 2 байти.
Пшеничний майстер

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