Keith sayısının verilen sayı olup olmadığını test edin


14

Fibonacci sayıları ve dizileri kod golf için popüler bir konu gibi göründüğünden, Keith numaraları ile golf kodlamak için eğlenceli bir meydan okuma olabileceğini düşündüm .

Bu yüzden bir tamsayı alan ve sayıya bağlı olarak doğru veya yanlış veren bir işlev oluşturmak için bir meydan okuma önermek bir Keith sayıdır.

Keith numaraları hakkında daha fazla bilgi

Rekreasyonel matematikte bir Keith numarası veya yeniden yapılandırma numarası (tekrarlayan Fibonacci benzeri basamağın kısaltması) aşağıdaki tamsayı dizisindeki bir sayıdır: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580,…

Numberphile'in bir Keith sayısının nasıl hesaplanacağını açıklayan bir videosu var. Ama temelde bir sayının rakamlarını alırsınız. Bunları bir araya getirin ve ardından orijinal numaranın son rakamlarını alın ve hesaplama toplamına ekleyin, durulayın ve tekrarlayın. Ve netleştirmek için örnek.

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

Giriş

Bir tam sayı.

Çıktı

Sayı bir Keith numarasıysa doğrudur. Değilse yanlış ..


Açıkçası, "bir tamsayı" sıfır veya negatif sayılar içerebilir. Eminim ki ikisi de Keith Number olamaz. Bunu hesaba katmamız gerekiyor mu?
Iszi

Çözümünüze bağlı olarak, tek basamaklı sayılar doğru görünebilir. Bu nedenle, girdideki olası hataları kontrol etmelisiniz.
Smetad Anarkist

Çıktısı olması gerekiyor mu true/ falseveya doğru / falsey bir şey olabilir mi?
Cyoce

Yanıtlar:


7

GolfScript ( 31 25 karakter)

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

Yığının üstünde bir tamsayı olarak girin. Çıktı 0 (yanlış) veya 1 (doğru). 100'e kadar Keith sayısını listeleyen çevrimiçi demo .


İle güzel bir fikir 0>. Ne yazık ki sadece bir kez + 1'leyebilirim.
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)]tüm sihri yapar. İlk öğeden başka her öğeyi alır n, n(ilk öğeyle birlikte) toplamına yapışır , sonra bunu ayarlar n.

Keşke listbir tamsayı arayabilir ve rakamları ayırabilseydiniz.

İade Falseiade eğer 10'un altında bütün girdilere 8 karakter daha kısa olabilir True.


Bunun n[0]yerine ile karşılaştırırsanız iki karakter kaydedebilirsiniz n[-1].
Howard

İle beş tane daha tasarruf edin print 9<a==n[0].
res

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

6

GolfScript, 32 29 karakter

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

Çevrimiçi olarak test edilebilen bir GolfScript uygulaması . Giriş yığın üzerinde üst öğe olarak verilir ve sırasıyla 0 (yani yanlış) veya 1 değerini döndürür.


@PeterTaylor Tam olarak yaptığım yerde sağlanan bağlantıya bakın - ve işe yarıyor ...
Howard

@PeterTaylor Çözümünüze baktığımda, yaklaşımımdaki karakter sayısını daha da azaltabilirim.
Howard

Yenilenmemeliydim, çünkü yorumum sürüm 1 için geçerlidir
Peter Taylor

4

APL, 36 34 39 36 33 29 27

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

1Keith varsa çıktı , 0aksi takdirde

GolfScript tekrar saldırıyor !!


Düzenle

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

⊢/Eksi 1 ( ) yerine Sağ azaltma ( ) kullanmak ¯1↑, doğrudan 1 karakter kaydetmek ve 1 değerini Disclose ( ) öğesinden dolaylı olarak kaydetmek

açıklama

⍎¨⍕x←⎕değerlendirilmiş girişi alır (sayı olarak kabul edilir) ve atar x. Bir karakter dizisine dönüştürür (diğer dillerde "dize" olarak da bilinir) ve her karakterde (rakam) döngü yaparak bir sayıya dönüştürür. Bu rakamların sayısal bir dizisi ile sonuçlanır.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}ana "döngü" fonksiyonudur: dizideki
+/⍵↑⍨-⍴⍕xson ⍴⍕x(basamak xsayısı) sayıları toplar ve toplar.
⍵,dizinin sonuna kadar birleştirir.
(x>⊢/⍵)dizideki son numaranın ( +/⍵↑⍨-⍴⍕xhenüz bitiştirilmemiş) küçük olup olmadığını kontrol edin ve bu işlevi yeni dizide birçok kez xdöndürür 1veya 0
∇⍣yürütür. Eğer son sayı daha küçükse x, bu fonksiyon tekrar eder. Aksi takdirde yeni diziyi döndürmeniz yeterlidir

İşlevi yürüttükten sonra, dizi, sayıların 2'sinden büyük veya ona eşit olan noktaya kadar toplamları içerir x(örneğin 14, üretecektir 1 4 5 9 14 23, 13üretecektir 1 3 4 7 11 18 29)
Son olarak, her sayının xsonuçtaki ikilinin eşit olup olmadığını kontrol edin dizi.


