Desafio do diamante

Nesse artigo iremos resolver o Desafio do Diamante em Java, que foi proposto na página de Exercícios envolvendo laços.


Desafio diamante de asteriscos:
Escreva um aplicativo Java que peça um número inteiro ímpar ao usuário e desenhe um diamante no seguinte formato:

    *
   ***
  *****
 *******
*********
 *******
  *****
   ***
    *


Nesse caso, o número é 9, pois há 9 colunas e 9 asteriscos na linha central.

SOLUÇÃO
Há duas coisas na figura: espaços em branco e asteriscos.
Vamos resolver esse desafio analisando o padrão do número de asteriscos (variável asteriscos) e do número de espaços em branco (variável espacos).

Antes de desenhar o diamante, temos que checar se o número que o usuário forneceu é ímpar, através de um teste condicional:
if(numero%2 != 0)

Se não for, o programa cai no else e nossa aplicação Java é finalizada.
Vamos desenhar o dito cujo.

Parte de cima do diamante
Qual o número inicial de espaços?
Note que é sempre: (numero-1)/2
...e essa é a lógica do problema, a parte mais difícil, que é notar esse padrão.

E o número de asteriscos inicial?
Fácil, é 1 e vai crescendo de 2 em 2 até que o número de asteriscos impressos seja igual a numero.

Pois bem, vamos desenhar linha por linha, imprimindo primeiro o número correto de espaços e depois o de asteriscos.
Esse controle de linhas é feito pela linha de código:
for(int linha=1 ; espacos > 0 ; linha++)

Ou seja, vamos imprimir da linha 1 até a linha central (note que a linha central é a que tem espacos=0).

Agora, dentro desse looping vamos imprimir, em cada linha, primeiro o número de espaços e depois os asteriscos.
Sabemos que o número inicial de espaços é (numero-1)/2 e o número inicial de asteriscos é 1.

Para imprimir o número correto de espaços e asteriscos vamos usar a variável count:
for(int count=1 ; count <= espacos ; count++)
for(int count=1 ; count <= asteriscos ; count++)

Após o looping maior, o das linhas, temos que decrementar o número de espaços em 1, e incrementar o número de asteriscos em 2, além da quebra de linha.


Parte de cima do diamante
A lógica é a mesma da de cima, porém o número de espaços aumenta em 2, e o número de asteriscos é decrementado em 2.
Outra diferença é que vamos imprimir uma linha a menos, pois a linha central já foi impressa. Assim, essas linhas são impressas desde a primeira abaixo da linha central, até enquanto houver asteriscos (até ter 1, que é o último):
for(int linha=1 ; asteriscos > 0 ; linha++)

Logo, nosso código Java fica assim:

import java.util.Scanner;

public class DesafioDoDiamante {
    public static void main(String[] args) {
        int numero,
            espacos,
            asteriscos;
        Scanner entrada = new Scanner(System.in);
        
        System.out.print("Insira um número ímpar: ");
        numero = entrada.nextInt();
        
        if(numero%2 != 0){
            
            //Imprimindo a parte de cima do diamante
            asteriscos = 1;
            espacos = (numero-1)/2;
            for(int linha = 1 ; espacos > 0 ; linha++){
                
                //Espaços
                for(int count = 1 ; count <= espacos ; count++){
                    System.out.print(" ");
                }
                
                //Asteriscos
                for(int count = 1 ; count <= asteriscos ; count++){
                    System.out.print("*");
                }
                
                espacos--;
                asteriscos += 2;
                System.out.println();
            }
            
            //Imprimindo a parte de baixo do diamante
            for(int linha=1 ; asteriscos > 0 ; linha++){
                
                //Espaços
                for(int count = 1 ; count <= espacos ; count++){
                    System.out.print(" ");
                }
                
                //Asteriscos
                for(int count = 1 ; count <= asteriscos ; count++){
                    System.out.print("*");
                }
                
                espacos++;
                asteriscos -= 2;
                System.out.println();
            }
            
        }else{
            System.out.println("Não é ímpar!");
        }
        
        
    }
}


