Doubt - Logic of numbers that change places

4

I'm trying to put together an algorithm in C to find integers that change places by multiplying by another.

I did not find problems like this on the internet, I do not even know if I can do this with integers. But a brief example with fractional numbers is: 12 * 1.75 = 21

For four-digit numbers; 1489, should be 9148.

I wanted your help not to receive a complete code, but rather a path / logic to follow to develop the code.

The way I'm thinking is the following:

a variable "counter = 1". a while body to find numbers that change places between 1 and 1 million. The multiplication numbers for tests are only 2, 3, 4, 5, 6, 7, 8 and 9. Instead of using ++ counter, use counter + = nTest;

Notes

I'm a beginner in programming. I can not find which condition to use to know if the number has changed position or not. I have not yet studied array's in C, so my code will only find a single number and display it. If I knew array's, I could go storing all the numbers I find up to a million and then display all of them. I tried to explain my doubt, but if you do not understand any part, just leave a comment.

Thank you.

The following code is quite early in what I'm trying to do;

#include <stdio.h>
#include <locale.h>

int main(int argc, char const *argv[]) {

    setlocale(LC_ALL, "");

    //Número inteiros.
    int u, d, c, m, md, mc, mi, contador;

    //Números de testes para multiplicação.
    int nTeste;


    /*int iU, iD, iC, iM, iMD, iMC, iMI, total;*/


    /*Variáveis para extrair os dígitos de cada posição.
    Ex: Para extrair "2" de "21"; "tempDecimal = 21 / d".*/
    u = 1;          //Unidades
    d = 10;         //Dezenas
    c = 100;        //Centenas
    m = 1000;       //Milhar
    md = 10000;     //Dezenas de milhar
    mc = 100000;    //Centenas de milhar
    mi = 1000000;   //Milhão


    while (nTeste >= 2 && nTeste <= 9) {
        printf("Digite um número para teste: [2 a 9]");
        scanf("%d", &nTeste);
    }

    while (contador <= mi) {

        if (contador <= u) {

        }

        if (contado > u && contador <= d) {

        }

        if (contado > d && contador <= c) {

        }

        if (contado > c && contador <= m) {

        }

        if (contado > m && contador <= md) {

        }

        if (contado > md && contador <= mc) {

        }

        if (contado > mc && contador <= mi) {

        }



    }

    return 0;
}
    
asked by anonymous 04.06.2015 / 16:52

2 answers

2

Your idea of dividing by powers of 10 to extract each digit from the number is essentially right; you do not need to save the numbers you found in an array to print only at the end: it's okay to have a if (/* número é válido */) { printf("%d\n", contador); } in the middle of your while; so your program will print the cyclic numbers as they are found.

The part that would normally be done with arrays would, as you might have guessed, compare if e.g. 1489 and 9148 have the same digits. With arrays, you can put each digit in the array, sort and compare the two arrays.

One trick that works for this particular case is to use Gödel numbering to find these cases. Specifically, consider the "cousins"

p_0 = 1
p_1 = 2
p_2 = 3
p_3 = 5
p_4 = 7
p_5 = 11
p_6 = 13
p_7 = 17
p_8 = 19
p_9 = 23

You will represent the number 1489 by the product p₁ × p₄ × p₈ × p₉ = 2 × 7 × 19 × 23 = 6118; and the number 9148 = p₉ × p₁ × p₄ × p₈ = 23 × 2 × 7 × 19 = 6118. These products are the Gödel number of the original number.

You must have learned at some point in your elementary school, every integer (positive) has a unique factorization as the product of prime numbers (eg 120 = 2³ × 3 × 5). Since the multiplication operation is commutative, it implies that two integers X and Y have the same Gödel number if and only if X and Y have the same digits (this is the key fact of the idea - if You do not understand why this is true, shout at the comments.)

How will you implement this in code? You will, for both the original number and the number multiplied by nTeste , do something like

int goedel = 1;
int digito;

/* extrai um dígito do número, guarda em digito */

if (digito == 0) { goedel *= 1; }
if (digito == 1) { goedel *= 2; }
if (digito == 2) { goedel *= 3; }
if (digito == 3) { goedel *= 5; }
if (digito == 4) { goedel *= 7; }
if (digito == 5) { goedel *= 11; }
if (digito == 6) { goedel *= 13; }
if (digito == 7) { goedel *= 17; }
if (digito == 8) { goedel *= 19; }
if (digito == 9) { goedel *= 23; }

After you've finished running this block from if s to each digit, you can compare the two values of goedel - if they are equal, you can conclude that contador and contador * nTeste have the same% digits (albeit in different orders).

(An important fact for this idea to work, whose relevance you will not understand today, but whose relevance you will understand when you have studied more programming, and in particular microprocessor of processors, is that 23⁷ is less than 2³².)

    
04.06.2015 / 17:50
1

Let x be a natural number and y another natural number that is anagram of x in base 10, / em> ≠ y .

To find the multiplier m that multiplied by x results in y , we have:

  

m * x = y
  m = y / x

Since both x and y are natural and x is nonzero *, then y / x is a rational number.

x is nonzero because if x is zero, y would also be zero, which would violate the x ≠ y .

The conclusion is that for ALL natural numbers x and y such that y is an anagram of x and x ≠ y , then there exists a rational number that multiplied by x results in y . > So the only numbers that do not become an anagram when multiplied by any other are those numbers that do not have anagrams, such as 11, 2222, 33, 5, 77, and so on. All others can change places when multiplied by something.

    
04.06.2015 / 17:51