How to identify "capicua" numbers that have 5 digits?

According to this definition of priberam.pt , a capicua number is:

Number that reads equally from right to left or vice versa and to which good luck is attributed.

Following this reasoning, capicua would be 12521, 37073, 10001, etc...

How to find out between 5-digit numbers, those that are capicua only using mathematical calculations, removing numbers that have all 5 identical digits like 55555, 33333, 00000, etc?

P.S.: no matter the language, only the logic to develop a way to solve it.

Author: Woss, 2017-09-21

8 answers

Let's initially consider a positive 5-digit integer value that can be written as abcde. From the definition, we have that this value will be considered a capicua if, and only if, abcde is equal to edcba. Thus, we have the first condition that defines our set:

  • b, c and d belong to the set of natural numbers, such that 0 ≤ b, c, d ≤ 9;
  • a and e belong to the set of non-null natural numbers, such that 0 < a, e ≤ 9;

Notice that the digits a and e can not be 0, as this would configure a 4-digit number, since in mathematics the zero Left is ignored.

Thus, considering the polynomial form of numbers in the decimal base, we can write:

insert the description of the image here

insert the description of the image here

insert the description of the image here

insert the description of the image here

insert the description of the image here

Being the natural numbers, this expression is only valid if, and only if, a - e = 0 and b - d = 0; that is, if a = e and b = d, as would already be expected. Thus, we can imagine a function:

insert the description of the image here

Being x the number abcde. The function f(x) will return 0 for any capicua number, but not only them. In truth, it will return 0 for any value that satisfies a - e = -(b - d), such as 65365, since 6 - 5 = -(5 - 6). Such a problem can be circumvented if we consider the modulus of the values:

insert the description of the image here

So it will remain zero for the capicuas numbers and different from zero for any other value. However, numbers with repeated digits would be considered equally, as they continue to satisfy this condition. To then identify the Capicua numbers with repeated digits, we can imagine a value:

insert the description of the image here

Collaboration of Jefferson Quesado .

Where w will be 0 for all repeated digit caps and 1 for any another capicua. We can then imagine a function g(x) such that:

insert the description of the image here

Return 1 for the non-repeated capices and any other value for other numbers, including repeated capices. In this case, g(x) will be the very value of w, then:

insert the description of the image here

Thus, we can calculate the values of a, b, c, d e e com:

insert the description of the image here

insert the description of the image here

insert the description of the image here

insert the description of the image here

insert the description of the image here

We can then generalize to a function that gets the nth digit of a number:

insert the description of the image here

JavaScript

I will do the implementation in JavaScript to take advantage that it is executable by the snippet of the site.

const digit = n => x => (x % Math.pow(10, n) - x % Math.pow(10, n-1)) / Math.pow(10, n-1);

const a = digit(5);
const b = digit(4);
const c = digit(3);
const d = digit(2);
const e = digit(1);

const g = x => Math.ceil(
    Math.abs(
        (a(x)+1000)/(b(x)+1000) + (b(x)+1000)/(c(x)+1000) + (c(x)+1000)/(d(x)+1000) + (d(x)+1000)/(e(x)+1000) - 4
    )
);

const f = x => Math.abs(a(x) - e(x)) + Math.abs(b(x) - d(x)) + g(x);

let capicuas = 0;

for (let x = 10000; x < 100000; x++) {
    
    // Verifica se é capicua:
    if (f(x) === 1) {
        
        capicuas++;
        
        // Confirma se realmente é invertendo a string:
        if (x.toString() != x.toString().split('').reverse().join('')) {
            console.log(`Não é capicua, mas foi considerado: ${x}.`)
        }
        
    } else {
        
        // O número é capicua, mas foi desconsiderado pela função:
        if (x.toString() == x.toString().split('').reverse().join('')) {
            console.log(`É capicua, mas não foi considerado: ${x}.`)
        }
        
    }
}

console.log(`Foram encontrados ${capicuas} números capicuas de 5 dígitos.`);
 29
Author: Woss, 2017-09-22 17:50:24

Basically it is necessary to invert the number and check if it is equal to the original input.

This implementation works for numbers with any number of digits.

Implementation in C#:

using static System.Console;

