ปาเป้าพบ Codegolf


11

ฉันคิดว่าทุกคนคุ้นเคยกับปาเป้าบางคนไม่เข้าใจคะแนนดังนั้นสำหรับคนเหล่านี้ที่นี่มีลิงก์ที่มีประโยชน์

คณะกรรมการ

สามารถเปรียบเทียบ dartboard กับการตัดวงกลมใน 20 ชิ้น แต่ละชิ้นแบ่งออกเป็น 4 ส่วน

  • วงแหวนรอบนอกขนาดเล็กที่เรียกว่า double (points x2)
  • แหวนขนาดใหญ่ที่เรียกว่าเดี่ยว (คะแนน x1)
  • วงแหวนขนาดเล็กอีกอันหนึ่งเรียกว่าสามเท่า (คะแนน x3)
  • วงแหวนขนาดใหญ่อีกอันหนึ่งเรียกว่าซิงเกิล (คะแนน x1)

ในช่วงกลางของบอร์ดจะมีวงแหวนเพิ่มอีก 2 อันสีเขียวและสีแดง (บอร์ดแบบคลาสสิก)

  • วงแหวนสีแดงตรงกลางของกระดานเรียกว่าเป้าหรือกระทิงคู่และดีสำหรับ 50 คะแนน อันนี้ถือว่าเป็นสองเท่าและเพราะมันอนุญาตให้เช็คเอาต์กับมัน
  • แหวนสีเขียวที่เรียกว่าวัวกระทิงตัวเดียวหรือเพียงแค่ 25 ตัวและนับเป็นหนึ่งเดียว

ท้าทาย

ค้นหาความเป็นไปได้ในการชำระเงินทั้งหมดที่มี 3 ลูกดอกหรือน้อยกว่า
ผู้ใช้สามารถป้อนจำนวนเต็มและคุณจะต้องตรวจสอบว่าเป็นไปได้ที่จะได้รับคะแนน 0 กับ 3 ลูกดอก (หรือน้อยกว่า)

ตัวอย่าง

ตัวอย่างที่ 1:

Input: 170  
Output: T20, T20, Bullseye

ตัวอย่างที่ 2:

Input: 6  
Output: D3;  
        S3,S1,D1;  
        S2,D2;  
        S2,S2,D1;  
        D2,D1;  
        S4,D1;  
        D1,D1,D1;  
        S1,S1,D2;  
        T1,S1,D1;

ตัวอย่างที่ 3:

Input: 169
Output: No possible checkout!

กฎระเบียบ

  • กฎลูกดอกพื้นฐานคุณต้องจบด้วย double (วงแหวนรอบนอกของกระดานหรือเป้า)
  • ไม่มีการใช้ทรัพยากรภายนอก
  • อนุญาตการเข้ารหัสที่เป็นไปได้อย่างหนัก แต่จำไว้ว่านี่คือ codegolf จะไม่ทำให้รหัสของคุณสั้น;)
  • เซลล์ที่ถูกโจมตีจะปรากฏในรูปแบบ C + N โดยที่ C = T สำหรับ Triple, D สำหรับ double และ S สำหรับ single
    • เป้าสามารถเรียกว่าเป้าหรือ DB, DBull หรือสิ่งที่คล้ายกัน

การชำระเงินที่เป็นไปได้

เพื่อให้คุณเริ่มต้นได้การชำระเงินที่เป็นไปได้สูงสุดคือ 170
ไม่สามารถทำได้ 169,168,166,165,163,162,159 ลูกใน 3 ลูกดอก
เช็คเอาต์ต่ำสุดที่เป็นไปได้คือ 2

นอกจากนี้

นี่ไม่ใช่ข้อกำหนดเพิ่มในความเป็นไปได้ที่จะแสดงเช็คเอาต์ที่เป็นไปได้ทั้งหมดสำหรับคะแนนทั้งหมด โดยพื้นฐานเพราะฉันสงสัยว่ามีความเป็นไปได้ที่จะรวมกันจำนวนมาก: P

ผู้ชนะจะได้รับรหัสที่สั้นที่สุด

การเข้ารหัสที่มีความสุข


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

1
@ PeterTaylor ฉันจะทำให้ชัดเจนมากขึ้นเนื่องจากแหวนสีเขียวและแหวนสีแดงที่อยู่ตรงกลางเรียกว่า Single bull และ bullseye หรือ double bull
Teun Pronk

