Tester si un numéro donné est un numéro Keith


14

Étant donné que les nombres et les séquences de Fibonacci semblent être un sujet populaire pour le golf de code, j'ai pensé que ce pourrait être un défi amusant de coder le golf avec des nombres de Keith .

Je propose donc un défi qui est de créer une fonction qui prend un entier et qui renvoie un vrai ou un faux selon que le nombre est un nombre de Keith ou non.

En savoir plus sur les chiffres de Keith

En mathématiques récréatives, un nombre Keith ou un nombre repfigit (abréviation de chiffre répétitif de type Fibonacci) est un nombre dans la séquence entière suivante: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580,…

Numberphile a une vidéo expliquant comment calculer un nombre Keith. Mais en gros, vous prenez les chiffres d'un nombre. Ajoutez-les ensemble, puis prenez les derniers chiffres du numéro d'origine et ajoutez-les à la somme du calcul, rincez et répétez. Et un exemple pour le clarifier.

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

Contribution

Un nombre entier.

Production

Vrai si le nombre est un nombre Keith. Faux si ce n'est pas ..


Strictement parlant, "un entier" peut inclure zéro ou des nombres négatifs. Je suis sûr que ni l'un ni l'autre ne peut être un Keith Number. Faut-il en tenir compte?
Iszi

Selon votre solution, des nombres à un chiffre peuvent apparaître comme vrais. Vous devez donc vérifier les éventuelles erreurs de saisie.
Smetad Anarkist

Doit-il produire true/ falseou peut-il être quelque chose de vrai / de falsey ?
Cyoce

Réponses:


7

GolfScript ( 31 25 caractères)

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

Saisissez un entier au-dessus de la pile. La sortie est 0 (faux) ou 1 (vrai). Démo en ligne qui répertorie les numéros Keith jusqu'à 100.


Belle idée avec le 0>. Malheureusement, je ne peux +1 qu'une seule fois.
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)]fait toute la magie. Il prend chaque élément, mais le premier élément de n, colle à la somme de n(avec le premier élément), puis définit cela n.

Je souhaite que vous puissiez appeler listun entier et séparer les chiffres.

Renvoie Falsetoutes les entrées inférieures à 10. Peut être 8 caractères plus court s'il est retourné True.


Vous pouvez enregistrer deux caractères si vous comparez avec n[0]au lieu de n[-1].
Howard

Économisez cinq de plus avec print 9<a==n[0].
res

n=n[1:]+[sum(n)]peut devenirn=n[1:]+sum(n),
Cyoce

6

GolfScript, 32 29 caractères

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

Une implémentation GolfScript qui peut être testée en ligne . L'entrée est donnée comme élément supérieur de la pile et elle renvoie respectivement 0 (c'est-à-dire faux) ou 1.


@PeterTaylor Regardez le lien fourni où j'ai fait exactement cela - et cela fonctionne ...
Howard

@PeterTaylor En regardant votre solution, je pourrais même réduire davantage le nombre de caractères dans mon approche.
Howard

Je ne dois pas avoir rafraîchi, car mon commentaire s'applique à la version 1.
Peter Taylor

4

APL, 36 34 39 36 33 29 27

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

Sortie 1si Keith, 0sinon

GolfScript frappe à nouveau !!


Éditer

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

Utilisation de Right-reduction ( ⊢/) au lieu de Take moins 1 (¯1↑ ), en sauvant directement 1 caractère et indirectement 1 en Disclose ( )

Explication

