[RESOLVIDO] Exercício apostila Caelum

Pessoal, sou nova em Java e estou tentando treinar minha lógica com os exercícios da apostila da Caelum. O exercício que eu vou colocar a seguir, pode ser que já tenha em outro tópico, porém, eu achei melhor não olhar para que eu possa treinar minha lógica como informei anteriormente e não simplesmente copiar e colar… eu quero entender o código.

Exercício:

Escreva um programa que, dada uma variável x (com valor 180, por exemplo), temos y de acordo
com a seguinte regra:
se x é par, y = x / 2
se x é impar, y = 3 * x + 1
imprime y
O programa deve então jogar o valor de y em x e continuar até que y tenha o valor final de 1. Por exemplo, para x = 13, a saída será:
40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1

Eu fiz vários códigos, mas aí eu apagava e fazia novamente quando não dava certo, o mais perto que consegui chegar é colocar o número 13 e mostrar o valor até 5, depois disso eu não conseguia fazê-lo voltar para a regra se o número for impar… Eu não sei o que usar: If, For, While… Na maioria eu usava o While com o IF, mas estava com problemas no incremento.

Meu último código foi esse, que não está dando certo:

[code]public class Teste {

public static void main(String[] args){
	
	
	int y = 0;
	

	String string = javax.swing.JOptionPane.showInputDialog("Entre com um valor numerico: ");
	int x = Integer.parseInt(string);
	
	if(x % 2 != 0){
		y = (x * 3) + 1;
		System.out.println(y);
		while (y % 2 != 0 && y >= 1){
			y = y * 3 + 1;
			System.out.println(y);
			x = y;
		}
	}else {
		y = x / 2;
		System.out.println(y);
		while (y % 2 == 0 && y >= 1){
			y = y / 2;
			System.out.println(y);
			x = y;
		}
	}	
}

}
[/code]

Alguém poderia me ajudar? Desde já, agradeço.

Bom eu to vendo algumas coisas meio que incoerentes se é que eu entendi o problema.

A regra é a seguinte:

se x é par a fórmula é essa:

y = x/2

se x é ímpar a fórmula é essa:

y = 3 * x + 1;

Transcrevendo essas hipóteses para o java ficaria assim:

     if(x % 2 == 0){//Se X é par
        y=x/2;
     }else{//Se x é ímpar
        y =3 * x+1;//Em java como em outras linguagens de programação multiplicação sempre tem precedência maior que a adição. Nesse caso era desnecessário o uso do parênteses. Você não precisa fazer isso:
        y = (3*x)+1;//o resultado seria o mesmo.
     }

E outra coisa no código vc imprime a variável y duas vezes a primeira logo quando entra no primeiro if vc faz o cálculo e exibe o resultado. Quando na verdade se é que eu entendi bem é que tem que gerar uma sequência de números. Acho que vc deveria colocar no while. E outra coisa isso por exemplo vc digita 13 e começa contando do 40 e vai até o 1. Ou seja, descresce, deveria ter uma variável de controle aí para decrescer de valor. E no final do loop após vc aplicar a forma novamente vc exibe o resultado e atribui y a x e não faz nada com essa variável pq?

Tentar aplicar o que eu te disse e posta aqui pra eu ver o código para eu te ajudar. Só não vou codificar tudo pra vc, pois assim não estarei te ajudando.

Olá paola, que tal você fazer um único while…

while (y != 1) {
  //codigos...
}

Eu fiz esse mesmo exercício usando o "Scanner" para ter a entrada de dados atraves do teclado sem que precisa-se ficar dependendo desses valores definidos pela apostila
O código é o seguinte:


import java.util.Scanner;
//Nao concegui finalizar o programa.

//Esquece o que tu disse em cima tu conseguiste finalizar o programa sim.
//Para ver qual exercicio e esse olhe na apostila da Caelum
//( caelum-java-objetos-fj11  Opcional 7, Pag 27  )


