Phi tiêu gặp Codegolf


11

Tôi nghĩ mọi người đều quen thuộc với phi tiêu, một số người không hiểu điểm số vì vậy đối với những người ở đây là một liên kết hữu ích về điều đó.

Hội đồng quản trị

Một phi tiêu có thể được so sánh với một chiếc bánh cắt thành 20 miếng. Mỗi mảnh được chia thành 4 phần.

  • một vòng ngoài nhỏ gọi là double (điểm x2)
  • một vòng lớn gọi là đơn (điểm x1)
  • một vòng nhỏ khác gọi là triple (điểm x3)
  • một vòng lớn khác gọi là đơn (điểm x1)

Ở giữa bảng là 2 vòng nữa, một vòng xanh và đỏ (bảng cổ điển)

  • Nhẫn đỏ, trung tâm của bảng gọi là bullseye hoặc double bull và tốt cho 50 điểm. Cái này được tính là gấp đôi và vì nó được phép thanh toán với nó.
  • Vòng màu xanh lá cây, được gọi là bò đực, bò đực đơn giản hoặc đơn giản là 25 và được tính là một con duy nhất.

Thử thách

Tìm tất cả các khả năng thanh toán với 3 phi tiêu hoặc ít hơn.
Người dùng có thể nhập một số nguyên và bạn sẽ phải kiểm tra xem có thể lấy điểm thành 0 bằng 3 phi tiêu (hoặc ít hơn).

Ví dụ

ví dụ 1:

Input: 170  
Output: T20, T20, Bullseye

Ví dụ 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;

Ví dụ 3:

Input: 169
Output: No possible checkout!

Quy tắc

  • Quy tắc phi tiêu cơ bản, bạn phải kết thúc bằng một đôi (vòng ngoài của bảng hoặc bullseye)
  • Không sử dụng các nguồn lực bên ngoài.
  • Mã hóa cứng của thanh toán có thể được cho phép nhưng hãy nhớ đây là codegolf, nó sẽ không khiến mã của bạn bị thiếu;)
  • Các ô cần nhấn sẽ được hiển thị ở định dạng C + N trong đó C = T cho Triple, D cho double và S cho đơn.
    • bullseye có thể được gọi là bullseye hoặc DB, DBull hoặc một cái gì đó tương tự.

Kiểm tra có thể

Để giúp bạn bắt đầu, kiểm tra cao nhất có thể là 170.
169,168,166,165,163,162,159 không thể thực hiện được trong 3 phi tiêu.
Thanh toán thấp nhất có thể là 2.

Ngoài ra

Đây không phải là một yêu cầu, thêm vào một khả năng để hiển thị tất cả các kiểm tra có thể cho tất cả các điểm. Về cơ bản vì tôi tự hỏi có bao nhiêu kết hợp có thể: P

Người chiến thắng sẽ là người có mã ngắn nhất.

Chúc mừng mã hóa.


1
Quy tắc được liệt kê đầu tiên là không chính xác (và làm mất hiệu lực ví dụ đầu tiên) bởi vì bạn cũng có thể hoàn thành trên một con bò. Sẽ rất hữu ích khi làm rõ liệu bạn đang mong đợi một chương trình, chức năng hay cả hai; và có bao nhiêu tính linh hoạt trong định dạng đầu ra.
Peter Taylor

1
@PeterTaylor Tôi sẽ làm rõ hơn điều này, vì vòng màu xanh lá cây và vòng màu đỏ ở giữa được gọi là Single bull và bullseye hoặc double bull.
Teun Pronk

1
+1 cho câu hỏi xuất sắc. Đây là loại vấn đề trong thế giới thực mà máy tính rất giỏi giải quyết. Bạn có thể ném 6 trong S2 D1 D1, thiếu từ đầu ra ví dụ của bạn (nó sẽ ở đó, trừ khi bạn coi S2 S2 D1 và D1 D1 D1 giống nhau, nhưng chúng được liệt kê rõ ràng là khác nhau.) Có một số sự mơ hồ nhỏ về định dạng đầu ra và đếm kết quả mà tôi sẽ giải quyết trong câu trả lời của mình.
Cấp sông St

