Imprimir quadrado usando apenas while e if [Resolvido]

Bom dia. Estou com um problema para fechar o lado vertical direito de um quadrado que é impresso com asteriscos. O usuário insere o valor do lado do quadrado e este deve ser impresso com nº de asteriscos igual ao valor do lado propriamente dito. Obrigado pela ajuda. :slight_smile:

package asteriscoquadrado;

/**
 *
 * @author Eduardo Felipe
 */
import java.util.Scanner;

public class AsteriscoQuadrado
{

    public static void main(String[] args)
    {

        int l = 0, l2, l3, l4;
        // variáveis utilizadas na construção do quadrado.
        Scanner input = new Scanner(System.in);

        // enquanto o usuário não inserir um valor no intervalo de 1 e 20
        while (l < 1 || l > 20)
        {
            System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");
            l = input.nextInt();
        }

        l2 = l;
        l3 = l;
        l4 = l;

       
        while (l != 0)
        {
            //impressão da reta horizontal superior
            System.out.print("*\b");
            --l;
        }

       // quais são as instruções necessárias para imprimir a reta vertical direita?
        
        while (l3 != 1)
        {
            // impressão da reta vertical esquerda
            System.out.print("\n*");
            --l3;
        }

        while (l4 != 1)
        {
            // impressão da reta horizontal inferior
            System.out.print("\b*");
            --l4;
        }

        System.out.println();
    } // fim de main
} // fim da classe AsteriscoQuadrado

Tio, não dá para fazer as coisas desse jeito aí que você quer fazer.
Não existe um caracter especial que se chame “retornar uma linha para cima” e que faça o contrário do “\n” que você usou aí.
O jeito certo de fazer isso é com espaços mesmo - mais ou menos assim:

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

Note que para os lados do quadrado com lado 5, você precisa imprimir um asterisco, a seguir 5 - 2 espaços, então outro asterisco. Você precisa imprimir 5 -2 linhas assim desse jeito. OK?

Entendi o que você quis dizer. Mas desta forma que você implementou, eu não teria que escrever a quantidade de asteriscos por conta própria? assim, não adiantaria nada o usuário inserir o lado para que o quadrado fosse desenhado na execução. Não teria como adicionar certas instruções logo abaixo do while do l1 para que fosse impressa a linha vertical direita com o valor do lado que o usuário inseriu ?

Eu dei o valor “5” só para você entender melhor o meu exemplo. Substitua “5” por “n” onde “n” é o número que foi digitado pelo usuário.

Mas eu não estou entendendo uma coisa. Por exemplo, vamos supor que o usuário tenha inserido 10 como valor de lado. Pelo que eu entendi que você me explicou, eu teria que dar espaços até conseguir " encaixar " o lado vertical direito no lado horizontal superior, não é mesmo? ou seja, eu teria que praticamente adivinhar o número que o usuário teria inserido para inserir a quantidade correta de espaços. Se ele inserisse 20, a quantidade de espaços arbitrários que eu teria criado seria insuficiente para esse valor e a reta vertical direita apareceria na metade da projeção da reta horizontal superior. Tipo assim:

[code]******************************
*
*
*
*

      [/code]

Não, não, não, não tem de adivinhar nada. Você ficou com essa idéia de desenhar cada lado de uma vez, mas isso não é possível usando print, já que não existe um caracter que “suba” em vez de “descer” linhas.

Não é para desenhar um quadrado de lado 5 (por exemplo)? Então o usuário entra com o valor 5, e aí seu programa:

  • Imprime a primeira linha, que contém 5 (ou seja, N) asteriscos. Use println para terminar a linha (não use “\n” que não é confiável).

  • Imprime 3 linhas (ou seja, N - 2 linhas), que contém um asterisco, mais N - 2 espaços, e depois um asterisco. Para terminar essa linha, use println.

  • Imprime a última linha, que contém N asteriscos.

[quote=entanglement] mais N - 2 espaços
[/quote]

Como eu faço isso? :?

Você sabe usar um “for”? O “for” é exatamente a mesma coisa que um “while” disfarçado. Você sabe usar um for para imprimir n - 2 espaços?

for (int i = 0; i < n - 2; i++) {
    System.out.print (" ");
}

Pois bem, o “while” correspondente seria:

int i;
i = 0;
while (i < n - 2) {
    System.out.print (" ");
    i++;
}

[quote]Você sabe usar um “for”? O “for” é exatamente a mesma coisa que um “while” disfarçado. Você sabe usar um for para imprimir n - 2 espaços?[/quote] Desculpa entanglement, eu deveria ter avisado que o exercício impôs a condição de serem usados só o while e o if. Eu estou tentando dar um jeito de imprimir os asteriscos \b asteriscos decrementando uma variável que eu criei para isso. Depois eu digo se consegui desenvolver o algoritmo. Muito obrigado pela ajuda entanglement! :slight_smile:

Uai, usei um while em vez de for para imprimir n - 2 brancos.

Uma coisa que ajuda bastante em computação é o seguinte: digamos que você saiba resolver as coisas de uma determinada maneira (com “for”), mas essa maneira é proibida.
Mas você sabe que essa tal maneira proibida é equivalente a outra maneira permitida (com “while”), de forma mecânica (você conseguiu ligar os pontos e ver como é que o for é equivalente ao while?)
Então você usa a forma permitida, mas pensando como se fosse a forma proibida.

