Java Puzzles - Puzzle 1: Oddity

4 views
Skip to first unread message

Maurício Linhares

unread,
Feb 21, 2008, 7:40:28 PM2/21/08
to PBJUG
Opa galera :)

A minha cópia do Java Puzzles chegou (meio tarde eu diria, mas chegou
- http://www.amazon.com/Java-TM-Puzzlers-Pitfalls-Corner/dp/032133678X/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1203640400&sr=8-1
) e eu, que já tinha achado a idéia do livro interessante (é uma
sequência de puzzles sobre a linguagem Java e programação em geral)
acho que seria uma boa se nós começassemos a responder eles aqui na
lista. A minha idéia é pegar um por semana, jogar aqui e o pessoal ir
respondendo com as suas soluções/explicações pra o que estiver
acontecendo, terminando a semana, quando for o dia de jogar o novo
puzzle, fecha-se a explicação do que estava acontecendo (usando a
explicação do livro ou até alguma das explicações dadas na lista) e o
jogo começa denovo com um novo quebra-cabeça.

Pra começar, o primeiro do livro, Oddity:

O código seguinte tem por objetivo determinar se o número passado como
seu argumento é ímpar. O método funciona?

public static boolean isOdd(int i) {


return i % 2 == 1;


}


Que venham as respostas (junto de suas respectivas explicações).

PS: Tá, eu sei que esse é peba, mas é pra ir esquentando :)

--
Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) |
http://codeshooter.wordpress.com/ (en)
João Pessoa, PB, +55 83 8867-7208

Bonifacio Segundo

unread,
Feb 21, 2008, 8:05:04 PM2/21/08
to pb...@googlegroups.com
Não funciona.

;)

Até embrião Java tem vez com esse Puzzle.
--
Bonifacio Segundo

Maurício Linhares

unread,
Feb 21, 2008, 8:11:31 PM2/21/08
to pb...@googlegroups.com
Porque não funciona? Cadê o código que funciona?

Não é só dizer que não funciona, tem que explicar =P

--

Bonifacio Segundo

unread,
Feb 21, 2008, 8:11:54 PM2/21/08
to pb...@googlegroups.com
public static boolean isOdd(int i) {
   return i % 2 == 1;
}


Se eu passar 2, que é par, 2%2 vai retornar 0. 0 == 1, retorna False. Logo, 2 não é ímpar.

Se eu passar 3, que é ímpar, 3%2 vai retornar 1. 1 == 1 é verdade. Logo, 3 é ímpar.

--
Bonifacio Segundo

Bonifacio Segundo

unread,
Feb 21, 2008, 8:13:28 PM2/21/08
to pb...@googlegroups.com
Minha antiga teoria tornou-se recentemente obsoleta e ultrapassada. Desconsidere a primeira resposta. :P

--
Bonifacio Segundo

Maurício Linhares

unread,
Feb 21, 2008, 8:15:06 PM2/21/08
to pb...@googlegroups.com
Eu já ia dizer isso =P

Mais opiniões?

--
Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) |
http://codeshooter.wordpress.com/ (en)
João Pessoa, PB, +55 83 8867-7208

Alberto Ivo

unread,
Feb 21, 2008, 8:16:53 PM2/21/08
to pb...@googlegroups.com
é isso mesmo que já foi respondido.. tem mais alguma coisa a acrescentar?
--
Atenciosamente,
Alberto Ivo Vieira

Maurício Linhares

unread,
Feb 21, 2008, 8:19:33 PM2/21/08
to pb...@googlegroups.com
Se fosse só isso já teríamos passado pra próxima, esse código tem um
probleminha gritante.

Mas eu não deveria estar dizendo isso, quando acabar eu aviso que
acabou, continuem conjecturando =D

2008/2/21 Alberto Ivo <alber...@gmail.com>:


> é isso mesmo que já foi respondido.. tem mais alguma coisa a acrescentar?
>

Arthur Gouveia

unread,
Feb 21, 2008, 8:24:45 PM2/21/08
to pb...@googlegroups.com
Funciona normal, não?
Testei aqui, e deu tudo certo...

2008/2/21 Maurício Linhares <mauricio...@gmail.com>:



--
Arthur Gouveia.

Maurício Linhares

unread,
Feb 21, 2008, 8:26:59 PM2/21/08
to pb...@googlegroups.com
Hahahahaha :)

Já vi que esse puzzle saiu melhor do que a encomenda \o/

--
Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) |
http://codeshooter.wordpress.com/ (en)
João Pessoa, PB, +55 83 8867-7208


2008/2/21 Arthur Gouveia <arthur....@gmail.com>:

Vinicius Ferraz

unread,
Feb 21, 2008, 8:28:17 PM2/21/08
to pb...@googlegroups.com
passar numeros negativos?
--
Vinícius Ferraz Campos Florentino
http://www.lsd.ufcg.edu.br/~vinicius
Stefanini IT Solutions
(061) 3212 7220
(061) 8147 6464

