Tìm kiếm ông già Noel


13

Tìm ông già Noel và chú tuần lộc của mình trong một khung cảnh đông đúc.

Đầu vào

Đầu vào sẽ nằm trên STDIN và sẽ là một số lượng các dòng ký tự có độ dài bằng nhau, nhưng thay đổi. Nếu ông già Noel (được đại diện bởi nhân vật S) có mặt trong cảnh đó, bao tải quà của ông (được đại diện bởi nhân vật P) sẽ ở một trong những vị trí liền kề với ông (theo chiều ngang, chiều dọc hoặc đường chéo). Tuần lộc của anh ấy (mỗi người được đại diện bởi nhân vật R) tất cả sẽ ở trong quảng trường 5x5 bao quanh anh ấy. Nếu Sxuất hiện trong cảnh không có bao tải quà tặng, hoặc không có ít nhất 4 con tuần lộc, thì đó không phải là ông già Noel.

Đầu ra

Khung cảnh xóa sạch mọi sự xáo trộn (tất cả các nhân vật không phải ông già Noel, không phải quà tặng, không tuần lộc được thay thế bằng một khoảng trống), cho thấy ông già Noel, bao tải quà và tuần lộc của ông - tất cả các nhân vật khác nên được thay thế bằng không gian. Nếu ông già Noel và tuần lộc không có mặt, hãy xuất ra nó không thay đổi. Nó được đảm bảo rằng sẽ chỉ có một giải pháp, vì vậy sẽ không bao giờ có nhiều hơn một ông già Noel hợp lệ và ông sẽ không bao giờ mang nhiều hơn một bao quà.

Ví dụ

Trong những ví dụ tôi chỉ sử dụng các *nhân vật để làm cho nó dễ dàng để xem S, PRký tự, nhưng chương trình của bạn sẽ có thể xử lý bất kỳ ký tự ascii từ !đến `(33-96). Tôi đã bỏ các ký tự chữ thường trở lên để tránh nhầm lẫn.

Đầu vào:

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

Đầu ra: (bỏ qua các dấu chấm, chúng buộc trang hiển thị các dòng trống)

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

Đầu vào: (không đủ tuần lộc)

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

Đầu ra:

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

Đầu vào: (không có bao quà)

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

Đầu ra:

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

Đầu vào: (quà không đủ gần)

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

Đầu ra:

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

Đầu vào: (một trong những con tuần lộc không nằm trong quảng trường 5x5 quanh Santa)

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

Đầu ra:

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

Kiểm tra tập lệnh

Như trong một số câu hỏi trước đây của tôi, một lần nữa tôi đã tìm hiểu một số tập lệnh kiểm tra do JoeyVentero tạo ra để cung cấp một số trường hợp kiểm tra cho câu hỏi này:

Sử dụng: ./test [your program and its arguments]

Phiên bản văn bản thuần túy của các bài kiểm tra để tham khảo: Văn bản thuần túy

Phần thưởng

Mỗi mục mà tôi có thể xác minh đáp ứng thông số kỹ thuật, vượt qua các bài kiểm tra và rõ ràng đã có một số nỗ lực chơi gôn sẽ nhận được một upvote từ tôi (vì vậy vui lòng cung cấp hướng dẫn sử dụng với câu trả lời của bạn). Giải pháp ngắn nhất vào cuối ngày 31/12/2013 sẽ được chấp nhận là người chiến thắng.


Tôi nhận ra điều này tương tự như câu hỏi trước đây của tôi Nhận dạng khuôn mặt , nhưng nó đã được một vài năm kể từ đó. Ngoài ra, tôi xin lỗi vì đã bỏ qua Câu hỏi Sandbox nhưng với nội dung liên quan đến Giáng sinh, nó cần phải được đăng nhanh chóng hoặc không liên quan.
Gareth

Đầu ra ví dụ đầu tiên không hiển thị đúng (có vẻ là kích thước nhỏ hơn).
Dennis Jaheruddin

@DennisJaheruddin Có vẻ như Markdown đang xóa tất cả các dòng trống. Tôi đã thêm dấu chấm ở đầu những dòng đó để cho thấy rằng chúng ở đó. Xin lỗi về sự nhầm lẫn.
Gareth

Câu trả lời:


2

MATLAB: 110 , 95 ký tự

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

Không chắc chắn về cách xử lý đầu vào, nhưng phần còn lại khá đơn giản.

Phiên bản thường được định dạng:

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

Ví dụ đầu vào:

M=['***********'
'***********'
'***********'
'*****R*****'
'******P****'
'*****SQL_2*'
'*****R*****'
'****R**R***'
'***********'
'***********'
'***********'
'***********'];

Hmmm, chạy các kịch bản thử nghiệm trên này sẽ rất khó xử. Một cái nhìn nhanh chóng trên các mã gợi ý rằng bạn chỉ sử dụng các ví dụ đưa ra ở trên mà sử dụng *các nhân vật như đám đông để làm cho nó dễ dàng hơn để xem S, PRnhân vật - trong khi các cuộc thử nghiệm trong việc sử dụng kịch bản thử nghiệm tất cả các ký tự ascii từ 33 ( !) lên đến (và bao gồm) 96 (`` `). Tôi sẽ làm rõ điều này trong câu hỏi. Tôi đã thực hiện một phiên bản văn bản đơn giản của các bài kiểm tra bạn cần vượt qua mà tôi cũng sẽ thêm vào câu hỏi.
Gareth

