Anak panah bertemu Codegolf

11

Saya pikir semua orang terbiasa dengan panah, beberapa orang tidak mengerti nilainya jadi bagi orang-orang di sini adalah tautan yang bermanfaat.

Papan

Papan dart dapat dibandingkan dengan potongan pai dalam 20 potong. Setiap bagian dibagi dalam 4 bagian.

  • cincin luar kecil yang disebut ganda (poin x2)
  • cincin besar yang disebut tunggal (poin x1)
  • cincin kecil lain yang disebut triple (poin x3)
  • cincin besar lain yang disebut tunggal (poin x1)

Di tengah papan ada 2 cincin lagi, yang hijau dan merah (papan klasik)

  • Cincin merah, tengah papan disebut bullseye atau double bull dan bagus untuk 50 poin. Yang ini dianggap sebagai dobel dan karena itu diperbolehkan untuk checkout dengannya.
  • Cincin hijau, disebut banteng, banteng tunggal atau hanya 25 dan dianggap sebagai satu.

Tantangan

Temukan semua kemungkinan checkout dengan 3 anak panah atau kurang.
Pengguna dapat memasukkan bilangan bulat dan Anda harus memeriksa apakah mungkin untuk mendapatkan skor 0 dengan 3 anak panah (atau lebih sedikit).

Contohnya

Contoh 1:

Input: 170  
Output: T20, T20, Bullseye

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

Contoh 3:

Input: 169
Output: No possible checkout!

Aturan

  • Aturan panah dasar, Anda harus mengakhiri dengan dobel (cincin luar papan atau bullseye)
  • Tidak menggunakan sumber daya eksternal.
  • Pengodean keras dari kemungkinan checkout diperbolehkan tetapi ingat ini adalah codegolf, itu tidak akan membuat kode Anda pendek;)
  • Sel yang dipukul akan ditampilkan dalam format C + N di mana C = T untuk Triple, D untuk double dan S untuk single.
    • Bullseye dapat disebut Bullseye atau DB, DBull atau sesuatu yang serupa.

Kemungkinan checkout

Untuk memulainya, checkout tertinggi yang mungkin adalah 170.
169.168.166.165.163.162.159 tidak dimungkinkan dalam 3 anak panah.
Checkout serendah mungkin adalah 2.

Tambahan

Ini bukan persyaratan, tambahkan kemungkinan untuk menampilkan semua kemungkinan checkout untuk semua skor. Pada dasarnya karena saya bertanya-tanya berapa banyak kombinasi yang mungkin: P

Pemenang akan menjadi orang dengan kode terpendek.

Selamat coding.

Teun Pronk
sumber
1
Aturan yang tercantum pertama tidak benar (dan membatalkan contoh pertama) karena Anda juga bisa menyelesaikan bull. Akan sangat membantu untuk memperjelas apakah Anda mengharapkan suatu program, fungsi, atau keduanya; dan seberapa banyak fleksibilitas yang ada dalam format output.
Peter Taylor
1
@PeterTaylor Saya akan membuat ini lebih jelas, karena cincin hijau dan cincin merah di tengah disebut Bull Tunggal dan Bullseye atau Bull ganda.
Teun Pronk
1
+1 untuk pertanyaan luar biasa. Ini adalah jenis masalah dunia nyata yang dipecahkan komputer. Anda bisa melempar 6 dalam S2 D1 D1, yang hilang dari contoh output Anda (harus ada di sana, kecuali jika Anda menganggap S2 S2 D1 dan D1 D1 sama, tetapi mereka jelas terdaftar sebagai berbeda.) Ada beberapa ambiguitas kecil tentang format output dan penghitungan hasil yang akan saya bahas dalam jawaban saya.
Level River St

Jawaban:

2

C ++ 248/228 230/214 karakter

Wahyu 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. Menyimpan beberapa karakter dengan mendeklarasikan semua variabel sekaligus, dan dengan menghilangkan tanda kurung yang tidak perlu. Ternyata di C ++ semua logika dan bitwise dan / atau lebih diutamakan daripada perbandingan.

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

Saya melakukan fungsi daripada program, seperti yang dilakukan orang lain. Ini mengembalikan jumlah total kemungkinan yang ditemukan. Ini dapat dikurangi dari 230 hingga 214 karakter dengan menghilangkan fitur totalising.

Output sampel, skor 6:

masukkan deskripsi gambar di sini

Saya menghitung anak panah pertama dan kedua yang berbeda sebagai kombinasi yang sama, seperti yang telah dilakukan OP (contoh:

T1 S1 D1 = S1 T1 D1) walaupun ini membutuhkan 7 karakter tambahan. Saya selalu membuat daftar skor yang lebih tinggi terlebih dahulu (mengabaikan penggandaan dan trebling) karena menurut saya ini lebih relevan bagi pemain (yang mungkin mengubah strateginya jika dia gagal dengan panah pertama.) Untuk alasan yang sama saya mendaftar panah sesuai dengan panah kedua. Saya menganggap panah ke-3 benar-benar berbeda dengan dua panah yang lain, oleh karena itu saya menganggap D1 D2 dan D2 D1 sebagai kasus yang berbeda sedangkan OP telah mendaftarkannya sebagai sama.

Dengan sistem penghitungan ini, saya mendapatkan 42336 kemungkinan total , sama seperti mmumboss. Menghitung anak panah pertama dan kedua yang berbeda sebagai kombinasi yang berbeda, ini meningkat hingga 83349.