Câu trả lời:


2

C ++ 248/228 230/214 ký tự

Rev 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. Đã lưu một số ký tự bằng cách khai báo tất cả các biến cùng một lúc và bằng cách loại bỏ các dấu ngoặc không cần thiết. Nó chỉ ra rằng trong C ++, tất cả logic và bitwise và / hoặc có độ ưu tiên thấp hơn so với so sánh.

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

Tôi đã làm một chức năng chứ không phải là chương trình, như những người khác đã làm. Nó trả về tổng số khả năng tìm thấy. Nó có thể được giảm từ 230 xuống còn 214 ký tự bằng cách loại bỏ tính năng tổng cộng.

Sản lượng mẫu, điểm 6:

nhập mô tả hình ảnh ở đây

Tôi đếm các phi tiêu thứ nhất và thứ hai khác nhau là cùng một tổ hợp, như OP đã làm (ví dụ:

T1 S1 D1 = S1 T1 D1) mặc dù điều này tốn thêm 7 ký tự. Tôi luôn liệt kê số điểm cao hơn trước (bỏ qua nhân đôi và trebling) vì tôi cho rằng điều này phù hợp hơn với người chơi (người có thể thay đổi chiến lược của mình nếu anh ta bỏ lỡ với phi tiêu đầu tiên.) Với cùng lý do tôi liệt kê các phi tiêu theo thứ tự phi tiêu thứ hai. Tôi coi phi tiêu thứ 3 hoàn toàn khác với hai phi tiêu kia, do đó tôi coi D1 D2 và D2 ​​D1 là các trường hợp khác nhau trong khi OP có chúng được liệt kê là giống nhau.

Với hệ thống đếm này, tôi nhận được tổng cộng 42336 , giống như mmumboss. Đếm các phi tiêu thứ nhất và thứ hai khác nhau như các kết hợp khác nhau, con số này lên tới 83349.

Tôi đã không sử dụng vòng lặp for với các bộ như những người khác đã làm (Tôi khá mới đối với C ++ và tôi thậm chí không biết nếu có thể.) Thay vào đó tôi lạm dụng một điều kiện trong gia số vòng lặp để nhảy từ 20 lên 25 . Tôi sử dụng biến từ một vòng lặp duy nhất để mã hóa tất cả các điểm có thể cho một phi tiêu duy nhất, như thế này: S1 D1 T1 S2 D2 T2, v.v. với mô đun và phép chia để giải mã. Điều này tiết kiệm tính chi tiết của việc khai báo nhiều hơn cho các vòng lặp, mặc dù nó làm cho các biểu thức phức tạp hơn.

Kết quả của việc này là một phi tiêu không được sử dụng được hiển thị là T0, nhưng tôi nghĩ nó rõ ràng có nghĩa là gì, đặc biệt là (bằng cách xem các phi tiêu thứ nhất và thứ hai khác nhau như một sự kết hợp) ngay từ đầu tôi đã có thể nhóm chúng lại với nhau đầu ra của tôi.

Phiên bản Ungolfed ở đây. Một vài tính năng khác được sử dụng các toán tử & và && có chọn lọc với | theo cách để đưa ra thứ tự ưu tiên mà tôi muốn mà không có dấu ngoặc.

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 ký tự)

Đây là lần chơi golf nghiêm túc đầu tiên của tôi. Nỗ lực đầu tiên của tôi (136 ký tự) cho kết quả chính xác, nhưng không phải với định dạng chính xác. Nó cung cấp cho tất cả các khả năng nhìn vào số điểm cho mỗi phi tiêu. Điều này có nghĩa là 20 và đôi 10 đơn có một mục riêng biệt, tuy nhiên, cả hai đều được hiển thị là 20. Tất nhiên phi tiêu cuối cùng luôn luôn là một đôi.

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,:)

