Google Code Jam - Neues Lotteriespiel


8

Ich habe mich im Internet umgesehen und dieses Google Code Jam Puzzle gefunden. Es hat mir sehr gut gefallen und ich habe beschlossen, es hier zu posten.

Neues Lotteriespiel

Die Lotterie verändert sich! Die Lotterie hatte früher eine Maschine, um eine zufällige Gewinnzahl zu generieren. Aufgrund von Betrugsproblemen hat die Lotterie beschlossen, eine weitere Maschine hinzuzufügen. Die neue Gewinnzahl ist das Ergebnis der bitweisen UND-Verknüpfung zwischen den beiden von den beiden Maschinen generierten Zufallszahlen.

Um das bitweise UND von X und Y zu finden , schreiben Sie beide in Binärform. dann hat ein Bit im Ergebnis in binär eine 1, wenn die entsprechenden Bits von X und Y beide 1 waren, und andernfalls eine 0. In den meisten Programmiersprachen wird das bitweise UND von X und Y in X & Y geschrieben .

Zum Beispiel: Die alte Maschine generiert die Nummer 7 = 0111 . Die neue Maschine generiert die Nummer 11 = 1011 . Die Gewinnzahl ist (7 UND 11) = (0111 UND 1011) = 0011 = 3 .

Mit dieser Maßnahme erwartet die Lotterie, die Fälle betrügerischer Ansprüche zu reduzieren, aber leider hat ein Mitarbeiter der Lotteriefirma die folgenden Informationen durchgesickert: Die alte Maschine generiert immer eine nicht negative Ganzzahl kleiner als A und die neue Maschine generiert immer eine nicht negative ganze Zahl kleiner als B .

Catalina möchte diese Lotterie gewinnen und versuchen, alle nicht negativen ganzen Zahlen unter K zu kaufen .

Angesichts von A , B und K möchte Catalina wissen, auf wie viele verschiedene Arten die Maschinen ein Zahlenpaar erzeugen können, das sie zu einer Gewinnerin macht.

Können Sie ihr helfen?

Eingang

Die erste Zeile der Eingabe gibt die Anzahl der Testfälle an, T. T-Zeilen folgen, jede Zeile mit drei Zahlen AB K.

Ausgabe

Geben Sie für jeden Testfall eine Zeile mit "Fall #x: y" aus, wobei x die Testfallnummer (beginnend mit 1) und y die Anzahl der möglichen Paare ist, die die Maschinen generieren können, um Catalina zu einem Gewinner zu machen.

Grenzen

1 ≤ T ≤ 100. Kleiner Datensatz

1 ≤ A ≤ 1000. 1 ≤ B ≤ 1000. 1 ≤ K ≤ 1000. Großer Datensatz

1 ≤ A ≤ 109. 1 ≤ B ≤ 109. 1 ≤ K ≤ 109. Probe

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

Im ersten Testfall sind dies die 10 möglichen Paare, die von der alten bzw. der neuen Maschine generiert werden und die sie zu einer Gewinnerin machen: <0,0>, <0,1>, <0,2>, <0,3> , <1,0>, <1,1>, <1,2>, <1,3>, <2,0> und <2,1>. Beachten Sie, dass <0,1> nicht mit <1,0> identisch ist. Auch wenn das Paar <2, 2> von den Maschinen erzeugt werden könnte, würde Catalina nicht gewinnen, da (2 UND 2) = 2 und sie nur die Zahlen 0 und 1 gekauft hat.

Hier ist der Link für das eigentliche Problem: https://code.google.com/codejam/contest/2994486/dashboard#s=p1

Dies ist Code-Golf, also gewinnt der kürzeste Code. Viel Glück


Ist eine nachfolgende Newline optional und eine führende Newline zulässig?
John Dvorak

Antworten:


6

Ruby, 107

Ich hatte erwartet, dass dies ein viel kürzeres Programm sein würde.

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

Erläuterung

  • Die erste Eingabezeile kann ignoriert werden.
  • $. ist die zuletzt gelesene Zeilennummer.
  • [*0...x]ist ein schneller Weg, um das Rangein ein zu verwandeln Array. Es verwendet den splat-Operator ( *). Beachten Sie, dass Rangees sich um eine exklusive handelt ( ...anstelle von ..).
  • Array#countnimmt einen Block. Es werden nur die Elemente gezählt, für die der Block einen wahrheitsgemäßen Wert zurückgibt.

Gibt es eine Chance, die du machen kannst $<.map{...}?
John Dvorak

Es ist eigentlich zwei Zeichen länger, weil es ein Argument braucht.
Britishtea

2

APL (63)

Es ist die E / A, die viel kostet.

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

Erläuterung:

  • {... }¨⍳⎕: Lesen Sie eine Zahl N von der Tastatur und führen Sie für jede Zahl von 1 bis N die folgende Funktion aus.
  • a b k←¯1+⍳¨⎕Lesen drei Zahlen von der Tastatur, um eine Liste von 0..n-1 für jede erzeugen und speichern diese in: a, b, und k.
  • a∘.{... }b: für jede Kombination von Werten aus aund b:
    • ⍺⍵⊤⍨10/2: Holen Sie sich die 10-Bit-Binärdarstellung für beide Werte (dies ist angesichts der Grenzwerte ausreichend)
    • ∧/: und zusammen alle Bitpaare
    • 2⊤: verwandle es wieder in eine Zahl
  • k∊⍨: Testen Sie für jeden dieser Werte, ob er in ist k
  • +/: summiere das Ergebnis
  • 'Case #',(⍕⍵),': ',⍕: Generieren Sie die Ausgabezeichenfolge für diesen Fall
  • : Verwandeln Sie das Ergebnis in eine Matrix, sodass jede Zeichenfolge in einer separaten Zeile endet.

Prüfung:

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

Hier ist meine Golfscript-Lösung (könnte wahrscheinlich verbessert werden):

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

Hier ist der Pseudocode, den ich dafür verwendet habe:

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

Nimmt eine gültige Eingabe an.


1

CJam - 62

Könnte wahrscheinlich verbessert werden; Dies ist nur eine Portierung meiner Golfscript-Antwort.

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

0

Rubin - 145

Ich lerne immer noch Ruby, daher gibt es wahrscheinlich einen kürzeren Weg, dies zu tun.

(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
Das Schleifen mit #mapist ein Zeichen kürzer als mit #each. Sie müssen keine Schleife durchlaufen 0...k, Sie können einfach überprüfen, ob die Binärdatei und niedriger als ist k. Wenn Sie nur eine Methode ohne Argumente in einem Block aufrufen, können Sie Symbol#to_proc( x.map &:to_i) verwenden.
Britishtea

0

J, 90 (70)

E / A zu stdin / stdout, arbeitet als Skript ( 90 ).

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

Eingabe auf stdin, Ausgabe implizit in REPL (ähnlich wie APL, glaube ich) ( 70 ).

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

Ergh, J ist bei solchen E / A-Anforderungen nicht gut.

Für die Neugierigen ist der Teil, der die schwere Arbeit erledigt +/@,@(>`(17 b./&i.)/@|.)&."., der eine einzelne Zeile des Problems löst (Nehmen und Zurückgeben einer Zeichenfolge).


0

CJAM - 57

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

Ich denke, das kann weiter gespielt werden.

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

Ausgabe:

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

li {"Case #"] _, 6 /) + ~ ': Sl ~: K; L \ {(2 $, {1 $ & @ + \}% ~} h; \; {K <} ,, N. } * zum Spaß macht dies das gleiche, aber anstatt einen Zähler für case # zu haben, zählt es die Anzahl der Elemente im Stapel.
kaine
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.