⍎¨⍕x←⎕ prend l'entrée évaluée (traitée comme un nombre) et l'affecte à x . Le convertit en un tableau de caractères (alias "chaîne" dans d'autres langues), et parcourt chaque caractère (chiffre), le convertissant en un nombre. Il en résulte donc un tableau numérique des chiffres.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}est la fonction principale de "boucle":
+/⍵↑⍨-⍴⍕xprend le dernier ⍴⍕x(nombre de chiffres x) du tableau et les additionne.
⍵,le concatène à la fin du tableau.
(x>⊢/⍵)vérifier si le dernier nombre du tableau (qui n'a pas encore été +/⍵↑⍨-⍴⍕xconcaténé) est plus petit que xet renvoie 1ou 0
∇⍣exécute cette fonction sur le nouveau tableau autant de fois. Donc, si le dernier nombre est inférieur à x, cette fonction se reproduit. Sinon, renvoyez simplement le nouveau tableau

Après l'exécution de la fonction, le tableau contient les sommes jusqu'au point où 2 des nombres sont supérieurs ou égaux x(par exemple 14va générer 1 4 5 9 14 23, 13va générer 1 3 4 7 11 18 29)
Enfin vérifier si chaque nombre est égal xet sortir la somme du binaire résultant tableau.


Éditer

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

Ajout de 2 caractères :-( pour faire une sortie 0si l'entrée est à un chiffre


Encore un autre montage

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

Explication

La fonction supprime maintenant le premier nombre ( 1↓) du tableau au lieu de prendre le dernier ⍴⍕x( ↑⍨-⍴⍕x).
Cependant, cette approche 1=ne permet pas de gérer des nombres à un chiffre. Donc, il supprime maintenant le dernier nombre du tableau avant de vérifier l'égalité x, en ajoutant 1 caractère


Vous l'avez deviné: EDIT

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

Se compare xà l'élément nouvellement ajouté au lieu de l'ancien dernier élément, donc laisser tomber le premier (au lieu du dernier) élément avant de vérifier l'égalité xest suffisant, en enregistrant un signe moins. Enregistre 3 autres en utilisant une autre forme de l'opérateur Power ( )

Et une réponse gs de 25 caractères apparaît (Orz)


Dernière modification

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

Je ne peux pas croire que j'ai raté ça.
Je ne peux plus jouer au golf.


1
Vous pouvez obtenir ce jusqu'à 24 caractères: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. Dans la fonction de puissance, est la valeur "après".
marinus

2

Lisp commun, 134

CL peut parfois être tout à fait illisible.

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

Quelques mises en forme pour éviter le défilement horizontal:

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

Tester:

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

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

1

F # - 184 caractères

J'espère que c'est ok que je participe à mon propre défi.

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

Modifier Correction d'un bug concernant les petits nombres.


C'est parfaitement bien :)
beary605

Votre solution renvoie vrai pour n <10, ce qui, je pense, devrait être faux.
Howard

Tu as raison. Je devrais examiner cela.
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 prend l'entrée de l'utilisateur, la stocke dans $ i.

$j=(... )-split''|?{$_}décompose les chiffres de $ i dans un tableau et les stocke dans $ j.

Merci à Rynant d' avoir souligné que cela n'était pas -ne''nécessaire.

While($x-lt$i) définit la boucle de type Fibonnaci suivante pour qu'elle s'exécute jusqu'à ce que la variable somme, $ x, atteigne ou dépasse $ i.

$x=0 met à zéro $ x, il est donc prêt à être utilisé pour la sommation (nécessaire lorsque la boucle revient).

$j|%{$x+=$_} utilise une boucle ForEach-Object pour additionner les valeurs de $ j à $ x.

$null,$j=$j+$x décale les valeurs de $ j vers la gauche, en rejetant la première, tout en ajoutant $ x.

Yay! J'ai finalement trouvé un moyen plus court de faire un shift-and-append et j'ai obtenu ce script sous 100!

$x-eq$i une fois la boucle while terminée, teste si la valeur de somme, $ x, est égale à la valeur initiale, $ i - généralement indicative d'un nombre Keith.

-and$x-gt9 invalide les nombres à un chiffre, zéro et les nombres négatifs, qui ne peuvent pas être des nombres Keith.

Ce script est un peu "salissant". Il peut gérer avec élégance les restes de $ i et $ j, mais vous devrez effacer $ x entre les exécutions.

Merci à Keith Hill et mjolinor pour certaines méthodes de décomposition des nombres en chiffres qui étaient utilisées dans les versions antérieures de ce script. Bien qu'ils ne soient pas dans la version finale, ils ont fourni une excellente expérience d'apprentissage.


Vous pouvez supprimer le -ne''afin qu'il soit juste ?{$_}.
Rynant

Merci @Rynant. On dirait que je peux aussi le réduire encore un en le remplaçant $i=read-host;$j=$i-split''|?{$_}'par $j=($i=read-host)-split''|?{$_}.
Iszi

0

Rubis, 82

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

Suspect Python est un meilleur outil pour celui-ci.


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 via harnais:

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

donne:

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

Vous pouvez remplacer i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;avec i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;et enregistrer deux caractères.
schnaader

0

R, 116

Arnaque Python:

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

Un exercice amusant! Je sais que c'est un vieux post mais j'ai remarqué que Perl manquait!

Je suis sûr que je peux améliorer ma façon de construire cela en digérant les autres réponses de manière plus approfondie, donc je vais probablement y revenir!


0

Smalltalk - 136 caractères

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

Envoyer ce bloc 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
Bienvenue sur CodeGolf.SE! Étant donné que cette question est un code-golf , vous devriez golf votre code (supprimer de nouvelles lignes, espaces blancs ...)
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]

Et c'est une fonction;)


0

Python - 116 caractères

Pas vraiment un expert en codegolf, donc vous l'avez - mon premier essai.

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

Apportez 2 modifications à une fonction:

  • Remplacer printparreturn
  • Attribuer xpour être le paramètre

PS je seconde @ beary605- ajouter un intégré pour séparer les chiffres / caractères / que ce soit.


0

Ruby (avec 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)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.