测试给定数字是否为Keith数


14

由于斐波那契数字和序列似乎是打高尔夫球的热门话题,所以我认为用基思数字打高尔夫球可能是一个有趣的挑战。

因此,我提出了一个挑战,即创建一个函数,该函数需要一个整数,并根据数字是否为Keith数字来返回true或false。

有关基思数字的更多信息

在娱乐数学中,Keith数或repfigit数(重复的斐波那契数位的缩写)是以下整数序列中的数字:14、19、28、47、61、75、197、742、1104、1537、2208, 2580,…

Numberphile的视频解释了如何计算Keith数。但基本上,您使用数字的位数。将它们加在一起,然后取原始数字的最后几位,并将它们加到计算总和中,然后冲洗并重复。并举例说明。

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

输入值

一个整数。

输出量

如果数字是基思数字,则为True。如果不是,则为假。


严格来说,“整数”可以包含零或负数。我很确定两者都不是基思数。我们需要考虑这个吗?
Iszi 2013年

根据您的解决方案,单个数字可能显示为true。因此,您应该检查输入中是否存在潜在错误。
Smetad Anarkist

它是否必须输出true/ false或者是真/假
Cyoce

Answers:


7

GolfScript(31 25个字符)

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

在堆栈顶部输入为整数。输出为0(假)或1(真)。在线演示,其中列出了不超过100的Keith数。


不错的主意0>。不幸的是,我只能+1。
霍华德

7

巨蟒(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)]做所有的魔术。它接受除的第一项之外的所有项n,并粘贴n(与第一项)的总和,然后将其设置为n

我希望您可以调用list一个整数并将数字分开。

返回False所有低于10的输入。如果返回,则可以短8个字符True


如果与n[0]而不是进行比较,则可以节省两个字符n[-1]
霍华德

使用节省更多print 9<a==n[0]
res

n=n[1:]+[sum(n)]可以成为n=n[1:]+sum(n),
Cyoce

6

GolfScript,32个 29个字符

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

一个可以测试的GolfScript实现 在线。输入作为堆栈顶部的元素给出,并且分别返回0(即false)或1。


@PeterTaylor看看提供的链接,我正是在该链接上进行的-它确实有效...
Howard

@PeterTaylor看着您的解决方案,我甚至可以进一步减少字符数。
霍华德

我一定不会刷新,因为我的评论是适用于版本1
彼得·泰勒

4

APL,36 34 39 36 33 29 27

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

输出量 1如果是基思0则,否则

GolfScript再次罢工!


编辑

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

使用减右(⊢/)代替取负1(¯1↑),直接保存1个字符,并间接从Disclose()保存1个字符

说明

⍎¨⍕x←⎕接受评估后的输入(视为数字)并将其分配给x。将其转换为字符数组(在其他语言中也称为“字符串”),并遍历每个字符(数字),将其转换为数字。因此,这将导致数字的数字数组。

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}是主要的“循环”功能:从数组中
+/⍵↑⍨-⍴⍕x获取最后一个⍴⍕x(数字中的数字x)并求和。
⍵,将其连接到数组的末尾。
(x>⊢/⍵)检查数组上的最后一个数字(+/⍵↑⍨-⍴⍕x尚未连接)是否小于,x并在新数组上多次返回10
∇⍣执行此函数。因此,如果最后一个数字小于x,则此函数重复出现。否则,只需返回新数组

执行完函数后,数组将包含直到两个数字大于或等于的总和x(例如,14将生成1 4 5 9 14 2313将生成1 3 4 7 11 18 29)。
最后检查每个数字是否等于x并输出结果二进制的总和数组。


编辑

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

添加2个字符:-( 0如果输入是一位数字则输出


另一个编辑

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

说明

该函数现在1↓从数组中删除第一个数字(),而不是获取最后一个⍴⍕x↑⍨-⍴⍕x)。
但是,这种方法1=不足以处理一位数字。因此,它现在在检查等于之前将数组中的最后一个数字删除x,添加1个字符


您猜对了:编辑

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

比较x到新添加的项目,而不是旧的最后一个项目,所以下降的第一个(而不是最后)项目检查平等之前x是足够了,节省了减号。使用另一种形式的Power运算符保存另外3个(

然后出现2​​5个字符的gs答案(Orz)


最后编辑

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

不敢相信我错过了。
不能再打高尔夫球了。


1
您最多可以输入24个字符:x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕。在幂函数中,是“之后”值。
marinus

2

普通Lisp,134

有时,CL可能非常难以理解。

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

避免水平滚动的一些格式:

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

测试:

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

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

1

F#-184个字符

我希望可以参加自己的挑战。

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

编辑修复了有关小数字的错误。


很好:)
beary605

对于n <10,您的解决方案返回true,我认为应该为false。
霍华德

你是对的。我应该调查一下。
Smetad Anarkist 2012年

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 从用户那里获取输入,并将其存储在$ i中。

$j=(... )-split''|?{$_}将$ i中的数字分解为一个数组,并将其存储在$ j中。

感谢Rynant指出这-ne''是不必要的。

While($x-lt$i) 设置以下类似Fibonnaci的循环运行,直到总和变量$ x达到或超过$ i。

$x=0 将$ x归零,因此可以用于求和(循环返回时需要)。

$j|%{$x+=$_} 使用ForEach-Object循环将$ j中的值加到$ x中。

$null,$j=$j+$x 将$ j中的值左移,丢弃第一个,同时附加$ x。

好极了!我终于想出了一种进行移位和追加的更短方法,并将此脚本控制在100以下!

$x-eq$i 在while循环完成之后,测试和值$ x是否等于初始值$ i-通常表示基思数。

-and$x-gt9 使一位数字,零和负数无效,这些数字不能为基思数字。

这个脚本有点“混乱”。它可以很好地处理$ i和$ j剩余的情况,但是您需要在两次运行之间清除$ x。

感谢Keith Hillmjolinor提供了一些将数字分解为数字的方法,该方法已在此脚本的早期版本中使用。尽管它们不是最终版本,但确实提供了很好的学习体验。


您可以删除,-ne''这样它才是?{$_}
雷纳特

谢谢@Rynant。看起来我也可以通过替换$i=read-host;$j=$i-split''|?{$_}'为来将其缩小一倍$j=($i=read-host)-split''|?{$_}
Iszi 2013年

0

露比(82)

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

怀疑Python是一个更好的工具。


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

通过线束测试:

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

给出:

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

您可以替换i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;并保存两个字符。
schnaader 2012年

0

R,116

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

一个有趣的运动!我知道这是一个旧帖子,但是我发现perl丢失了!

我确信我可以通过更彻底地消化其他响应来改进构建此响应的方式,因此我可能会重新考虑!


0

Smalltalk-136个字符

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

发送此块 value:


0

爪哇-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
欢迎来到CodeGolf.SE!由于这个问题是代码高尔夫球场,你应该打高尔夫球你的代码(删除空格,换行...)
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]

这是一个功能;)


0

Python-116个字符

并不是真正的codegolf专家,所以您有我第一次尝试。

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

对功能进行2个更改:

  • 更改printreturn
  • 分配x为参数

PS I第二个@ beary605-添加了一个内置功能,以分隔数字/字符/任何数字。


0

Ruby(带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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.