public class Program
{
    public static void Main()
    {
        int num;
        int original = num = 51315;     
        int rev = 0;

        while (num > 0)
        {
            int dig = num % 10; //Captura cada dígito

            rev = rev * 10 + dig; 
            // (^) Adiciona o dígito na variável 'rev'.
            // Como usamos a base 10, tudo o que já existe 
            // em rev precisa ser mulplicado por 10

            num = num / 10;
            // Controla o loop
        }

        WriteLine(original == rev ? "É capícua" : "Não é capícua");
    }
}

See working on .NET Fiddle | code on GitHub for future reference

 24
Author: LINQ, 2018-01-19 16:14:51

To be capicua, just separate all the digits and compare the Digit d_a with its complement d_(5-a+1). Note that the middle digit is ignored because it is equal to itself.

Consider // the integer division operation as described by the Python language. Consider lines beginning with # as comments.

Tip of @ AndersonCarlosWoss , Initially I had not defined that I was using integer division

d1 = n // 10000
r1 = n % 10000

d2 = r1 // 1000
r2 = r1 % 1000

d3 = r2 // 100
r3 = r2 % 100

d4 = r3 // 10
r4 = r3 % 10

d5 = r4

# garantia de capicua:
d1 == d5 and d2 == d3

# garantia de que tem algum dígito distinto:
not (d1 == d2 and d2 == d3 and d3 == d4 and d4 == d5)

# portanto, para ser capicua com algum dígito distinto
return d1 == d5 and d2 == d3 and not (d1 == d2 and d2 == d3 and d3 == d4 and d4 == d5)
 15
Author: Jefferson Quesado, 2019-08-15 16:04:38

I can define a word as being a set of tuples formed by character/position. Thus, the word banana would have the following mathematical representation:

{
  ('b',0),
  ('a',1),
  ('n',2),
  ('a',3),
  ('n',4),
  ('a',5)
}

I can change the definition a bit so that each letter is mapped to a set of positions; then, banana would look like this:

{
  ('b',{0}),
  ('a',{1,3,5}),
  ('n',{2,4})
}

Something interesting about this definition is that if my letter is not in the word, I can associate it with the Empty Set:

{
  ('a',{1,3,5}),
  ('b',{0}),
  ('c',{}),
  ('d',{}),
  ('e',{}),
  ('f',{}),
  ('g',{}),
  ('h',{}),
  ('i',{}),
  ('j',{}),
  ('k',{}),
  ('l',{}),
  ('m',{}),
  ('n',{2,4}),
  ('o',{}),
  ('p',{}),
  ('q',{}),
  ('r',{}),
  ('s',{}),
  ('t',{}),
  ('u',{}),
  ('v',{}),
  ('w',{}),
  ('x',{}),
  ('y',{}),
  ('z',{})
}

This type of structure of data, from a key map to a set of elements, is called multimap . Generally speaking, multimapa has two operations: enter value and redeem set.

Then, in the multimap of banana (hereinafter referred to as mm_banana), we can add s at the position 6:

mm_banana.put('s', 6)

// conteúdo de mm_banana modificado sem conjuntos vazios:

{
  ('a',{1,3,5}),
  ('b',{0}),
  ('n',{2,4}),
  ('s',{6})
}

If we add 's',6, 'e',7 and 's',8 to mm_banana, it would look like this:

mm_banana.put('s', 6)
mm_banana.put('e', 7)
mm_banana.put('s', 8)

// conteúdo de mm_banana modificado sem conjuntos vazios:

{
  ('a',{1,3,5}),
  ('b',{0}),
  ('e',{7}),
  ('n',{2,4}),
  ('s',{6,8})
}

The decimal representation of a number is a multi-word map (as described above), being that the alphabet of the key is the decimal digits.

To get its decimal representation from any number x, we make successive divisions and store the rest. For the sake of simplicity, let's consider the writing of the decimal word in little-endian, where the least significant comes first. Thus, the number 0x10 has its representation in decimal word little-endian 61. The following Python code to follow demonstrate this:

def representacao_base(x, base):
  digit_pos = 0
  while (x > 0):
    digito = x % base
    print("digito %d, posição %d" % (digito, digit_pos));
    x //= base
    digitPos += 1