1
+1 สำหรับคำถามที่ยอดเยี่ยม นี่เป็นปัญหาในโลกแห่งความจริงที่คอมพิวเตอร์แก้ปัญหาได้ดี คุณสามารถขว้าง 6 ใน S2 D1 D1 ซึ่งหายไปจากตัวอย่างของคุณ (มันควรจะมีเว้นแต่คุณจะพิจารณา S2 S2 D1 และ D1 D1 D1 D1 ให้เหมือนกัน แต่พวกเขามีการระบุไว้อย่างชัดเจนแตกต่างกัน) มีบางอย่าง ความคลุมเครือเล็กน้อยเกี่ยวกับรูปแบบผลลัพธ์และการนับผลลัพธ์ที่ฉันจะตอบในคำตอบของฉัน
Level River St

คำตอบ:


2

c ++ 248/228 230/214 ตัวอักษร

การหมุนรอบ 0:

int f(int s){char m[4]="SDT";int t=0;for(int b=2;b<77;b+=1+(b==62)*12)for(int a=2;a<77;a+=1+(a==62)*12){int c=s-a/3*(a%3+1)-b/3*(b%3+1);if(((c+38)/40==1)|(c==50)&&(c%2==0)&(a>=b)){printf("%c%d %c%d D%d\n",m[a%3],a/3,m[b%3],b/3,c/2);t++;}}return t;}

Rev 1. บันทึกตัวละครบางตัวโดยการประกาศตัวแปรทั้งหมดในครั้งเดียวและโดยการกำจัดวงเล็บที่ไม่จำเป็น ปรากฎว่าใน C ++ ทุกตรรกะและ bitwise และ / หรือมีความสำคัญต่ำกว่าการเปรียบเทียบ

int f(int s){char m[4]="SDT";int a,b,c,t=0;for(b=2;b<77;b+=1+(b==62)*12)for(a=2;a<77;a+=1+(a==62)*12){c=s-a/3*(a%3+1)-b/3*(b%3+1);if(c>1&c<41|c==50&&c%2==0&a>=b){printf("%c%d %c%d D%d\n",m[a%3],a/3,m[b%3],b/3,c/2);t++;}}return t;}

ฉันทำหน้าที่มากกว่าโปรแกรมเหมือนที่คนอื่นทำ มันจะคืนค่าความเป็นไปได้ทั้งหมดที่พบ สามารถลดจาก 230 เป็น 214 ตัวอักษรโดยการกำจัดคุณสมบัติการรวม

ตัวอย่างผลลัพธ์คะแนน 6:

ป้อนคำอธิบายรูปภาพที่นี่

ฉันนับลูกดอกลูกที่หนึ่งและสองที่แตกต่างกันเป็นชุดเดียวกันตามที่ OP ได้ทำ (ตัวอย่าง:

T1 S1 D1 = S1 T1 D1) แม้ว่าจะมีราคาเพิ่มอีก 7 ตัวอักษร ฉันมักจะทำรายการคะแนนที่สูงกว่าก่อนเสมอ (ไม่ต้องเพิ่มเป็นสองเท่าและเพิ่มขึ้นสามเท่า) เนื่องจากฉันคิดว่ามันเกี่ยวข้องกับผู้เล่นมากกว่า (ซึ่งอาจเปลี่ยนกลยุทธ์ของเขาถ้าเขาคิดถึงโผแรก) เพราะเหตุผลเดียวกับที่ฉันแสดงรายการปาเป้าตามลำดับ ลูกดอกลูกที่สอง ฉันคิดว่าลูกดอกลูกที่สามนั้นแตกต่างอย่างสิ้นเชิงกับอีกสองลูกดังนั้นฉันจึงพิจารณา D1 D2 และ D2 D1 เป็นกรณีที่แตกต่างกันในขณะที่ OP มีรายการเหล่านั้นเหมือนกัน

ด้วยระบบการนับนี้ฉันได้รับความเป็นไปได้ทั้งหมด 42336 เท่ากับ mmumboss การนับลูกดอกลูกที่หนึ่งและสองที่แตกต่างกันเป็นชุดค่าผสมที่แตกต่างกันซึ่งจะสูงถึง 83349

