Verzweifelt auf der Suche nach Santa

13

Finde den Weihnachtsmann und sein Rentier in einer überfüllten Szene.

Eingang

Die Eingabe erfolgt auf STDIN und ist eine variable Anzahl von Zeichenzeilen gleicher, aber variabler Länge. Wenn sich der Weihnachtsmann (dargestellt durch den Charakter S) in der Szene befindet, befindet sich sein Sack mit Geschenken (dargestellt durch den Charakter P) in einer der ihm benachbarten Positionen (horizontal, vertikal oder diagonal). Sein Rentier (jedes durch den Charakter dargestellt R) wird sich alle innerhalb des ihn umgebenden 5x5-Quadrats befinden. Wenn eine Sin der Szene erscheint, die keinen Sack Geschenke hat oder nicht von mindestens 4 Rentieren begleitet wird, dann ist es nicht der Weihnachtsmann.

Ausgabe

Die Szene wurde von jeglicher Verschleierung befreit (alle Nicht-Weihnachtsmann-, Nicht-Geschenk-, Nicht-Rentier-Charaktere, die durch ein Leerzeichen ersetzt wurden) und zeigt den Weihnachtsmann, seinen Sack mit Geschenken und sein Rentier - alle anderen Charaktere sollten durch Leerzeichen ersetzt werden. Wenn der Weihnachtsmann und sein Rentier nicht in der Szene sind, geben Sie sie unverändert aus. Es ist garantiert, dass es nur eine Lösung gibt, es wird also nie mehr als einen gültigen Weihnachtsmann geben und er wird niemals mehr als einen Sack Geschenke tragen.

Beispiele

In diesen Beispielen verwende ich nur den *Charakter , um es die leicht zu machen , zu sehen S, Pund RZeichen, aber Ihr Programm soll beliebige ASCII - Zeichen aus zu handhaben können, !zu `(33 bis 96). Ich habe Kleinbuchstaben und höher weggelassen, um Verwirrung zu vermeiden.

Eingang:

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

Ausgabe: (Punkte ignorieren, sie sollen die Seite zwingen, die leeren Zeilen anzuzeigen)

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

Input: (nicht genug Rentiere)

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

Ausgabe:

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

Input: (kein Sack mit Geschenken)

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

Ausgabe:

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

Input: (Geschenke nicht nah genug)

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

Ausgabe:

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

Eingabe: (eines der Rentiere nicht innerhalb des 5x5 Quadrats um den Weihnachtsmann)

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

Ausgabe:

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

Testskripte

Wie in einigen meiner früheren Fragen habe ich auch hier einige Testskripte geschlachtet, die ursprünglich von Joey und Ventero erstellt wurden , um einige Testfälle für diese Frage bereitzustellen:

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

Klartextversion der Tests als Referenz: Klartext

Belohnung

Jeder Beitrag, bei dem ich nachprüfen kann, ob er der Spezifikation entspricht, die Tests besteht und offensichtlich einen Golfversuch unternommen hat, wird von mir positiv bewertet (bitte geben Sie die Verwendungsanleitung mit Ihrer Antwort an). Die kürzeste Lösung bis Ende 31.12.2013 wird als Sieger anerkannt.

Gareth
quelle
Mir ist klar, dass dies meiner vorherigen Frage zur Gesichtserkennung ähnelt , aber seitdem sind einige Jahre vergangen . Ich entschuldige mich auch dafür, dass ich die Frage Sandbox übersprungen habe, aber da sie mit Weihnachten zu tun hat, musste sie schnell gepostet werden, sonst wäre sie nicht relevant.
Gareth
Die erste Beispielausgabe wird nicht richtig angezeigt (scheint kleiner zu sein).
Dennis Jaheruddin
@DennisJaheruddin Es sieht so aus, als ob der Markdown alle leeren Zeilen entfernt. Ich habe am Anfang dieser Zeilen Punkte eingefügt, um zu zeigen, dass sie dort sind. Entschuldigung für die Verwirrung.
Gareth

Antworten:

2

MATLAB: 110 , 95 Zeichen

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

Ich bin mir nicht sicher, wie die Eingabe verarbeitet werden soll, aber der Rest ist ziemlich einfach.

Normal formatierte Version:

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

Beispiel Eingabe:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];
Dennis Jaheruddin
quelle
Hmmm, das Ausführen der Testskripte wird schwierig. Ein kurzer Blick über den Code läßt vermuten , dass Sie nur die Beispiele verwenden , über der gegebene Verwendung *Zeichen , als die Menge zu erleichtern, um das zu sehen S, Pund RZeichen - während der Tests im Testskript verwendet alle ASCII - Zeichen von 33 ( !) nach oben bis (und einschließlich) 96 (`` `). Ich werde dies in der Frage klarstellen. Ich habe eine Klartextversion der Tests erstellt, die Sie bestehen müssen, und die ich auch der Frage hinzufügen werde.
Gareth
@Gareth Aktualisiert, scheint die Tests jetzt zu bestehen. Schade, dass der Weihnachtsmann keinen QUilt trägt, hätte mir mindestens 2 Charaktere erspart.
Dennis Jaheruddin
Okay. Ich habe kein Matlab, also lade ich nur Octave herunter (laut Internet die beste kostenlose Möglichkeit, Matlab-Code auszuführen) und führe die Tests am Morgen durch, um dies zu überprüfen.
Gareth
Okay, ich habe dies überprüft und es scheint die Spezifikation zu erfüllen. Der eine Ort, an dem es einen unfairen Vorteil hat, sind die Eingabeanforderungen. Ich habe aufgestimmt, aber ich werde es nicht als Gewinner akzeptieren können, es sei denn, es liest Eingaben (aus einer Datei, da Matlab anscheinend nicht aus STDIN liest).
Gareth
Du bist SQL_2in die Beispiel-Eingabe gerutscht ... nett :)
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]

