หาซานต้าอย่างสิ้นหวัง


13

ค้นหาซานต้าและกวางเรนเดียร์ของเขาในฉากที่แออัด

อินพุต

อินพุตจะอยู่ใน STDIN และจะเป็นจำนวนตัวแปรของบรรทัดของตัวละครที่เท่ากัน แต่ตัวแปรความยาว ถ้าซานต้า (แสดงโดยตัวละครS) อยู่ในฉากกระสอบของขวัญของเขา (แสดงโดยตัวละครP) จะอยู่ในตำแหน่งใดตำแหน่งหนึ่งที่อยู่ติดกับเขา (แนวนอนแนวตั้งหรือแนวทแยงมุม) กวางเรนเดียร์ของเขา (ซึ่งแสดงโดยตัวละครแต่ละตัวR) จะอยู่ในพื้นที่ 5x5 รอบตัวเขา หากSปรากฏในฉากที่ไม่มีถุงของขวัญหรือไม่มีกวางเรนเดียร์อย่างน้อย 4 ตัวแสดงว่าไม่ใช่ซานต้า

เอาท์พุต

ฉากถูกลบล้างของความสับสน (ทั้งหมดที่ไม่ใช่ซานต้า, ไม่ใช่ของขวัญ, ตัวละครที่ไม่ใช่กวางเรนเดียร์แทนที่ด้วยช่องว่าง) แสดงให้เห็นซานต้า, กระสอบของของขวัญและกวางเรนเดียร์ของเขา - ตัวละครอื่น ๆ ทั้งหมดควรแทนที่ด้วยช่องว่าง ถ้าซานต้าและกวางเรนเดียร์ของเขาไม่ได้อยู่ในฉากเอาท์พุทมันไม่เปลี่ยนแปลง มีการรับประกันว่าจะมีทางออกเดียวเท่านั้นดังนั้นจะไม่มีซานต้าที่ถูกต้องมากกว่าหนึ่งรายการและเขาจะไม่ถือของขวัญมากกว่าหนึ่งถุง

ตัวอย่าง

ในตัวอย่างเหล่านี้ฉันแค่ใช้*ตัวอักษรที่จะทำให้มันง่ายที่จะเห็นS, PและRตัวอักษร แต่โปรแกรมของคุณควรจะสามารถที่จะจัดการกับอักขระ ASCII ใด ๆ จาก!ไป`(33-96) ฉันไม่ได้ใช้ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่เพื่อหลีกเลี่ยงความสับสน

การป้อนข้อมูล:

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

ผลลัพธ์: (ละเว้นจุดพวกเขาจะบังคับให้หน้าแสดงบรรทัดว่าง)

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

อินพุต: (กวางเรนเดียร์ไม่เพียงพอ)

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

เอาท์พุท:

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

อินพุต: (ไม่มีถุงของขวัญ)

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

เอาท์พุท:

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

อินพุต: (นำเสนอไม่ใกล้พอ)

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

เอาท์พุท:

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

อินพุต: (กวางเรนเดียร์ตัวใดตัวหนึ่งไม่อยู่ในสี่เหลี่ยม 5x5 รอบซานต้า)

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

เอาท์พุท:

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

สคริปต์ทดสอบ

ในบางคำถามที่ผ่านมาของฉันฉันได้พบเห็นสคริปต์ทดสอบอีกครั้ง แต่เดิมสร้างโดยJoeyและVenteroเพื่อให้กรณีทดสอบสำหรับคำถามนี้:

การใช้งาน: ./test [your program and its arguments]

รุ่นข้อความธรรมดาของการทดสอบสำหรับการอ้างอิง: ข้อความธรรมดา

รางวัล

แต่ละรายการที่ฉันสามารถตรวจสอบว่าตรงตามข้อกำหนดผ่านการทดสอบและเห็นได้ชัดว่ามีความพยายามในการเล่นกอล์ฟบางอย่างจะได้รับ upvote จากฉัน (ดังนั้นโปรดให้คำแนะนำการใช้งานพร้อมคำตอบของคุณ) ทางออกที่สั้นที่สุดภายในวันที่ 31 ธันวาคม 2556 จะได้รับการยอมรับในฐานะผู้ชนะ


ฉันรู้ว่าสิ่งนี้คล้ายกับคำถามก่อนหน้านี้การจดจำใบหน้าแต่ไม่กี่ปีที่แล้ว นอกจากนี้ฉันต้องขออภัยในการข้ามคำถามแซนด์บ็อกซ์แต่ด้วยความเกี่ยวข้องกับคริสต์มาสมันจำเป็นต้องโพสต์อย่างรวดเร็วไม่เช่นนั้นจะไม่เกี่ยวข้องกัน
Gareth

เอาต์พุตตัวอย่างแรกไม่แสดงอย่างถูกต้อง (ดูเหมือนจะมีขนาดเล็กกว่า)
Dennis Jaheruddin

@DennisJaheruddin ดูเหมือนว่า Markdown จะลบบรรทัดว่างทั้งหมดออก ฉันได้เพิ่มจุดเริ่มต้นของบรรทัดเหล่านั้นเพื่อแสดงว่าพวกเขาอยู่ที่นั่น ขออภัยเกี่ยวกับความสับสน
Gareth

คำตอบ:


2

MATLAB: 110 , 95ตัวอักษร

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

ไม่แน่ใจเกี่ยวกับวิธีการป้อนข้อมูลที่ควรประมวลผล แต่ส่วนที่เหลือค่อนข้างตรงไปตรงมา

เวอร์ชันที่จัดรูปแบบปกติ:

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

อินพุตตัวอย่าง:

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

อืมการเรียกใช้สคริปต์ทดสอบบนนี้จะไม่สะดวก ดูอย่างรวดเร็วกว่ารหัสที่แสดงให้เห็นว่าคุณกำลังใช้เพียงตัวอย่างที่กำหนดข้างต้นซึ่งใช้*ตัวอักษรเป็นฝูงชนที่จะทำให้มันง่ายที่จะเห็นS, PและRตัวอักษร - ในขณะที่การทดสอบในการใช้งานสคริปต์ทดสอบอักขระ ASCII ทั้งหมดจาก 33 ( !) ขึ้น ถึง (และรวมถึง) 96 (`` `) ฉันจะทำให้ชัดเจนในคำถาม ฉันทำแบบทดสอบข้อความธรรมดาที่คุณต้องผ่านซึ่งฉันจะเพิ่มในคำถามด้วย
Gareth

