ทำคะแนนเกมโหลดป้องกันและยิง


11

สมัยที่ฉันยังเด็กฉันเคยเล่นเกมนี้บ่อยครั้งมาก

กฎระเบียบ

มีผู้เล่นสองคน (เรียกพวกเขาว่า A และ B) และผู้เล่นแต่ละคนใช้มือของเขาเป็นปืน มีการเคลื่อนไหวที่เป็นไปได้สามประการ:

  1. ยกมือขึ้นเพื่อโหลดกระสุนใส่ปืนของคุณ

    ปืนแต่ละกระบอกเริ่มว่างเปล่า การโหลดจะเพิ่มกระสุนหนึ่งนัด

  2. มือชี้ไปที่ผู้เล่นอื่นเพื่อยิง

    สิ่งนี้จะลดปริมาณกระสุนทีละอัน คุณต้องมีกระสุนอย่างน้อยหนึ่งหน่วยในการยิง

  3. ไขว้แขนเพื่อป้องกันตัวเองจากการถูกยิง

ผู้เล่นทั้งสองเคลื่อนไหวพร้อมกัน หากผู้เล่นทั้งสองยิงพร้อมกันกระสุนนัดต่อกันและเกมจะดำเนินต่อไป เกมจะจบลงเมื่อผู้เล่นคนหนึ่งยิงขณะที่อีกคนกำลังโหลดกระสุน

การถ่ายภาพและปืนที่ว่างเปล่าถือว่าโกง หากผู้เล่นโกงในขณะที่อีกคนหนึ่งดำเนินการทางกฎหมายคนโกงจะสูญเสียทันที หากผู้เล่นทั้งคู่โกงในเวลาเดียวกันเกมจะดำเนินต่อไป

ความพยายามในการโกงไม่ลดกระสุนดังนั้นมันจึงไม่มีทางเป็นไปได้

ท้าทาย

จากการเคลื่อนไหวของผู้เล่น A และ B ผลลัพธ์ที่ผู้เล่นชนะในเกม: 1สำหรับผู้เล่น A -1สำหรับผู้เล่น B และ0เพื่อเสมอ คุณสามารถใช้ค่าตอบแทนสามเท่าอื่น ๆ ได้ แต่คุณต้องระบุคำตอบที่คุณใช้

เกมอาจ:

  • จบโดยไม่ต้องดำเนินการเคลื่อนไหวทั้งหมด;
  • ไม่ได้จบลงด้วยการเคลื่อนไหวที่กำหนดและดังนั้นจึงถือเป็นการจับสลาก

อินพุตสามารถนำมาได้:

  • เป็นสตริง
  • เป็นอาร์เรย์ / รายการจำนวนเต็ม
  • ในวิธีอื่นใดที่ไม่ได้ประมวลผลอินพุตล่วงหน้า

อนุญาตให้ใช้โปรแกรมหรือฟังก์ชั่นเต็มรูปแบบ ตั้งแต่นี้เป็นคำตอบสั้นที่สุดในไบต์ชนะ!

กรณีทดสอบ

A: "123331123"
B: "131122332"
    -----^                Player B shoots player A and wins.

Output: -1
A: "111322213312"
B: "131332221133"
    -------^              Player B cheats and loses.

Output: 1
A: "1333211232221"
B: "1213211322221"
    ----------^^          Both players cheat at the same time. The game continues.

Output: 0
A: "12333213112222212"
B: "13122213312232211"
         |       || ^---- Player A shoots player B and wins.
         ^-------^^------ Both players cheat at the same time. The game continues.

Output: 1

1
KotH ที่เกี่ยวข้อง (น่าสนใจฉันไม่เคยเล่นเกมนี้มาก่อนฉันคิดว่าคำถามที่เชื่อมโยงได้รับแรงบันดาลใจจากเพื่อนที่มี แต่เมื่อนานมาแล้วที่ฉันจำไม่ได้อีกแล้ว)
Doorknob

คำตอบ:


6

เยลลี่33 32 24 ไบต์

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ

พิมพ์นี้5แทน-1และ7แทน1 ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

Zæ%1.»0$+¥\>-‘żZḅ3Ff5,7Ḣ  Main link. Argument: A (digit list array)

Z                         Zip; group corresponding digits.
 æ%1.                     Map the digits in (-1.5, 1.5].
                          This replaces [1, 2, 3] with [1, -1, 0].
          \               Cumulatively reduce the pairs by doing the following.
     »0$                    Take the maximum of the left value and 0, i.e., replace
                            a -1 with a 0.
        +¥                  Add the modified left value to the right value.
                          This computes the available ammo after each action. An
                          ammo of -1 indicates a cheating attempt.
           >-             Compare the results with -1.
             ‘            Increment. And unilateral cheating attempt is now [1, 2]
                          or [2, 1], where 1 signals the cheater and 2 the winner.
              żZ          Pair each result with the corr., original digits.
                ḅ3        Convert each pair from base 3 to integer.
                          This maps [1, 2] and [2, 1] to 5 and 7.
                  F       Flatten the resulting, nested list.
                   f5,7   Discard all but 5's and 7's.
                       Ḣ  Grab the first element (5 or 7).
                          If the list is empty, this returns 0.

