Dart Codegolf ile buluşuyor


11

Herkesin dart aşina olduğunu düşünüyorum, bazı insanlar bu insanlar için çok puanlarını anlamıyorum burada bu konuda yararlı bir bağlantıdır.

Pano

Bir dart tahtası, 20 parça halinde kesilmiş bir pasta ile karşılaştırılabilir. Her parça 4 bölüme ayrılmıştır.

  • çift ​​denilen küçük bir dış halka (nokta x2)
  • single denilen büyük bir yüzük (puan x1)
  • üçlü denilen başka bir küçük halka (puan x3)
  • single denilen başka bir büyük halka (puan x1)

Tahtanın ortasında 2 halka daha, yeşil ve kırmızı bir tane var (klasik tahta)

  • Kırmızı halka, tahtanın ortasına bullseye veya çift boğa denir ve 50 puan için iyidir. Bu bir çift sayılır ve bu nedenle onunla ödeme yapmasına izin verilir.
  • Yeşil halka, boğa, tek boğa veya sadece 25 olarak adlandırılır ve tek olarak sayılır.

Meydan okuma

3 veya daha az dartla tüm ödeme imkanlarını bulun.
Kullanıcı bir tamsayı girebilir ve skoru 3 dart (veya daha az) ile 0'a getirmenin mümkün olup olmadığını kontrol etmeniz gerekir.

Örnekler

örnek 1:

Input: 170  
Output: T20, T20, Bullseye

Örnek 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;

Örnek 3:

Input: 169
Output: No possible checkout!

kurallar

  • Temel dart kuralı, bir çift ile bitmelisiniz (tahtanın dış halkası veya bullseye)
  • Dış kaynak kullanımı yok.
  • Olası check-out'ların sabit kodlamasına izin verilir, ancak bunun codegolf olduğunu unutmayın, kodunuzu kısa almaz;
  • Vurulacak hücreler C + N biçiminde görüntülenir; burada Üçlü için C = T, çift için D ve tek için S.
    • bullseye bullseye veya DB, DBull veya simüler bir şey olarak adlandırılabilir.

Muhtemel ödemeler

Başlamak için, mümkün olan en yüksek ödeme
170'tir. 169,168,166,165,163,162,159 3 dartta mümkün değildir.
Mümkün olan en düşük ödeme 2'dir.

Ek olarak

Bu bir zorunluluk değildir, tüm puanlar için olası tüm ödeme gösterme imkanı ekleyin. Temel olarak kaç kombinasyon mümkün olduğunu merak ediyorum: P

Kazanan en kısa koda sahip olacak.

Mutlu kodlama.


1
Listelenen ilk kural yanlıştır (ve ilk örneği geçersiz kılar) çünkü bir boğa üzerinde de bitirebilirsiniz. Bir program, işlev veya her ikisini de beklediğinizi açıklığa kavuşturmak faydalı olacaktır; ve çıktı biçiminde ne kadar esneklik olduğunu.
Peter Taylor

1
@PeterTaylor Bunu daha net yapacağım, çünkü ortadaki yeşil halka ve kırmızı halka Tek boğa ve bullseye veya çift boğa olarak adlandırılıyor.
Teun Pronk

1
Mükemmel soru için +1. Bu, bilgisayarların çözmede iyi olduğu gerçek dünya problemidir. S2 D1 D1'e örnek çıkışınızda eksik olan bir 6 atabilirsiniz (S2 S2 D1 ve D1 D1 D1'in aynı olduğunu düşünmediğiniz sürece orada olmalı, ancak açıkça farklı olarak listeleniyorlar.) Çıktı formatı ve cevabımda ele alacağım sonuçların sayılması ile ilgili küçük belirsizlikler.
Level River St

Yanıtlar:


2

C ++ 248/228 230/214 karakter

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. Tüm değişkenleri bir kerede bildirerek ve gereksiz parantezleri kaldırarak bazı karakterleri kaydetti. C ++ 'da tüm mantık ve bitsel ve / veya karşılaştırmalardan daha düşük önceliğe sahip olduğu ortaya çıktı.

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

Diğerleri gibi programdan ziyade bir işlev yaptım. Bulunan toplam olasılık sayısını döndürür. Toplama özelliği ortadan kaldırılarak 230'dan 214 karaktere düşürülebilir.

Örnek çıktı, skor 6:

resim açıklamasını buraya girin

OP'nin yaptığı gibi aynı kombinasyon olarak farklı birinci ve ikinci dartları sayıyorum (örnek:

T1 S1 D1 = S1 T1 D1), bu fazladan 7 karaktere rağmen. Her zaman önce en yüksek puanı listelerim (iki katına çıkmayı ve çınlamayı görmezden gelirim), bunun oyuncu ile daha alakalı olduğunu anlıyorum (ilk dartla özlerse stratejisini değiştirebilecek.) Aynı nedenle dartları sırasıyla ikinci dart. 3. dartın diğer ikisinden tamamen farklı olduğunu düşünüyorum, bu nedenle D1 D2 ve D2 D1'in farklı durumlar olduğunu düşünüyorum, oysa OP bunları aynı şekilde listeledi.