Arthur Gouveia

unread,
Feb 21, 2008, 8:30:50 PM2/21/08
to pb...@googlegroups.com
Se eu passar -5 ou 5, retorna True (é ímpar). Passando -4 ou 4, retorna false(par).
Qual o pró aí?

2008/2/21 Vinicius Ferraz <viniciu...@gmail.com>:



--
Arthur Gouveia.

Alberto Ivo

unread,
Feb 21, 2008, 8:31:27 PM2/21/08
to pb...@googlegroups.com
se passar números negativos, o resultado será sempre falso, nao importa o número

2008/2/21 Vinicius Ferraz <viniciu...@gmail.com>:

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:31:59 PM2/21/08
to pb...@googlegroups.com
Complementando:

Não funciona para números ímpares negativos, pois o % retornaria -1 que comparado com 1 daria falso. Eu corrigiria para
return Math.abs(i % 2) == 1;

Boa iniciativa!

Em 21/02/08, Vinicius Ferraz <viniciu...@gmail.com> escreveu:
passar numeros negativos?


Arthur Gouveia

unread,
Feb 21, 2008, 8:33:56 PM2/21/08
to pb...@googlegroups.com
Oh yeah :D
Vacilei no teste =O

Que venha o próximo.
--
Arthur Gouveia.

Vinicius Ferraz

unread,
Feb 21, 2008, 8:34:11 PM2/21/08
to pb...@googlegroups.com
ou: i % 2 != 0

talvez seja melhor, =]

On Thu, Feb 21, 2008 at 10:31 PM, Frederico Guedes Pereira <fredgued...@gmail.com> wrote:

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:34:32 PM2/21/08
to pb...@googlegroups.com
Num tem um Servlets puzzles aí não?

2008/2/21, Frederico Guedes Pereira <fredgued...@gmail.com>:

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:36:39 PM2/21/08
to pb...@googlegroups.com
Aí teria que mudar o nome do método para isEven() e não isOdd().

2008/2/21, Vinicius Ferraz <viniciu...@gmail.com>:

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:39:03 PM2/21/08
to pb...@googlegroups.com
É isso mesmo, Vinicius, tá certo! E acho que sua versão é até mais eficiente do que o que usa o Math, pois dispensa uma invocação de método.

Em 21/02/08, Frederico Guedes Pereira <fredgued...@gmail.com> escreveu:

Vinicius Ferraz

unread,
Feb 21, 2008, 8:39:17 PM2/21/08
to pb...@googlegroups.com
veja q coloquei !=, e nao ==

2008/2/21 Frederico Guedes Pereira <fredgued...@gmail.com>:

Maurício Linhares

unread,
Feb 21, 2008, 8:39:27 PM2/21/08
to pb...@googlegroups.com
No alvo, Fred e Vinícius :)

Mas ainda dá pra deixar esse código ainda mais rápido (operações de
resto são custosas pra máquina virtual).

Se eu quisesse tirar o máximo de performance desse código, qual seria
o jeito mais rápido de saber se um número é par ou impar sem usar o
operador de resto?

--

Maurício Linhares

unread,
Feb 21, 2008, 8:41:04 PM2/21/08
to pb...@googlegroups.com
Fred, acabei de rodar ele aqui e nada, acho que não tem não =P

Mas se esse negócio der certo mesmo agente pode pegar o Head First e
tirar uns presentes de lá também :)

Servlets tem magia negra o suficiente pra gerar diversos puzzles.

2008/2/21 Frederico Guedes Pereira <fredgued...@gmail.com>:

--

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:42:00 PM2/21/08
to pb...@googlegroups.com
Operador bit a bit?

return i & 1 == 1;

Fred

Em 21/02/08, Maurício Linhares <mauricio...@gmail.com> escreveu:

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:44:46 PM2/21/08
to pb...@googlegroups.com
Testei aqui e tem um erro de precedência. O correto é:

return (i & 1) == 1;


Fred


Maurício Linhares

unread,
Feb 21, 2008, 8:45:38 PM2/21/08
to pb...@googlegroups.com
Agora morreu =P

Só falta você explicar o que acontece aí Fred.

--

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:49:47 PM2/21/08
to pb...@googlegroups.com
O operador bit-a-bit faz um AND entre os bits da variável i com o valor inteiro literal 1. Da pré-infância binária de nós todos, sabemos que o valor 1 em binário é um 1 seguido por 35 zeros (inteiros em Java possuem 4 bytes). Quando você faz um AND destes com o valor de i, só resultará em 1 se o valor de i for ímpar (números pares têm o bit mais à direita igual a zero, sempre). Exemplo:

10100101011  -> numero impar
10100101010  -> numero par
AND
00000000001  -> 1 em binario

Apenas o primeiro numero (ímpar) AND 1 resultará em 1, o segundo (par) AND 1 resultará em zero.

Fred

