ダーツとCodegolfの出会い


11

私は誰もがダーツに精通していると思う、何人かの人々はスコアを理解していないので、ここのそれらの人々にとってはそれに関する有用なリンクです。

ボード

ダーツボードは、20個に分割されたパイと比較できます。各ピースは4つのセクションに分かれています。

  • ダブルと呼ばれる小さな外輪(ポイントx2)
  • シングルと呼ばれる大きなリング(ポイントx1)
  • トリプルと呼ばれる別の小さなリング(ポイントx3)
  • シングルと呼ばれる別の大きなリング(ポイントx1)

ボードの中央にはさらに2つのリング、緑と赤のリングがあります(クラシックボード)

  • 赤いリング、ブルズアイまたはダブルブルと呼ばれるボードの中央にあり、50ポイントに適しています。これはダブルとしてカウントされ、そのためチェックアウトが許可されています。
  • ブル、シングルブル、または単に25と呼ばれるグリーンリングは、シングルとしてカウントされます。

チャレンジ

3ダーツ以下ですべてのチェックアウトの可能性を見つけます。
ユーザーは整数を入力でき、3ダーツ(またはそれ以下)でスコアを0にできるかどうかを確認する必要があります。

例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!

ルール

  • 基本的なダーツルール、ダブル(ボードの外輪またはブルズアイ)で終わる必要があります
  • 外部リソースを使用しません。
  • 可能なチェックアウトのハードコーディングは許可されますが、これはcodegolfであることを忘れないでください。コードを短くすることはできません;)
  • ヒットするセルは、C + Nの形式で表示されます。C= Tはトリプル、Dはダブル、Sはシングルです。
    • ブルズアイは、ブルズアイまたはDB、DBullまたは類似したものと呼ばれます。

可能なチェックアウト

開始するには、可能な限り最高のチェックアウトは170です
。169本、168本、166本、165本、163本、162本、159本は3ダーツでは不可能です。
最低のチェックアウトは2です。

加えて

これは必須ではありません。すべてのスコアのすべての可能なチェックアウトを表示する可能性を追加します。基本的には、いくつの組み合わせが可能だろうと思うからです:P

勝者はコードが最も短いものになります。

ハッピーコーディング。


1
最初にリストされたルールは正しくありません(そして最初の例を無効にします)。これは雄牛でも終了できるためです。プログラム、関数、またはその両方を期待しているのかどうかを明確にしておくと役立ちます。そして、出力フォーマットにどれだけの柔軟性があるか。
ピーターテイラー14

1
@PeterTaylor中央の緑のリングと赤のリングはシングルブルとブルズアイまたはダブルブルと呼ばれるので、これをより明確にします。
テウンプロンク14

1
素晴らしい質問のために+1。これは、コンピュータが解決するのが得意な一種の現実世界の問題です。サンプル出力にはないS2 D1 D1に6をスローできます(S2 S2 D1とD1 D1 D1が同じであると思わない限り、そこにあるはずですが、明らかに異なるものとしてリストされています)。出力形式と結果のカウントに関するマイナーなあいまいさについては、回答で説明します。
レベルリバーセント14

回答:


2

C ++ 248/228 230/214文字

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

改訂1.すべての変数を一度に宣言し、不要な角かっこを削除して、一部の文字を保存しました。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;}

他の人が行ったように、プログラムではなく機能を実行しました。見つかった可能性の総数を返します。合計機能を削除することにより、230文字から214文字に減らすことができます。

サンプル出力、スコア6:

ここに画像の説明を入力してください

OPが行ったように、異なる1つ目と2つ目のダーツを同じ組み合わせとしてカウントします(例:

T1 S1 D1 = S1 T1 D1)これは7文字余分にかかりますが。私はこれがプレーヤーに関連性が高いと考えているので、常に高いスコアを最初にリストします(ダブリングとトレブルを無視します) 2番目のダーツ。3番目のダーツは他の2つのダーツとは完全に異なると考えているため、D1 D2とD2 D1は異なるケースであると考えますが、OPでは同じようにリストされています。

このカウントシステムでは、mmumbossと同じ42336の可能性があります。異なる第1ダーツと第2ダーツを異なる組み合わせとして数えると、これは83349まで上がります。

他の人が行ったように、セットでforループを使用していません(私はC ++にかなり慣れていないので、それが可能かどうかさえ知りません)。代わりに、ループインクリメントの条件を悪用して20から25にジャンプします。 。単一のループの変数を使用して、次のように、1つのダーツのすべての可能なスコアをエンコードします:S1 D1 T1 S2 D2 T2など。これにより、式がより複雑になりますが、より多くのforループを宣言する冗長性が節約されます。

この結果、未使用のダーツはT0として表示されますが、特に(最初と2番目の異なるダーツを同じ組み合わせと見なすことで)最初にそれらをすべてグループ化することができたので、何を意味するのかは明確だと思います私の出力の。

ここにゴルフバージョンはありません。他のいくつかの機能は、&および&&演算子の選択的な使用です。括弧なしで必要な優先順位を与えるような方法で。

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

2番目の試みでは、書式設定が改善されました。これにより、もちろん文字数が増加しました。

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。質問でこれをより明確にします。いい
感じ

1
はい、私はすでにそれを自分で指摘しました。これは最初の未完の試みです。;)
mmumboss 14

申し訳ありませんが、コードと結果に興味がありました
。xDの

これは良いはずです。私が考えることができるのは、雄牛がまだ25と表示されているということだけです。しかし、これは大丈夫です。
mmumboss 14

25のような単一の雄牛はあなたがとにかく1つのダートで25を投げることができる唯一の方法は、実際に受け入れられる
Teunプロンク

2

ルビー(260文字)

「最後の1つはダブルである必要があります」は欠落している部分でした-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(?,)};"})})}

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文字)

pythonが1行を許可するかどうかはわかりませんが、彼は3行です。

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

これは、2ダーツ仕上げの場合の重複を防ぐために使用されます(例:[''、 'S1'、 'D1']および['S1'、 ''、 'D1'])。私は重要であると考えています(ねえ-最後のダーツはダブルでなければならないので、明確に注文する必要があります)が、非スローは特別な場合です。


1

05AB1E、43 バイト

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

かなり遅い..リストのリストとして出力するか、終了できない場合は空のリストとして出力します。私の雄牛はS25and 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)最大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は、Level River StのC ++の回答に基づいています。

{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.