ฉันไม่ได้ใช้สำหรับวนรอบกับชุดที่คนอื่นทำ (ฉันค่อนข้างใหม่กับ C ++ และฉันก็ไม่รู้ด้วยซ้ำว่ามันเป็นไปได้) แทนที่จะใช้เงื่อนไขในการเพิ่มการวนซ้ำเพื่อข้ามจาก 20 เป็น 25 ฉันใช้ตัวแปรจากลูปเดียวเพื่อเข้ารหัสคะแนนที่เป็นไปได้ทั้งหมดสำหรับโผเดี่ยวเช่นนี้: S1 D1 T1 S2 D2 T2 ฯลฯ พร้อมโมดูลัสและการหารเพื่อถอดรหัส สิ่งนี้ช่วยประหยัดในการใช้คำฟุ่มเฟือยของการประกาศเพิ่มเติมสำหรับลูปแม้ว่ามันจะทำให้การแสดงออกที่ซับซ้อนมากขึ้น

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

เวอร์ชั่นที่ไม่ดี คุณสมบัติอื่น ๆ อีกสองอย่างคือการใช้ตัวดำเนินการ & & && โดยเลือกด้วย | ในลักษณะที่จะให้ลำดับความสำคัญฉันต้องการโดยไม่ต้องวงเล็บ

int f(int s)
{
  char m[4] = "SDT";
  int a,b,c,t=0;
    for (b = 2; b < 77; b += 1 + (b == 62) * 12)
      for (a = 2; a < 77; a += 1 + (a == 62) * 12){
        c = s - a / 3 * (a % 3 + 1) - b / 3 * (b % 3 + 1);
        if (c>1 & c<41 | c == 50 && c % 2 == 0 & a >= b){
          printf("%c%d %c%d D%d\n", m[a % 3], a / 3, m[b % 3], b / 3, c / 2);
          t++;
        }
     }
   return t;
}


4

MATLAB ( 299 249 241 ตัวอักษร)

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

function f(x);u=[1:20 25].';y=[u;2*u; 3*u(1:end-1)];v=combvec([combnk(y,2);[y y];[zeros(62,1) y];[0 0]].',y(22:42).').';v(sum(v,2)==x,:)

ในความพยายามครั้งที่สองการจัดรูปแบบได้รับการปรับปรุงซึ่งแน่นอนว่าเป็นการเพิ่มจำนวนอักขระ:

function f(x);h=.1;u=h+[1:20,25].';y=[u;2*u;3*u(1:20)];v=combvec([combnk(y,2);[y,y];h*ones(62,1),y];[h,h]].',y(22:42).').';t='SDT';r=@fix;strrep(arrayfun(@(x)[t(int8((x-r(x))/h)),num2str(h*r(x)/(x-r(x)))],v(sum(r(v),2)==x,:),'un',0),'S0','')

ปรับปรุงจาก 299 เป็น 249 ตัวอักษรในขณะเดียวกันก็ปรับปรุงรูปแบบเอาต์พุต สำหรับรุ่นที่ปรับปรุงแล้วนี้เอาต์พุตสำหรับกรณีตัวอย่างคือ:

f (170):

'T20'    'T20'    'D25'

f (6):

'S1'    'S3'    'D1'
'S1'    'T1'    'D1'
'S2'    'D1'    'D1'
'S2'    'S2'    'D1'
'D1'    'D1'    'D1'
''      'S4'    'D1'
''      'D2'    'D1'
'S1'    'S1'    'D2'
''      'S2'    'D2'
''      'D1'    'D2'
''      ''      'D3'

f (169):

Empty cell array: 0-by-3

เพิ่มเติม:

จากทักษะการคำนวณของฉันมีความเป็นไปได้ทั้งหมด 42336 รายการที่จะจบเกมปาเป้า


ผลควรจะแสดงสิ่งที่มือถือเพื่อตีดังนั้นในครั้งแรกมันบอกว่าควรจะเป็น60 60 50 T20 T20 Bullseyeฉันจะทำให้ชัดเจนยิ่งขึ้นในคำถาม ที่ดีแม้ว่าจะเกือบมี :)
Teun Pronk

1
ใช่ฉันชี้ให้เห็นแล้วว่าตัวเอง นี่เป็นความพยายามครั้งแรกที่ยังไม่เสร็จ ;)
mmumboss

