Oblicz n liczb Kaprekara

12

Liczba Kaprekara jest liczbą n-cyfrową k, która po dodaniu pierwszych n lub n-1 cyfr k ^ 2 do drugich n cyfr N ^ 2 daje wynik N.

Przykłady:

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

Sekwencja Kaprekara zaczyna się od 1.

Napisz program, który oblicza i generuje pierwsze n liczb Kaprekara, przy czym n znajduje się w zakresie od 1 do 100, ale nie ogranicza się do tego zakresu. Każda liczba Kaprekara musi być oddzielona spacjami i niczym więcej.

Więcej liczb Kaprekara można znaleźć tutaj, aby sprawdzić swój program, ale ten zasób NIE MOŻE być użyty w żaden sposób, aby pomóc w obliczeniach - innymi słowy, nie należy kodować na stałe, czytać z tego źródła ani używać go w żadnym innym exploicie sposób - wszystkie liczby muszą zostać wygenerowane przez Twój program.

Najkrótszy kod wygrywa.


źródło
@devnull Czy to jest lepsze? Oznacza to, że program musi obsługiwać nmaksymalnie 100.
Definicja MathWorld jest w konflikcie z A006886 (MathWorld określa, że m jest długością oryginalnej liczby, A006886 określa, że ​​jest co najmniej tak duża). Twoja definicja w pierwszym akapicie jest nieco inna niż obie.
primo
@primo OK, rozumiem teraz. Skoryguje.
Ach, masz rację. Są to równoważne stwierdzenia. Należy jednak zauważyć, że dwie definicje nie są identyczne. 4879 jest pierwszym kontratakiem (kwadrat jest podzielony na 3: 5, a nie 4: 4).
primo
@primo Czy to jest lepsze? Więc długość liczby do kwadratu musi być równa dwukrotności długości liczby lub dwukrotności długości liczby plus 1?

Odpowiedzi:

5

Perl - 63 bajty

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

Licząc shebang jako jeden bajt. Dane wejściowe są pobierane z stdin.

Ma to akceptowalny czas działania dla n ≤ 50 , po czym robi się nieco wolniejszy.

Przykładowe użycie:

$ 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
źródło
Nie ma problemu z czasem działania. To tylko golf golfowy.
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--);}
  • z nmaksymalnie 17 byłoby dobrze, aby usunąć long long,
  • Przekroczony parametr printf jest nadużywany :)
  • Dlaczego nie można użyć pustej instrukcji w operatorze trójskładnikowym? te dwie 1są głupie ...
  • Dziękujemy Joshowi za dodatkowe 3 znaki ...
VX
źródło
1
Jeśli zależy ci tylko na wartości fałszywej, możesz użyć logiki logicznej zamiast instrukcji trójskładnikowej. Przykładem (i-i*i/x-i*i%x)||printf(...).
Josh
1
Możesz również zainicjować xi iw zasięgu globalnym zamiast w forpętli, aby zapisać kilka znaków.
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)   

Test

g[14]

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

DavidC
źródło
Twój wynik nie spełnia kryteriów Każdy numer Kaprekara musi być oddzielony spacjami i niczym więcej.
RononDex
RononDex. Dostosowałem moc wyjściową.
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

Wynik :

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.
źródło
Dane wejściowe określają liczbę wartości do wydrukowania, a nie wartość maksymalną.
primo
przegapiłem to, naprawione!
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.,
Dlaczego nie przechowujesz wartości w tablicy i po prostu do nich dołączasz?
Ismael Miguel
3

python - 98

Użyłem fajnego krojenia Pythona, aby zgolić kilka znaków.

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
źródło
Dobra robota. Na dziś zabrakło mi głosów, ale za godzinę będę głosować za nimi.
3

C # - 255 znaków.

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 jest liczbą liczb Kaprekara, które ma znaleźć kod. Zostało to przetestowane w zakresie od 1 do 100, ale powinno obsługiwać znacznie więcej. Powrót do 100 liczb zajął dwie i kwadrans, chociaż pierwsze 50 zajęło około 1 sekundy - potem stopniowo zwalniało.

Wynik:

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

Ułożono ten kod w następujący sposób;

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

Chciałbym wiedzieć, czy można to jeszcze bardziej skrócić.

użytkownik17567
źródło
3

C, 90 76 75 bajtów

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

Python 2.7, 144 (w tym nowe wiersze)

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

Dane wyjściowe dla c = 10:

1 9 45 55 99 297 703 999 2223 2728

Wyjście dla u = 20:

1 9 45 55 99 297 703 999 2223 2728 4950 5050 7272 7777 9999 17344 22222 77778 82656 95121
KBKarma
źródło
Ups! Naprawiono to teraz. Nieco dłużej, ale poprawnie. Odkryłem średniki w Pythonie! Hurra!
KBKarma
2
Wtedy to zadziwi twój umysł: linia 7 może przejść na koniec poprzedniej linii.
primo
... Och Ach cholera. No cóż. Nadal całkiem nieźle jak na coś, co zapukałem podczas przerwy na lunch, biorąc pod uwagę, że moja znajomość Pythona jest w najlepszym razie skromna.
KBKarma
2

R, 99 znaków

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

Ponieważ ijest to połowa liczby k^2zaokrąglonych w górę, ocena mokra k jest liczbą Kaprekara wykonywaną tutaj przez dodanie ilorazu, a pozostałą część liczby całkowitej k^2przez 10^i(iloraz to lewa połowa cyfr zaokrąglona w dół i pozostała część prawa zaokrąglona w górę).

plannapus
źródło
2

bash + sed, 75 znaków

Bash wykonuje arytmetykę tylko liczb całkowitych i reprezentuje liczby jako ciągi dziesiętne; atrybuty te są przydatne do gry w golfa. Przyjmuje się, że również niezadeklarowane / nieprzypisane zmienne mają wartość 0 podczas wykonywania arytmetyki.

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

Zirytowało mnie, żebym tam włożył 10#, ale coś takiego jest konieczne, jeśli druga połowa podziału zaczyna się od 0. Podczas wykonywania arytmetyki traktuje takie liczby jak ósemkowe, chyba że podstawa jest wyraźnie określona.

$ ./kaprekar.sh 10
1
9
45
55
99
297
703
999
2223
2728
$ 
Cyfrowa trauma
źródło
1

Python 3.3 - 117 znaków

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

Każdy poziom wcięcia i każda nowa linia z wyjątkiem ostatniego liczy się 1 znak. Myślę, że jest to sprawiedliwe dla kodu Python. Skrypt oczekuje, że użytkownik wprowadzi liczbę liczb Kaprekara do obliczenia.

Tomasz
źródło
1

J - 64

Trochę brzydkie, ale nadal. Sprawdza wszystkie liczby do miliona, a następnie bierze nje, więc działa tylko dla n <= 50.

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

n jest gdzie umieścić dane wejściowe

śmigać
źródło
W specyfikacji podano, że obliczy do 100 z nich. Prawdopodobnie nie dodałoby tak wielu znaków, aby dodać kolejną zmienną wyłącznie do zliczania liczby znalezionych liczb Kaprekara.