Google Code Jam - Novo jogo de loteria


8

Eu estava olhando na web e encontrei esse quebra-cabeça do Google Code Jam. Eu realmente gostei, então decidi postar aqui.

Novo jogo de loteria

A loteria está mudando! A loteria costumava ter uma máquina para gerar um número vencedor aleatório. Mas, devido a problemas de trapaça, a loteria decidiu adicionar outra máquina. O novo número vencedor será o resultado da operação AND bit a bit entre os dois números aleatórios gerados pelas duas máquinas.

Para encontrar o AND bit a bit de X e Y , escreva-os ambos em binário; então um bit no resultado em binário terá 1 se os bits correspondentes de X e Y forem 1 e 0 caso contrário. Na maioria das linguagens de programação, o AND bit a bit de X e Y é escrito X&Y .

Por exemplo: A máquina antiga gera o número 7 = 0111 . A nova máquina gera o número 11 = 1011 . O número vencedor será (7 AND 11) = (0111 AND 1011) = 0011 = 3 .

Com essa medida, a Loteria espera reduzir os casos de reclamações fraudulentas, mas, infelizmente, um funcionário da empresa da Loteria vazou as seguintes informações: a máquina antiga sempre gera um número inteiro não negativo menor que A e a nova sempre gera um número inteiro não negativo menos de B .

Catalina quer ganhar essa loteria e para dar-lhe uma tentativa, ela decidiu comprar todos os inteiros não negativos menos de K .

Dado A , B e K , Catalina gostaria de saber de quantas maneiras diferentes as máquinas podem gerar um par de números que a tornarão uma vencedora.

Você poderia ajudá-la?

Entrada

A primeira linha da entrada fornece o número de casos de teste, linhas T. T. seguem, cada linha com três números AB K.

Resultado

Para cada caso de teste, imprima uma linha contendo "Caso nº x: y", onde x é o número do caso de teste (começando em 1) e y é o número de pares possíveis que as máquinas podem gerar para tornar a Catalina uma vencedora.

Limites

1 ≤ T ≤ 100. Conjunto de dados pequeno

1 ≤ A ≤ 1000. 1 ≤ B ≤ 1000. 1 ≤ K ≤ 1000. Grande conjunto de dados

1 ≤ A ≤ 109. 1 ≤ B ≤ 109. 1 ≤ K ≤ 109. Amostra

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

No primeiro caso de teste, esses são os 10 pares possíveis gerados pela máquina antiga e nova, respectivamente, que a tornarão uma vencedora: <0,0>, <0,1>, <0,2>, <0,3> , <1,0>, <1,1>, <1,2>, <1,3>, <2,0> e <2,1>. Observe que <0,1> não é o mesmo que <1,0>. Além disso, embora o par <2, 2> pudesse ser gerado pelas máquinas, não faria Catalina vencer, já que (2 AND 2) = 2 e ela só comprou os números 0 e 1.

Aqui está o link para o problema real: https://code.google.com/codejam/contest/2994486/dashboard#s=p1

Isso é código-golfe, então o código mais curto vence. Boa sorte


Uma nova linha à direita é opcional e uma nova linha à frente é permitida?
John Dvorak

Respostas:


6

Ruby, 107

Eu esperava que este fosse um programa muito mais curto.

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

Explicação

  • A primeira linha de entrada pode ser ignorada.
  • $. é o último número da linha de leitura.
  • [*0...x]é uma maneira rápida de transformar o arquivo Rangeem Array. Ele usa o operador splat ( *). Observe que o Rangeé exclusivo (em ...vez de ..).
  • Array#countleva um bloco. Contará apenas os elementos para os quais o bloco retorna um valor verdadeiro.

Alguma chance de você fazer $<.map{...}?
John Dvorak #

Na verdade, são dois caracteres a mais, porque é preciso argumentar.
britishtea

2

APL (63)

É a E / S que custa muito.

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

Explicação:

  • {... }¨⍳⎕: leia um número N no teclado e execute a seguinte função para cada número de 1 a N.
  • a b k←¯1+⍳¨⎕: Ler três números do teclado, gerar uma lista de 0..n-1 para cada, e armazená-los em a, be k.
  • a∘.{... }b: para cada combinação de valores de ae b:
    • ⍺⍵⊤⍨10/2: obtenha a representação binária de 10 bits para ambos os valores (isso é suficiente, considerando os limites)
    • ∧/: e juntos todos os pares de bits
    • 2⊤: transformá-lo novamente em um número
  • k∊⍨: para cada um desses valores, teste se está em k
  • +/: soma o resultado
  • 'Case #',(⍕⍵),': ',⍕: gere a sequência de saída para este caso
  • : transforme o resultado em uma matriz, para que cada sequência termine em uma linha separada.

Teste:

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

Aqui está minha solução Golfscript (provavelmente poderia ser melhorada):

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

Aqui está o pseudocódigo que eu usei para isso:

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

Pressupõe entrada válida.


1

CJam - 62

Provavelmente poderia ser melhorado; Esta é apenas uma porta da minha resposta Golfscript.

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

0

Ruby - 145

Ainda estou aprendendo Ruby, então provavelmente há uma maneira mais curta de fazer isso.

(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
Fazer loop com #mapum caractere é menor que com #each. Você não precisa fazer um loop 0...k, basta verificar se o binário e é menor que k. Quando você está chamando apenas um método sem argumentos em um bloco, pode usar Symbol#to_proc( x.map &:to_i).
britishtea

0

J, 90 (70)

E / S para stdin / stdout, funciona como um script ( 90 ).

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

Entrada no stdin, saída implícita no REPL (semelhante ao APL, acredito) ( 70 ).

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

Ergh, J não é bom em requisitos de E / S como estes.

Para os curiosos, é a parte que faz o trabalho pesado +/@,@(>`(17 b./&i.)/@|.)&."., que resolve uma única linha do problema (pegar e devolver uma string).


0

CJAM - 57

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

Eu acho que isso pode ser jogado ainda mais.

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

Resultado:

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

li {"Caso #"] _, 6 /) + ~ ': Sl ~: K; L \ {(2 $, {1 $ & @ + \}% ~} h; \; {K <} ,, N } * para se divertir, isso faz a mesma coisa, mas em vez de ter um contador para o caso #, ele conta o número de elementos na pilha.
kaine
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.