Putus asa mencari Santa

13

Temukan Santa dan rusa di adegan yang ramai.

Memasukkan

Input akan di STDIN dan akan menjadi jumlah variabel baris karakter yang sama, tetapi variabel, panjang. Jika Santa (diwakili oleh karakter S) ada dalam adegan, karung hadiahnya (diwakili oleh karakter P) akan berada di salah satu posisi yang berdekatan dengannya (horizontal, vertikal atau diagonal). Rusa-nya (masing-masing diwakili oleh karakter R) semua akan berada dalam kotak 5x5 di sekitarnya. Jika seorang Smuncul dalam adegan yang tidak memiliki sekarung hadiah, atau tidak disertai oleh setidaknya 4 rusa, maka itu bukan Santa.

Keluaran

Adegan dibersihkan dari semua kebingungan (semua karakter non-Santa, non-hadiah, non-rusa diganti dengan spasi), menunjukkan Santa, karung hadiahnya, dan rusa-nya - semua karakter lain harus diganti dengan spasi. Jika Santa dan rusa kutubnya tidak ada di tempat kejadian, hasilnya tidak berubah. Dijamin hanya akan ada satu solusi, jadi tidak akan pernah ada lebih dari satu Santa yang valid dan dia tidak akan pernah membawa lebih dari satu karung hadiah.

Contohnya

Dalam contoh ini saya hanya menggunakan *karakter untuk membuatnya mudah untuk melihat S, Pdan Rkarakter, tetapi program Anda harus dapat menangani setiap karakter ascii dari !ke `(33-96). Saya telah meninggalkan karakter huruf kecil ke atas untuk menghindari kebingungan.

Memasukkan:

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

Output: (abaikan titik, mereka harus memaksa halaman untuk menampilkan garis kosong)

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

Input: (tidak cukup rusa)

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

Keluaran:

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

Input: (tidak ada karung hadiah)

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

Keluaran:

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

Input: (hadiah tidak cukup dekat)

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

Keluaran:

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

Input: (salah satu rusa tidak dalam kotak 5x5 di sekitar Santa)

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

Keluaran:

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

Tes Script

Seperti pada beberapa pertanyaan saya di masa lalu, saya sekali lagi membantai beberapa skrip uji yang awalnya dibuat oleh Joey dan Ventero untuk memberikan beberapa kasus uji untuk pertanyaan ini:

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

Versi teks tes untuk referensi: Teks polos

Hadiah

Setiap entri yang saya dapat verifikasi yang memenuhi spesifikasi, lulus tes dan jelas telah mencoba golf akan menerima upvote dari saya (jadi tolong berikan instruksi penggunaan dengan jawaban Anda). Solusi terpendek pada akhir 31/12/2013 akan diterima sebagai pemenang.

Gareth
sumber
Saya menyadari ini mirip dengan pertanyaan saya Pengenalan wajah sebelumnya , tetapi sudah beberapa tahun sejak itu. Juga, saya minta maaf karena melewatkan Pertanyaan Sandbox tetapi dengan itu terkait Natal itu perlu diposting cepat atau tidak akan relevan.
Gareth
Contoh output pertama tidak ditampilkan dengan benar (ukurannya tampak lebih kecil).
Dennis Jaheruddin
@ DennisJaheruddin Sepertinya Markdown menghapus semua baris kosong. Saya telah menambahkan titik di awal baris untuk menunjukkan bahwa mereka ada di sana. Maaf tentang kebingungannya.
Gareth

Jawaban:

2

MATLAB: 110 , 95 karakter

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

Tidak yakin tentang cara input seharusnya diproses, tetapi sisanya cukup mudah.

Versi biasanya diformat:

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

Input contoh:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];
Dennis Jaheruddin
sumber
Hmmm, menjalankan skrip uji pada ini akan menjadi canggung. Melihat sekilas kode menunjukkan bahwa Anda hanya menggunakan contoh yang diberikan di atas yang menggunakan *karakter sebagai kerumunan untuk membuatnya lebih mudah untuk melihat S, Pdan Rkarakter - sedangkan tes dalam skrip tes menggunakan semua karakter ascii dari 33 ( !) ke atas ke (dan termasuk) 96 (`` `). Saya akan menjelaskan hal ini dalam pertanyaan. Saya telah melakukan tes teks versi sederhana yang harus Anda lewati yang juga akan saya tambahkan ke pertanyaan.
Gareth
@ Gareth Updated, tampaknya lulus tes sekarang. Sayang sekali santa tidak memakai Quilt, akan menyelamatkan saya setidaknya 2 karakter.
Dennis Jaheruddin
Baik. Saya tidak punya Matlab jadi saya hanya mengunduh Octave (yang menurut internet adalah cara gratis terbaik untuk menjalankan kode Matlab) dan akan menjalankan tes di pagi hari untuk memeriksa.
Gareth
Oke saya sudah memeriksa ini dan tampaknya memenuhi spesifikasi. Satu tempat yang memiliki keunggulan tidak adil adalah pada persyaratan input. Saya telah memutakhirkan, tetapi saya tidak akan dapat menerimanya sebagai pemenang kecuali itu membaca input (dari sebuah file karena sepertinya Matlab tidak membaca dari STDIN).
Gareth
Anda memasukkan SQL_2input sampel ... bagus :)
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]