Lembrando que essa é apenas uma solução, é possível fazer usando menos linhas, porém o entendimento é mais complicado. Tente!

7 comentários:

rafa correa disse...

Incrível como este simples exercício desperta diversos conhecimentos!
parabéns pelo site!

Maxwell Aguiar Silva disse...

Javascript: usando raiz quadrada você pode fazer a parte de baixa no mesmo laço!

x=5;
str="";
if(! x % 2)return false;
borda=x-1;
for(i=-borda;i<=borda;i++){
str+="\n";
for(j=0;j<Math.sqrt(i*i);j++)str+=" ";
for(j=0;j<(x-Math.sqrt(i*i))*2-1;j++)str+="*";
}

Giovani Pan Berra disse...

O meu ficou assim:


package diamante;

import java.util.Scanner;

public class Diamante {

public static void main(String[] args) {
int n;
Scanner entrada = new Scanner(System.in);

System.out.println("Informe um numero impar para o tamanho do diamente: ");
n = entrada.nextInt();
if (n % 2 == 0){
System.out.println("Número informado não é impar. Programa encerrando");
}
else {
for (int count_l = 0; count_l < n; ++count_l){
if (count_l <= n/2 ){
for (int count_c = 0; count_c < n; ++count_c){
if (count_c < n /2 - count_l || count_c > n/2 + count_l ){
System.out.print(" ");
}
else {
System.out.print("*");
}
}
}
else {
for (int count_c = 0; count_c < n; ++count_c){
if (count_c < n/2 - (n - count_l -1) || count_c > n/2 + (n - count_l -1) ){
System.out.print(" ");
}
else {
System.out.print("*");
}
}
}
System.out.print("\n");
}
}
}
}

Rerivaldo disse...

Eu usei um Do While, para repetir a pergunta se o usuário não digitar um número impar. Ficou assim:

import java.util.Scanner;
public class Diamante_de_Aster1 {
public static void main(String[]args){
int impar;
boolean continuar = true;
Scanner entrada=new Scanner(System.in);
do{
System.out.print("DIGITE UM NÚMERO INTEIRO IMPAR: ");
impar = entrada.nextInt();

if((impar%2)!=0){
continuar=false;
System.out.println("O NÚMERO DIGITADO É IMPAR: ");
System.out.println();
for(int cont=0;cont<=(impar/2)-0.5;cont++){
for(int cont1=0;cont1<((impar/2)-cont);cont1++){
System.out.print(" ");
}
for(int cont2=0;cont2<=2*cont;cont2++){
System.out.print("*");
}
System.out.println();
}
for(int cont4=1;cont4<=impar;cont4++){//EXECUTA A IMPRESSÃO DOS ASTERISCOS
System.out.print("*"); //DO MEIO DO DIAMANTE(LOSANGO).
}
System.out.println();
for(int cont=0;cont<=(impar/2)-0.5;cont++){

for(int cont2=0;cont2<=cont;cont2++){
System.out.print(" ");
}
for(int cont3=0;cont3<((impar-2)-2*cont);cont3++){
System.out.print("*");//EXECUTA A IMPRESSÃO DOS ASTERISCOS, INFERIORES.
}
System.out.println();
}
break;
}
else{
System.out.println("O NÚMERO DIGITADO É PAR!");
System.out.println();
}
}while(continuar);
}
}

Anônimo disse...

Olá pessoal. Evisclei.
Parabéns pela iniciativa, na internet tem muito mais sobre Java, mas é preciso garimpar em muitos locais diferentes.

Olha só como ficou o meu código do desafio, notem que eu consegui utilizar os mesmos laços tanto para a primeira quanto para a segunda parte do "diamante" com o auxilio de um 'if...else' e da Matemática -- santa Matemática. Com isso eu consegui diminuir muito o número de linhas de código.


Scanner entrada = new Scanner(System.in);

//Número ímpar qualquer
int n;
System.out.print("Informe um número impar qualquer: ");

n = entrada.nextInt();