public class Exercicio
{
public static void main(String[] args)
{
//Criando a class Scanner para poder receber um numero inteiro.
Scanner digite = new Scanner(System.in);
int x = digite.nextInt();//converte a string digitado pelo usuario em um inteiro
int a = x;// Isso aqui foi colocado para que não interfira no calculo do numero
//Impar.

int y = 0;//Aqui voce inicializa o y com zero.

if( (x % 2) == 1 ) //Nesse if executa o calculo para saber se x e Impar.
{


y = 3 * x + 1 ; //Esse e um calculo que estava na apostila da caelum
   


System.out.println(y + "\nNumero Impar\n");//Imprime na tela "Numero Impar" sem aspas.
System.out.print(y + (" -> " ));//Imprime o resultado disso aqui y = 3 * x + 1;


}//Fim do if.

while(y > 1 ) //Enquanto y maior que um, ele vai executar o seguinte codigo.
{
x = y; //Aqui esta sendo atribuido a x o resultado disso aqui: y = 3 * x + 1; que foi exibida na tela.
//Aqui x recebeu o valor de y.
if((x % 2 ) == 0 )//Esse é o calculo para saber se x e Par, No caso aqui
    //x é par.
{
 y = x / 2;//Esse e outro calculo que estava na apostila da caelum.

System.out.print(y + (" -> " ));  //Vai imprimir o resultado disso aqui: y = x / 2;



}//Fim do primeiro if dentro do while.


if ((x % 2) == 1)//Esse e o calculo para saber se x e Impar.
{
y = 3 * x + 1;//Esse e outro calculo que estava na apostila da caelum.
System.out.print(y + (" -> "));//Vai imprimir na tela o resultado disso aqui: y = 3 * x + 1;


}//Fim do segundo if dentro do while dentro do if.


}//Fim do primeiro while.


//________________________________
//Se o numero digitado for Par executara esse codigo abaixo.

if((a % 2) == 0 )
{
y = a / 2;

System.out.println(y +(" O resultado do Calculo de Impar"));
System.out.println("Numero Par ");
}//Fim do segundo if.

while(y > 1 ) //Enquanto y maior que um, ele vai executar o seguinte codigo.
{
a = y; //Aqui esta sendo atribuido a "a" o resultado disso aqui: y = 3 * x + 1; que foi exibida na tela.
//Aqui x recebeu o valor de y.
if((a % 2 ) == 1 )//Esse é o calculo para saber se "a" e Par, No caso aqui
    //"a" é par.
{
 y = 3 * a + 1;//Esse e outro calculo que estava na apostila da caelum.

System.out.print(y + (" -> " ));  //Vai imprimir o resultado disso aqui: y = x / 2;



}//Fim do primeiro if dentro do while.


if ((a % 2) == 0)//Esse e o calculo para saber se "a" e Impar.
{
y = a / 2;//Esse e outro calculo que estava na apostila da caelum.
System.out.print(y + (" -> "));//Vai imprimir na tela o resultado disso aqui: y = 3 * x + 1;


}//Fim do segundo if dentro do while dentro do if.


}//Fim do Segundo while.



}
}

[quote=quil]Eu fiz esse mesmo exercício usando o "Scanner" para ter a entrada de dados atraves do teclado sem que precisa-se ficar dependendo desses valores definidos pela apostila
O código é o seguinte:

[code]

import java.util.Scanner;
//Nao concegui finalizar o programa.

//Esquece o que tu disse em cima tu conseguiste finalizar o programa sim.
//Para ver qual exercicio e esse olhe na apostila da Caelum
//( caelum-java-objetos-fj11 Opcional 7, Pag 27 )

public class Exercicio
{
public static void main(String[] args)
{
//Criando a class Scanner para poder receber um numero inteiro.
Scanner digite = new Scanner(System.in);
int x = digite.nextInt();//converte a string digitado pelo usuario em um inteiro
int a = x;// Isso aqui foi colocado para que não interfira no calculo do numero
//Impar.

int y = 0;//Aqui voce inicializa o y com zero.

if( (x % 2) == 1 ) //Nesse if executa o calculo para saber se x e Impar.
{

y = 3 * x + 1 ; //Esse e um calculo que estava na apostila da caelum

System.out.println(y + “\nNumero Impar\n”);//Imprime na tela “Numero Impar” sem aspas.
System.out.print(y + (" -> " ));//Imprime o resultado disso aqui y = 3 * x + 1;

}//Fim do if.

while(y > 1 ) //Enquanto y maior que um, ele vai executar o seguinte codigo.
{
x = y; //Aqui esta sendo atribuido a x o resultado disso aqui: y = 3 * x + 1; que foi exibida na tela.
//Aqui x recebeu o valor de y.
if((x % 2 ) == 0 )//Esse é o calculo para saber se x e Par, No caso aqui
//x é par.
{
y = x / 2;//Esse e outro calculo que estava na apostila da caelum.

System.out.print(y + (" -> " )); //Vai imprimir o resultado disso aqui: y = x / 2;

}//Fim do primeiro if dentro do while.

if ((x % 2) == 1)//Esse e o calculo para saber se x e Impar.
{
y = 3 * x + 1;//Esse e outro calculo que estava na apostila da caelum.
System.out.print(y + (" -> "));//Vai imprimir na tela o resultado disso aqui: y = 3 * x + 1;

}//Fim do segundo if dentro do while dentro do if.

}//Fim do primeiro while.

//________________________________
//Se o numero digitado for Par executara esse codigo abaixo.

if((a % 2) == 0 )
{
y = a / 2;

System.out.println(y +(" O resultado do Calculo de Impar"));
System.out.println("Numero Par ");
}//Fim do segundo if.

while(y > 1 ) //Enquanto y maior que um, ele vai executar o seguinte codigo.
{
a = y; //Aqui esta sendo atribuido a “a” o resultado disso aqui: y = 3 * x + 1; que foi exibida na tela.
//Aqui x recebeu o valor de y.
if((a % 2 ) == 1 )//Esse é o calculo para saber se “a” e Par, No caso aqui
//“a” é par.
{
y = 3 * a + 1;//Esse e outro calculo que estava na apostila da caelum.

System.out.print(y + (" -> " )); //Vai imprimir o resultado disso aqui: y = x / 2;

}//Fim do primeiro if dentro do while.

if ((a % 2) == 0)//Esse e o calculo para saber se “a” e Impar.
{
y = a / 2;//Esse e outro calculo que estava na apostila da caelum.
System.out.print(y + (" -> "));//Vai imprimir na tela o resultado disso aqui: y = 3 * x + 1;

}//Fim do segundo if dentro do while dentro do if.

}//Fim do Segundo while.

}
}

