Rozpaczliwie szukam Świętego Mikołaja

13

Znajdź Świętego Mikołaja i jego renifery w zatłoczonej scenie.

Wejście

Dane wejściowe będą na STDIN i będą zmienną liczbą wierszy znaków o jednakowej, ale zmiennej długości. Jeśli Święty Mikołaj (reprezentowany przez postać S) jest na scenie, jego worek prezentów (reprezentowany przez postać P) będzie na jednej z sąsiadujących z nim pozycji (poziomo, pionowo lub po przekątnej). Jego renifery (każdy reprezentowany przez postać R) będą znajdować się wokół otaczającego go kwadratu 5x5. Jeśli Sna scenie pojawi się coś , co nie ma worka prezentów lub nie towarzyszy mu co najmniej 4 reniferów, to nie jest to Święty Mikołaj.

Wynik

Scena została oczyszczona z wszelkich zaciemnień (wszystkie postacie inne niż Święty Mikołaj, nie-prezenty, nierenifery zastąpione spacją), przedstawiające Świętego Mikołaja, jego worek prezentów i jego renifery - wszystkie inne postacie należy zastąpić spacjami. Jeśli Świętego Mikołaja i jego renifera nie ma na scenie, wyjmij go bez zmian. Gwarantujemy, że będzie tylko jedno rozwiązanie, więc nigdy nie będzie więcej niż jednego ważnego Świętego Mikołaja i nigdy nie będzie nosił więcej niż jednego worka prezentów.

Przykłady

W tych przykładach Ja tylko używając *charakter sprawiają, że łatwo zobaczyć S, Pi Rznaki, ale program powinien być w stanie obsłużyć każdy znak ASCII od !do `(33 do 96). Pominąłem małe litery i powyżej, aby uniknąć nieporozumień.

Wejście:

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

Dane wyjściowe: (ignoruj ​​kropki, aby zmusić stronę do wyświetlania pustych linii)

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

Wkład: (za mało reniferów)

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

Wynik:

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

Wejście: (bez worka prezentów)

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

Wynik:

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

Dane wejściowe: (prezenty nie są wystarczająco blisko)

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

Wynik:

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

Wejście: (jeden z reniferów poza polem 5x5 wokół Świętego Mikołaja)

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

Wynik:

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

Skrypty testowe

Podobnie jak w niektórych moich poprzednich pytaniach, po raz kolejny opracowałem skrypty testowe pierwotnie stworzone przez Joeya i Ventero, aby zapewnić kilka przypadków testowych dla tego pytania:

Stosowanie: ./test [your program and its arguments]

Wersja testu z tekstem jawnym : tekst zwykły

Nagrody

Każdy wpis, który mogę zweryfikować, który spełnia specyfikację, przechodzi testy i oczywiście miał pewne próby gry w golfa, otrzyma ode mnie opinię (więc proszę o podanie instrukcji użytkowania wraz z odpowiedzią). Najkrótsze rozwiązanie do końca 31.12.2013 zostanie zaakceptowane jako zwycięzca.

Gareth
źródło
Zdaję sobie sprawę, że jest to podobne do mojego poprzedniego pytania Rozpoznawanie twarzy , ale od tego czasu minęło kilka lat. Przepraszam również za pominięcie piaskownicy pytań, ale ponieważ była związana z Bożym Narodzeniem, musiała zostać szybko opublikowana, w przeciwnym razie nie będzie to istotne.
Gareth,
Pierwszy przykładowy wynik nie wyświetla się poprawnie (wydaje się być mniejszy).
Dennis Jaheruddin
@DennisJaheruddin Wygląda na to, że Markdown usuwa wszystkie puste linie. Dodałem kropki na początku tych linii, aby pokazać, że tam są. Przepraszam za zamieszanie.
Gareth

Odpowiedzi:

2

MATLAB: 110 , 95 znaków

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

Nie jestem pewien, w jaki sposób dane wejściowe powinny być przetwarzane, ale reszta jest dość prosta.

Wersja normalnie sformatowana:

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

Przykładowe dane wejściowe:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];
Dennis Jaheruddin
źródło
Hmmm, uruchamianie skryptów testowych na tym będzie niezręczne. Szybkie spojrzenie na kod sugeruje, że używasz tylko Przytoczone przykłady, które używają *znaków jak tłum, aby łatwiej było zobaczyć S, Pa Rznaki - Zważywszy, że badania w zakresie wykorzystania skryptu testu wszystkie znaki ASCII od 33 ( !) w górę do (włącznie) 96 (`` `). Wyjaśnię to w pytaniu. Zrobiłem tekstową wersję testów, które musisz zaliczyć, którą również dodam do pytania.
Gareth,
@Gareth Zaktualizowano, wydaje się teraz zdawać testy. Szkoda, że ​​Święty Mikołaj nie nosi Quilt, uratowałby mi co najmniej 2 postacie.
Dennis Jaheruddin,
W porządku. Nie mam Matlaba, więc właśnie pobieram Octave (który według mnie jest najlepszym darmowym sposobem na uruchomienie kodu Matlaba) i rano przejdę testy, żeby to sprawdzić.
Gareth,
Ok, sprawdziłem to i wydaje się, że jest zgodne ze specyfikacją. Jedynym miejscem, w którym ma niesprawiedliwą przewagę, są wymagania dotyczące nakładów. Poparłem głosowanie, ale nie będę w stanie zaakceptować go jako zwycięzcy, dopóki nie odczyta danych wejściowych (z pliku, ponieważ wydaje się, że Matlab nie czyta ze STDIN).
Gareth,
SQL_2
Wsunąłeś
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]

