Calcular n números Kaprekar

12

Um número de Kaprekar é um número de n dígitos k que, quando os primeiros n ou n-1 dígitos de k ^ 2 são adicionados ao segundo n dígitos de N ^ 2, o resultado é N.

Exemplos:

9^2 = 81.  8+1 = 9.
45^2 = 2025.  20+25 = 45.
297^2 = 88,209. 88+209 = 297

A sequência de Kaprekar começa em 1.

Escreva um programa que calcule e produza os primeiros n números de Kaprekar, com n estando no intervalo, mas não limitado ao intervalo, de 1 a 100. Cada número de Kaprekar deve ser separado por espaço em branco e nada mais.

Mais números de Kaprekar podem ser encontrados aqui para verificar seu programa, mas esse recurso NÃO PODE ser usado de forma alguma para ajudar no cálculo - em outras palavras, nenhuma codificação codificada, leitura desta fonte ou uso em qualquer outra exploração maneira - todos os números devem ser gerados pelo seu programa.

O menor código vence.


fonte
@devnull Isso é melhor? Isso significa que o programa deve suportar naté pelo menos 100. #
A definição do MathWorld entra em conflito com A006886 (MathWorld especifica que m é o comprimento do número original, A006886 especifica que ele é pelo menos tão grande). Sua definição no primeiro parágrafo é ligeiramente diferente de ambas.
primo
@primo OK, eu entendi agora. Irá revisar.
Ahh, você está certo. São declarações equivalentes. Note-se que as duas definições não são idênticas. 4879 é o primeiro exemplo de contador (o quadrado é dividido em 3: 5, em vez de 4: 4).
primo
@primo Isso é melhor? Portanto, o comprimento do número ao quadrado deve ser igual ao dobro do comprimento do número ou o dobro do comprimento do número mais 1?

Respostas:

5

Perl - 63 bytes

