Testen Sie, ob die angegebene Nummer eine Keith-Nummer ist


14

Da Fibonacci-Zahlen und -Sequenzen ein beliebtes Thema für Codegolf zu sein scheinen, dachte ich, dass es eine unterhaltsame Herausforderung sein könnte, Golf mit Keith-Zahlen zu codieren .

Also schlage ich eine Herausforderung vor, die darin besteht, eine Funktion zu erstellen, die eine Ganzzahl annimmt und je nachdem, ob es sich bei der Zahl um eine Keith-Zahl handelt oder nicht, ein Wahr oder Falsch zurückgibt.

Mehr über Keith-Zahlen

In der Freizeitmathematik ist eine Keith-Zahl oder eine Nachkommazahl (kurz für repetitive Fibonacci-ähnliche Ziffer) eine Zahl in der folgenden ganzzahligen Folge: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208. 2580,…

Numberphile hat ein Video, in dem erklärt wird, wie eine Keith-Zahl berechnet wird. Aber im Grunde genommen nimmst du die Ziffern einer Zahl. Addiere sie und nimm dann die letzten Ziffern der ursprünglichen Zahl und addiere sie zur Summe der Berechnung, spüle und wiederhole. Und zum Beispiel um es klar zu machen.

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

Eingang

Eine ganze Zahl.

Ausgabe

True, wenn die Nummer eine Keith-Nummer ist. Falsch, wenn es nicht ist ..


Streng genommen kann "eine ganze Zahl" null oder negative Zahlen enthalten. Ich bin mir ziemlich sicher, dass beides keine Keith-Nummer sein kann. Müssen wir das berücksichtigen?
Iszi

Abhängig von Ihrer Lösung können einstellige Zahlen als wahr angezeigt werden. Sie sollten also nach möglichen Fehlern bei der Eingabe suchen.
Smetad Anarkist

Muss es etwas ausgeben true/ falseoder kann es etwas Wahres / Falsches sein ?
Cyoce

Antworten:


7

GolfScript ( 31 25 Zeichen)

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

Eingabe als Ganzzahl über dem Stapel. Die Ausgabe ist 0 (falsch) oder 1 (wahr). Online-Demo, die die Keith-Nummern bis zu 100 auflistet.


Gute Idee mit dem 0>. Leider kann ich nur einmal +1 geben.
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)]macht die ganze Magie. Es nimmt jedes Element außer dem ersten Element von n, setzt die Summe von n(mit dem ersten Element) auf und setzt diese dann auf n.

Ich wünschte, Sie könnten listeine Ganzzahl aufrufen und die Ziffern trennen lassen.

Gibt Falsebei allen Eingaben unter 10 zurück. Kann bei Rückgabe 8 Zeichen kürzer sein True.


Sie können zwei Zeichen speichern, wenn Sie mit n[0]anstelle von vergleichen n[-1].
Howard

Sparen Sie fünf weitere mit print 9<a==n[0].
Res

n=n[1:]+[sum(n)]werden kannn=n[1:]+sum(n),
Cyoce

6

GolfScript, 32 29 Zeichen

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

Eine GolfScript-Implementierung, die getestet werden kann online werden kann . Die Eingabe wird als oberstes Element im Stapel angegeben und gibt 0 (dh false) bzw. 1 zurück.


@ Peter Taylor Schauen Sie sich den Link an, wo ich genau das getan habe - und es funktioniert ...
Howard

@PeterTaylor Wenn ich mir Ihre Lösung anschaue, könnte ich sogar die Anzahl der Zeichen in meinem Ansatz weiter reduzieren.
Howard

Ich muss nicht aktualisiert haben, da mein Kommentar für Version 1 gilt.
Peter Taylor

4

APL, 36, 34, 39 36 33 29 27

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

Ausgabe 1wenn Keith, 0sonst

GolfScript schlägt wieder zu !!


Bearbeiten

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

Verwenden von Right-reduction ( ⊢/) anstelle von Take minus 1 (¯1↑ ) verwenden, wird 1 Zeichen direkt und 1 Zeichen indirekt aus Disclose ( ) gespeichert.

Erläuterung

⍎¨⍕x←⎕ Nimmt ausgewertete Eingaben (als Zahl behandelt) und weist sie zu x . Konvertiert es in ein Zeichenfeld (in anderen Sprachen auch als "Zeichenfolge" bezeichnet) und durchläuft jedes Zeichen (Ziffer) in einer Schleife, um es in eine Zahl umzuwandeln. Dies ergibt also ein numerisches Array der Ziffern.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}ist die "Schleifen" -Funktion:
+/⍵↑⍨-⍴⍕xNimmt die letzten ⍴⍕x( xAnzahl der Ziffern in ) Zahlen aus dem Array und summiert sie.
⍵,verkettet es an das Ende des Arrays.
(x>⊢/⍵)Überprüfen Sie, ob die letzte Nummer im Array (die noch nicht +/⍵↑⍨-⍴⍕xverkettet ist) kleiner ist als xund 1oder zurückgibt0
∇⍣ diese Funktion auf dem neuen Array so oft ausführt. Wenn also die letzte Zahl kleiner als ist x, wird diese Funktion wiederholt. Anderenfalls geben Sie einfach das neue Array zurück

Nach dem Ausführen der Funktion enthält das Array die Summen bis zu dem Punkt, an dem 2 der Zahlen größer oder gleich sind x(z. B. 14werden generiert 1 4 5 9 14 23, 13werden generiert 1 3 4 7 11 18 29).
Überprüfen Sie schließlich, ob jede Zahl gleich ist, xund geben Sie die Summe der resultierenden Binärzahl aus Array.


Bearbeiten

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

