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


Ś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.


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.


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.


@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.


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)

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.


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

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.


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.


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

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

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!


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:


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

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


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.


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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.