#!perl -l
map{1while$l=length++$_,$_**2=~/.{$l}$/,$`+$&^$_;print}($_)x<>

Contando o shebang como um byte. A entrada é retirada de stdin.

Isso tem um tempo de execução aceitável para n ≤ 50 , depois fica um pouco lento.

Uso da amostra:

$ echo 20 | perl kaprekar.pl
1
9
45
55
99
297
703
999
2223
2728
4950
5050
7272
7777
9999
17344
22222
77778
82656
95121
primo
fonte
Não há problema com o tempo de execução. Isso é apenas código de golfe.
4

C, 109 106

long long i=1;x=10,n;main(){scanf("%d",&n);for(;n;x*=x<=++i?10:1)(i-i*i/x-i*i%x)||printf("%lld ",i,n--);}
  • com naté 17, seria bom remover o long long,
  • O parâmetro printf excedente é abusado :)
  • Por que não é possível usar a declaração vazia no operador ternário? os dois 1são bobos ...
  • Obrigado a Josh por 3 caracteres adicionais ...
VX
fonte
1
Se você se importa apenas com o valor falso, pode usar a lógica booleana em vez de uma instrução ternária. Exemplo (i-i*i/x-i*i%x)||printf(...),.
27414 Josh
1
Você também pode inicializar xe ino escopo global em vez de no forloop para salvar alguns caracteres.
Josh
3

Mathematica 144 154

k@m_:=((x=m^2)-(w=FromDigits[Take[IntegerDigits@x,y=-IntegerLength@m]]))*10^y+w==m;
g@n_:=(s={};i=0;While[Length@s<n,If[k@i,s=Append[s,i]];i++];s)   

Teste

g[14]

0
1
9
45
55
99
297
703
999
2223
2728
4950
5050
7272

DavidC
fonte
Sua saída não atende aos critérios. Cada número do Kaprekar deve ser separado por espaço em branco e mais nada.
RononDex
RononDex. Eu ajustei a saída.
DavidC 27/02
3

Javascript 96

for(i=0,n=prompt(s='');n;i++){t=''+i*i;if(t.substr(0,l=t.length/2)==i-t.substr(‌​l))n--,s+=i+' '}s

Resultado :

0 1 9 45 55 99 297 703 999 2223 2728 4950 5050 7272 7777 9999 17344 22222 77778 82656 95121 99999 142857 148149 181819 187110 208495 318682 329967 351352 356643 390313 461539 466830 499500 500500 533170 538461 609687 643357 648648 670033 681318 791505 812890 818181 851851 857143 961038 994708 999999 
Michael M.
fonte
A entrada especifica o número de valores a serem emitidos, e não o valor máximo.
primo
perdeu isso, consertado!
Michael M.
1
96 :for(i=0,n=prompt(s='');n;i++){t=''+i*i;if(t.substr(0,l=t.length/2)==i-t.substr(l))n--,s+=i+' '}s
Florent
Bien joué Florent :)
Michael M.
Por que você não armazena os valores em uma matriz e simplesmente os junta?
Ismael Miguel
3

python - 98

Eu usei algumas fatias de python legais para raspar alguns caracteres.

i=n=0
while n<20:
 i+=1;s=str(i**2);l=-len(str(i))
 if int("0"+s[:l])+int(s[l:])==i:print(i);n+=1
qwr
fonte
Bom trabalho. Eu fiquei sem votos para hoje, mas vou votá-lo em uma hora.
3

C # - 255 caracteres.

int x=100;decimal k=0;while(x>0){k++;decimal d=k*k;string s=d.ToString("n").Replace(",","").Split('.')[0];int g=k.ToString().Length;int h=s.Length;if(k==d||(h!=g&&long.Parse(s.Substring(h-g))+long.Parse(s.Substring(0,h-g))==k)){Console.Write(k+" ");x--;}}

x é o número de números Kaprekar que você deseja que o código encontre. Isso foi testado na faixa de 1 a 100, mas deve suportar muito mais do que isso. 100 números levavam duas horas e quinze para retornar, embora os primeiros 50 levassem apenas 1 segundo - as coisas diminuíram gradualmente depois disso.

Resultado:

1 9 45 55 99 297 703 999 2223 2728 4950 5050 7272 7777 9999 17344 22222 77778 
82656 95121 99999 142857 148149 181819 187110 208495 318682 329967 351352 356643 
390313 461539 466830 499500 500500 533170 538461 609687 643357 648648 670033 
681318 791505 812890 818181 851851 857143 961038 994708 999999 4444444 4927941 
5072059 5555556 9372385 9999999 11111112 13641364 16590564 19273023 19773073 
24752475 25252525 30884184 36363636 38883889 44363341 44525548 49995000 50005000 
55474452 55636659 61116111 63636364 69115816 74747475 75247525 80226927 80726977 
83409436 86358636 88888888 91838088 94520547 99999999 234567901 332999667 
432432432 567567568 667000333 765432099 999999999 1111111111 1776299581 2020202020 
3846956652 3888938889 4090859091 4132841328 4756047561

Estabelecido esse código é o seguinte;

        int x = 100;
        decimal k = 0; 
        while (x > 0) 
        {
            k++;
            decimal d = k * k;
            string s = d.ToString("n").Replace(",", "").Split('.')[0];
            int g = k.ToString().Length; 
            int h = s.Length; 

            if (k == d || (h != g && long.Parse(s.Substring(h - g)) + long.Parse(s.Substring(0, h - g)) == k) )
            { 
                Console.Write(k + " "); x--; 
            } 
        }

Eu adoraria saber se isso pode ser reduzido ainda mais.

user17567
fonte
3

C, 90 76 75 bytes

long long d,r=1;k(n){for(;++d/r?r*=10:--n;d-d*d/r-d*d%r||printf("%d ",d));}
o79y
fonte
2

Python 2.7, 144 (incluindo novas linhas)

def c(c):
 l="1";i=2;u=1
 while u<c:
  r=str(i**2);w=len(r)
  if w>1:
   if i==int(r[:w/2])+int(r[w/2:]):
    l+=" "+str(i);u+=1
  i+=1
 print l

Saída para c = 10:

1 9 45 55 99 297 703 999 2223 2728

Saída para u = 20:

1 9 45 55 99 297 703 999 2223 2728 4950 5050 7272 7777 9999 17344 22222 77778 82656 95121
KBKarma
fonte
Ops! Corrigido isso agora. Um pouco mais, mas correto. Descobri ponto e vírgula em Python! Viva!
KBKarma
2
Então isso vai surpreender: a linha 7 pode ir no final da linha anterior.
primo
... Oh. Ah, droga. Ah bem. Ainda muito bom para algo que bati juntos durante o meu horário de almoço, considerando que meu conhecimento sobre Python é escasso na melhor das hipóteses.
KBKarma
2

R, 99 caracteres

k=n=0;N=scan();while(n<N){k=k+1;j=k^2;i=10^ceiling(nchar(j)/2);if(k==j%/%i+j%%i){cat(k," ");n=n+1}}

Com imetade do número de dígitos k^2arredondados para cima, a avaliação de k é um número Kaprekar é realizada aqui adicionando o quociente e o restante da divisão inteira de k^2por 10^i(o quociente é a metade esquerda dos dígitos arredondados para baixo e o restante a metade direita arredondada para cima).

plannapus
fonte
2

bash + sed, 75 caracteres

O Bash faz aritmética somente com números inteiros e representa números como cadeias decimais; esses atributos são úteis para jogar golfe nesse desafio. Também, variáveis ​​não declaradas / não atribuídas são assumidas como tendo um valor 0 ao fazer aritmética.

for((;s=++i*i,l=${#s}/2,1;));{
((${s:0:l}+10#${s:l}-i))||echo $i
}|sed $1q

Irritou-me colocar o 10#lá dentro, mas algo assim é necessário se a segunda metade da divisão começar com a 0. Ao fazer aritmética, o trata números como octal, a menos que a base seja explicitamente declarada.

$ ./kaprekar.sh 10
1
9
45
55
99
297
703
999
2223
2728
$ 
Trauma Digital
fonte
1

Python 3.3 - 117 caracteres

n=int(input())
p=1
while n>0:
    v=str(p**2)
    l=len(v)
    if p==int(v[l//2:])+int('0'+v[:l//2]):
        print(p)
        n-=1
    p+=1

Cada nível de indentação e cada nova linha, exceto a final, contam para 1 caractere. Eu acho que é justo para o código Python. O script espera que o usuário insira o número de números Kaprekar para calcular.

Thomas
fonte
1

J - 64

Meio feio, mas ainda assim. Ele verifica todos os números de até um milhão e, em seguida, obtém ndeles, então funciona apenas para n <= 50.

n{.}.I.(]=+/&;&:(10&#.&.>)&(<.@-:@#({.;}.)])&(10&#.inv@*:))i.1e6

n é onde colocar a entrada

swish
fonte
Na especificação, ele disse para calcular até 100 deles. Provavelmente não adicionaria tantos caracteres para adicionar outra variável apenas para contar o número de números Kaprekar encontrados.