โอ๊ะขอโทษนะครับ, ผมจะอยากรู้อยากเห็นเกี่ยวกับรหัสและผลผมไม่ได้อ่านเรื่องราวข้างต้น xD
Teun Pronk

ควรจะดีกว่านี้ สิ่งเดียวที่ฉันคิดได้ก็คือวัวยังคงแสดงเป็น 25 แต่ฉันหวังว่ามันจะโอเคไม่เช่นนั้นจะไม่มีความเป็นไปได้อื่นนอกจากรหัสยากซึ่งมันไม่สนุก
mmumboss

วัวตัวผู้ที่อายุ 25 ปีเป็นที่ยอมรับมันเป็นหนทางเดียวที่คุณสามารถโยน 25 ลูกดอกดาร์ท 1 ลูกได้
Teun Pronk

2

ทับทิม (260 ตัวอักษร)

"ชิ้นสุดท้ายควรเป็นสองเท่า" เป็นชิ้นส่วนที่ขาดหายไป - ไม่สามารถเข้าใจได้ว่าทำไม 168 จึงไม่ได้ผลลัพธ์ ... :

c=->n,d=3{d=d-1;r=[];n==0?[r]:(d>=0&&n>0?(o='0SDT';((1..20).map{|p|(1..3).map{|h|c.(n-p*h,d).map{|m|r<<["#{o[h]}#{p}"]+m}}};c.(n-50,d).map{|m|r<<['DB']+m};c.(n-25,d).map{|m|r<<[?B]+m})):1;r.select{|*i,j|j[?D]}.tap{|x|d!=2?1:puts(x.map{|i|"#{i.join(?,)};"})})}

ค. (170)

T20,T20,DB;

ค. (6)

S1,S1,D2;
S1,T1,D1;
S1,S3,D1;
D1,D1,D1;
D1,S2,D1;
D1,D2;
T1,S1,D1;
S2,D1,D1;
S2,S2,D1;
S2,D2;
D2,D1;
S3,S1,D1;
D3;
S4,D1;

1

Python 2.7 (270 ตัวอักษร)

ไม่แน่ใจว่าหลามจะอนุญาตให้มีหนึ่งซับ แต่เขาอยู่ในสาม

def f(n):
 a={'%s%s'%('0SDT'[i],n):n*i for n in range(1,21)+[25] for i in [1,2,3] if n*i<75};a['']=0
 for r in [' '.join(h[:3]) for h in [(x,y,z,a[x]+a[y]+a[z]) for x in a for y in a for z in {k:a[k] for k in a if 'D' in k}] if h[3]==n and len(h[0])<=len(h[1])]:print r

หรือ 278+ ตัวอักษรที่มีข้อความ 'ไม่ชำระเงิน' ที่เหมาะสม (เช่น 290 ที่นี่):

def f(n):
 a={'%s%s'%('0SDT'[i],n):n*i for n in range(1,21)+[25] for i in [1,2,3] if n*i<75};a['']=0;
 for r in [' '.join(h[:3]) for h in [(x,y,z,a[x]+a[y]+a[z]) for x in a for y in a for z in {k:a[k] for k in a if 'D' in k}] if h[3]==n and len(h[0])<=len(h[1])] or ['No Checkout']:print r

ไปเลย:

f (170)

T20 T20 D25

f (6)

S3 S1 D1
S2 S2 D1
S2 D1 D1
S1 S3 D1
S1 S1 D2
S1 T1 D1
 S2 D2
 S4 D1
  D3
 D2 D1
 D1 D2
T1 S1 D1
D1 S2 D1
D1 D1 D1

f (169)

No Checkout

สิ่งที่ฉันไม่พอใจ:

for x in a for y in a for z in

นี่คือมากกว่า 10% ของทั้งหมด มีวิธีที่กะทัดรัดกว่าโดยไม่มี itertools ฯลฯ

and len(h[0])<=len(h[1])

ใช้เพื่อป้องกันการซ้ำซ้อนในกรณีที่โผสองจบ (เช่น ['', 'S1', 'D1'] และ ['S1', '', 'D1']) ฉันเห็นว่ามีความสำคัญ (เฮ้ - โผสุดท้ายจะต้องเป็นสองเท่าดังนั้นจึงมีคำสั่งอย่างชัดเจน) แต่การไม่โยนเป็นกรณีพิเศษ


