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


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.