Saya belum pernah menggunakan for for dengan set seperti yang dilakukan orang lain (saya cukup baru untuk C ++ dan saya bahkan tidak tahu apakah itu mungkin.) Sebagai gantinya saya menyalahgunakan syarat dalam kenaikan loop untuk melompat dari 20 hingga 25 Saya menggunakan variabel dari satu loop untuk mengkodekan semua skor yang mungkin untuk satu anak panah, seperti ini: S1 D1 T1 S2 D2 T2 dll dengan modulus dan pembagian untuk memecahkan kode. Ini menghemat verbositas menyatakan lebih banyak untuk loop, meskipun itu membuat ekspresi lebih rumit.

Hasil dari ini adalah bahwa panah yang tidak digunakan ditampilkan sebagai T0, tapi saya pikir itu jelas apa yang dimaksud, terutama karena (dengan mempertimbangkan anak panah pertama dan kedua sebagai kombinasi yang sama), saya telah dapat mengelompokkan mereka semua bersama-sama di awal. dari output saya.

Versi tidak dikolomasikan di sini. Beberapa fitur lainnya adalah penggunaan operator & & && secara selektif dengan | sedemikian rupa untuk memberikan urutan prioritas yang saya inginkan tanpa tanda kurung.

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;
}
Level River St
sumber
204 byte
ceilingcat
4

MATLAB ( 299 249 241 karakter)

Ini adalah golf serius pertama saya. Upaya pertama saya (136 karakter) memberikan hasil yang benar, tetapi tidak dengan format yang benar. Ini memberikan semua kemungkinan melihat jumlah poin untuk setiap panah. Ini berarti bahwa tunggal 20 dan ganda 10 memiliki entri yang terpisah, namun keduanya ditampilkan sebagai 20. Tentu saja panah terakhir selalu ganda.

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

Dalam upaya kedua pemformatan ditingkatkan, yang tentu saja meningkatkan jumlah karakter:

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

Ditingkatkan dari 299 menjadi 249 karakter, sementara pada saat yang sama bahkan meningkatkan format output. Untuk versi yang ditingkatkan ini keluaran untuk contoh kasus adalah:

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

Tambahan:

Menurut kemampuan berhitung saya, ada total 42336 kemungkinan untuk mengakhiri permainan panah.

mmumboss
sumber
Hasil harus menunjukkan sel yang akan dipukul, jadi yang pertama mengatakan 60 60 50seharusnya T20 T20 Bullseye. Saya akan menjelaskan hal ini dalam pertanyaan. Nice going though, hampir di sana :)
Teun Pronk
1
Ya, saya sudah menunjukkannya sendiri. Ini adalah upaya pertama yang belum selesai. ;)
mmumboss
oops maaf lol, saya ingin tahu tentang kode dan hasilnya saya tidak membaca cerita di atas xD
Teun Pronk
Ini seharusnya lebih baik. Satu-satunya hal yang dapat saya pikirkan adalah bahwa banteng masih ditampilkan sebagai 25. Tapi saya harap ini baik-baik saja, karena kalau tidak, tidak ada kemungkinan lain selain hard code ini, yang sama sekali tidak menyenangkan.
mmumboss
Sapi jantan tunggal sebagai 25 memang bisa diterima, itu satu-satunya cara Anda bisa melempar 25 dengan 1 anak panah
Teun Pronk
2

Ruby (260 karakter)

"Yang terakhir harus ganda" adalah bagian yang hilang - tidak bisa mengetahui mengapa 168 tidak memiliki hasil ...:

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;
Uri Agassi
sumber
1

Python 2.7 (270 karakter)

Tidak yakin python akan mengizinkan satu-liner, tetapi ia dalam tiga.

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

Atau 278+ karakter dengan pesan 'No Checkout' yang tepat (mis. 290 di sini):

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

Kita mulai:

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

Hal-hal yang tidak saya sukai:

for x in a for y in a for z in

Ini lebih dari 10% dari total. Apakah ada cara yang lebih ringkas tanpa itertools dll?

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

Ini digunakan untuk mencegah duplikat dalam kasus finish dua panah (misalnya ['', 'S1', 'D1'] dan ['S1', '', 'D1']). Saya anggap penting (hei - panah terakhir harus ganda, jadi jelas urutan masalah), tetapi lemparan non-lemparan adalah kasus khusus.

psion5mx
sumber
1

05AB1E , 43 byte

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

Cukup lambat .. Keluaran sebagai daftar daftar, atau daftar kosong jika tidak ada penyelesaian yang mungkin. Kerbau saya adalah S25dan D25; jika ini tidak diizinkan, saya bisa mengubahnya.

Cobalah secara online atau verifikasi beberapa uji sekaligus .

Penjelasan:

Ada beberapa langkah:

1) Buat daftar semua anak panah yang mungkin tunggal, ganda, dan tiga kali lipat:

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) Dapatkan semua pelapis yang mungkin (diakhiri dengan dua kali lipat) hingga 3 anak panah:

Ð           # 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) Hanya simpan yang nilai totalnya sama dengan bilangan masukan:

ʒ   }       # 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) Konversi data ke daftar hasil yang tercetak cantik (yaitu [[20,3],[5,1],[1,2]]menjadi ["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)
Kevin Cruijssen
sumber
0

Kotlin , 254 byte

Catatan: algorythm didasarkan pada jawaban 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!")}

Cobalah online!

JohnWells
sumber