Google Code Jam-新しい宝くじゲーム


8

私はWebを見回していて、このGoogle Code Jamパズルを見つけました。本当に気に入ったので、ここに投稿することにしました。

新しい宝くじゲーム

宝くじが変わります!宝くじには、ランダムな当選番号を生成するマシンがありました。しかし、不正行為の問題により、宝くじは別のマシンを追加することを決定しました。新しい当選番号は、2つのマシンによって生成された2つの乱数間のビットごとのAND演算の結果です。

XとYのビットANDを見つけるには、両方をバイナリで記述します。その結果、バイナリの結果のビットは、XとYの対応するビットが両方とも1の場合は1になり、それ以外の場合は0になります。ほとんどのプログラミング言語では、の-ANDビット単位のXとYが書かれているX&Yを。

例:古いマシンは7 = 0111を生成します。新しいマシンは11 = 1011を生成します。当選番号は(7 AND 11)=(0111 AND 1011)= 0011 = 3になります。

この措置により、宝くじは不正請求のケースを減らすことを期待していますが、残念ながら宝くじ会社の従業員は次の情報を漏らしました:古いマシンは常にA未満の負でない整数を生成し、新しいマシンは常に生成しますBより小さい負でない整数。

カタリナはこの宝くじに当たって、それを試すために、K未満のすべての負でない整数を購入することにしました。

A、B、およびKが与えられた場合、カタリナは、マシンが彼女を勝者とする数値のペアを生成できるさまざまな方法で知りたいと考えています。

彼女を助けてくれませんか?

入力

入力の最初の行は、テストケースの数を示します。T行が続き、各行には3つの数値AB Kが付いています。

出力

各テストケースについて、「Case #x:y」を含む1行を出力します。xはテストケース番号(1から開始)であり、yはマシンがCatalinaを勝者にするために生成できる可能なペアの数です。

限界

1≤ T ≤100小セット

1≤ A ≤1000 1≤ B ≤1000 1≤ K ≤1000大規模データセット

1≤ A ≤109 1≤ B ≤109 1≤ K ≤109サンプル

Input                 Output
5                     Case #1: 10
3 4 2                 Case #2: 16
4 5 2                 Case #3: 52
7 8 5                 Case #4: 2411
45 56 35              Case #5: 14377
103 143 88

最初のテストケースでは、新旧のマシンによって生成された10のペアがそれぞれ勝者となります。<0,0>、<0,1>、<0,2>、<0,3> 、<1,0>、<1,1>、<1,2>、<1,3>、<2,0>および<2,1>。<0,1>は<1,0>と同じではないことに注意してください。また、ペア<2、2>はマシンによって生成される可能性がありますが、(2 AND 2)= 2であり、彼女は数字の0と1しか購入しなかったため、カタリナは勝ちません。

実際の問題のリンクは次のとおりです:https : //code.google.com/codejam/contest/2994486/dashboard#s=p1

これはコードゴルフなので、最短のコードが優先されます。幸運を


末尾の改行はオプションであり、先頭の改行は許可されますか?
— John Dvorak

回答:


6

Ruby、107

これはもっと短いプログラムになると思いました。

gets
loop{a,b,k=gets.split.map &:to_i
puts"Case ##{$.-1}: #{[*0...a].product([*0...b]).count{|x,y|x&y<k}}"}

説明

  • 入力の最初の行は無視できます。
  • $. 最後に読み込まれた行番号です。
  • [*0...x]オンにする簡単な方法であるRangeにArray。スプラット演算子(*)を使用します。Rangeは(の...代わりに..)排他的なものであることに注意してください。
  • Array#countブロックを取ります。ブロックが真の値を返す要素のみをカウントします。

あなたができるチャンスはあり$<.map{...}ますか?
— John Dvorak

引数を取る必要があるため、実際には2文字長くなります。
— britishtea 2014年

2

APL(63)

コストがかかるのはI / Oです。

↑{a b k←¯1+⍳¨⎕⋄'Case #',(⍕⍵),': ',⍕+/∊k∊⍨a∘.{2⊥∧/⍺⍵⊤⍨10/2}b}¨⍳⎕

説明:

  • {... }¨⍳⎕:キーボードから数値Nを読み取り、1からNまでの数値ごとに次の関数を実行します。
  • a b k←¯1+⍳¨⎕:、キーボードからの3つの数字を読み取る毎0..N-1からリストを生成し、これらを格納しa、bおよびk。
  • a∘.{... }b:からの値の組み合わせごとaとb:
    • ⍺⍵⊤⍨10/2:両方の値の10ビットのバイナリ表現を取得します(これは制限を考えれば十分です)
    • ∧/:と一緒にすべてのビット対
    • 2⊤:数値に戻す
  • k∊⍨:これらの各値について、値が含まれているかどうかをテストします k
  • +/:結果を合計する
  • 'Case #',(⍕⍵),': ',⍕:このケースの出力文字列を生成します
  • ↑:結果を行列に変換し、各文字列が別々の行に配置されるようにします。

