Block Prints

Asked

Viewed 69 times

1

The programme should:

  • receive a 4 digit number,
  • sort and keep,
  • sort downward and save.
  • Subtract increasing to decreasing and save so that the process starts again until subtraction equals 6174.

I cannot use arrays class methods.

I don’t understand how I should block the prints once I use a While the program goes into infinite loop.

If anyone can help

Example:

1: N=2016 A=6210 B=0126 A-B=6084

2: N=6084 A=8640 B=0468 A-B=8172

3: N=8172 A=8721 B=1278 A-B=7443

4: N=7443 A=7443 B=3447 A-B=3996

5: N=3996 A=9963 B=3699 A-B=6264

6: N=6264 A=6642 B=2466 A-B=4176

7: N=4176 A=7641 B=1467 A-B=6174

8: N=6174 A=7641 B=1467 A-B=6174

The code performed:

import java.util.Scanner;

public class Kaprekar {

    public static void main(String[]args){

        Scanner in = new Scanner (System.in);

        System.out.println("");
        int n0 = in.nextInt();

        do{
        int n1=0, n2=0, n3=0, n4=0;

        n1=(n0/1000);
        n2=((n0-n1*1000)/100);
        n3=((n0-n1*1000-n2*100)/10);
        n4=n0-n1*1000-n2*100-n3*10;

        int dmaior=n1, dmedio1=n1, dmedio2=n1, dmenor=n1;

        if(n2>n1&&n2>n3&&n2>n4){
            dmaior=n2;
            if(n3>n4&&n3>n1)
                dmedio1=n3;
            if(n4>n3&&n4>n1)
                dmedio1=n4;
            if(n3>n4&&n3<n1||n3>n1&&n3<n4)
                dmedio2=n3;
            if(n4>n3&&n4<n1||n4>n1&&n4<n3)
                dmedio2=n4;
            if(n3<n4&&n3<n1)
                dmenor=n3;
            if(n4<n3&&n4<n1)
                dmenor=n4;  
        }
        else if(n3>n1&&n3>n2&&n3>n4){
            dmaior=n3;
            if(n2>n4&&n2>n1)
                dmedio1=n2;
            if(n4>n2&&n4>n1)
                dmedio1=n4;
            if(n2>n4&&n2<n1||n2>n1&&n2<n4)
                dmedio2=n2;
            if(n4>n2&&n4<n1||n4>n1&&n4<n2)
                dmedio2=n4;
            if(n2<n4&&n2<n1)
                dmenor=n2;
            if(n4<n2&&n4<n1)
                dmenor=n4;  
        }
        else if(n4>n1&&n4>n2&&n4>n3){
            dmaior=n4;
            if(n3>n2&&n3>n1)
                dmedio1=n3;
            if(n2>n3&&n2>n1)
                dmedio1=n2;
            if(n3>n2&&n3<n1||n3>n1&&n3<n2)
                dmedio2=n3;
            if(n2>n3&&n2<n1||n2>n1&&n2<n3)
                dmedio2=n2;
            if(n3<n2&&n3<n1)
                dmenor=n3;
            if(n2<n3&&n2<n1)
                dmenor=n2;  
        }

        int dr=dmaior*1000+dmedio1*100+dmedio2*10+dmenor;
        int cmaior=dmenor;
        int cmedio1=dmedio2;
        int cmedio2=dmedio1;
        int cmenor=dmaior;
        int cr=cmaior*1000+cmedio1*100+cmedio2*10+cmenor;
        int rr=dr-cr;

        System.out.println("N="+n0+" A="+cr+" B="+dr+" A-B="+rr);

        n0=rr;

        }
        while (n0!=6174);

    }
}

1 answer

1


The real problem is that your ordering does not consider all possibilities. For example, you do not have a if checking whether the n1 is the largest number. I would advise you to separate that part of the ordering into a separate method and I can’t think at the moment of a method that wouldn’t get too large comparing number by number, so I simplified it using a array. Your code would look like this:

import java.util.Arrays;
import java.util.Scanner;

public class Kaprekar {

  public static void main(String[] args) {

    Scanner in = new Scanner(System.in);

    System.out.println("");
    int n0 = in.nextInt();

    do {
      int cr = ordenar(n0);
      int dr = inverter(cr);
      int rr = dr - cr;

      System.out.println("N=" + n0 + " A=" + cr + " B=" + dr + " A-B=" + rr);

      n0 = rr;

    } while (n0 != 6174);

  }

  private static int ordenar(int numero) {
    int[] listaNumero;

    listaNumero = inteiroParaArray(numero);
    Arrays.sort(listaNumero);

    return arrayParaInt(listaNumero);
  }

  private static int inverter(int numero) {
    StringBuilder construtor;
    String invertido;
    String texto;

    texto = String.format("%04d", numero); // Completa com 0
    construtor = new StringBuilder(texto);
    invertido = construtor.reverse().toString();

    return Integer.parseInt(invertido);
  }

  private static int[] inteiroParaArray(int numero) {
    String numeroString = String.valueOf(numero);
    int[] resultado = new int[numeroString.length()];
    int indice;

    for (indice = 0; indice < numeroString.length(); indice++) {
      resultado[indice] = numeroString.charAt(indice) - '0';
    }

    return resultado;
  }

  private static int arrayParaInt(int[] numeros) {
    StringBuilder numeroString = new StringBuilder();
    int resultado;

    for (int numero : numeros) {
      numeroString.append(numero);
    }

    resultado = Integer.parseInt(numeroString.toString());

    return resultado;
  }
}

One observation is that the output you put in your question produces the opposite result since To should be crescent.

I rewrote your code to make it a little more organized, using a little clearer nomenclature and also dividing it into methods. I also altered it so that the logic wasn’t in the method main:

import java.util.Arrays;
import java.util.Scanner;

public class Kaprekar {

  public static void main(String[] args) {
    Kaprekar kaprekar = new Kaprekar();

    kaprekar.ler();
  }

  public void ler() {
    Scanner entrada;
    String lido;

    entrada = new Scanner(System.in);
    /* Utilizei nextLine para que você possar validar se realmente é um inteiro
     * ou não, afinal se o usuário digitar algo que não seja número será retornado
     * um erro ilegível */
    lido = entrada.nextLine();
    try {
      this.validar(lido);

      while (!lido.equals("6174")) {
        int milhar;
        int centena;
        int dezena;
        int unidade;
        int[] listaCrescente;
        int[] listaDecrescente;
        int crescente;
        int decrescente;
        int subtracao;

        // Pega os valores numéricos para serem utilizados na ordenação de acordo com a posição
        milhar = Character.getNumericValue(lido.charAt(0));
        centena = Character.getNumericValue(lido.charAt(1));
        dezena = Character.getNumericValue(lido.charAt(2));
        unidade = Character.getNumericValue(lido.charAt(3));

        listaCrescente = new int[]{milhar, centena, dezena, unidade};
        // Ordena o array de forma crescente
        Arrays.sort(listaCrescente);
        listaDecrescente = inverter(listaCrescente);

        crescente = this.arrayParaInt(listaCrescente);
        decrescente = this.arrayParaInt(listaDecrescente);
        subtracao = decrescente - crescente;

        System.out.println("N=" + lido
                + " A=" + this.mostrarFormatado(crescente)
                + " B=" + this.mostrarFormatado(decrescente)
                + " A-B=" + this.mostrarFormatado(subtracao));
        lido = String.valueOf(subtracao);
      }
    } catch (NumberFormatException ex) {
      System.out.println("O valor lido não é um número");
    } catch (Exception ex) {
      System.out.println(ex.getMessage());
    }
  }

  /**
   * Valida o que foi incluído pelo usuário
   *
   * @param lido
   * @throws Exception
   */
  private void validar(String lido) throws Exception {
    Integer.parseInt(lido); // Retornará um NumberFormatException que será tratado no método que chamou

    if (lido.length() != 4) {
      throw new Exception("O valor lido " + lido + " não tem 4 caracteres");
    }
  }

  /**
   * Inverte o array de inteiro
   *
   * @param base
   * @return Um novo array invertido
   */
  private int[] inverter(int[] base) {
    int[] resultado = new int[base.length];
    int indiceBase;
    int indiceRetorno;

    indiceRetorno = 0;

    // Percorre o array de base de trás pra frente
    for (indiceBase = (base.length - 1); indiceBase >= 0; indiceBase--) {
      resultado[indiceRetorno] = base[indiceBase];
      indiceRetorno++;
    }

    return resultado;
  }

  /**
   * Transforma um array de inteiro um novo inteiro
   *
   * @param numeros
   * @return Um inteiro com as posições do array
   */
  private int arrayParaInt(int[] numeros) {
    StringBuilder numeroString = new StringBuilder();
    int resultado;

    for (int numero : numeros) {
      numeroString.append(numero);
    }

    resultado = Integer.parseInt(numeroString.toString());

    return resultado;
  }

  /**
   * Mostra um inteiro formatado com 4 dígitos
   *
   * @param numero
   * @return
   */
  private String mostrarFormatado(int numero) {
    return String.format("%04d", numero);
  }
}

EDIT 1

If you don’t want to use arrays as it was added in the question you can change the method ordenar to the following and apply it in the first example by removing methods that will be unused:

private static int ordenar(int numero) {
  int a = numero / 1000;
  int b = ((numero - a * 1000) / 100);
  int c = ((numero - a * 1000 - b * 100) / 10);
  int d = numero - a * 1000 - b * 100-c * 10;
  int tmp;

  if (a > b) { tmp = a; a = b; b = tmp; }
  if (c > d) { tmp = c; c = d; d = tmp; }
  if (a > c) { tmp = a; a = c; c = tmp; }
  if (b > d) { tmp = b; b = d; d = tmp; }
  if (b > c) { tmp = b; b = c; c = tmp; }

  return a * 1000 + b * 100 + c * 10 + d;
}

Your final code without using Integer.parseInt would look like this:

import java.util.Scanner;

public class Kaprekar {

  public static void main(String[] args) {

    Scanner in = new Scanner(System.in);

    System.out.println("");
    int n0 = in.nextInt();
    int ultimoResultado;

    do {
      int cr = ordenar(n0);
      int dr = inverter(cr);
      int rr = dr - cr;

      System.out.println("N=" + n0 + " A=" + dr + " B=" + cr + " A-B=" + rr);
      ultimoResultado = n0;
      n0 = rr;
    } while (n0 != ultimoResultado);

  }

  private static int ordenar(int numero) {
    int a = numero / 1000;
    int b = ((numero - a * 1000) / 100);
    int c = ((numero - a * 1000 - b * 100) / 10);
    int d = numero - a * 1000 - b * 100-c * 10;
    int tmp;

    if (a > b) { tmp = a; a = b; b = tmp; }
    if (c > d) { tmp = c; c = d; d = tmp; }
    if (a > c) { tmp = a; a = c; c = tmp; }
    if (b > d) { tmp = b; b = d; d = tmp; }
    if (b > c) { tmp = b; b = c; c = tmp; }

    return a * 1000 + b * 100 + c * 10 + d;
  }

  private static int inverter(int numero) {
    int a = numero / 1000;
    int b = ((numero - a * 1000) / 100);
    int c = ((numero - a * 1000 - b * 100) / 10);
    int d = numero - a * 1000 - b * 100-c * 10;

    return d * 1000 + c * 100 + b * 10 + a;
  }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.