Upaya pertama untuk menulis kode sekompak mungkin. Python sebenarnya bukan bahasa untuk itu, karena lekukan dan baris baru hanya diperlukan oleh desain. Saya terutama memilih untuk menggunakan bahasa ini, karena cara Anda bisa bermain dengan daftar, dan string sebagai daftar. Bahasa dengan manipulasi matriks yang mudah akan ideal untuk tugas ini, tetapi sayangnya saya tidak tahu satu pun dari mereka.

Untuk menguji sesuatu, sesuatu perlu ditugaskan ke, misalnya

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

Hal menarik utama dalam kode ini mungkin:

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

yang merupakan cara penulisan yang mewah: "b menjadi daftar representasi (string 25 karakter) dari setiap 5x5 persegi dalam representasi asli".

Sumurai8
sumber
Sementara Matlab mungkin mengalami kesulitan membaca dari STDIN, Python tidak takut. Membaca input dari STDIN adalah salah satu persyaratan (untuk membuat menjalankan skrip pengujian sebanyak mungkin untuk menghentikan orang dari datang dengan format input mereka sendiri).
Gareth
Ups, sangat merindukan itu.
Sumurai8
Mengubah kode, tetapi tidak dapat menguji apakah itu benar-benar berfungsi di sini. Seharusnya membacanya dalam format yang sama seperti dulu.
Sumurai8
Oke, saya punya kesempatan untuk menjalankan tes ini sekarang dan ada beberapa masalah. 1) Dalam kasus di mana Santa ditemukan, input dikeluarkan seperti sebelum solusi Anda. 2) Solusi Anda berukuran berbeda dari input. Saya sudah mencoba membuat pertanyaan lebih jelas tentang hal ini - semua karakter non-(santa, hadiah, rusa) harus diganti dengan spasi. Seperti ini pada contoh pertama, tetapi tidak dinyatakan secara eksplisit dalam pertanyaan. 3) Ketika Santa tidak ditemukan output memiliki spasi baris ganda.
Gareth
0

Seharusnya hanya ada satu Santa di file (jika lebih dari 2 "S", saya perlu memperbarui kode).

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

Jalankan perintah awk seperti di bawah ini

awk -f santa.awk file

Hasil

found Santa



     R
    R R
    PS
    RR
    R  R
BMW
sumber
Permintaan maaf karena tidak meninjau ini lebih cepat (saya sedang berlibur dan tidak memiliki akses mudah ke wifi). Sayangnya, 2 Sdiizinkan selama hanya satu yang merupakan Santa 'valid'. Tes (disediakan dalam pertanyaan) memiliki beberapa kasus yang akan gagal karena alasan ini.
Gareth