2

Pyth, 48 46 49 47 ไบต์

.xhfT|M.e,-FmgF.b/<dhkY2S2Q?}b_BS2-FbZ.b,NYCQ)0

ลองที่นี่!

ขอบคุณ @isaacg สำหรับการบันทึก2 4 ไบต์!

รับอินพุตเป็น 2-tuple พร้อมกับรายการการเคลื่อนไหวของผู้เล่น A ลำดับแรกและการเคลื่อนไหวของผู้เล่น B วินาที การส่งออกเป็นเช่นเดียวกับในความท้าทาย

คำอธิบาย

ภาพรวมสั้น ๆ

  • ครั้งแรกที่เราจัดกลุ่มการเคลื่อนไหวของผู้เล่นทั้งสองเข้าด้วยกันดังนั้นเราจึงได้รับรายชื่อของ 2-tuples
  • จากนั้นเราจับคู่แต่ละ tuples กับอีก 2 tuple ในรูปแบบที่[cheating win, fair win]มีค่าที่เป็นไปได้-1, 0, 1สำหรับแต่ละรายการเพื่อระบุว่าผู้เล่นชนะที่จุดนี้ ( -1, 1) หรือถ้าเกมดำเนินต่อไป ( 0)
  • ตอนนี้เราแค่ต้องได้รับอันดับแรกซึ่งไม่ใช่[0,0]และใช้องค์ประกอบที่ไม่ใช่ศูนย์แรกของมันซึ่งบ่งชี้ผู้ชนะ

การวิเคราะห์รหัส

.xhfT | Me, -FmgF.b / <dhkY2S2Q?} b_BS2-FbZ.b, NYCQ) 0 # Q = รายการของรายการย้าย

                                      .b, NYCQ # จับคู่องค์ประกอบของทั้งสองรายการอินพุต
       .e # map ในรายการคู่ด้วย 
                                                 # b เป็นคู่และ k เป็นดัชนี
            m Q # แผนที่แต่ละรายการเคลื่อนไหว d
               .b 2S2 # แผนที่บน [1,2] ฉันไม่สามารถใช้ m ได้เพราะมัน
                                                 # lambda ตัวแปรขัดแย้งกับหนึ่งจาก. e
                  <dhk # d [: k + 1]
                 / Y # นับปรากฏเป็น 1 หรือ 2 ในรายการนี้
          -F # (จำนวน 1 วินาที) - (จำนวน 2 วินาที) หมายถึงการชนะการโกง
                           ?} b_BS2 # ถ้า b คือ (1,2) หรือ (2,1)
                                  -Fb # รับความแตกต่างแสดงถึงการชนะอย่างยุติธรรม
                                     Z # else 0 ยังไม่มีผู้ชนะ
         , # จับคู่ค่า 2 ค่าเหล่านั้น
     | M # สำหรับคู่ที่เกิดขึ้นให้จับคู่แรกถ้า
                                                 # มันไม่เป็นศูนย์มิฉะนั้นอย่างที่สอง
   fT # กรองค่าศูนย์ทั้งหมดออก
.xh # ลองใช้ค่าแรกซึ่งระบุผู้ชนะ
                                             ) 0 # ถ้าเป็นไปไม่ได้เพราะรายการว่างเปล่า
                                                 # เอาต์พุตศูนย์เพื่อบ่งชี้ถึงการจับสลาก

m|Fd|Mเป็นเช่นเดียวกับ
isaacg

@isaacg ขอบคุณ! ฉันมักจะลืมว่าMมันก็เป็นเหมือนกัน Btw: ปัญหาเกี่ยวกับตัวแปรแลมบ์ดาที่เรากล่าวถึงในการแชททำให้ฉันต้องเสียค่าใช้จ่ายหลายไบต์ที่นี่: P
Denker

,1 2เป็นเช่นเดียวกับS2
isaacg

ฉันได้เพิ่ม testcase อื่น)
ลบ

@isaacg ขอบคุณอีกครั้ง! ไม่รู้ว่าฉันจะทำยังไง
Denker

1

Python ขนาด 217 ไบต์

def f(A,B):
 x=y=0;c=[-1,1,0]
 for i in range(len(A)):
  a=A[i];b=B[i]
  for s in[0,1]:
   if(a,b)==(2,1):return c[s]*c[x<1]
   if(a,b)==(2,3)and x<1:return-c[s]
   x-=c[a-1];x+=x<0;a,b,x,y=b,a,y,x
 return 0