Trong lần thử thứ hai, định dạng được cải thiện, điều này tất nhiên đã tăng số lượng ký tự:

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','')

Cải thiện từ 299 đến 249 ký tự, đồng thời cải thiện định dạng đầu ra. Đối với phiên bản cải tiến này, đầu ra cho các trường hợp ví dụ là:

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

Bổ sung:

Theo kỹ năng tính toán của tôi, có tổng cộng 42336 khả năng để kết thúc trò chơi phi tiêu.


Kết quả sẽ hiển thị những gì tế bào để đánh, vì vậy trong lần đầu tiên nó 60 60 50nên được T20 T20 Bullseye. Tôi sẽ làm cho điều này rõ ràng hơn trong câu hỏi. Mặc dù rất vui, gần như vậy :)
Teun Pronk

1
Vâng, tôi đã chỉ ra rằng bản thân mình. Đây là nỗ lực dang dở đầu tiên. ;)
mmumboss

Rất tiếc, tôi đã tò mò về mã và kết quả là tôi đã không đọc câu chuyện trên xD
Teun Pronk

Điều này nên được tốt hơn. Điều duy nhất tôi có thể nghĩ là con bò đực vẫn được hiển thị là 25. Nhưng tôi hy vọng điều này là ổn, vì nếu không thì không có khả năng nào khác ngoài việc mã cứng này, điều này đơn giản là không vui.
mmumboss

Con bò đực đơn lẻ 25 là thực sự chấp nhận được, đó là cách duy nhất bạn có thể ném 25 với 1 phi tiêu bằng mọi cách
Teun Pronk

2

Ruby (260 ký tự)

"Cái cuối cùng nên là một đôi" là phần còn thiếu - không thể hiểu tại sao 168 không nên có kết quả ...:

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(?,)};"})})}

c. (170)

T20,T20,DB;

C 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 ký tự)

Không chắc chắn con trăn sẽ cho phép một lớp lót, nhưng nó là ba.

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

Hoặc hơn 278 ký tự với thông báo 'Không thanh toán' thích hợp (ví dụ: 290 tại đây):

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

Ở đây chúng tôi đi:

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

Những điều tôi không hài lòng với:

for x in a for y in a for z in

Đây là hơn 10% trong tổng số. Có một cách nhỏ gọn hơn mà không có itertools vv?

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

Điều này được sử dụng để ngăn ngừa trùng lặp trong trường hợp kết thúc hai phi tiêu (ví dụ: ['', 'S1', 'D1'] và ['S1', '', 'D1']). Tôi coi thứ tự là vấn đề (hey - phi tiêu cuối cùng phải là một đôi, vì vậy rõ ràng thứ tự vấn đề), nhưng ném không là một trường hợp đặc biệt.


1

05AB1E , 43 byte

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

Khá chậm .. Kết quả là một danh sách các danh sách hoặc một danh sách trống nếu không có kết thúc nào là có thể. Những con bò của tôi là S25D25; Nếu điều này không được phép, tôi có thể thay đổi nó.

Hãy thử trực tuyến hoặc xác minh một vài trường hợp thử nghiệm cùng một lúc .

Giải trình:

Có một vài bước:

1) Tạo một danh sách tất cả các phi tiêu đơn, đôi và ba có thể:

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) Nhận tất cả các kết thúc có thể (kết thúc bằng một cú đúp) tối đa 3 phi tiêu:

Ð           # 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) Chỉ giữ những số có tổng điểm bằng số nguyên đầu vào:

ʒ   }       # 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) Chuyển đổi dữ liệu sang danh sách kết quả được in đẹp (nghĩa là [[20,3],[5,1],[1,2]]trở thành ["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 byte

Lưu ý: đại số dựa trên câu trả lời C ++ của 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!")}

Hãy thử trực tuyến!

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.