Lock Prints [closed]

1

The program should:

  • receive a 4-digit number,
  • Increasing sorting and saving,
  • Sorting in descending order and saving.
  • Subtract from ascending to descending and save so that you can run the process from scratch until the subtraction equals 6174.

I can not use arrays class methods.

I do not understand how I should block the prints once using a While the program goes into infinite loop.

If anyone can help thank you

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 used:

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);

    }
}
    
asked by anonymous 20.11.2016 / 15:33

1 answer

1

The real problem is that your ordering does not consider all possibilities. For example, you do not have if checking that n1 is the largest number. I would advise you to separate this part of the ordering into a separate method and I can not think of a method that would not look great by comparing number by number, so I simplified using 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 note is that the output you put into your question produces the inverse result since A should be growing . >

I rewrote your code to make it a bit more organized, using a slightly clearer nomenclature and also dividing it into methods. I also changed so that the logic was not in the main method:

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 do not want to use arrays as added in the question you can change the method ordenar to the following and apply it in the first example, removing methods that will be left 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;
  }
}
    
20.11.2016 / 16:55