Buscando desesperadamente a Santa

13

Encuentra a Santa y sus renos en una escena llena de gente.

Entrada

La entrada estará en STDIN y será un número variable de líneas de caracteres de igual longitud, pero variable. Si Santa (representado por el personaje S) está en la escena, su saco de regalos (representado por el personaje P) estará en una de las posiciones adyacentes a él (horizontal, vertical o diagonal). Sus renos (cada uno representado por el personaje R) estarán todos dentro del cuadrado de 5x5 que lo rodea. Si Saparece en la escena que no tiene un saco de regalos, o no está acompañado por al menos 4 renos, entonces no es Santa.

Salida

La escena se despejó de toda ofuscación (todos los personajes que no son Santa, no presentes, no renos reemplazados por un espacio), mostrando a Santa, su saco de regalos y sus renos; todos los demás personajes deben reemplazarse por espacios. Si Papá Noel y sus renos no están en la escena, déjelos sin cambios. Se garantiza que solo habrá una solución, por lo que nunca habrá más de un Papá Noel válido y nunca llevará más de un saco de regalos.

Ejemplos

En estos ejemplos sólo estoy usando el *personaje para que sea fácil de ver los S, Py Rpersonajes, pero su programa debe ser capaz de manejar cualquier carácter ASCII a partir !de `(33 a 96). He omitido los caracteres en minúscula y superiores para evitar confusiones.

Entrada:

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

Salida: (ignore los puntos, obligarán a la página a mostrar las líneas en blanco)

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

Entrada: (no hay suficientes renos)

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

Salida:

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

Entrada: (sin saco de regalos)

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

Salida:

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

Entrada: (presenta no lo suficientemente cerca)

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

Salida:

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

Entrada: (uno de los renos que no está dentro del cuadrado de 5x5 alrededor de Santa)

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

Salida:

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

Scripts de prueba

Como en algunas de mis preguntas anteriores, una vez más eliminé algunos scripts de prueba creados originalmente por Joey y Ventero para proporcionar algunos casos de prueba para esta pregunta:

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

Versión de texto sin formato de las pruebas para referencia: texto sin formato

Recompensas

Cada entrada que pueda verificar que cumpla con las especificaciones, pase las pruebas y obviamente haya tenido algún intento de jugar al golf recibirá un voto positivo de mí (así que proporcione instrucciones de uso con su respuesta). La solución más corta para fines del 31/12/2013 será aceptada como ganadora.

Gareth
fuente
Me doy cuenta de que esto es similar a mi pregunta anterior Reconocimiento facial , pero han pasado un par de años desde entonces. Además, pido disculpas por omitir el Sandbox de preguntas, pero al estar relacionado con la Navidad, debía publicarse rápidamente o no sería relevante.
Gareth
El primer ejemplo de salida no se muestra correctamente (parece ser de menor tamaño).
Dennis Jaheruddin
@DennisJaheruddin Parece que Markdown está eliminando todas las líneas en blanco. Agregué puntos al comienzo de esas líneas para mostrar que están allí. Perdón por la confusión.
Gareth

Respuestas:

2

MATLAB: 110 , 95 caracteres

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

No estoy seguro sobre la forma en que se supone que se procesa la entrada, pero el resto es bastante sencillo.

Versión con formato normal:

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

Entrada de ejemplo:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];
Dennis Jaheruddin
fuente
Hmmm, ejecutar los scripts de prueba en esto va a ser incómodo. Una mirada rápida sobre el código sugiere que sólo está utilizando los ejemplos anteriores que utilizan *caracteres cuando parte del público para que sea más fácil ver la S, Py Rcaracteres - mientras que las pruebas en el uso script de prueba todos los caracteres ASCII de 33 ( !) hasta a (e incluyendo) 96 (`` `). Dejaré esto claro en la pregunta. He hecho una versión en texto plano de las pruebas que necesita pasar, que también agregaré a la pregunta.
Gareth
@Gareth actualizado, parece pasar las pruebas ahora. Lástima que santa no use un Qedredón, me habría salvado al menos 2 personajes.
Dennis Jaheruddin
Bueno. No tengo Matlab, así que solo estoy descargando Octave (que según me dicen los internautas es la mejor forma gratuita de ejecutar el código de Matlab) y ejecutaré las pruebas por la mañana para verificar.
Gareth
Bien, he comprobado esto y parece cumplir con las especificaciones. El único lugar en el que tiene una ventaja injusta es en los requisitos de entrada. He votado a favor, pero no podré aceptarlo como ganador a menos que lea la entrada (de un archivo, ya que parece que Matlab no lee desde STDIN).
Gareth
Te metiste SQL_2en la entrada de muestra ... agradable :)
Timtech
1

Pitón 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]

Primer intento de escribir código lo más compacto posible. Python no es realmente el lenguaje para eso, ya que el diseño simplemente requiere sangría y nuevas líneas. Principalmente elijo usar este lenguaje, debido a la forma en que puedes jugar con listas y cadenas como listas. Un lenguaje con fácil manipulación matricial sería ideal para esta tarea, pero lamentablemente no conozco ninguno de ellos.

Para probar algo, algo debe asignarse a un, p. Ej.

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

Lo más interesante de este código es probablemente:

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

que es una forma elegante de escribir: "b se convierte en una lista de una representación (cadena de 25 caracteres) de cada cuadrado de 5x5 en la representación original".

Sumurai8
fuente
Si bien Matlab puede tener dificultades para leer STDIN, Python no me temo. Leer la entrada de STDIN es uno de los requisitos (hacer posible la ejecución del script de prueba tanto como evitar que las personas presenten su propio formato de entrada).
Gareth
Uy, lo extrañé por completo.
Sumurai8
Modificó el código, pero no puedo probar si realmente funciona aquí. Debería leerlo en el mismo formato en que solía estar.
Sumurai8
Bien, he tenido la oportunidad de ejecutar las pruebas sobre esto ahora y hay un par de problemas. 1) En los casos en que se encuentra Santa, la entrada se emite como antes de su solución. 2) Su solución es de un tamaño diferente al de la entrada. He tratado de aclarar la pregunta sobre este punto: todos los personajes que no son (santa, presentes, renos) deben reemplazarse con espacios. Fue así en el primer ejemplo, pero no se mencionó explícitamente en la pregunta. 3) Cuando no se encuentra a Santa, la salida tiene un doble espacio entre líneas.
Gareth
0

Debe haber solo un Santa en el archivo (si hay más de 2 "S", necesito actualizar el código).

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

Ejecute el comando awk como se muestra a continuación

awk -f santa.awk file

Resultado

found Santa



     R
    R R
    PS
    RR
    R  R
BMW
fuente
Disculpas por no revisar esto antes (estoy de vacaciones y no tengo fácil acceso a wifi). Desafortunadamente, Sse permiten 2 siempre y cuando solo uno sea un Santa 'válido'. Las pruebas (proporcionadas en la pregunta) tienen un par de casos que fallarían por este motivo.
Gareth