representacao_base(0x10, 10)

See working on ideone .

Did you notice that I wrote in a generalized way for any base? Yes, the advantage of this is that we can check if a number is capicua on any basis later. So 12 would be represented as 0011 in base 2 using little-endian. The endianISM does not influence the decision of the number to be capicua or not, just as writing a word in reverse does not influence the fact that it is or not palindrome.

To detect that a number is capicua, we use the algorithm above to break it down and put each digit as the key of the multimap, each position as the value being entered into the multimap. In Java, I achieved this as follows:

public class Multimapa {
    Set<Integer>[] pos;
    int size;
    int base;

    private void initPos(int base) {
        pos = new HashSet[base];

        for (int i = 0; i < base; i++) {
            pos[i] = new HashSet<>();
        }
    }

    public Multimapa(int n, int base) {
        this.base = base;
        initPos(base);

        if (n == 0) {
            pos[0].add(0);
            size = 1;
            return;
        }
        if (n < 0) {
            n = -n;
        }
        int digitPos = 0;
        while (n > 0) {
            int digit = n % base;
            pos[digit].add(digitPos);

            n /= base;
            digitPos++;
        }
        size = digitPos;
    }
}

Note that since the key is a digit, and a digit in turn is an integer, the multimap is provided by the attribute pos; pos[7] will get the positions in little-endian that digit 7 occupies in the base past. Detail: the key is an integer and the value is a set (set in English means set in Portuguese, in the mathematical context) of integers.

Thus, to demonstrate that the Multimapa class behaves like the multi-map data structure described above, I need to show that it supports the same insert and rescue operations.

The rescue operation is simple. Given one digit d, pos[d] rescues the corresponding set. To make the adding the position p to the digit d, just do pos[d].add(p). Note that this is an idempotent operation, so pos[d].add(p); has the same effect as pos[d].add(p); pos[d].add(p); pos[d].add(p);.

Remember the multi-map representation of the word using empty set for the non-existence of that letter in the word? We are using the same concept here, to facilitate rescue and addition operations without needing additional negotiations or offending the definition.

To determine if the number is repeated, we can check if it has more than one non-null digit. To do this, just iterate on the digits and check the size of the sets. If there is only one digit with non-null size, then the number is repeated. To detect if it is not repeated, just do the logical inversion. Since there is no digitless Number option, then the minimum of digits with at least one position in the number is 1. Therefore, the negation of being a single-digit number is to have the count > 1.

private static boolean ehNaoRepetido(Multimapa mm) {
    int nDigitosDistintos = 0;

    for (int i = 0; i < mm.base; i++) {
        nDigitosDistintos += mm.pos[i].size() > 0? 1: 0;
    }

    return nDigitosDistintos > 1;
}

To check if a number it is capicua in the defined base, we need to ensure that every digit in the position p has another digit in the specular position p'. A special case is the number of the intermediate position with numbers of odd size: it is its own specular, so it can be ignored.

The relationship between p, p' and the size size of the number is:

p + p' = size - 1

      ||
      \/

p' = size - 1 - p

The intermediate position t, which will be ignored, is calculated as follows:

t = size % 2 == 1? size/2: -1;

As there are only filled positions from 0, putting -1 will ensure that t will always be ignored for numbers of a pair size of digits.

Thus, the following check deals with this:

private static boolean ehCapicua(Multimapa mm) {
    int somaSimetrica = mm.size - 1;
    int posIgnorada = mm.size % 2 == 1? mm.size/2: -1;

    for (int d = 0; d < mm.base; d++) {
        for (Integer p: mm.pos[d]) {
            // só tenta verificar se tem o complemento se e somente se não é ignorado
            if (p != posIgnorada) {
                int posComplemento = somaSimetrica - p;

                // se não existe o dígito na posição complementar, então não é capicua
                if (!mm.pos[d].contains(posComplemento)) {
                    return false;
                }
            }
        }
    }
    return true;
}

Follows the complete code used to verify that a number is capicua not repeated on the given bases:

package capicua;

import java.util.HashSet;
import java.util.Set;

public class Multimapa {

    Set<Integer>[] pos;
    int size;
    int base;