@Gareth Cập nhật, dường như vượt qua các bài kiểm tra ngay bây giờ. QThật tệ là ông già Noel không mặc đồ , sẽ cứu tôi ít nhất 2 nhân vật.
Dennis Jaheruddin

Được chứ. Tôi không có Matlab vì vậy tôi chỉ tải xuống Octave (mà các internets nói với tôi là cách miễn phí tốt nhất để chạy mã Matlab) và sẽ chạy qua các bài kiểm tra vào buổi sáng để kiểm tra.
Gareth

Được rồi tôi đã kiểm tra điều này và nó dường như đáp ứng thông số kỹ thuật. Một nơi nó có một lợi thế không công bằng là các yêu cầu đầu vào. Tôi đã nâng cấp, nhưng tôi sẽ không thể chấp nhận nó là người chiến thắng trừ khi nó đọc đầu vào (từ một tệp vì có vẻ như Matlab không đọc từ STDIN).
Gareth

Bạn trượt SQL_2vào đầu vào mẫu ... tốt đẹp :)
Timtech 22/12/13

1

Con tră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]

Lần đầu tiên cố gắng viết mã càng nhỏ gọn càng tốt. Python không thực sự là ngôn ngữ cho điều đó, vì thụt lề và dòng mới chỉ đơn giản là yêu cầu thiết kế. Tôi chủ yếu chọn sử dụng ngôn ngữ này, vì cách bạn có thể chơi với danh sách và chuỗi dưới dạng danh sách. Một ngôn ngữ với thao tác ma trận dễ dàng sẽ là lý tưởng cho nhiệm vụ này, nhưng thật đáng buồn là tôi không biết bất kỳ ngôn ngữ nào trong số đó.

Để kiểm tra điều, một cái gì đó cần phải được gán cho một, ví dụ

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

Điều thú vị chính trong mã này có lẽ là:

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

đó là một cách viết lạ mắt: "b trở thành một danh sách đại diện (chuỗi 25 ký tự) của mỗi ô vuông 5x5 trong biểu diễn ban đầu".


Mặc dù Matlab có thể gặp khó khăn khi đọc từ STDIN, nhưng Python không sợ. Đọc đầu vào từ STDIN là một trong những yêu cầu (để làm cho việc chạy tập lệnh thử nghiệm có thể càng nhiều càng tốt để ngăn mọi người đến với định dạng đầu vào của riêng họ).
Gareth

Rất tiếc, hoàn toàn bỏ lỡ điều đó.
Sumurai8

Đã thay đổi mã, nhưng không thể kiểm tra nếu nó thực sự hoạt động ở đây. Nó nên đọc nó theo cùng định dạng trước đây.
Sumurai8

Được rồi, tôi đã có cơ hội để chạy thử nghiệm bây giờ và có một số vấn đề. 1) Trong trường hợp tìm thấy ông già Noel, đầu vào là đầu ra như trước giải pháp của bạn. 2) Giải pháp của bạn có kích thước khác với đầu vào. Tôi đã cố gắng làm cho câu hỏi rõ ràng hơn vào thời điểm này - tất cả các ký tự không (santa, quà, tuần lộc) nên được thay thế bằng khoảng trắng. Nó giống như thế này trong ví dụ đầu tiên, nhưng nó không được nêu rõ ràng trong câu hỏi. 3) Khi không tìm thấy ông già Noel, đầu ra có khoảng cách hai dòng.
Gareth

0

Chỉ nên có một ông già Noel trong tệp (nếu có nhiều hơn 2 "S", tôi cần cập nhật mã).

Sử dụng 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
                }
           }
    }

Chạy lệnh awk như dưới đây

awk -f santa.awk file

Kết quả

found Santa



     R
    R R
    PS
    RR
    R  R

Xin lỗi vì đã không xem xét vấn đề này sớm hơn (Tôi đang trong kỳ nghỉ và không dễ dàng truy cập wifi). Thật không may, 2 Sđược cho phép miễn là chỉ có một ông già Noel "hợp lệ". Các xét nghiệm (được cung cấp trong câu hỏi) có một vài trường hợp sẽ thất bại vì lý do này.
Gareth
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.