[/code][/quote]

Caraca meu até pode funcionar o seu código, mais com +/- 15 linhas esse exercicio pode ser resolvido.

Pessoal, valeu mesmo pela ajuda, o código que eu fiz com as dicas funcionou e ficou muito mais limpo:

[code]public class Teste {

public static void main(String[] args){
	
	
	
	String string = javax.swing.JOptionPane.showInputDialog("Entre com um valor numerico: ");
	int x = Integer.parseInt(string);
	
	int y = x;

	while(y != 1){
		if(y % 2 == 0){
			y = x / 2;
			System.out.println(y);
		}else{
			y = (x * 3) + 1;
			System.out.println(y);
		}
	x = y;
	}
}

}
[/code]

marcoslogan com relação ao (), eu coloco por achar que o código fica mais “limpo” mesmo, com relação as variáveis, refiz tantas vezes que até pra mim ficou confuso e também por não saber utilizar o incremento no while, em uma situação que é o usuário que coloca um determinado valor, pois todas as vezes que o utilizei no meu treinamento em Java, quem iniciava o valor era eu mesma, primeira vez que me deparo com essa situação. Sua dica foi bem importante.

worldsoft em nenhuma das vezes que coloquei no while !=, sempre colocava >= e aí não dá certo… Valeu mesmo! Mas vc poderia me explicar o motivo de não dar certo colocando >= 1? Ele também não deveria parar no número 1 dessa forma?

Obrigada mais uma vez!

[quote=worldsoft]

Caraca meu até pode funcionar o seu código, mais com +/- 15 linhas esse exercicio pode ser resolvido.[/quote]

É que eu me empolguei um pouco escrevendo o código. Ah, e o programa funciona belezinha :lol:

Valeu quil , é sempre bom saber outras formas de fazer a mesma coisa, mesmo sendo “um pouco” maior…rs!

Se empolgou mesmo heim rs… :stuck_out_tongue:

[quote=Paola89]Pessoal, valeu mesmo pela ajuda, o código que eu fiz com as dicas funcionou e ficou muito mais limpo:

[code]public class Teste {

public static void main(String[] args){
	
	
	
	String string = javax.swing.JOptionPane.showInputDialog("Entre com um valor numerico: ");
	int x = Integer.parseInt(string);
	
	int y = x;

	while(y != 1){
		if(y % 2 == 0){
			y = x / 2;
			System.out.println(y);
		}else{
			y = (x * 3) + 1;
			System.out.println(y);
		}
	x = y;
	}
}

}
[/code]

marcoslogan com relação ao (), eu coloco por achar que o código fica mais “limpo” mesmo, com relação as variáveis, refiz tantas vezes que até pra mim ficou confuso e também por não saber utilizar o incremento no while, em uma situação que é o usuário que coloca um determinado valor, pois todas as vezes que o utilizei no meu treinamento em Java, quem iniciava o valor era eu mesma, primeira vez que me deparo com essa situação. Sua dica foi bem importante.

worldsoft em nenhuma das vezes que coloquei no while !=, sempre colocava >= e aí não dá certo… Valeu mesmo! Mas vc poderia me explicar o motivo de não dar certo colocando >= 1? Ele também não deveria parar no número 1 dessa forma?

Obrigada mais uma vez!

[/quote]

O que acontece é que como você digitava por exemplo o nº 13 a condição while não era feita, pois 13 >= 1 então a condição já estava satisfeita e o programa passava para a próxima linha fora do bloco while, mais se você colocar o != ele vai ficar no loop até satisfazer a condição.

e outra coisa esse exercicio pode ser feito também com if ternário simplificando a lógica do seu programa.