Em 21/02/08, Maurício Linhares <mauricio...@gmail.com> escreveu:

Frederico Guedes Pereira

unread,
Feb 21, 2008, 8:56:44 PM2/21/08
to pb...@googlegroups.com

sabemos que o valor 1 em binário é um 1 seguido por 35 zeros (inteiros em Java possuem 4 bytes). Quando você faz um AND

"1 *precedido* por 35 zeros..."

Acho que essa foi a mensagem com participações mais rápidas da história da lista! Alguém cronometrou? Vai para o livro mais amado pelos brasileiros...:-P

Fred

Maurício Linhares

unread,
Feb 21, 2008, 9:00:22 PM2/21/08
to pb...@googlegroups.com
O GMail me diz que tudo aconteceu em 1 hora e 16 minutos.

Ótima explicação Fred, mais um motivo pra se prestar atenção nos
operadores bit-a-bit do Java.

Mas agora é hora de puxar o ronco, amanhã sai o Puzzle 2 =D

2008/2/21 Frederico Guedes Pereira <fredgued...@gmail.com>:
>
>

--

Alberto Ivo

unread,
Feb 21, 2008, 9:07:35 PM2/21/08
to pb...@googlegroups.com
Mauricio.. o livro tambem mostra todas as possíveis respostas?

2008/2/21 Maurício Linhares <mauricio...@gmail.com>:

Maurício Linhares

unread,
Feb 21, 2008, 9:10:38 PM2/21/08
to pb...@googlegroups.com
Mostra sim, foram exatamente as que apareceram aqui :)

--
Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) |
http://codeshooter.wordpress.com/ (en)
João Pessoa, PB, +55 83 8867-7208


2008/2/21 Alberto Ivo <alber...@gmail.com>:

Rodrigo C. L.

unread,
Feb 21, 2008, 10:06:54 PM2/21/08
to pb...@googlegroups.com
Fascinante...

Deve ser ótimo pra testar quem enseja uma certificação... ou um concurso...
Mas independente de qq coisa, achei legal! Vc comprou pela amazon? Será q tem em algum site de venda brasileño?

|| "Sofisticado - 1. Falsificado, contrafeito, adulterado. (...)"
|| Aurélio Ed. Eletrônica v3.0
||

Luiz Augusto B. Florentino Filho

unread,
Feb 21, 2008, 10:12:20 PM2/21/08
to pb...@googlegroups.com
Bom tentarei explicar. Todos os números ímpares em binário tem o bit
menos significativo (alguém lembra disso? o mais a direita) com o valor 1.

Exemplo:

O número 1 em binário: 00001 -> ímpar
O número 2 em binário: 00010
O número 3 em binário: 00011 -> ímpar
O número 4 em binário: 00100
O número 5 em binário: 00101 -> ímpar....

Então fazendo um AND bit a bit com 1 teríamos:

1 & 1 = ?
00001
00001 AND
-----
00001

2 & 1 = ?
00010 AND
00001
-----
00000

Desta maneira todo o resultado da operação lógica AND entre um número
ímpar com o número 1 resultará sempre em 1.

Sem contar que não existem divisões e restos... Essa é considerada a
melhor solução (falando de performance) para identificar se um número é
par o ímpar.

Espero ter esclarecido. =]

Maurício Linhares escreveu:

Francisco Azevedo

unread,
Feb 22, 2008, 6:57:58 AM2/22/08
to pb...@googlegroups.com
Fred,

 Não seriam 31 zeros ?!?!


Frederico Guedes Pereira <fredgued...@gmail.com> escreveu:
O operador bit-a-bit faz um AND entre os bits da variável i com o valor inteiro literal 1. Da pré-infância binária de nós todos, sabemos que o valor 1 em binário é um 1 seguido por 35 zeros (inteiros em Java possuem 4 bytes). Quando você faz um AND destes com o valor de i, só resultará em 1 se o valor de i for ímpar (números pares têm o bit mais à direita igual a zero, sempre). Exemplo:

Abra sua conta no Yahoo! Mail, o único sem limite de espaço para armazenamento!

Maurício Linhares

unread,
Feb 22, 2008, 7:08:31 AM2/22/08
to pb...@googlegroups.com
Aqui no Brasil eu nunca vi não. Sobre a certificação, eu não acho que
ele seja tão interessante assim não, ele é mais sobre os
"corner-cases", coisas da linguagem que acontecem por acidentes
sintáticos ou por causa de regras "obscuras", mas é uma boa compra de
qualquer forma.

2008/2/22 Rodrigo C. L. <tapeted...@gmail.com>:

Frederico Guedes Pereira

unread,
Feb 22, 2008, 7:15:51 AM2/22/08
to pb...@googlegroups.com
31! Multipliquei 4x8 e deu 36. Minha ULA tá com defeito. :-P

Fred

Em 22/02/08, Maurício Linhares <mauricio...@gmail.com> escreveu:
Reply all
Reply to author
Forward
0 new messages