Учитывая стол, место в стульях


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.
Wheat Wizard

Ответы:


34

Python 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:

Для каждой итерации мы хотим передать каждый символ в 2D-списке (исключая внешние отступы)

 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 " ". Если мы передаем эти условия, мы устанавливаем текущую ячейку, чтобы быть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то она переназначит текущую ячейку на стул, указывающий в направлении наружу.


Теперь нам просто нужно вывести. Однако мы не можем просто напечатать, есть пара вещей, которые мы должны сделать в первую очередь. Мы должны преобразовать обратно в строку и удалить все Is, которые мы создали. Это делается в одну строку.

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

Разве вы не можете использовать пробел для первого уровня отступа, табуляции для двух, табуляции и пробела для трех? Это сэкономит несколько байтов.
Райли

3
Это может быть самый повторный ответ.
Волшебная Осьминог Урна

2
Работает i,o="I "вместо i="I";o=" "работы?
Аднан

1
@ErikGolfer ー リ ッ ク ゴ ル フ ァ ー Создание nстоит 4 байта и спасает меня 6. Хотя я не использую это часто, это экономит 2 байта.
Wheat Wizard

1
@ Pietu1998 Спасибо, что указали на это. Я исправил проблему
Wheat Wizard
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.