while (y != 1) {
			y = (x % 2 != 0 ? (x * 3) + 1  :  x / 2);  											
			x = y;
			System.out.println(y);  				            
}   

Dá de evitar declarar o y

veja:

[code] public class Teste {
public static void main(String[] args){
String string = javax.swing.JOptionPane.showInputDialog("Entre com um valor numerico: ");
int x = Integer.parseInt(string);

     while(x != 1){  
         x = (x % 2 != 0) ? (x * 3) + 1  :  x / 2;
         System.out.println(x);
     }  
 }  

}[/code]

uma coisa interessante você notar é que para diminuir a repetição de código deve-se colocar dentro do bloco if … else somente o que depender da condição. No seu código, por exemplo, você não deveria fazer a impressão dentro do bloco, pois por ventura depois houvesse modificação do método de impressão (para swing, por exemplo), você teria que editar em 2 locais, aumentando as chances de erro.

Boa sorte no estudo da lógica! é a parte mais importante para se tornar um bom programador!
Uma dica para cometer menos erros de lógica seria refletir sobre o problema antes de começar a desenvolver e praticar bastante!

Até!

Ah legal worldsoft , para um exercício simples como esse (agora que eu vejo que é simples, rs), o ideal é usar o if ternário mesmo… Obrigada por mais essa dica.

Então InSeOfKn, na internet há bastante material de livros de lógica e etc… Mas tem algum que tenha bastante exercícios e que é realmente bom para quem está iniciando, que você me aconselha?

Bom eu entendi essa parte, só não consegui fazer o resto que imprime aquela parte 40,10…
Acho que estou fazendo algo errado alguém me ajuda?

[code] package Teste2;
public class Atividade8{
public static void main (String args []){
int x=13;
int y=0;
int j=0;
if (x%2==0)
{
y=x/2;
System.out.println(y+",x e par!");
}
else
{
y=(3*x)+1;
System.out.println(“Não é par!”);
}

x=y;

if (x==y)
while (y != 1) {
j=x/2;
System.out.println(j);
}
}
}

[/code]

Se alguém puder me ajudar! Agradeço… Mas não coloquem algo tão monstruoso lembrando que eu sou super inciante nessa área e se usarem alguma outra classe vocês expliquem se puder por favor :wink:

Bom não sei se é meu netbeans, mas quando usei o operador ternário só deu 0 aqui!
Acho que tá dando problema :wink:

Oi rafaelaalves, beleza?

Vamos lá, você já ouviu falar do laço do while?
Bem, ele é como se fosse o while, sendo que ele sempre entra obrigatoriamente uma vez no teu laço e depois verifica a condição.
No seu problema ele evitaria a repetição de código e você poderia colocar o if else dentro do laço para fazer a verificação.

O problema pede que a repetição seja feita até que o valor de y = 1
Então de cara teríamos algo como:

do{
//Seu algoritmo
} while(y != 1);

Esse laço será o responsável por iterar o seu algoritmo que tem duas possíveis valores para y.
Se x é par teremos:

if( (x%2) == 0 ){
    y = x/2;
}

Caso contrário teremos:

else{ y = (3*x) + 1; }

Após isso o valor de y é impresso e então atribui-se o valor de y a x, para que o laço possa continuar a sua iteração.

Espero que tenha entendido, caso contrário pode postar sua dúvida que tentaremos lhe ajudar.

Abraços,

rafaelaalves, você está definindo a variável com o valor fixo de 13, porém o exercício pede que o usuário insira um valor. Dá uma olhada no código abaixo e faça o teste com qualquer número:

[code]public class ExerSete {

public static void main(String[] args){
	
int y = 0;

String string = javax.swing.JOptionPane.showInputDialog("Entre com um valor numerico: ");
int x = Integer.parseInt(string);

	while(x != 1){ 
		if(x % 2 == 0){
			y = x / 2;
			System.out.println(y);
		}else{
			y = (3 * x) + 1;
			System.out.println(y);
		}
	x = y;
	}
}	

}
[/code]

Você não precisa declarar todas aquelas variáveis…

Ou, você pode inicializar o y assim:

[code]public class ExerSete {

public static void main(String[] args){
	
String string = javax.swing.JOptionPane.showInputDialog("Entre com um valor numerico: ");
int x = Integer.parseInt(string);

int y = x;

	while(x != 1){... 

[/code]

Ôpa, sabia sim, mas havia esquecido como era a declaração eu não tinha percebido a segunda página e estava tentando algumas formas de resolver, mas foi ótima a dica!! Vou tentar resolver com ele.
Diane muito interessante o que vc me mostrou! Vou fazer uma mistura aqui :stuck_out_tongue_winking_eye: & depois mostro o resultado se eu conseguir!!
Valeu gente .