1

05AB1E , 43 ไบต์

20L25ª3Lâ¨Ðʒθ<}Uã«XâXìε˜2ô}ʒPOQ}εε`…TSDsèì

ค่อนข้างช้า .. เอาท์พุทเป็นรายการของรายการหรือรายการว่างเปล่าหากไม่สามารถเสร็จสิ้นได้ บูลส์ของฉันคือS25และD25; หากไม่ได้รับอนุญาตฉันสามารถเปลี่ยนได้

ลองใช้แบบออนไลน์หรือตรวจสอบกรณีทดสอบสองสามรายการพร้อมกัน

คำอธิบาย:

มีสองขั้นตอนดังนี้

1) สร้างรายการปาเป้าเดี่ยวคู่และทริปเปิลที่เป็นไปได้ทั้งหมด:

20L         # Create a list in the range [1,20]
   25ª      # Append 25 to this list
      3L    # Create a list in the range [1,3]
        â   # Create all possible pairs of these two lists
         ¨  # Remove the last pair (which is the Triple Bull)
            # Now we have a list of all possible darts:
            #  [[1,1],[1,2],[1,3],[2,1],...,[20,3],[25,1],[25,2]]

2) รับผลสำเร็จที่เป็นไปได้ทั้งหมด (ลงท้ายด้วย double) มากถึง 3 ปาเป้า:

Ð           # Triplicate this list
 ʒ  }       # Filter the top copy by:
  θ         #  Where the last value
   <        #  Decremented by 1 is truthy (==1), so all doubles
     U      # Pop this filtered list of doubles, and store it in variable `X`
 ã          # Create all possible pairs of the list of darts with itself
  «         # Merge it with the list of darts
            # We now have a list containing all possible variations for 1 or 2 darts
 Xâ         # Then create all possible pairs of these with the doubles from variable `X`
   Xì       # And prepend the doubles themselves as well
            # Now we have all possible variations of 1 double; 1 dart + 1 double;
            # or 2 darts + 1 double
     ε   }  # Map each to:
      ˜     #  Deep-flatten the list
       2ô   #  And split it into parts of size 2
            #  (this is to convert for example a 2 darts + 1 double from
            #   [[[20,3],[5,1]],[1,2]] to [[20,3],[5,1],[1,2]])
            # Now we have a list of all possible finishers of up to 3 darts

3) เก็บเฉพาะคะแนนรวมที่เท่ากับจำนวนเต็ม:

ʒ   }       # Filter this list by:
 P          #  Get the product of each inner-most lists
            #   i.e. [[20,3],[5,1],[1,2]] → [60,5,2]
  O         #  Take the sum of those
            #   i.e. [60,5,2] → 67
   Q        #  Check if this value is equal to the (implicit) input-integer
            # Now we only have the finishers left with a total value equal to the input

4) แปลงข้อมูลเป็นรายการผลลัพธ์ที่พิมพ์สวย (เช่น[[20,3],[5,1],[1,2]]กลายเป็น["T20","S5","D2"]):

ε           # Map each of the remaining finishers of up to 3 darts to:
 ε          #  Map each inner list to:
  `         #   Push both values separately to the stack ([20,3] → 20 and 3)
   TSD     #   Push string "TSD"
       s    #   Swap to get the integer for single/double/triple at the top of the stack
        è   #   Use it to index into the string
            #   NOTE: 05AB1E has 0-based indexing with automatic wraparound,
            #   so the triple 3 will wrap around to index 0 for character "T"
         ì  #   Prepend this character in front of the dart-value
            # (after which the result is output implicitly as result)

0

Kotlinขนาด 254 ไบต์

หมายเหตุ: algorythm ขึ้นอยู่กับคำตอบ C ++ ของ Level River St

{s:Int->val m="SDT"
var c=0
val r=(2..62).toList()+listOf(75,76)
for(t in r)for(o in r){val l=s-o/3*(o%3+1)-t/3*(t%3+1)
if((l>1&&l<41||l==50)&&l%2==0&&o>=t){println("${m[o%3]}${o/3},${m[t%3]}${t/3},D${l/2}")
c++}}
if(c<1)println("No possible checkout!")}

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.