Düzenle

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

0Giriş tek basamaklıysa çıktı yapmak için 2 karakter :-( eklendi


Yine başka bir düzenleme

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

açıklama

Fonksiyon şimdi 1↓, last ⍴⍕x( ↑⍨-⍴⍕x) sayısını almak yerine dizideki ilk sayıyı ( ) bırakır .
Ancak, bu yaklaşım 1=tek haneli sayıları işlemek için yeterli değildir. Böylece x, eşitliği kontrol etmeden önce diziden son sayıyı düşürüyor ve 1 karakter ekliyor.


Tahmin ettiniz: EDIT

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

xEski son öğe yerine yeni eklenen öğeyle karşılaştırır , bu nedenle eşitliği kontrol etmeden önce ilk (son yerine) öğeyi bırakmak xyeterli olur, eksi işareti kaydedilir. Power operatörünün başka bir biçimini kullanarak başka bir 3 kaydeder ( )

Ve 25 karakterlik bir cevap görünür (Orz)


Son düzenleme

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

Bunu özlediğime inanamıyorum.
Artık golf olamaz.


1
Sen 24 karakter bu hakkı elde edebilirsiniz: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. Güç fonksiyonunda "after" değeridir.
marinus

2

Yaygın Lisp, 134

CL bazen okunamayabilir.

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

Yatay kaydırmayı önlemek için bazı biçimlendirme:

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

Ölçek:

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

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

1

F # - 184 karakter

Umarım kendi mücadeleme katılırım.

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

Düzenle Küçük sayılarla ilgili bir hata düzeltildi.


Tamamen iyi :)
beary605

Çözümünüz yanlış olması gerektiğini düşündüğüm n <10 için doğru döndürür.
Howard

Haklısın. Buna bakmalıyım.
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 kullanıcıdan girdi alır, $ i içinde saklar.

$j=(... )-split''|?{$_}$ i'den basamakları bir diziye ayırır ve $ j içinde saklar.

Bunun gereksiz olduğuna işaret ettiği için Rynant'a teşekkürler -ne''.

While($x-lt$i) $ x, $ i değerine ulaşana veya bu değeri aşana kadar çalışacak aşağıdaki Fibonnaci benzeri döngüyü ayarlar.

$x=0 $ x değerini sıfırlar, bu nedenle toplama için kullanılmaya hazırdır (döngü geri geldiğinde gereklidir).

$j|%{$x+=$_} $ j ile $ x arasındaki değerleri eklemek için bir ForEach-Object döngüsü kullanır.

$null,$j=$j+$x $ j değerini eklerken, $ j içindeki değerleri sola kaydırır.

Yaşasın! Sonunda shift-and-append yapmak için daha kısa bir yol buldum ve bu script 100 altında var!

$x-eq$i while döngüsü tamamlandıktan sonra, $ x toplam değerinin başlangıç ​​değerine eşit olup olmadığını test eder, $ i - genellikle bir Keith Number'ı gösterir.

-and$x-gt9 Keith Numbers olamaz tek basamaklı sayıları, sıfır ve negatif sayıları geçersiz kılar.

Bu komut dosyası biraz "dağınık". $ İ ve $ j artık olmak zarifçe işleyebilir, ancak çalışır arasında $ x temizlemek gerekir.

Bu yazının önceki sürümlerinde kullanılan sayıları basamaklara bölmenin bazı yöntemleri için Keith Hill ve mjolinor'a teşekkürler . Son versiyonda olmasalar da, harika bir öğrenme deneyimi sağladılar.


-ne''Böylece sadece kaldırabilirsiniz ?{$_}.
Rynant

Teşekkürler @Rynant. Ben gibi görünüyor da değiştirerek bir daha aşağı trim $i=read-host;$j=$i-split''|?{$_}'ile $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

Şüpheli Python bunun için daha iyi bir araç.


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

koşum takımı ile test:

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

verir:

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

Sen yerini alabilir i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;ile i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;ve iki karakter kaydet.
schnaader

0

R, 116

Python soygunu:

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

Eğlenceli bir egzersiz! Eski bir yazı olduğunu biliyorum ama perl eksik olduğunu fark ettim!

Eminim bunu, diğer yanıtları daha ayrıntılı bir şekilde sindirerek inşa etme yöntemimi geliştirebilirim, bu yüzden muhtemelen tekrar ziyaret edeceğim!


0

Smalltalk - 136 karakter

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

Bu bloğu gönder 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
CodeGolf.SE'ye hoş geldiniz! Bu soru olması nedeniyle kod golf yapmanız gerekir golf kodunuzu (remove boşlukların, yeni hatlar ...)
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]

Ve bu bir işlevdir;)


0

Python - 116 karakter

Codegolf'ta gerçekten uzman değil, işte orada - ilk denemem.

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

Bir işlev için 2 değişiklik yapın:

  • Değişim printiçinreturn
  • xParametre olarak ata

PS I second @ beary605- rakamları / karakterleri / her neyse ayırmak için bir dahili ekleyin.


0

Ruby (OOP ile)

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.