    private void initPos(int base) {
        pos = new HashSet[base];

        for (int i = 0; i < base; i++) {
            pos[i] = new HashSet<>();
        }
    }

    public Multimapa(int n, int base) {
        this.base = base;
        initPos(base);

        if (n == 0) {
            pos[0].add(0);
            size = 1;
            return;
        }
        if (n < 0) {
            n = -n;
        }
        int digitPos = 0;
        while (n > 0) {
            int digit = n % base;
            pos[digit].add(digitPos);

            n /= base;
            digitPos++;
        }
        size = digitPos;
    }

    public static void main(String... args) {
        int qntNumerosInteressantes = 0;
        for (int i = 0; i < 99999999; i++) {
            if (julga(i, 10)) {
                System.out.println(i + " é capicua não repetido na base " + 10);
                qntNumerosInteressantes++;
            }
        }

        System.out.println("quantidade de números capicua e não repetidos nas base 10: " + qntNumerosInteressantes);

        qntNumerosInteressantes = 0;
        for (int i = 0; i < 99999999; i++) {
            if (julga(i, 16)) {
                System.out.println(i + " é capicua não repetido na base " + 16);
                qntNumerosInteressantes++;
            }
        }

        System.out.println("quantidade de números capicua e não repetidos nas base 16: " + qntNumerosInteressantes);

        meta_julga(0xffeff, 10); // 1048319
        meta_julga(121, 10);
        meta_julga(1221, 10);
        meta_julga(12721, 10);
        meta_julga(12721, 16); // 31b1
        meta_julga(0xffeff, 16);
        meta_julga(0xffdead, 16);
        meta_julga(0101, 8);
        meta_julga(0171, 8);
        meta_julga(01267621, 8);
        meta_julga(01267421, 8);

        meta_julga(5, 2); // 101
        meta_julga(6, 2); // 110
        meta_julga(7, 2); // 111
        meta_julga(4, 2); // 10
        meta_julga(16, 3); // 121
        meta_julga(10, 3); // 101
        meta_julga(12, 3); // 110
    }

    private static void meta_julga(int n, int base) {
        if (julga(n, base)) {
            System.out.println(n + " é capicua não repetido na base " + base);
        } else {
            System.out.println(n + " não é capicua não repetido na base " + base);
        }
    }

    // retorna verdade se todos os dígitos do número passado forem idênticos
    //
    // algoritmo de detecção: se, por acaso, existirem pelo menos dois dígitos com 1 ou mais posições, então é não repetido.
    // caso seja tudo zero exceto por um único dígito, então é repetido
    private static boolean ehNaoRepetido(Multimapa mm) {
        int nDigitosDistintos = 0;

        for (int i = 0; i < mm.base; i++) {
            nDigitosDistintos += mm.pos[i].size() > 0? 1: 0;
        }

        return nDigitosDistintos > 1;
    }

