Procurando desesperadamente o Papai Noel

13

Encontre o Papai Noel e suas renas em uma cena lotada.

Entrada

A entrada estará em STDIN e será um número variável de linhas de caracteres de comprimento igual, mas variável. Se o Papai Noel (representado pelo personagem S) estiver em cena, seu saco de presentes (representado pelo personagem P) estará em uma das posições adjacentes a ele (horizontal, vertical ou diagonal). Suas renas (cada uma representada pelo personagem R) estarão todas dentro do quadrado 5x5 ao seu redor. Se um Saparece na cena que não tem um saco de presentes ou não é acompanhado por pelo menos quatro renas, então não é o Papai Noel.

Resultado

A cena limpa de toda ofuscação (todos os personagens que não são do Papai Noel, presentes ou não-renas são substituídos por um espaço), mostrando Papai Noel, seu saco de presentes e sua rena - todos os outros personagens devem ser substituídos por espaços. Se o Papai Noel e suas renas não estiverem em cena, produza-os inalterados. É garantido que haverá apenas uma solução; portanto, nunca haverá mais de um Papai Noel válido e ele nunca estará carregando mais de um saco de presentes.

Exemplos

Nestes exemplos Estou apenas usando o *personagem para torná-lo fácil de ver S, Pe Rpersonagens, mas o seu programa deve ser capaz de lidar com qualquer caracteres ASCII a partir !de `(33 a 96). Eu deixei de fora caracteres minúsculos e acima para evitar confusão.

Entrada:

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

Saída: (ignore pontos, eles devem forçar a página a mostrar as linhas em branco)

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

Entrada: (rena insuficiente)

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

Resultado:

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

Entrada: (sem saco de presentes)

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

Resultado:

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

Entrada: (apresenta não perto o suficiente)

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

Resultado:

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

Entrada: (uma das renas fora do quadrado 5x5 em torno do Papai Noel)

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

Resultado:

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

Scripts de teste

Como em algumas das minhas perguntas anteriores, mais uma vez massacrei alguns scripts de teste criados originalmente por Joey e Ventero para fornecer alguns casos de teste para esta pergunta:

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

Versão em texto sem formatação dos testes para referência: Texto sem formatação

Recompensas

Cada entrada que eu possa verificar que atenda às especificações, passa nos testes e obviamente teve alguma tentativa de jogar golfe receberá um voto positivo de mim (por isso, forneça instruções de uso com sua resposta). A solução mais curta até o final de 31/12/2013 será aceita como vencedora.

Gareth
fonte
Sei que isso é semelhante à minha pergunta anterior Reconhecimento facial , mas já se passaram alguns anos desde então. Além disso, peço desculpas por pular a Sandbox de perguntas, mas, por estar relacionada ao Natal, precisava ser publicada rapidamente ou não seria relevante.
Gareth
O primeiro exemplo de saída não é exibido corretamente (parece ser um tamanho menor).
Dennis Jaheruddin
@DennisJaheruddin Parece que o Markdown está removendo todas as linhas em branco. Adicionei pontos no início dessas linhas para mostrar que eles estão lá. Desculpe a confusão.
24513 Gareth

Respostas:

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

Não tenho certeza sobre como a entrada deve ser processada, mas o resto é bem direto.

Versão normalmente formatada:

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

Exemplo de entrada:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];
Dennis Jaheruddin
fonte
Hmmm, a execução dos scripts de teste será incômoda. Um rápido olhar sobre o código sugere que você está usando apenas os exemplos dados acima que usam *caracteres como a multidão para torná-lo mais fácil de ver a S, Pe Rpersonagens - enquanto que os testes no uso script de teste todos os caracteres ASCII de 33 ( !) até para (e incluindo) 96 (`` `). Vou deixar isso claro na pergunta. Fiz uma versão em texto simples dos testes que você precisa passar, que também adicionarei à pergunta.
Gareth
@Gareth Atualizado, parece passar nos testes agora. Pena que o Papai Noel não usa uma Qcoleira, teria me poupado pelo menos 2 caracteres.
Dennis Jaheruddin
OK. Eu não tenho o Matlab, então estou apenas baixando o Octave (que os internets me dizem ser a melhor maneira gratuita de executar o código do Matlab) e executarei os testes pela manhã para verificar.
Gareth
Ok, eu verifiquei isso e parece atender às especificações. O único lugar em que ele tem uma vantagem injusta é sobre os requisitos de entrada. Fiz um voto positivo, mas não poderei aceitá-lo como vencedor a menos que leia a entrada (de um arquivo, pois parece que o Matlab não lê do STDIN).
Gareth
Você escorregou SQL_2na entrada de amostra ... nice :)
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]

Primeira tentativa de escrever o código o mais compacto possível. Python não é realmente a linguagem para isso, pois o recuo e as novas linhas são simplesmente exigidos pelo design. Eu escolho principalmente usar esse idioma, devido à maneira como você pode brincar com listas e cordas como listas. Uma linguagem com fácil manipulação de matriz seria ideal para esta tarefa, mas, infelizmente, não conheço nenhuma delas.

Para testar algo, algo precisa ser atribuído a um, por exemplo

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

A principal coisa interessante neste código é provavelmente:

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 é uma maneira elegante de escrever: "b se torna uma lista de uma representação (sequência de 25 caracteres) de cada quadrado de 5x5 na representação original".

Sumurai8
fonte
Enquanto o Matlab pode ter dificuldade em ler no STDIN, o Python não tem medo. A leitura da entrada do STDIN é um dos requisitos (para possibilitar a execução do script de teste e impedir que as pessoas apresentem seu próprio formato de entrada).
Gareth
Opa, perdi totalmente isso.
Sumurai8
Alterou o código, mas não pode testar se ele realmente funciona aqui. Deve lê-lo no mesmo formato em que costumava estar.
Sumurai8
Ok, tive a chance de executar os testes agora e há alguns problemas. 1) Nos casos em que o Papai Noel é encontrado, a entrada é emitida como antes da sua solução. 2) Sua solução é de tamanho diferente da entrada. Tentei esclarecer a questão nesse ponto - todos os caracteres que não são de santa (presentes, renas) devem ser substituídos por espaços. Foi assim no primeiro exemplo, mas não foi declarado explicitamente na pergunta. 3) Quando o Papai Noel não é encontrado, a saída possui um espaçamento de linha duplo.
Gareth
0

Deve haver apenas um Papai Noel no arquivo (se houver mais de 2 "S", preciso atualizar o 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
                }
           }
    }

Execute o comando awk como abaixo

awk -f santa.awk file

Resultado

found Santa



     R
    R R
    PS
    RR
    R  R
BMW
fonte
Desculpas por não ter comentado isso antes (estou de férias e não tenho acesso fácil a wifi). Infelizmente, 2 Ssão permitidos desde que apenas um seja um Papai Noel 'válido'. Os testes (fornecidos na pergunta) têm alguns casos que falhariam por esse motivo.
Gareth