Calcular n números Kaprekar

12

Un número de Kaprekar es un número k de n dígitos que, cuando se suman los primeros n o n-1 dígitos de k ^ 2 al segundo n los dígitos de N ^ 2, el resultado es N.

Ejemplos:

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

La secuencia de Kaprekar comienza en 1.

Escriba un programa que calcule y genere los primeros n números de Kaprekar, con n estando en el rango, pero no limitado al rango, de 1 a 100. Cada número de Kaprekar debe estar separado con espacios en blanco y nada más.

Más números Kaprekar se pueden encontrar aquí para comprobar su programa en contra, pero este recurso no pueden ser utilizados en cualquier forma para ayudar con el cálculo - en otras palabras, sin codificar duro, la lectura de esta fuente, o usarlo en cualquier otro explotador manera: todos los números deben ser generados por su programa.

El código más corto gana.


fuente
@devnull ¿Es esto mejor? Significa que el programa debe admitir nhasta un mínimo de 100.
La definición de MathWorld entra en conflicto con A006886 (MathWorld especifica que m es la longitud del número original, A006886 especifica que es al menos tan grande). Su definición en el primer párrafo es ligeramente diferente de ambas.
primo
@primo OK, lo entiendo ahora. Lo revisaremos.
Ahh, tienes razon. Son declaraciones equivalentes. Sin embargo, debe tenerse en cuenta que las dos definiciones no son idénticas. 4879 es el primer ejemplo de contador (el cuadrado se divide 3: 5, en lugar de 4: 4).
primo
@primo ¿Esto es mejor? Entonces, ¿la longitud del número al cuadrado debe ser igual al doble de la longitud del número o el doble de la longitud del número más 1?

Respuestas:

5

Perl - 63 bytes

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

Contando el shebang como un byte. La entrada se toma de stdin.

Esto tiene un tiempo de ejecución aceptable para n ≤ 50 , después de eso se vuelve un poco lento.

Uso de la muestra:

$ 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
fuente
No hay problema con el tiempo de ejecución. Esto es solo código golf.
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--);}
  • con nhasta 17 estaría bien eliminar el long long,
  • Se abusa del exceso del parámetro printf :)
  • ¿Por qué no es posible usar una declaración vacía en el operador ternario? los dos 1son tontos ...
  • Gracias a Josh por 3 personajes adicionales ...
VX
fuente
1
Si solo le importa el valor falso, puede usar la lógica booleana en lugar de una declaración ternaria. Ejemplo, (i-i*i/x-i*i%x)||printf(...).
Josh
1
También puede inicializar xy ien el ámbito global en lugar de en el forbucle para guardar un par de 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)   

Prueba

g[14]

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

DavidC
fuente
Su salida no cumple con los criterios. Cada número de Kaprekar debe separarse con espacios en blanco y nada más.
RononDex
RononDex. Ajusté la salida.
DavidC
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

Salida:

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.
fuente
La entrada especifica el número de valores a emitir, y no el valor máximo.
primo
perdí eso, arreglado
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 qué no almacena los valores en una matriz y simplemente los une?
Ismael Miguel
3

pitón - 98

Utilicé algunas rebanadas de python para afeitar algunos 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
fuente
Buen trabajo. Me quedé sin votos para hoy, pero lo votaré en una 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 es el número de números de Kaprekar que desea que encuentre el código. Esto se ha probado en el rango de 1 a 100, pero debería admitir mucho más que esto. 100 números tardaron dos horas y cuarto en regresar, aunque los primeros 50 solo tomaron aproximadamente 1 segundo; las cosas se desaceleraron gradualmente después de eso.

Salida:

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

Presentado este código es el siguiente;

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

Me encantaría saber si esto se puede acortar aún más.

usuario17567
fuente
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
fuente
2

Python 2.7, 144 (incluidas las nuevas líneas)

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

Salida para c = 10:

1 9 45 55 99 297 703 999 2223 2728

Salida para u = 20:

1 9 45 55 99 297 703 999 2223 2728 4950 5050 7272 7777 9999 17344 22222 77778 82656 95121
KBKarma
fuente
Whoops! Solucionado eso ahora. Un poco más largo, pero correcto. ¡Descubrí el punto y coma en Python! ¡Hurra!
KBKarma
2
Entonces esto te dejará boquiabierto: la línea 7 puede ir al final de la línea anterior.
primo
... Oh. Ah maldita sea. Oh bien. Todavía es bastante bueno para algo que reuní durante mi hora de almuerzo, teniendo en cuenta que mi conocimiento de Python es escaso en el mejor de los casos.
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}}

Con la imitad del número de dígitos de k^2redondeado, la evaluación de si k es un número de Kaprekar se realiza aquí sumando el cociente y el resto de la división entera de k^2by 10^i(el cociente es la mitad izquierda de los dígitos redondeados hacia abajo y el resto la mitad derecha redondeada).

plannapus
fuente
2

bash + sed, 75 caracteres

Bash hace aritmética de enteros y representa números como cadenas decimales; Estos atributos son útiles para jugar al golf en este desafío. También se supone que las variables no declaradas / no asignadas tienen un valor de 0 al hacer aritmética.

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

Me molestó ponerlo 10#allí, pero algo así es necesario si la segunda mitad de la división comienza con un 0. Al hacer aritmética, trata tales números como octales, a menos que la base se indique explícitamente.

$ ./kaprekar.sh 10
1
9 9
45
55
99
297
703
999
2223
2728
PS 
Trauma digital
fuente
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 nivel de sangría y cada nueva línea, excepto la última, cuentan para 1 personaje. Creo que eso es justo para el código Python. El script espera que el usuario ingrese el número de números de Kaprekar para calcular.

Thomas
fuente
1

J - 64

Un poco feo, pero aún así. Comprueba todos los números hasta un millón y luego los toma n, por lo que funciona solo para n <= 50.

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

n es donde poner la entrada

silbido
fuente
En la especificación, decía calcular hasta 100 de ellos. Probablemente no agregaría tantos caracteres para agregar otra variable únicamente para contar la cantidad de números de Kaprekar encontrados.