Erster Versuch, Code so kompakt wie möglich zu schreiben. Python ist nicht wirklich die Sprache dafür, da Einrückungen und Zeilenumbrüche einfach vom Design verlangt werden. Ich habe mich hauptsächlich für diese Sprache entschieden, da man mit Listen und Strings als Listen spielen kann. Eine Sprache mit einfacher Matrixmanipulation wäre ideal für diese Aufgabe, aber leider kenne ich keine von ihnen.

Um etwas zu testen, muss etwas einem zugewiesen werden, z

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

Die wichtigste interessante Sache in diesem Code ist wahrscheinlich:

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

Dies ist eine ausgefallene Schreibweise: "b wird eine Liste einer Darstellung (Zeichenfolge mit 25 Zeichen) von jedem 5x5-Quadrat in der ursprünglichen Darstellung".

Sumurai8
quelle
Während Matlab möglicherweise Schwierigkeiten beim Lesen von STDIN hat, habe ich keine Angst vor Python. Das Lesen der Eingabe aus STDIN ist eine der Anforderungen (um das Ausführen des Testskripts zu ermöglichen und um zu verhindern, dass Benutzer ein eigenes Eingabeformat entwickeln).
Gareth
Hoppla, das habe ich total verpasst.
Sumurai8
Der Code wurde geändert, kann aber nicht testen, ob er hier tatsächlich funktioniert. Es sollte das gleiche Format haben wie früher.
Sumurai8
Okay, ich hatte jetzt die Möglichkeit, die Tests darüber durchzuführen, und es gibt ein paar Probleme. 1) In Fällen, in denen der Weihnachtsmann gefunden wird, wird die Eingabe wie vor Ihrer Lösung ausgegeben. 2) Ihre Lösung hat eine andere Größe als die Eingabe. Ich habe versucht, die Frage in diesem Punkt klarer zu machen - alle Nicht- (Weihnachts-, Geschenk-, Rentier-) Zeichen sollten durch Leerzeichen ersetzt werden. Dies war im ersten Beispiel so, wurde aber in der Frage nicht explizit angegeben. 3) Wenn der Weihnachtsmann nicht gefunden wird, hat die Ausgabe einen doppelten Zeilenabstand.
Gareth
0

Es sollte nur ein Weihnachtsmann in der Datei sein (wenn mehr als 2 "S" vorhanden sind, muss der Code aktualisiert werden).

Awk benutzen

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

Führen Sie den Befehl awk wie folgt aus

awk -f santa.awk file

Ergebnis

found Santa



     R
    R R
    PS
    RR
    R  R
BMW
quelle
Entschuldigung, dass ich das nicht früher überprüft habe (ich bin im Urlaub und habe keinen einfachen Zugang zu WLAN). Leider sind 2 Serlaubt, solange nur einer ein 'gültiger' Weihnachtsmann ist. Die Tests (in der Frage bereitgestellt) haben einige Fälle, die aus diesem Grund fehlschlagen würden.
Gareth