@ Gareth Updated, ดูเหมือนว่าจะผ่านการทดสอบตอนนี้ น่าเสียดายที่ซานต้าไม่สวมผ้าคลุมQผมจะช่วยฉันอย่างน้อย 2 ตัวอักษร
Dennis Jaheruddin

ตกลง. ฉันไม่มี Matlab ดังนั้นฉันแค่ดาวน์โหลด Octave (ซึ่ง internets บอกฉันเป็นวิธีที่ดีที่สุดในการเรียกใช้รหัส Matlab) และจะทำการทดสอบในตอนเช้าเพื่อตรวจสอบ
Gareth

โอเคฉันได้ตรวจสอบเรื่องนี้แล้วและดูเหมือนว่าตรงตามข้อกำหนด ที่เดียวที่มีความได้เปรียบอย่างไม่เป็นธรรมอยู่ที่ข้อกำหนดของอินพุต ฉันอัปโหลดแล้ว แต่ฉันจะไม่สามารถยอมรับได้ในฐานะผู้ชนะเว้นแต่จะอ่านอินพุต (จากไฟล์เนื่องจากดูเหมือนว่า Matlab ไม่ได้อ่านจาก STDIN)
Gareth

คุณเล็ดรอดSQL_2เข้าไปในตัวอย่างอินพุต ... ดี :)
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]

ความพยายามครั้งแรกในการเขียนโค้ดให้เล็กที่สุด Python ไม่ใช่ภาษาที่ใช้ในการออกแบบเนื่องจากการออกแบบการเยื้องและการขึ้นบรรทัดใหม่ ฉันเลือกที่จะใช้ภาษานี้เป็นหลักเนื่องจากวิธีที่คุณสามารถเล่นกับรายการและสตริงเป็นรายการ ภาษาที่มีการปรับแมทริกซ์ง่ายเหมาะสำหรับงานนี้ แต่น่าเสียดายที่ฉันไม่รู้เลย

ในการทดสอบสิ่งต่าง ๆ จะต้องมีการกำหนดให้เช่น

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

สิ่งที่น่าสนใจหลักในรหัสนี้น่าจะเป็น:

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

ซึ่งเป็นวิธีแฟนซีของการเขียน: "b กลายเป็นรายการของการเป็นตัวแทน (สตริง 25 ตัวอักษร) ของทุกตาราง 5x5 ในการเป็นตัวแทนดั้งเดิม"


แม้ว่า Matlab อาจมีปัญหาในการอ่านจาก STDIN แต่ Python ก็ไม่ได้กลัว การอ่านอินพุตจาก STDIN เป็นหนึ่งในข้อกำหนด (เพื่อให้สามารถรันสคริปต์ทดสอบได้มากเท่าที่จะหยุดผู้คนไม่ให้เข้ามาในรูปแบบอินพุตของตนเอง)
Gareth

อ๊ะพลาดไปโดยสิ้นเชิง
Sumurai8 8

แก้ไขรหัสแล้ว แต่ไม่สามารถทดสอบว่าใช้งานได้จริงหรือไม่ ควรอ่านในรูปแบบเดียวกับที่เคยเป็นมา
Sumurai8

โอเคฉันมีโอกาสที่จะทำการทดสอบในตอนนี้และมีปัญหาสองสามข้อ 1) ในกรณีที่พบซานต้าอินพุตจะถูกส่งออกมาก่อนโซลูชันของคุณ 2) โซลูชันของคุณมีขนาดแตกต่างจากอินพุต ฉันได้พยายามทำให้คำถามชัดเจนขึ้นในจุดนี้ควรเปลี่ยนอักขระที่ไม่ใช่ (ซานต้า, นำเสนอ, กวางเรนเดียร์) ทั้งหมดด้วยช่องว่าง มันเป็นเช่นนี้ในตัวอย่างแรก แต่ไม่ได้ระบุไว้อย่างชัดเจนในคำถาม 3) เมื่อไม่พบซานต้าเอาต์พุตจะมีระยะห่างระหว่างบรรทัดสองเท่า
Gareth

0

ควรมีซานตาในไฟล์เดียว (หากมากกว่า 2 "S" ฉันต้องอัปเดตรหัส)

ใช้ 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
                }
           }
    }

เรียกใช้คำสั่ง awk ดังนี้

awk -f santa.awk file

ผลลัพธ์

found Santa



     R
    R R
    PS
    RR
    R  R

ขออภัยที่ไม่ได้ตรวจสอบเร็วกว่านี้ (ฉันอยู่ในช่วงวันหยุดและไม่สามารถเข้าถึง wifi ได้อย่างง่ายดาย) น่าเสียดายSที่อนุญาตให้2 ใช้ได้ตราบใดที่มีเพียงซานต้าที่ 'ถูกต้อง' เท่านั้น การทดสอบ (มีให้ในคำถาม) มีสองกรณีที่จะล้มเหลวด้วยเหตุผลนี้
Gareth
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.