Bu sayma sistemi ile mmumboss ile aynı 42336 olasılık elde ediyorum. Farklı birinci ve ikinci dartları farklı kombinasyonlar olarak saymak, bu 83349'a kadar çıkıyor.

Başkalarının yaptığı gibi setlerle bir for döngüsü kullanmadım (C ++ için oldukça yeniyim ve bunun mümkün olup olmadığını bile bilmiyorum.) Bunun yerine, 20'den 25'e atlamak için döngü artışında bir koşullu kötüye kullanıyorum Tek bir döngüdeki değişkeni tek bir dart için tüm olası puanları kodlamak için kullanıyorum, örneğin: S1 D1 T1 S2 D2 T2 vb. Bu, ifadeleri daha karmaşık hale getirmesine rağmen, döngüler için daha fazlasını bildirme ayrıntılarından tasarruf sağlar.

Bunun sonucu, kullanılmayan bir dartın T0 olarak gösterilmesidir, ancak ne anlama geldiğinin açık olduğunu düşünüyorum, özellikle (farklı birinci ve ikinci dartları aynı kombinasyon olarak düşünerek) başlangıçta hepsini bir araya getirebildim benim çıktı.

Burada unngolfed versiyonu. Diğer bazı özellikler, & ve && operatörlerinin | köşeli parantez olmadan istediğim öncelik sırasını verecek şekilde.

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

Bu benim ilk ciddi golf oyunum. İlk denemem (136 karakter) doğru sonucu veriyor ancak doğru biçimlendirmeyle vermiyor. Her dart için puan sayısına bakarak tüm olasılıkları verir. Bu, tek 20 ve çift 10'un ayrı bir girişi olduğu anlamına gelir, ancak her ikisi de 20 olarak görüntülenir. Tabii ki son dart her zaman bir çifttir.

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

İkinci denemede, elbette karakter sayısını artıran biçimlendirme geliştirildi:

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'dan 249 karaktere, aynı zamanda çıktı biçimlendirmesini bile geliştirdi. Bu geliştirilmiş sürüm için örnek durumlar için çıktı:

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

Ek:

Hesaplama becerilerime göre dart oyununu sona erdirmek için toplam 42336 olasılık var.


Sonuç, hangi hücrenin vurulacağını göstermelidir, bu yüzden ilk önce 60 60 50olması gerekir T20 T20 Bullseye. Bunu soruda daha açık hale getireceğim. Güzel olsa da, neredeyse orada :)
Teun Pronk

1
Evet, bunu zaten kendime işaret ettim. Bu bitmemiş ilk girişim. ;)
mmumboss

Üzgünüz lol, ben kod hakkında merak ve sonuç xD yukarıdaki hikayeyi okumadım oldu
Teun Pronk

Bu daha iyi olmalı. Aklıma gelen tek şey boğa hala 25 olarak görüntüleniyor. Ama umarım bu tamamdır, aksi takdirde bunu zor kodlamaktan başka bir olasılık yoktur, ki bu sadece eğlenceli değildir.
mmumboss

25 gibi tek boğa gerçekten kabul edilebilir, onun da yine de 1 dart ile 25 atmak tek yolu
Teun Pronk

2

Yakut (260 karakter)

"Sonuncusu bir çift olmalı" eksik parçaydı - 168'in neden sonuç vermemesi gerektiğini anlayamadım ...:

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

Python'un bir astara izin vereceğinden emin değil, ama üçte.

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

Veya uygun bir 'Ödeme Yok' mesajıyla 278+ karakter (ör. Burada 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

İşte başlıyoruz:

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

Memnun olmadığım şeyler:

for x in a for y in a for z in

Bu, toplamın% 10'unun üzerindedir. Itertools vs olmadan daha kompakt bir yol var mı?

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

Bu, iki dart yüzeyde (örn. ['', 'S1', 'D1'] ve ['S1', '', 'D1']) kopyaları önlemek için kullanılır. Ben önemini emrediyorum (hey - son dart bir çift olmalı, bu yüzden açıkça sipariş önemlidir), ama atmayan özel bir durum.


1

05AB1E , 43 bayt

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

Oldukça yavaş .. Liste listesi veya bitiş mümkün değilse boş bir liste olarak çıktılar. Boğalarım S25ve D25; buna izin verilmiyorsa değiştirebilirim.

Çevrimiçi deneyin veya aynı anda birkaç test vakasını doğrulayın .

Açıklama:

Birkaç adım var:

1) Tüm olası tek, çift ve üçlü dartların bir listesini oluşturun:

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) 3 dart'a kadar tüm olası sonlandırıcıları (bir çift ile biten) alın:

Ð           # 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) Yalnızca toplam puanın girdi-tamsayıya eşit olduğu değerleri koruyun:

ʒ   }       # 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) Verileri güzel yazdırılmış sonuç listesine dönüştürün (yani [[20,3],[5,1],[1,2]]olur ["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 bayt

Not: algoritma Level River St'nin C ++ cevabına dayanmaktadır.

{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!")}

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.