Personal tools
You are here: Home Blog (português) A "provinha" do Google Developer Day

A "provinha" do Google Developer Day

Posted by Ricardo Bánffy at Oct 01, 2010 06:00 AM |

Algumas pessoas acharam estranho o processo de inscrição para o Google Developer Day. Nas edições anteriores, você preenchia um formulário, contava o que você fazia e onde trabalhava e ficava nisso. Os primeiros a se inscreverem iriam ao evento e pronto. Os menos atentos ganhavam a lista de espera. Agora, além do formulário, você tem que mandar um currículo e resolver alguns problemas que exigem familiaridade com alguma ferramenta de programação.

Não sei se foi essa a intenção da Google, mas, com esse processo de inscrição, eles têm seus dados de contato, seu currículo e sua avaliação em uma prova.

Mas não se anime. Essa prova não deve ser a que o RH do Google usa. Eu, pessoalmente, acredito que ela apenas existe para separar quem vai entender alguma coisa do GDD de quem não vai entender nada e evitar, com isso, que gente que poderia melhor aproveitar o evento fique de fora.

Agora que as inscrições foram fechadas e o prazo para a entrega das provas terminou, eu me sinto à vontade para publicar esse post.

A prova

A prova tem 5 questões, um pouco diferentes para cada candidato. Eu não sei se foi honesto, mas eu resolvi as minhas com uma janela e um interpretador Python do lado. E eu vou fazer o mesmo aqui.

O que esse programa faz?

x = 7
y = 4
if y > 2, then
   y = y * 2
else
   x = x * 2
print (x + y)

Esse é facil. Na janela do ipython:

In [1]: x = 7

In [2]: y = 4

In [3]: if y > 2:
   ...:     y = y * 2
   ...: else:
   ...:     x = x * 2
   ...:     
   ...:     

In [4]: x + y
Out[4]: 15

Quantas vezes esse programa imprime "hello"?

Uma observação: os loops incluem as extremidades.

for i = 1 to 5
   if i != 2, then
      for j = 1 to 9
         print 'hello'

De novo, com o mesmo truque (só que em Python, o range não inclui a extremidade maior):

In [1]: for i in range(1, 6):
   ...:     if i != 2:
   ...:         for j in range(1, 10):
   ...:             print 'hello'
   ...:             
   ...:             
hello
hello
hello
hello
...

Erm... Chato assim. Vamos tentar de outro jeito

In [1]: linha = 1

In [2]: for i in range(1, 6):
   ...:     if i != 2:
   ...:         for j in range(1, 10):
   ...:             print linha, 'hello'
   ...:             linha += 1
   ...:             
   ...:             
1 hello
2 hello
3 hello
4 hello
(...)
36 hello

Agora sim. Mesmo sem o computador, de olhar dá pra sacar que o primeiro loop roda 5 vezes e o segundo, 9. Como a condição que pula o segundo loop pula uma iteração (nem todos os testes fazem isso), o programa imprime 4 x 9 hello's.

Quais números, entre 5 e 2675 são pares e divisíveis por 3?

O exercício diz que eu posso escrever um programa para isso. Deve ser pra acomodar o pessoal que não vive sem um compilador.

In [1]: len([ n for n in range(5, 2676) if n % 2 == 0 and n % 3 == 0 ])
Out[1]: 445

Mas isso foi porco. Quem estava acordado no ginásio vai lembrar que se um número é par (divisível por 2 - essa é do primário) e divisível por 3, ele é divisível por 6. Assim, podemos simplificar nossa solução:

In [2]: len([ n for n in range(5, 2676) if n % 6 == 0 ])
Out[2]: 445

Podemos respirar aliviados agora que vimos que o resultado continua o mesmo.

Números bonitos

A pergunta nos apresenta Barbara e seus critérios para que números sejam ou não bonitos. Para ela, números são bonitos se contiverem um dígito 4 e não contiverem um dígito 9. Ao final, nos pergunta quais números entre 14063 and 24779, inclusive, são bonitos.

Para saber quantos são bonitos, podemos começar com uma função:

In [1]: def bonito(x):
   ...:     return '4' in str(x) and '9' not in str(x)
   ...:

E podemos testá-la, para ver se  fizemos tudo direito:

In [2]: bonito(4)
Out[2]: True

In [3]: bonito(9)
Out[3]: False

In [4]: bonito(49)
Out[4]: False

In [5]: bonito(1491)
Out[5]: False

Daí, basta aplicá-la usando a mesma técnica que usamos no problema anterior:

In [6]: len([ n for n in range(14063, 24780) if bonito(n) ])
Out[6]: 3047

Se você preferir, pode fazer tudo em uma linha:

In [7]: len([ n for n in range(14063, 24780) if '4' in str(n) and '9' not in str(n) ])
Out[7]: 3047

Ou, ainda:

In [8]: len(filter( lambda x: '4' in str(x) and '9' not in str(x), range(14063, 24780)))
Out[8]: 3047

Os telefones

A última pergunta nos apresenta um país em que os números de telefone têm 6 dígitos. Números não podem ter dois dígitos consecutivos idênticos, porque isso é caído. A soma dos dígitos tem que ser par, porque isso é legal e o último dígito não pode ser igual ao primeiro, porque isso dá azar.

Vamos começar com os caídos

In [1]: def caido(x):
   ...:     for i in range(0, len(str(x))):
   ...:         if str(x)[i] == str(x)[i - 1]:
   ...:             return True
   ...:     return False
   ...:

Agora vamos para os legais

In [2]: def legal(x):
   ...:     return sum([ int(n) for n in str(x) ]) % 2 == 0
   ...:

E, se olharmos a função "caido", vamos ver que ela considera caídos os números que dão azar.

In [3]: caido(123451)
Out[3]: True

Assim, basta usarmos duas no nosso critério:

In [4]: len([ n for n in range(100000, 1000000) if not caido(n) and legal(n) ])
Out[4]: 238500

Mas o exercício não perguntou quantos caídos entre 100000 e 999999. Eles nos deu uma lista. Com um pouco de mágica de clipboard, colocamos os números em uma string, que quebramos e fazemos uma lista:

In [5]: tudo = '''214966
   ...: 215739
   ...: 220686
   ...: 225051
   ...: 225123
   ...: 226810
   ...: 228256
(...)
   ...: 720576
   ...: '''

In [6]: tudo
Out[6]: '214966\n215739\n220686\n225051\n225123\n...720202\n720568\n720576\n'

Opa! Tem um '\n' no final do qual precisamos nos livrar

In [7]: numeros = tudo.split('\n')[:-1]

In [8]: len(numeros)
Out[8]: 200

Então, usamos a lista e chegamos no resultado:

In [9]: len([ n for n in numeros if not caido(n) and legal(n) ])
Out[9]: 61

61 de 200 parece razoável.

Motivo para pânico?

Não desanime se seus números forem muito diferentes dos meus. Os enunciados variam de teste para teste. Além disso, até agora eu não recebi confirmação da minha inscrição. Isso pode indicar que eu errei tudo.

Boa sorte!