Pierwsza próba napisania kodu tak kompaktowego, jak to możliwe. Python nie jest tak naprawdę językiem do tego, ponieważ wcięcia i znaki nowej linii są po prostu wymagane przez projekt. Głównie wybieram używanie tego języka, ze względu na sposób, w jaki możesz grać z listami i ciągami jako listami. Język z łatwą obsługą macierzy byłby idealny do tego zadania, ale niestety nie znam żadnego z nich.

Aby przetestować, coś należy przypisać np

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

Główną interesującą rzeczą w tym kodzie jest prawdopodobnie:

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)]]]

co jest fantazyjnym sposobem pisania: „b staje się listą reprezentacji (ciąg 25 znaków) każdego kwadratu 5x5 w oryginalnej reprezentacji”.

Sumurai8
źródło
Podczas gdy Matlab może mieć trudności z czytaniem ze STDIN, Python nie boję się. Odczytywanie danych wejściowych ze STDIN jest jednym z wymagań (aby umożliwić uruchomienie skryptu testowego tak, aby powstrzymać ludzi przed wymyśleniem własnego formatu wejściowego).
Gareth,
Ups, całkowicie tego przegapiłem.
Sumurai8,
Zmieniono kod, ale nie można przetestować, czy rzeczywiście tutaj działa. Powinien przeczytać w tym samym formacie, w jakim był.
Sumurai8,
OK, miałem okazję teraz przetestować to i jest kilka problemów. 1) W przypadkach, w których znaleziono Świętego Mikołaja, dane wejściowe są wyprowadzane tak, jak przed rozwiązaniem. 2) Twoje rozwiązanie ma inny rozmiar niż wejście. W tym miejscu starałem się wyjaśnić pytanie - wszystkie postacie inne niż (santa, prezenty, renifery) powinny być zastąpione spacjami. Tak było w pierwszym przykładzie, ale nie zostało to wyraźnie określone w pytaniu. 3) Gdy Mikołaj nie zostanie znaleziony, wyjście ma podwójne odstępy między wierszami.
Gareth,
0

W pliku powinien znajdować się tylko jeden Święty Mikołaj (jeśli więcej niż 2 „S”, potrzebuję zaktualizować kod).

Korzystanie z 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
                }
           }
    }

Uruchom komendę awk jak poniżej

awk -f santa.awk file

Wynik

found Santa



     R
    R R
    PS
    RR
    R  R
BMW
źródło
Przepraszamy za wcześniejsze sprawdzenie tego (jestem na wakacjach i nie mam łatwego dostępu do Wi-Fi). Niestety, 2 Ssą dozwolone, o ile tylko jeden jest „ważnym” Mikołajem. Testy (podane w pytaniu) mają kilka przypadków, które z tego powodu zakończyłyby się niepowodzeniem.
Gareth