Sprawdź, czy podany numer jest liczbą Keitha

14

Ponieważ liczby i sekwencje Fibonacciego wydają się być popularnym tematem dla golfa kodowego, pomyślałem, że może być fajnym wyzwaniem dla kodowania golfa z liczbami Keitha .

Proponuję więc wyzwanie polegające na utworzeniu funkcji, która przyjmuje liczbę całkowitą i zwraca wartość prawda lub fałsz w zależności od liczby lub liczby Keitha.

Więcej o liczbach Keitha

W matematyce rekreacyjnej liczba Keitha lub liczba powtórek (skrót od powtarzalnej cyfry podobnej do Fibonacciego) to liczba w następującej liczbie całkowitej: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580,…

Numberphile ma wideo wyjaśniające, jak obliczyć liczbę Keitha. Ale w zasadzie bierzesz cyfry liczby. Dodaj je razem, a następnie weź ostatnie cyfry oryginalnego numeru i dodaj je do sumy obliczeń, spłucz i powtórz. I przykład, aby to wyjaśnić.

14
1 + 4 = 5
4 + 5 = 9
5 + 9 = 14

Wejście

Liczba całkowita.

Wynik

Prawda, jeśli liczba jest liczbą Keitha. Fałsz, jeśli nie jest ...

Smetad Anarkist
źródło
Ściśle mówiąc, „liczba całkowita” może zawierać liczby zerowe lub ujemne. Jestem prawie pewien, że żaden z nich nie może być Keith Number. Czy musimy to uwzględnić?
Iszi
W zależności od rozwiązania liczby jednocyfrowe mogą być wyświetlane jako prawdziwe. Więc powinieneś sprawdzić potencjalne błędy na wejściu.
Smetad Anarkist,
Czy musi to generować true/ falseczy może być czymś prawdziwym / falsey ?
Cyoce,

Odpowiedzi:

7

GolfScript ( 31 25 znaków)