テスト:

      ↑{a b k←¯1+⍳¨⎕⋄'Case #',(⍕⍵),': ',⍕+/∊k∊⍨a∘.{2⊥∧/⍺⍵⊤⍨10/2}b}¨⍳⎕
⎕:
      5
⎕:
      3 4 2
⎕:
      4 5 2
⎕:
      7 8 5
⎕:
      45 56 35
⎕:
      103 143 88
Case #1: 10   
Case #2: 16   
Case #3: 52   
Case #4: 2411 
Case #5: 14377

1

Golfscript- 74 64

これが私のGolfscriptソリューションです(おそらく改善される可能性があります)。

n/(;0:m;{[~0:w.{{.2$&3$<w+:w;)}4$*;)0}5$*];'Case #'m):m': 'w n}%

これが私がこれに使用した疑似コードです:

Split string at newlines
Get rid of first element (this is not needed, as I am looping through each element anyway)
Let m=0 (case #)
For each group of 3 numbers A, B, and K:
  Let w=0 (number of winning combinations)
  For(C,0,A-1)
    For(D,0,B-1)
      If (A&B)<K
        Let w=w+1 (one more winning combination)
      End
    End
  End
  Let m=m+1 (case # incremented)
  Output("Case #",m,": ",w,"/n")
End

有効な入力を想定しています。


1

CJam-62

おそらく改善される可能性があります。これは私のGolfscript回答のポートにすぎません。

qN/(;{[~0_{{_2$&3$<V+:V;)}4$*;)0}5$*];"Case #"T):T": "V0:V;N}%

0

ルビー-145

私はまだRubyを学んでいるので、おそらくこれを行うためのより短い方法があるでしょう。

(1..gets.to_i).each{|_|a,b,k=gets.split.map{|x|x.to_i};x=0;(0...k).each{|i|(0...a).each{|j|(0...b).each{|k|x+=1 if j&k==i}}};p"Case ##{_}: #{x}"}

Ungolfed:

( 1 .. gets.to_i ).each{ | _ |
    a, b, k = gets.split.map{ | x | x.to_i }
    x = 0

    ( 0 ... k ).each{ | i |
        ( 0 ... a ).each{ | j |
            ( 0 ... b ).each{ | k |
                x += 1 if j & k == i
            }
        }
    }

    p "Case ##{_}: #{x}"
}

1
とのループは、#mapと比べて1文字短くなり#eachます。ループする必要はありません。0...kバイナリとがより小さいかどうかを簡単に確認できますk。ブロック内で引数なしのメソッドのみを呼び出す場合は、Symbol#to_proc(x.map &:to_i)を使用できます。
— britishtea 2014年

0

J、90(70)

stdin / stdoutへのI / Oはスクリプトとして機能します(90)。

,&LF@('Test #'&,)"1@(":@#,{:)\@:}.@:(': '&,"1)@(+/@,@(>`(17 b./&i.)/@|.)&.".;._2)&.stdin''

stdinでの入力、REPLでの暗黙的な出力(APLと同様)(70)。

'Test #',"1(":@#,{:)\}.': ',"1+/@,@(>`(17 b./&i.)/@|.)&.".;._2 stdin''

えーと、JはこのようなI / O要件が得意ではありません。

好奇心が強い人にとっては、重い作業を行う部分は+/@,@(>`(17 b./&i.)/@|.)&.".であり、これにより問題の1行が解決されます(文字列を取得して返す)。


0

CJAM-57

0li{)"Case #"\':Sl~:K;L\{(2$,{1$&@+\}%~}h;\;{K<},,N4$}\*;

これはさらにゴルフできると思います。

0                                  acts as a counter for the case #
  li{                              accepts the first line of input as integer/opens block
     )                             iterates counter
      "Case #"\':S                 adds "Case #X: " to stack (though in 4 parts)
       l~:K;L\                     takes next line of input, assign K, add null array
         {
          (2$,                     decrease B and generate list of number <A
           {
            1$&                    Copy the current value of B, do & with current n<A
             @+\                   Add the new possible lottery number to array
           }%~                     loop for each element if the list of numbers <A
         }h                        loop which repeats for all numbers less than B
       ;/;{K<},,                   trim and count the possible numbers less than K
      N4$                          add new line and copy the counter back in place
  }\*                              runs the block T times
;                                  removes the counter so it doesn't print

出力:

Case #1: 10
Case #2: 16
Case #3: 52
Case #4: 2411
Case #5: 14377

li {"ケース番号"] _、6 /)+〜 ':Sl〜:K; L \ {(2 $、{1 $&@ + \}%〜} h; \; {K <} ,, N } *楽しみのために、これは同じことを行いますが、case#のカウンターの代わりに、スタック内の要素の数をカウントします
— kaine
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.