Отчаянно Ищу Санту


13

Найдите Санту и его северного оленя в людной сцене.

вход

Ввод будет осуществляться через STDIN и будет переменным числом строк символов одинаковой, но переменной длины. Если Санта (представлен персонажем S) находится на сцене, его мешок подарков (представлен персонажем P) будет находиться в одной из соседних с ним позиций (по горизонтали, вертикали или диагонали). Его северный олень (каждый из которых представлен персонажем R) будет находиться в квадрате 5x5, окружающем его. Если Sна сцене появляется человек, у которого нет мешка с подарками, или если его не сопровождает хотя бы 4 оленя, то это не Санта.

Выход

Сцена очищена от всех запутываний (все персонажи, не принадлежащие Санте, не присутствующие, не являющиеся оленями, заменены пробелами), показывающие Санту, его мешок подарков и его оленей - все остальные персонажи должны быть заменены пробелами. Если Санты и его северного оленя нет на сцене, выведите его без изменений. Гарантируется, что будет только одно решение, поэтому никогда не будет более одного действительного Санты, и он никогда не будет нести более одного мешка подарков.

Примеры

В этих примерах я просто с помощью *символа , чтобы сделать его легко увидеть S, Pи Rсимволы, но ваша программа должна быть в состоянии справиться с любым из символов ASCII !в `(33 до 96). Я пропустил символы нижнего регистра и выше, чтобы избежать путаницы.

Входные данные:

***********
***********
***********
*****R*****
******P****
*****S*****
*****R*****
****R**R***
***********
***********
***********
***********

Вывод: (игнорируйте точки, они заставляют страницу показывать пустые строки)

.           
.          
.           
     R     
      P    
     S     
     R     
    R  R   
.           
.           
.           
.           

Вход: (недостаточно оленей)

***********
***********
***********
***********
******P****
*****S*****
*****R*****
****R**R***
***********
***********
***********
***********

Выход:

***********
***********
***********
***********
******P****
*****S*****
*****R*****
****R**R***
***********
***********
***********
***********

Вход: (без мешка подарков)

***********
***********
***********
*****R*****
***********
*****S*****
*****R*****
****R**R***
***********
***********
***********
***********

Выход:

***********
***********
***********
*****R*****
***********
*****S*****
*****R*****
****R**R***
***********
***********
***********
***********

Вход: (подарки не достаточно близко)

***********
***********
***********
*****R*****
***********
*****S*P***
*****R*****
****R**R***
***********
***********
***********
***********

Выход:

***********
***********
***********
*****R*****
***********
*****S*P***
*****R*****
****R**R***
***********
***********
***********
***********

Вход: (один из северных оленей не в квадрате 5x5 вокруг Санты)

***********
***********
***********
*****R*****
******P****
*****S*****
*****R*****
****R******
*******R***
***********
***********
***********

Выход:

***********
***********
***********
*****R*****
******P****
*****S*****
*****R*****
****R******
*******R***
***********
***********
***********

Тестовые сценарии

Как и в некоторых из моих прошлых вопросов, я еще раз вырезал некоторые тестовые сценарии, изначально созданные Джои и Вентеро, чтобы предоставить несколько тестовых примеров для этого вопроса:

Использование: ./test [your program and its arguments]

Текстовая версия тестов для справки: простой текст

Награды

Каждая заявка, которую я могу проверить, которая соответствует спецификации, проходит тесты и, очевидно, была попытка сыграть в гольф, получит от меня отклик (поэтому, пожалуйста, предоставьте инструкции по использованию вместе с вашим ответом). Самое короткое решение к концу 31.12.2013 будет принято победителем.


Я понимаю, что это похоже на мой предыдущий вопрос Распознавание лиц , но с тех пор прошло уже пару лет. Кроме того, я прошу прощения за пропуск Песочницы Вопроса, но поскольку это было связано с рождеством, это должно было быть отправлено быстро, или это не было бы уместно.
— Гарет

Первый пример вывода не отображается должным образом (кажется, меньшего размера).
— Деннис Джаэруддин

@DennisJaheruddin Похоже, что Markdown удаляет все пустые строки. Я добавил точки в начале этих строк, чтобы показать, что они есть. Извините за путаницу.
— Гарет

Ответы:


2

MATLAB: 110 , 95 символов

f=@(x,y) filter2(ones(x),y);a=M==83;b=M==82;c=M==80;d=f(5,a&f(5,b)>3&f(3,c))&(a|b|c);if ~d,M,else,M(~d)=32,end

Не уверен насчет способа обработки ввода, но все остальное довольно просто.

Нормально отформатированная версия:

f=@(x,y) filter2(ones(x),y);
a=M==83;
b=M==82;
c=M==80;
d=f(5,a&f(5,b)>3&f(3,c))&(a|b|c);
if ~d
  M
else
  M(~d)=32
end

Пример ввода:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];

Хм, запускать тестовые сценарии на этом будет неловко. Быстрый взгляд через код предполагает , что вы используете только примеры , приведенные выше , которые используют *символы , как толпы , чтобы сделать его легче увидеть S, Pа Rсимволы - в то время как тесты в использовании сценариев тестирования все символы ASCII с 33 ( !) до до (и в том числе) 96 (`` `). Я поясню это в вопросе. Я сделал простую текстовую версию тестов, которые вам нужно пройти, и я также добавлю к вопросу.
— Гарет