..[10base{.{+}*+(\}@*]?0>

Wprowadź jako liczbę całkowitą na górze stosu. Dane wyjściowe to 0 (fałsz) lub 1 (prawda). Demo online z listą liczb Keitha do 100.

Peter Taylor
źródło
Niezły pomysł z 0>. Niestety mogę dać +1 tylko raz.
Howard,
7

Python ( 78 75)

a=input()
n=map(int,`a`)
while a>n[0]:n=n[1:]+[sum(n)]
print(a==n[0])&(a>9)

n=n[1:]+[sum(n)]robi całą magię. Bierze każdy element oprócz pierwszego elementu n, przybija sumę n(z pierwszym elementem), a następnie ustawia na n.

Chciałbym, żebyś mógł wpisać listliczbę całkowitą i oddzielić cyfry.

Zwraca Falsewszystkie dane wejściowe poniżej 10. Może być o 8 znaków krótszy, jeśli zostanie zwrócony True.

beary605
źródło
Możesz zapisać dwa znaki, jeśli porównasz z n[0]zamiast n[-1].
Howard
Zaoszczędź jeszcze pięć print 9<a==n[0].
res
n=n[1:]+[sum(n)]może stać sięn=n[1:]+sum(n),
Cyoce,
6

GolfScript, 32 29 znaków

...[10base\{.{+}*+(\}*]&,\9>&

Implementacja GolfScript, którą można przetestować online . Dane wejściowe są podawane jako górny element na stosie i zwraca odpowiednio 0 (tj. Fałsz) lub 1.

Howard
źródło
@PeterTaylor Spójrz na podany link, gdzie dokładnie to zrobiłem - i to działa ...
Howard
@PeterTaylor Patrząc na twoje rozwiązanie, mogłem nawet zmniejszyć liczbę znaków w moim podejściu.
Howard
Nie musiałem się odświeżać, ponieważ mój komentarz dotyczy wersji 1.
Peter Taylor,
4

APL, 36 34 39 36 33 29 27

*+/x={(∇⍣(⊃x>¯1↑⍵))⍵,+/⍵↑⍨-⍴⍕x}⍎¨⍕x←⎕

Wyjście, 1jeśli Keith, w 0przeciwnym razie

GolfScript uderza ponownie !!


Edytować

+/x={(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}⍎¨⍕x←⎕

Użycie funkcji Right-redukcja ( ⊢/) zamiast Take minus 1 ( ¯1↑) bezpośrednio zapisuje 1 znak i pośrednio zapisuje 1 z Disclose ( )

Wyjaśnienie

⍎¨⍕x←⎕pobiera dane wejściowe (traktowane jako liczba) i przypisuje je do x. Konwertuje go na tablicę znaków (inaczej „ciąg” w innych językach) i zapętla każdy znak (cyfrę), konwertując go na liczbę. W rezultacie powstaje tablica liczbowa cyfr.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}jest główną funkcją „pętli”:
+/⍵↑⍨-⍴⍕xpobiera ostatnie ⍴⍕x(liczbę cyfr w x) liczby z tablicy i sumuje je.
⍵,konkatenuje to do końca tablicy.
(x>⊢/⍵)sprawdzić, czy ostatnia cyfra na tablicy (które nie zostały +/⍵↑⍨-⍴⍕xjeszcze łączone) jest mniejszy niż xi powroty 1lub 0
∇⍣Wykonuje tę funkcję w nowej tablicy, że wiele razy. Więc jeśli ostatnia liczba jest mniejsza niż x, ta funkcja się powtarza. W przeciwnym razie po prostu zwróć nową tablicę

Po wykonaniu funkcji tablica zawiera sumy do punktu, w którym 2 liczby są większe lub równe x(np. 14Wygeneruje 1 4 5 9 14 23, 13wygeneruje 1 3 4 7 11 18 29)
Na koniec sprawdź, czy każda liczba jest równa xi wypisz sumę wynikowego pliku binarnego szyk.


Edytować

1=+/x={(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}⍎¨⍕x←⎕

Dodano 2 znaki :-(, aby dane wyjściowe były 0jednocyfrowe


Jeszcze jedna edycja

+/x=¯1↓{(∇⍣(x>⊢/⍵))1↓⍵,+/⍵}⍎¨⍕x←⎕

Wyjaśnienie

Funkcja usuwa teraz pierwszą liczbę ( 1↓) z tablicy zamiast brać ostatnią ⍴⍕x( ↑⍨-⍴⍕x).
Jednak takie podejście 1=nie jest odpowiednie do obsługi liczb jednocyfrowych. Więc teraz usuwa ostatnią liczbę z tablicy przed sprawdzeniem równości x, dodając 1 znak


Zgadłeś: EDYCJA

+/x=1↓{1↓⍵,+/⍵}⍣{x≤+/⍵}⍎¨⍕x←⎕

Porównuje xdo nowo dodanego elementu zamiast starego ostatniego elementu, więc xwystarczy upuścić pierwszy (zamiast ostatniego) element przed sprawdzeniem równości, aby zapisać znak minus. Zapisuje kolejne 3 za pomocą innej formy operatora Power ( )

I pojawia się 25-znakowa odpowiedź gs (Orz)


Ostatnia edycja

x∊1↓{1↓⍵,+/⍵}⍣{x≤+/⍵}⍎¨⍕x←⎕

Nie mogę uwierzyć, że to przegapiłem.
Nie mogę już dłużej grać w golfa.

TwiNight
źródło
1
Można dostać to w dół do 24 znaków: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. W funkcji zasilania jest wartością „po”.
marinus
2

Common Lisp, 134

Czasami CL może być dość nieczytelne.

(defun k(n)(do((a(map'list #'digit-char-p(prin1-to-string n))(cdr(nconc a(list(apply'+ a))))))((>=(car a)n)(and(> n 9)(=(car a)n)))))

Niektóre formatowanie, aby uniknąć przewijania w poziomie:

(defun k(n)
  (do
    ((a(map'list #'digit-char-p(prin1-to-string n))(cdr(nconc a(list(apply'+ a))))))
    ((>=(car a)n)(and(> n 9)(=(car a)n)))))

Test:

(loop for i from 10 to 1000
      if (k i)
      collect i)

=> (14 19 28 47 61 75 197 742)
daniero
źródło
1

F # - 184 znaków

Mam nadzieję, że mogę wziąć udział w moim wyzwaniu.

let K n=
let rec l x=if n<10 then false else match Seq.sum x with|v when v=n->true|v when v<n->l(Seq.append(Seq.skip 1 x)[Seq.sum x])|_->false
string n|>Seq.map(fun c->int c-48)|>l

Edytuj Naprawiono błąd dotyczący małych liczb.

Smetad Anarkist
źródło
Wszystko w porządku :)
beary605 28.12.12
Twoje rozwiązanie zwraca true dla n <10, co moim zdaniem powinno być fałszywe.
Howard
Masz rację. Powinienem się temu przyjrzeć.
Smetad Anarkist
1

K, 55

{(x>9)&x=*|a:{(1_x),+/x}/[{~(x~*|y)|(+/y)>x}x;"I"$'$x]}

.

k)&{(x>9)&x=*|a:{(1_x),+/x}/[{~(x~*|y)|(+/y)>x}x;"I"$'$x]}'!100000
14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909 31331 34285 34348 55604 62662 86935 93993
tartin
źródło
1

PowerShell: 120 128 123 111 110 97

$j=($i=read-host)-split''|?{$_};While($x-lt$i){$x=0;$j|%{$x+=$_};$null,$j=$j+$x}$x-eq$i-and$x-gt9

$i=read-host pobiera dane wejściowe od użytkownika, przechowuje je w $ i.

$j=(... )-split''|?{$_}dzieli cyfry z $ i na tablicę i przechowuje je w $ j.

Dzięki Rynantowi za wskazanie, że -ne''jest to niepotrzebne.

While($x-lt$i) ustawia następującą pętlę podobną do Fibonnaci, aby działała, dopóki zmienna suma, $ x, nie osiągnie lub przekroczy $ i.

$x=0 zeruje $ x, więc jest gotowy do użycia do sumowania (konieczne, gdy pętla wróci).

$j|%{$x+=$_} używa pętli ForEach-Object, aby dodać wartości z $ j do $ x.

$null,$j=$j+$x przesuwa wartości w lewo $ j, odrzucając pierwszą, jednocześnie dodając $ x.

Tak! W końcu wymyśliłem krótszy sposób na zmianę i dołączanie, i ten skrypt jest poniżej 100!

$x-eq$i po zakończeniu pętli while sprawdza, czy wartość sumy $ x jest równa wartości początkowej $ i - ogólnie wskazującej na liczbę Keitha.

-and$x-gt9 unieważnia liczby jednocyfrowe, zerowe i ujemne, które nie mogą być liczbami Keitha.

Ten skrypt jest nieco „niechlujny”. Może z wdziękiem poradzić sobie z pozostawieniem $ i i $ j, ale musisz wyczyścić $ x między biegami.

Podziękowania dla Keith Hill i mjolinor za niektóre metody dzielenia liczb na cyfry, które były używane we wcześniejszych wersjach tego skryptu. Chociaż nie są one w ostatecznej wersji, zapewniły wspaniałe wrażenia z nauki.

Iszi
źródło
Możesz usunąć -ne''tak, aby było po prostu ?{$_}.
Rynant,
Dzięki @Rynant. Wygląda na to, że mogę go jeszcze przyciąć, zastępując $i=read-host;$j=$i-split''|?{$_}'go $j=($i=read-host)-split''|?{$_}.
Iszi
0

Ruby, 82

def keith?(x)
  l="#{x}".chars.map &:to_i
  0while(l<<(s=l.inject :+)).shift&&s<x
  (s==x)&l[1]
end

Podejrzewam, że Python jest lepszym narzędziem do tego.

histocrat
źródło
0

C, 123

k(v){
    int g[9],i,n,s,t=v;
    for(n=s=0;t;t/=10)s+=g[n++]=t%10;
    for(i=n;s<v;){
        i=(i+n-1)%n;
        t=g[i];g[i]=s;s=s*2-t;
    }
    return n>1&&s==v;
}

test za pomocą uprzęży:

main(i){
    for(i=0;i<20000;i++)
        if(k(i)) printf("%d ",i);
}

daje:

14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909
króliczek
źródło
Można wymienić i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;z i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;zaoszczędzisz dwóch znaków.
schnaader
0

R 116

Zdzieranie Pythona:

a=scan();n=as.numeric(strsplit(as.character(a),"")[[1]]);while(a>n[1])n=c(n[-1],sum(n));if((n[1]==a)&&(a>9))T else F
Paolo
źródło
0

Perl, 90

sub k{$-=shift;$==@$=split//,$-;push@$,eval join'+',@$[-$=..-1]while@$[-1]<$-;grep/$-/,@$}

Zabawne ćwiczenie! Wiem, że to stary post, ale zauważyłem, że Perl zaginął!

Jestem pewien, że mogę poprawić sposób, w jaki to buduję, dzięki dokładniejszemu przeanalizowaniu innych odpowiedzi, więc prawdopodobnie wrócę do tego!

Dom Hastings
źródło
0

Smalltalk - 136 znaków

 [:n|s:=n asString collect:[:c|c digitValue]as:OrderedCollection.w:=s size.[n>s last]whileTrue:[s add:(s last:w)sum].^(s last=n and:n>9)]

Wyślij ten blok value:

Paul Richter
źródło
0

Java - 1437

import java.io.*;
class keith
{
    public int reverse(int n)
    {
        int i,c=0;
        while(n>0)
        {
            c=(c*10)+(n%10);
            n/=10;
        }
        return(c);
    }
    public int countdigit(int n)
    {
        int i,c=0;
        while(n>0)
        {
            c++;
            n/=10;
        }
        return(c);
    }
    public void keith_chk()throws IOException
    {
        BufferedReader br=new BufferedReader(
        new InputStreamReader(System.in));
        int n,digi,r,p=0,a,tot=0,i;
        System.out.print("Enter number :-");
        n=Integer.parseInt(br.readLine());
        digi=countdigit(n);

        int ar[]=new int[digi+1];
        r=reverse(n);
        while(r>0)
        {
            a=r%10;
            ar[p++]=a;
            tot=tot+a;
            r/=10;
        }
        ar[p]=tot;
        while(true)
        {
            for(i=0;i<=p;i++)
            System.out.print(ar[i]+"\t");
            System.out.println(); 
            if(tot == n)
            {
                System.out.print("Keith Number....");
                break;
            }
            else if(tot > n)
            {
                System.out.print("Not Keith Number.....");
                break;
            }
            tot=0;
            for(i=1;i<=p;i++)
            {
                ar[i-1]=ar[i];
                tot=tot+ar[i];
            }
            ar[p]=tot;
        }
    }
}
mousami
źródło
3
Witamy w CodeGolf.SE! Ponieważ kwestia ta jest code-golf , należy golf kodzie (odstępy usuwania, nowe linie ...)
Vereos
0

Python3 104

#BEGIN_CODE
def k(z):
 c=str(z);a=list(map(int,c));b=sum(a)
 while b<z:a=a[1:]+[b];b=sum(a)
 return(b==z)&(len(c)>1)
#END_CODE score: 104

print([i for i in filter(k, range(1,101))])  #[14, 19, 28, 47, 61, 75]

I to jest funkcja;)

gcq
źródło
0

Python - 116 znaków

Nie jestem ekspertem od codegolf, więc proszę bardzo - moja pierwsza próba.

x=input();n=`x`;d=[int(i)for i in n];f=d[-1]
while f<x:d+=[sum(d[-len(n):])];f=d[-1]
if f==x>13:print 1
else:print 0

Wprowadź 2 zmiany dla funkcji:

  • Zmień printnareturn
  • Przypisz, xaby był parametrem

PS I drugi @ beary605 - dodaj wbudowane, aby oddzielić cyfry / znaki / cokolwiek.

Dan the Man
źródło
0

Rubin (z OOP)

class Recreationalmathematics
def Check_KeithSequence(digit) 
    sequence,sum=digit.to_s.split(//).to_a,0
    while(sum<digit) do
        sum=0
        sequence.last(digit.to_s.size).each{|v|  sum=sum+v.to_i}
        sequence<<sum
    end 
    return (sum==digit)?"true":"false" 
end
end
test = Recreationalmathematics.new
puts test.Check_KeithSequence(197)
puts test.Check_KeithSequence(198)
początkujący
źródło