for (int i = 1; i <= n; i++) {
//Espaços que serão inseridos antes dos asterísticos.
int espacos;
//Este if...else controla se o número de asteríscos é crescente ou decrescente.
if (i <= (n + 1) / 2) {
espacos = (n - 2 * i + 1) / 2;
} else {
espacos = (2 * i - n - 1) / 2;
}
//Varíavel utilizada para controle do laço 'while' e inserção de espaços ou asterísticos.
int j = 1;
//O número de repetições do laço 'while' é igual ao número de espaços
// que tem antes dos asterísticos mais o número de asterísticos.
while (j <= n - espacos) {
if (j <= espacos) {
System.out.print(" ");
} else {
System.out.print("*");
}
j++;
}
System.out.print("\n");
}

Jhionan (Ice Dragon) disse...

Não quis olhar a solução e acabei perdendo umas 3 horas pra descobrir o que estava dando errado no meu diamante, no fim percebi que não era o inicio do laço que tinha q decrementar e sim a comparação...

fica ai meu diamante..



package diamante;
import java.util.Scanner;
/**
*
* @author E
*/
public class Diamante {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here


Scanner ent = new Scanner(System.in);

int tamanho;

System.out.print("Digite o tamanho do diamante: ");
tamanho = ent.nextInt();

if (tamanho%2 !=1) //se o numero for par o diamante será o numero + 1
{

tamanho = tamanho +1;
}

System.out.println("\n");

int m = (tamanho/2); //tamanho do espaço max do diamante.

//laço de repetição para criar cada linha
for (int i=1; i<=tamanho; i++)
{

if ((i==1)||(i%2!=0)) //if para imprimir só linhas impares
{
for (int es=1; es<=m; es++) //laço para impressão dos espaços (m decremento fora do laço)
{
System.out.print(" ");

}
m--;
for (int x=1; x<=i; x=x+1) //laço para impressação do *
{

System.out.print("*");
}
System.out.print("\n");// pula linha




}
}
//Parte de baixo do diamante m sempre será 1 na primeira linha
m=1;
for (int i=(tamanho-2); i>=1; i--) //laço de pular linha decrementando pra usar de valor nos *
{

if ((i==1)||(i%2!=0)) //imprime nas linahs impares
{
for (int es=1; es<=m; es++) //imprime espaços
{
System.out.print(" ");

}
m++; //incrementa m
for (int x=1; x<=i; x=x+1) //imprime *
{

System.out.print("*");
}
System.out.print("\n"); //pula linha




}





}
}

}

games disse...

O meu programa ficou com 34 linhas e seguiu uma lógica bem diferente. Usei mais funções. Usei o programa Geogebra pra achar a fórmula da função de uma reta a partir de dois pontos. E o meu programa n precisou de duas partes, uma pra parte de cima e outro pra parte debaixo. Acho muito legal isso de haver várias formas de resolver o mesmo problema.

package main;

import static java.lang.Math.abs;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner entrada = new Scanner(System.in);
System.out.println("Digite");
int f = entrada.nextInt();
if (f % 2 == 1) {
for (int linha = 1; linha <= f; linha++) {
for (int space = abs(linha - ((f + 1) / 2)); space > 0; space--) {
System.out.print(" ");
}
if (linha <= ((f + 1) / 2)) {
for (int sterix = (2 * linha - 1); sterix > 0; sterix--) {
System.out.print("*");
}
} else {
for (int sterix = ((-2) * linha + (2 * f + 1)); sterix > 0; sterix--) {
System.out.print("*");
}

}
System.out.print("\n");

}
} else {
System.out.print("Digite um número impar\n");
}
}
}

Dicas e Novidades de Java por e-mail

Sabe quanto custa um bom livro de java?
Entre R$ 100,00 e R$300,00

Sabe quanto custa um bom curso presencial de Java?
Entre R$ 1.500,00 até R$ 4.000,00

Sabe quanto custa estudar pelo Java Progressivo?
Absolutamente nada.

Porém, também precisamos de sua ajuda e apoio.
Para isso, basta curtir nossa Fan Page e clicar no botão G+ do Google.