@Gareth Обновлено, похоже, сейчас проходит испытания. Жаль, что Санта не носил ни Qодного, спас бы меня, по крайней мере, 2 символа.
— Деннис Джаэруддин

Ладно. У меня нет Matlab, поэтому я просто загружаю Octave (который, по словам интернет-пользователей, является лучшим бесплатным способом запуска кода Matlab) и утром проверю тесты.
— Гарет

Хорошо, я проверил это, и это, кажется, соответствует спецификации. Единственное место, где оно имеет несправедливое преимущество, - это требования к входным данным. Я проголосовал, но я не смогу принять его как победителя, пока он не прочитает ввод (из файла, поскольку кажется, что Matlab не читает из STDIN).
— Гарет

Вы проскользнули SQL_2в пример ввода ... приятно :)
— Timtech

1

Python 2 ( 353 381)

import re,sys
a=sys.stdin.readlines()
h=len(a)
w=len(a[0])
a=''.join(a)+' '*99
print a
b=[''.join(q) for x in range(0,w) for y in range(0,h) for q in [[a[(y+z)*w+x:(y+z)*w+x+5] for z in range(0,5)]]]
for c in b:
 if c[12]=='S' and 'P' in ''.join([c[1+5*z:4+5*z] for z in range(1,4)]) and c.count('R')>3:
  a=re.sub('[^RPS]','.',c)
  w=h=5
for y in range(0,h):
 print a[y*w:(y+1)*w]

Первая попытка написать код настолько компактным, насколько это возможно. Python на самом деле не является языком для этого, так как отступы и переводы строки просто необходимы для дизайна. Я выбираю этот язык в основном из-за того, как вы можете играть со списками и строками в виде списков. Язык с легким манипулированием матрицей был бы идеальным для этой задачи, но, к сожалению, я не знаю ни одного из них.

Чтобы проверить, что-то должно быть назначено, например,

a=['1**********','*2*********','**3********','***4*******','****5*P****','*****S*****','*****,*****','****R**R***','***********','***********','****R******','**RPSRRR***']

Вероятно, главное интересное в этом коде:

b=[''.join(q) for x in range(0,w) for y in range(0,h) for q in [[a[(y+z)*w+x:(y+z)*w+x+5] for z in range(0,5)]]]

который является причудливым способом записи: «b становится списком представления (строка из 25 символов) каждого квадрата 5x5 в исходном представлении».


Хотя Matlab может испытывать трудности при чтении из STDIN, я не боюсь Python. Чтение входных данных из STDIN является одним из требований (чтобы запуск сценария тестирования был максимально возможен, чтобы люди не могли придумать свой собственный формат ввода).
— Гарет

упс, полностью пропустил это.
— Sumurai8

Изменил код, но не могу проверить, действительно ли он работает здесь. Она должна быть прочитана в том же формате, в котором она была.
— Sumurai8

Хорошо, у меня был шанс провести тесты по этому поводу сейчас, и есть пара проблем. 1) В случаях, когда Санта найден, ввод выводится как есть до вашего решения. 2) Ваше решение отличается от входного. Я постарался прояснить вопрос по этому вопросу - все символы (не Санта, подарки, олени) должны быть заменены пробелами. Так было в первом примере, но в вопросе об этом прямо не сказано. 3) Когда Санта не найден, выход имеет двойной межстрочный интервал.
— Гарет

0

В файле должен быть только один Санта (если больше 2 "S", мне нужно обновить код).

Использование awk

cat santa.awk

BEGIN{FS=""}
{ for (i=1;i<=NF;i++)
         { a[NR FS i]=$i
           if ($i=="S") {l=NR;c=i}
         }
     }
END{ if (l=="") {print "No Santa";exit}
     for (i=l-1;i<=l+1;i++)
        for (j=c-1;j<=c+1;j++)
          if (a[i FS j]=="P") p++
     if (p<1) {print "Santa has no presents";exit}
     for (i=l-2;i<=l+2;i++)
        for (j=c-2;j<=c+2;j++)
          if (a[i FS j]=="R") r++
     if (r<4) {print "Santa has no enough reindeers";exit}
     else {  print "found Santa "
             for (i=1;i<=NR;i++)
               { for (j=1;j<=NF;j++)
                   if (a[i FS j]~/[R|S|P]/) {printf a[i FS j]} else {printf " "}
                 printf RS
                }
           }
    }

Запустите команду awk, как показано ниже

awk -f santa.awk file

Результат

found Santa



     R
    R R
    PS
    RR
    R  R

Извините за то, что не рассмотрел это раньше (я в отпуске и у меня нет свободного доступа к Wi-Fi). К сожалению, 2 Sдопускаются, если только один является «действительным» Дедом Морозом. У тестов (предусмотренных в вопросе) есть несколько случаев, которые по этой причине потерпят неудачу.
— Гарет
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.