Es wurden 2 Zeichen hinzugefügt :-(, um eine Ausgabe zu machen, 0wenn die Eingabe eine Ziffer ist


Noch eine Änderung

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

Erläuterung

Die Funktion löscht nun die erste Zahl ( 1↓) aus dem Array, anstatt die letzte ⍴⍕x( ↑⍨-⍴⍕x) zu nehmen.
Dieser Ansatz ist jedoch 1=nicht ausreichend, um einstellige Zahlen zu verarbeiten. Daher löscht es jetzt die letzte Zahl aus dem Array, bevor es die Gleichheit mit überprüft xund 1 Zeichen hinzufügt


Sie haben es erraten: BEARBEITEN

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

Vergleicht xmit dem neu hinzugefügten Element anstelle des alten letzten Elements. Löschen Sie daher das erste (anstelle des letzten) Element, bevor Sie die Gleichheit mit überprüfenx löschen und ein Minuszeichen zu speichern. Speichert weitere 3 mit einer anderen Form des Power-Operators ( )

Und es erscheint eine 25-stellige Antwort (Orz)


Letzte Bearbeitung

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

Ich kann nicht glauben, dass ich das verpasst habe.
Kann es nicht mehr Golf spielen.


1
Sie können diese bis zu 24 Zeichen erhalten: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. In der Power-Funktion steht der "After" -Wert.
Marinus

2

Common Lisp, 134

CL kann manchmal ziemlich unlesbar sein.

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

Einige Formatierungen, um horizontales Scrollen zu vermeiden:

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

Prüfung:

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

=> (14 19 28 47 61 75 197 742)

1

F # - 184 Zeichen

Ich hoffe, dass es in Ordnung ist, an meiner eigenen Herausforderung teilzunehmen.

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

Bearbeiten Es wurde ein Fehler in Bezug auf kleine Zahlen behoben.


Es ist völlig in Ordnung :)
beary605

Ihre Lösung liefert true für n <10, was meiner Meinung nach false sein sollte.
Howard

Du hast recht. Ich sollte das untersuchen.
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 Nimmt Eingaben vom Benutzer entgegen und speichert sie in $ i.

$j=(... )-split''|?{$_}zerlegt die Ziffern von $ i in ein Array und speichert sie in $ j.

Vielen Dank an Rynant für den Hinweis, dass dies -ne''nicht erforderlich ist.

While($x-lt$i) Legt fest, dass die folgende Fibonnaci-ähnliche Schleife ausgeführt wird, bis die Summenvariable $ x $ i erreicht oder überschreitet.

$x=0 setzt $ x auf Null, damit es für die Summierung verwendet werden kann (erforderlich, wenn die Schleife zurückkehrt).

$j|%{$x+=$_} verwendet eine ForEach-Object-Schleife, um die Werte von $ j zu $ ​​x zu addieren.

$null,$j=$j+$x verschiebt die Werte in $ j nach links und verwirft die erste, während $ x angehängt wird.

Yay! Ich habe endlich einen kürzeren Weg gefunden, Shift-and-Append zu machen und dieses Skript unter 100 zu bekommen!

$x-eq$i Nach Abschluss der while-Schleife wird geprüft, ob der Summenwert $ x gleich dem Anfangswert $ i ist - im Allgemeinen ein Hinweis auf eine Keith-Zahl.

-and$x-gt9 macht einstellige Zahlen, Nullen und negative Zahlen ungültig, bei denen es sich nicht um Keith-Zahlen handeln kann.

Dieses Skript ist ein bisschen "chaotisch". $ I und $ j, die übrig bleiben, können problemlos verarbeitet werden, aber Sie müssen $ x zwischen den Läufen löschen.

Vielen Dank an Keith Hill und mjolinor für einige Methoden zum Aufteilen von Zahlen in Ziffern, die in früheren Versionen dieses Skripts verwendet wurden. Während sie nicht in der endgültigen Version sind, haben sie für eine großartige Lernerfahrung gesorgt.


Sie können das -ne''so entfernen , dass es gerade ist ?{$_}.
Rynant

Vielen Dank @Rynant. Sieht aus wie ich kann es auch eine weitere Verschlankung durch den Ersatz $i=read-host;$j=$i-split''|?{$_}'mit $j=($i=read-host)-split''|?{$_}.
Iszi

0

Rubin, 82

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

Verdächtige, dass Python ein besseres Werkzeug für dieses ist.


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 über Kabelbaum:

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

gibt:

14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909

Sie können ersetzen i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;mit i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;und speichern zwei Zeichen.
Schnaader

0

R 116

Python-Abzocke:

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/$-/,@$}

Eine lustige Übung! Ich weiß, dass es ein alter Beitrag ist, aber ich habe gemerkt, dass Perl fehlt!

Ich bin mir sicher, dass ich die Art und Weise, wie ich das aufbaue, verbessern kann, indem ich die anderen Antworten gründlicher verdaue, also werde ich das wahrscheinlich noch einmal wiederholen!


0

Smalltalk - 136 Zeichen

 [: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)]

Senden Sie diesen Block 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
Willkommen bei CodeGolf.SE! Da diese Frage Code-Golf ist , sollten Sie Ihren Code Golf (entfernen Sie Leerzeichen, neue Zeilen ...)
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]

Und es ist eine Funktion;)


0

Python - 116 Zeichen

Ich bin kein wirklicher Codegolf-Experte, also haben Sie es - meinen ersten Versuch.

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

Nehmen Sie zwei Änderungen für eine Funktion vor:

  • Wechseln Sie printzureturn
  • Weisen Sie xzu, der Parameter zu sein

PS Ich zweite @ beary605-Add ein eingebautes, um die Ziffern / Zeichen / was auch immer zu trennen.


0

Ruby (mit 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)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.