Шукаю Санта


13

Знайдіть Санта та його північних оленів у переповненій сцені.

Вхідні дані

Вхід буде на STDIN і буде змінною кількістю рядків символів однакової, але змінної довжини. Якщо Санта (представлений персонажем S) знаходиться на сцені, його мішок подарунків (представлений персонажем P) опиниться в одному з сусідніх з ним положень (горизонтально, вертикально або по діагоналі). Його північний олень (кожен представлений символом R) буде знаходитися в межах 5х5 квадрата, що його оточує. Якщо 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***
***********
***********
***********
***********

Введення: (один із північних оленів не в межах 5х5 квадрата навколо Санта-Клауса)

***********
***********
***********
*****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

Пітон 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, наприклад

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 символів) кожні 5х5 квадрата в оригінальному поданні".


Хоча у 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

Вибачте, що не переглядаю це раніше (я у відпустці і не маю легкого доступу до wifi). На жаль, Sдозволено 2 , якщо тільки один є "дійсним" Санта. Тести (надані у запитанні) мають кілька випадків, які з цієї причини не зможуть.
Гарет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.