Por favor, amigo, não insista nesse jeito de fazer com “\b”. É perda de tempo.

Procure por System.out.printf (ou String.format) e os argumentos possíveis para formatação. Por exemplo:

System.out.printf("%10s%n", "Olá");

Esse código imprime “Olá” alinhado à direita, usando 10 casas (ou seja, ele já completa com os devidos espaços se preciso).

Essa eu não sabia… qual o motivo de não ser confiável?

Bom, estava simplificando um pouco o problema pro PhoenixWings.
É que normalmente o caracter que serve para ir para a próxima linha é o “\n”, mas no caso do Windows a sequência correta é “\r\n” (2 caracteres), e o println já toma conta dessa diferença para você.
Em vez de aprender que é para usar “\n” (e descobrir que quando for criar um arquivo no Windows para o Notepad - Bloco de Notas - ler é necessário usar “\r\n” para evitar que o Notepad se confunda), é melhor aprender que se deve usar “println” que já faz as coisas automáticas para você.

É verdade, o Windows tem dessas também… mas no caso do printf, basta usar “%n” que funciona perfeitamente.

Obrigado a todos pela ajuda :slight_smile: . Eu consegui implementar o algoritmo para imprimir as retas verticais da direita e esquerda ao mesmo tempo. Só que agora eu não estou conseguindo colocar o resto dos asteriscos entre a primeira linha e a última linha. Toda instrução que eu escrevo faz com que os asteriscos saiam do escopo do desenho do quadrado. Eu já tentei vários testes mas não consegui. Segue abaixo o código do algoritmo das retas verticais:

[code]

// L é o valor do lado que declarei anteriormente
L2 = L;
L3 = L;
L4 = L;
int i = 0;

/* código para imprimir as retas verticais da esquerda e da direita
* ao mesmo tempo */
while (L != 0)

    {
       System.out.print("*");

        while (i < L2)
        
        {
            System.out.print(" ");
            i++;
        }
       
       System.out.print("*");
       System.out.println();
        --L;
        i = 0;
        // atribui novamente ao i o valor zero para que os espaços sejam considerados de novo
    } [/code]

olá phoenix,

não sei se é bem o que você queria, mais fiz uma coisinha aqui… testa pra ver se funciona… acabou meu expediente e estou meio atrasado…

[code]import java.util.Scanner;

public class AsteriscoQuadrado {

private int comprimento = 0;

private int getComprimento() {
    Scanner input = new Scanner(System.in);
    return input.nextInt();
}

private void geraLinha() {
    int i = 0;
    while (i < this.comprimento) {
        System.out.print("*");
        i++;
    }
}

private void exibe() {
    System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");
    
    this.comprimento = this.getComprimento();

    if (this.comprimento < 1 || this.comprimento > 20) {
        this.exibe();
    }

    this.geraLinha();

    System.out.print("\n*");
    int i = 0;
    while (i < (this.comprimento -2)) {
        System.out.print(" ");
        i++;
    }
    System.out.print("*\n");

    this.geraLinha();
}

public static void main(String[] args) {
    new AsteriscoQuadrado().exibe();
}

}[/code]

até mais…

Boa noite joselmocs. É parecido com o que eu queria: só faltaram mesmo as linhas verticais terem a quantidade de asteriscos das horizontais. Mas muito obrigado! vou estudar detalhadamente o seu algoritmo agora mesmo!

A idéia consiste em criar o quadrado abaixo (lógico, com o tamanho variando dependendo do valor do lado inserido pelo usuário):

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

Pessoal não consegui, obrigado a todos. Acredito que falta-me conhecimento. Depois eu volto a este código. :cry:

Olá phoenix,

entendi o que você quer agora, vê se este código te serve:

[code]import java.util.Scanner;

public class AsteriscoQuadrado {

private int comprimento = 0;

private int getComprimento() {
    Scanner input = new Scanner(System.in);
    return input.nextInt();
}

private void geraLinha() {
    int i = 0;
    while (i < this.comprimento) {
        System.out.print("*");
        i++;
    }
}

private void exibe() {
    System.out.print("Informe o lado do quadrado (comprimento de 1 a 20): ");

    this.comprimento = this.getComprimento();

    if (this.comprimento < 1 || this.comprimento > 20) {
        this.exibe();
    }

    this.geraLinha();
    this.geraHorizontal();
    this.geraLinha();
}

private void geraHorizontal() {
    int l = 0;
    System.out.print("\n");
    while (l < (this.comprimento -2)) {
        System.out.print("*");
        int i = 0;
        while (i < (this.comprimento -2)) {
            System.out.print(" ");
            i++;
        }
        System.out.print("*\n");
        l++;
    }
}

public static void main(String[] args) {
    new AsteriscoQuadrado().exibe();
}

}[/code]

abraços

Serve sim, obrigado joselmocs! eu vou estudar o algoritmo implementado por você. Abraços!

Compreendi a lógica do seu algoritmo. Anteriormente, eu havia entendido que comprimento - 2 significava a quantidade de espaços menos os asteriscos. Contudo, eu tinha esquecido que após a impressão do asterisco, o cursor ficava no próprio asterisco.