คำอธิบาย : ใช้ A และ B เป็นรายการจำนวนเต็ม เพียงแค่ผ่านการเคลื่อนไหวแต่ละคู่เพิ่มหรือลบ 1 ถ้าจำเป็นและส่งกลับเมื่อมีคนโกงหรือชนะ ทำสิ่งเดียวกันสองครั้งโดยใช้ห่วงอีกครั้งหนึ่งครั้งสำหรับการเคลื่อนไหวของ A และอีกครั้งสำหรับการเคลื่อนไหวของ B เพิ่ม 1 ถ้า x ไปต่ำกว่า 0 ถึง -1


1

Java, 226 212 200 196 194 ไบต์

-14 ไบต์โดยตรรกะการสั่งซื้อใหม่

-12 ไบต์ขอบคุณMr. Public ที่ชี้ให้เห็นว่าจะใช้การดำเนินการแบบไตรภาคสำหรับตรรกะการถ่ายภาพได้อย่างไร

-4 ไบต์โดยการยัดเยียดตรรกะการโหลดลงในหนึ่งการลัดวงจรถ้า

-2 ไบต์เพราะ==1=== <2เมื่อป้อนข้อมูลเท่านั้นสามารถ1, 2,3

(a,b)->{for(int m=0,n=0,w,v,r=0,i=0,x;i<a.length;){w=a[i];v=b[i++];x=w==2?m<1?r--:m--:0;x=v==2?n<1?r++:n--:0;if(r!=0)return r;if(w<2&&++m>0&v==2)return -1;if(v<2&&++n>0&w==2)return 1;}return 0;}

การใช้งานและเวอร์ชันที่เยื้อง:

static BiFunction<Integer[], Integer[], Integer> game = (a,b) -> {
    for(int m=0,n=0,w,v,r=0,i=0,x;i<a.length;) {
        w=a[i];v=b[i++];
        // shoot
        x=w==2?m<1?r--:m--:0;
        x=v==2?n<1?r++:n--:0;
        if(r!=0)return r;
        // load
        if(w<2&&++m>0&v==2)return -1;
        if(v<2&&++n>0&w==2)return 1;
    }
    return 0;
};

public static void main(String[] args) {
    System.out.println(game.apply(new Integer[] {1,2,3,3,3,1,1,2,3}, new Integer[] {1,3,1,1,2,2,3,3,2}));
    System.out.println(game.apply(new Integer[] {1,1,1,3,2,2,2,1,3,3,1,2}, new Integer[] {1,3,1,3,3,2,2,2,1,1,3,3}));
    System.out.println(game.apply(new Integer[] {1,3,3,3,2,1,1,2,3,2,2,2,1}, new Integer[] {1,2,1,3,2,1,1,3,2,2,2,2,1}));
}

การใช้กฎของเกมไม่ซับซ้อนอีกต่อไป แต่ก็ง่าย แต่ละรอบทำการดำเนินการเหล่านี้:

  • โหลดย้ายไปยังตัวแปรชั่วคราว
  • หากผู้เล่นยิง
    • ปราศจากกระสุน: อคติโกงrต่อการสูญเสีย
    • ด้วยกระสุน: กระสุนลดลง
  • ถ้าโกงrไม่ได้0ส่งคืนค่าเพราะมีคนโกง
  • หากผู้เล่นโหลดซ้ำ
    • กระสุนที่เพิ่มขึ้น
    • หากผู้เล่นอื่นยิงกลับมาขาดทุน

x เป็นตัวแปรดัมมี่ที่ใช้สร้างคอมไพเลอร์ให้ฉันใช้นิพจน์ประกอบไปด้วย

เดี๋ยวก่อน Java นั้นสั้นกว่า Python ใช่ไหม


ฉันได้เพิ่ม testcase อื่น)
ลบ

1
@ WashingtontonGuedes และฉันทำงานในกรณีนี้ขอบคุณตรรกะของฉันสั่งใหม่!
CAD97

ifs สามารถทำเป็น ternarys ได้หรือไม่? เช่นw==2&&m<1?r--:m++
Downgoat

@Downgoat สิ่งอื่นก็อยู่ข้างในถ้าเป็นอย่างที่คุณเขียนมันในระดับอุดมศึกษาจะไม่ทำงาน อย่างไรก็ตามฉันอาจทำเช่นนั้นกับภายในถ้า ฉันจะทดสอบเมื่อมีโอกาส
CAD97

1
@ CAD97 @Downgoat จริง ๆ แล้วคุณสามารถใช้ตัวดำเนินการประกอบสำหรับคำสั่ง if สำหรับไตรภาคแรกint x=w==2?m<1?r--:r:m--;จากนั้นใช้ x (เช่นนี้เป็นเพียงตัวแปรจำลองเพื่อให้ประกอบไปด้วยไตรภาค) เช่นx=v==2?n<1?r++:r:n--;
Mr Public
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.