    // retorna verdadeiro caso seja capicua
    //
    // algoritmo: verifica cada dígito; se for de tamanho `t` ímpar, então o dígito da posição `floor(t/2)` deve ser ignorado
    // para um dígito `d` na posição `p` não ignorado, é necessário existir um outro dígito `d` na posição complementar `p'`, tal que `p + p' = t - 1`
    private static boolean ehCapicua(Multimapa mm) {
        int somaSimetrica = mm.size - 1;
        int posIgnorada = mm.size % 2 == 1? mm.size/2: -1;

        for (int d = 0; d < mm.base; d++) {
            for (Integer p: mm.pos[d]) {
                // só tenta verificar se tem o complemento se e somente se não é ignorado
                if (p != posIgnorada) {
                    int posComplemento = somaSimetrica - p;

                    // se não existe o dígito na posição complementar, então não é capicua
                    if (!mm.pos[d].contains(posComplemento)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    private static boolean julga(int n, int base) {
        Multimapa mm = new Multimapa(n, base);

        if (ehNaoRepetido(mm)) {
            if (ehCapicua(mm)) {
                return true;
            }
        }

        return false;
    }
}

See working on ideone .

 11
Author: Jefferson Quesado, 2018-02-09 00:18:35

You can get an estimate of how many digits there are in a number using the logarithm in base 10:

  • (log10 1 = 0)
  • (log10 10 = 1)
  • (log10 100 = 2)
  • (log10 1000 = 3)

The logarithm is a strictly increasing function. Therefore, if we round down its value, we will have this:

  • from 1 to 9: result is 0.
  • from 10 to 99: result is 1.
  • from 100 to 999: result is 2.
  • from 1000 to 9999: result is 3.
  • ...

If we add 1 to this value, we have the number of digits in base 10 of a number. This formula can be generalized to other bases by changing the base of the logarithm to the corresponding base. With this we can mount this function:

function digitos(numero) {
    return numero === 0 ? 1 : Math.floor(Math.log10(numero)) + 1;
}

It is possible to determine whether a number has all repeated digits based on this from here. However I took a slightly different approach:

  • A number terminated at zero that does not let zero itself never be a repetition of digits.

  • Any number consisting of a repetition of digits, when multiplied by 9, will have all the resulting digits except perhaps the first and last as a sequence of nines. This has to do with the fact that in the 9 tabulation, all multiples of 9 between 9 and 90 when they have their digits added together, produces 9 as a result. As a consequence, by doing the multiplication of a number that is a repetition by 9, these digits will add up in all positions except the first and last, producing several nines in the middle of the number.

  • Let r be the number that is a repetition of digits and let k=9r be. If r ends with 1 (let's call this last digit d), the last digit of k (let's call it m)) will be 9. If it ends with 2, it will be 8 ((9 x 2 = 18)). If it ends with 3, it will be 7 ((9 x 3 = 27)). That is, (m = 10-d), and therefore (m + d = 10). So, when we do k + m, we will have 10 as result in the last digit and let's unshackle a sequence of "vai-uns" in all nines then having a number g such that g = b x 10^p, 1 < = b < = 9, b and N and p and N.

  • If r starts with 1, then k starts with 9. If r starts with 2, then k starts with 1. If r starts with 3, then k starts with 2... This can be seen in the table of 9. By adding 1 to the first digit of k, you have a number whose first digit is the first digit of r. It it means that after the entire "vai-uns" sequence of the above item, we have b = d. So when we do g / d, if and only if the result is a power of 10, it is because r is a repetition of digits. We can check if it is a power of 10 if the logarithm at base 10 is integer.

Putting all this together:

function repetido(numero) {
    if (numero === 0) return true;
    var d = numero % 10;
    if (d === 0) return false;
    var g = numero * 9 + d; 
    var n = Math.log10(g / d);
    return n === Math.floor(n);
}

A number can be checked if it is palindrome by separating the digits using exponentiation, modulus, and rounding (no strings) and checked in pairs from outside to inside.

Putting all this together:

function palindromo(numero) {
    var numDigitos = digitos(numero);
    for (var i = 0; i < numDigitos / 2; i++) {
        var a = Math.floor(numero / Math.pow(10, i)) % 10;
        var b = Math.floor(numero / Math.pow(10, numDigitos - i - 1)) % 10;
        if (a !== b) return false;
    }
    return true;
}

Finally, a capicuia number is a palindrome that is not a repetition:

function capicua(numero) {
    return !repetido(numero) && palindromo(numero);
}

Below is the code that checks if a number is capicuia (for any number of digits). It also has a test that checks if the implementation is correct for all numbers from 0 up to 99999. The test was done to show only the numbers that went wrong (and the way it is does not show any, it works for everyone). Then in addition, it shows some examples for testing.

function digitos(numero) {
    return numero === 0 ? 1 : Math.floor(Math.log10(numero)) + 1;
}

function repetido(numero) {
    if (numero === 0) return true;
    var d = numero % 10;
    if (d === 0) return false;
    var g = numero * 9 + d; 
    var n = Math.log10(g / d);
    return n === Math.floor(n);
}

function palindromo(numero) {
    var numDigitos = digitos(numero);
    for (var i = 0; i < numDigitos / 2; i++) {
        var a = Math.floor(numero / Math.pow(10, i)) % 10;
        var b = Math.floor(numero / Math.pow(10, numDigitos - i - 1)) % 10;
        if (a !== b) return false;
    }
    return true;
}

function capicua(numero) {
    return !repetido(numero) && palindromo(numero);
}

function testeNumero(numero) {

    var numeroStr = "" + numero;
    var numDigitos = numeroStr.length;

    var palindromoStr = numeroStr.split("").reverse().join("") === numeroStr;

    var repetidoStr = true;
    for (var i = 1; i < numDigitos; i++) {
        if (numeroStr.charAt(i) !== numeroStr.charAt(0)) {
            repetidoStr = false;
            break;
        }
    }

    if (digitos(numero) !== numDigitos) {
        document.write("Falhou digitos com " + numero + ".<br>");
    }

    if (palindromo(numero) !== palindromoStr) {
        document.write("Falhou palindromo com " + numero + ".<br>");
    }

    if (repetido(numero) !== repetidoStr) {
        document.write("Falhou repetido com " + numero + ".<br>");
    }

    if (capicua(numero) !== (!repetidoStr && palindromoStr)) {
        document.write("Falhou capicua com " + numero + ".<br>");
    }
}

function teste() {
   document.write("Começando...<br>");
   for (var i = 0; i < 100000; i++) {
        testeNumero(i);
   }
   document.write("Teste concluído.<br>");
}

teste();
document.write("53035 é capicua? " + (capicua(53035) ? "Sim" : "Não") + "<br>");
document.write("53035 é repetido? " + (repetido(53035) ? "Sim" : "Não") + "<br>");
document.write("53567 é capicua? " + (capicua(53567) ? "Sim" : "Não") + "<br>");
document.write("8765678 é capicua? " + (capicua(8765678) ? "Sim" : "Não") + "<br>");
document.write("369 é capicua? " + (capicua(369) ? "Sim" : "Não") + "<br>");
document.write("363 é capicua? " + (capicua(363) ? "Sim" : "Não") + "<br>");
document.write("55555 é capicua? " + (capicua(55555) ? "Sim" : "Não") + "<br>");
document.write("55555 é repetido? " + (repetido(55555) ? "Sim" : "Não") + "<br>");
document.write("55455 é repetido? " + (repetido(55455) ? "Sim" : "Não") + "<br>");

I tried to find a formula that would check if it is palindrome not only without using strings, but also without using loops and neither recursion. However, I couldn't and had to settle for a noose. In this attempt, the best I could do is prove that every palindrome number with an even amount of digits is multiple of 11 (but not every multiple of 11 is palindrome).

 8
Author: Victor Stafusa, 2017-09-23 01:57:47

I did some examples in C#, but converting the number to string:

First:

public static bool Capicua(int x) //0.046s
{
    string s = x.ToString();
    int l = s.Length/2;


    for (int i =0; i<= l; i++)
    {
        if (s[i] != s[s.Length-1-i])
        {
            return false;
        }
    }

    return true;

}

Second:

public static bool Capicua2(int x) //0.063s
{
    string s = x.ToString();
    return s == Reverse(s);
}

public static string Reverse(string s )
{
    char[] charArray = s.ToCharArray();
    Array.Reverse( charArray );
    return new string( charArray );
}

Helper method to remove numbers where all digits are equal:

public static bool TodosIguais(int x)
{
    string s = x.ToString();
    char c = s[0];
    for (int i =1; i< s.Length;i++)
    {
        if (s[i] != c)
        {
            return false;
        }
    }

    return true;

}

Running the application:

public static void Main()
{
    int encontrados = 0;
    for (int i =10000; i <= 90000; i++)
    {
        //if (!TodosIguais(i) && Capicua(i))
        //if (!TodosIguais(i) && Capicua2(i))
        if (CapicuaLINQ(i))
        {
            Console.WriteLine("Capicua: "+ i);
            encontrados++;
        }
    }
    Console.WriteLine("Encontrados: "+ encontrados);
}

Result:

Capicua: 10001
Capicua: 10101
Capicua: 10201
Capicua: 10301
Capicua: 10401
Capicua: 10501
Capicua: 10601
...
Capicua: 89698
Capicua: 89798
Capicua: 89898
Capicua: 89998
Encontrados: 792

However, the code posted by LINQ as a response, does not convert to string, which is better, being faster the time of execution. I just made the change not to take the numbers where all digits are equal:

///LINQ
public static bool CapicuaLINQ(int x) //0.019s
{
    int num;
    int original = num = x;     
    int rev = 0;
    int digAnt =  num % 10;
    bool todosIguais = true;

    while (num > 0)
    {
        int dig = num % 10; //Captura cada dígito

        if (dig != digAnt)
        {
            todosIguais = false;
        }

        rev = rev * 10 + dig; 
        // (^) Adiciona o dígito na variável 'rev'.
        // Como usamos a base 10, tudo o que já existe 
        // em rev precisa ser mulplicado por 10

        num = num / 10;
        // Controla o loop
    }

    return original == rev && !todosIguais;

}

I put no .NetFiddle: https://dotnetfiddle.net/IWXftW

 5
Author: Rovann Linhalis, 2017-09-21 21:37:01

One logic I found was as follows, separating 3 information from the 5-digit number, which I call x:

  1. take the first 2 digits (I'll call it left2).
  2. take the last 2 digits and reverse their order (I will call right2_reverse).
  3. take only the first digit (I will call it x1).

the middle number (the third) is ridiculous and does not enter the question.

With these 3 information, just apply comparison:

Is left2 equal to right2_reverse?

If yes , then it is capicua .

But you don't want numbers where all digits are equal, type 00000, 11111 etc...

Just divide the number x by its first digit x1 (after all they are all the same). If the result is different from 11,111, then it is capicua without having all the digits equal.

Whenever any number where all digits are equal is divided for 1 digit of this number, the result will be a sequence of 1 with the same number of digits:

Ex. 99.999 / 9 = 11.111

The problem is the number 00,000, which if divided by 0 gives error, due to the mathematical rule where "no number can be divided by zero".

In this case, just check if the absolute value of the number x is zero. If it is, just ignore it.

Examples:

Let the number x = 37073

left2 = 37
right2_reverse = 37

Are the same, so it is capicua.


Be the number x = 37075

left2 = 37
right2_reverse = 57

Are different, so not is capicua.

I made a code in JavaScript for verification:

digitos = 5;

for(x=0;x<=99999;x++){
	if( x.toString().length < digitos ){
		while(x.toString().length < digitos){
			x = "0"+x;
		}
	}
	left2 = x.toString().substring(0,2);
	right2_1 = x.toString().substring(x.toString().length-2,x.toString().length-1);
	right2_2 = x.toString().substring(x.toString().length-1,x.toString().length);
	right2_reverse = right2_2+right2_1;
	
	x1 = parseFloat(x.toString().substring(0,1));

	if(left2 == right2_reverse && x/x1 != 11111 && Math.abs(x) != 0){
		capicua = " capicua!";
	}else{
		capicua = "";
	}
	$("#teste").append(x+capicua+"<br />");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="teste">
</div>

Another programmatic way would be to divide the number x by its mirrored value, if the result is equal to 1, so it is capicua.

 4
Author: Sam, 2017-09-23 00:57:32

By the way, there is a beating solution (I only know how to do these ☺): generate them instead of recognizing them.

The general idea is: a 5-digit capicua has the following structure abcde in which:

  • ab it is the inverse of de i.e. de = b*10+a (or even ab%10*10 + int(ab/10))

    inv(ac)= mod(ab,10)×10 + int(ab/10)
    
  • So the set of 5-digit capicuas is

    { ab×1000 + c×100 + inv(ab) |  ab ∈ 10..99, c ∈ 0..9 }
    
  • To check if a number is capicua: "yes" se ele ∈ conjunto

To create a concrete program, for example using Perl, we can write:

perl -E 'say for map {$a=$_; 
                      map {$a*1000+$_*100 +$a%10*10+int($a/10)} 
                          0..9
                     } 
                     10..99 '

To generate the 5-digit capicuas;

To recognize them: BEGIN{calculates set} for each line: say if it belongs

perl -nlE '
  BEGIN{ $p{$_}=1 
         for map {$a=$_;map {$a*1000+$_*100+$a%10*10+int($a/10)} 0..9} 11..99} 
  say "yes" if $p{$_}'
 4
Author: JJoao, 2017-10-22 14:41:07