Tes jika diberi nomor jika nomor Keith

14

Karena angka dan urutan Fibonacci sepertinya merupakan subjek yang populer untuk kode golf, saya pikir itu mungkin merupakan tantangan yang menyenangkan untuk kode golf dengan angka Keith .

Jadi saya mengusulkan tantangan yaitu membuat fungsi yang mengambil bilangan bulat dan memberikan kembali benar atau salah tergantung pada nomor apakah itu nomor Keith atau tidak.

Lebih lanjut tentang nomor Keith

Dalam matematika rekreasional, angka Keith atau angka repfigit (kependekan dari digit mirip Fibonacci berulang) adalah angka dalam urutan bilangan bulat berikut: 14, 19, 28, 47, 61, 75, 75, 197, 742, 1104, 1537, 2208, 2580, ...

Numberphile memiliki video yang menjelaskan cara menghitung nomor Keith. Tetapi pada dasarnya Anda mengambil digit angka. Tambahkan bersama-sama dan kemudian ambil angka terakhir dari nomor asli dan tambahkan ke jumlah perhitungan, bilas dan ulangi. Dan contoh untuk membuatnya jelas.

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

Memasukkan

Bilangan bulat.

Keluaran

Benar jika nomor tersebut adalah nomor Keith. Salah jika tidak ..

Smetad Anarkist
sumber
Sebenarnya, "bilangan bulat" dapat menyertakan angka nol atau negatif. Saya cukup yakin tidak ada yang bisa menjadi Nomor Keith. Apakah kita perlu memperhitungkan ini?
Iszi
Bergantung pada solusi Anda, angka satu digit dapat ditampilkan sebagai benar. Jadi, Anda harus memeriksa kemungkinan kesalahan dalam input.
Smetad Anarkist
Apakah harus menampilkan true/ falseatau dapatkah itu sesuatu yang benar / salah ?
Cyoce

Jawaban:

7

GolfScript ( 31 25 karakter)

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

Input sebagai bilangan bulat di atas tumpukan. Output adalah 0 (salah) atau 1 (benar). Demo online yang mencantumkan nomor Keith hingga 100.

Peter Taylor
sumber
Ide bagus dengan 0>. Sayangnya saya hanya dapat memberi +1 satu kali.
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)]melakukan semua keajaiban. Dibutuhkan setiap item kecuali item pertama n, menempel pada jumlah n(dengan item pertama), lalu mengaturnya menjadi n.

Saya berharap Anda bisa memanggil listbilangan bulat dan memiliki digit yang terpisah.

Mengembalikan Falsesemua input di bawah 10. Dapat lebih pendek 8 karakter jika dikembalikan True.

beary605
sumber
Anda dapat menyimpan dua karakter jika dibandingkan dengan n[0]bukan n[-1].
Howard
Hemat lima lagi dengan print 9<a==n[0].
res
n=n[1:]+[sum(n)]bisa menjadin=n[1:]+sum(n),
Cyoce
6

GolfScript, 32 29 karakter

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

Implementasi GolfScript yang dapat diuji secara online . Input diberikan sebagai elemen teratas pada stack dan mengembalikan masing-masing 0 (mis. Salah) atau 1.

Howard
sumber
@PeterTaylor Lihat tautan yang disediakan tempat saya melakukan hal itu - dan berfungsi ...
Howard
@PeterTaylor Melihat solusi Anda, saya bahkan dapat mengurangi jumlah karakter dalam pendekatan saya.
Howard
Saya pasti belum menyegarkan, karena komentar saya berlaku untuk versi 1.
Peter Taylor
4

APL, 36 34 39 36 33 29 27

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

Keluaran 1jika Keith, 0jika tidak

GolfScript menyerang lagi !!


Edit

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

Menggunakan Pengurangan Hak (⊢/ ) alih-alih Take minus 1 ( ¯1↑), langsung menyimpan 1 char dan secara tidak langsung menghemat 1 dari Disclose ( )

Penjelasan

⍎¨⍕x←⎕mengambil input yang dievaluasi (diperlakukan sebagai angka) dan menetapkannya untuk x. Mengubahnya menjadi array karakter (alias "string" dalam bahasa lain), dan loop melalui masing-masing karakter (digit), mengubahnya menjadi angka. Jadi ini menghasilkan array angka digit.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}adalah fungsi "loop" utama:
+/⍵↑⍨-⍴⍕xmengambil angka terakhir ⍴⍕x(no. digit x) dari array dan menjumlahkannya.
⍵,menggabungkannya ke akhir array.
(x>⊢/⍵)periksa apakah angka terakhir pada array (yang belum +/⍵↑⍨-⍴⍕xdigabungkan) lebih kecil dari xdan mengembalikan 1atau 0
∇⍣mengeksekusi fungsi ini pada array baru yang berkali-kali. Jadi jika angka terakhir lebih kecil darix , fungsi ini berulang. Jika tidak, kembalikan saja array yang baru

Setelah menjalankan fungsi, array berisi jumlah sampai ke titik di mana 2 angka lebih besar atau sama dengan x(misalnya 14akan menghasilkan 1 4 5 9 14 23, 13akan menghasilkan 1 3 4 7 11 18 29)
Akhirnya memeriksa apakah setiap angka sama denganx dan output jumlah dari biner yang dihasilkan Himpunan.


Edit

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

Menambahkan 2 karakter :-( untuk membuat output 0jika inputnya satu digit


Sunting lagi

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

Penjelasan

Fungsi sekarang menjatuhkan angka pertama ( 1↓) dari array alih-alih mengambil yang terakhir ⍴⍕x( ↑⍨-⍴⍕x).
Namun, pendekatan ini membuat 1=tidak memadai untuk menangani angka satu digit. Jadi sekarang menjatuhkan nomor terakhir dari array sebelum memeriksa kesetaraan x, menambahkan 1 karakter


Anda dapat menebaknya: EDIT

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

Bandingkan xdengan item yang baru ditambahkan daripada item terakhir yang lama, jadi jatuhkan item pertama (bukan yang terakhir) sebelum memeriksa kesetaraan kex sudah mencukupi, menyimpan tanda minus. Menghemat 3 lainnya dengan menggunakan bentuk lain dari operator Power ( )

Dan jawaban 25-char gs muncul (Orz)


Sunting terakhir

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

Tidak percaya saya melewatkan itu.
Tidak bisa bermain golf lagi.

TwiNight
sumber
1
Anda bisa berjalan turun ini untuk 24 karakter: x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. Dalam fungsi daya, adalah nilai "setelah".
marinus
2

Common Lisp, 134

CL kadang-kadang bisa sangat tidak bisa dibaca.

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

Beberapa pemformatan untuk menghindari pengguliran 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)))))

Uji:

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

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

F # - 184 karakter

Saya harap tidak apa-apa bahwa saya akan berpartisipasi dalam tantangan saya sendiri.

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

Sunting Memperbaiki bug terkait jumlah kecil.

Smetad Anarkist
sumber
Tidak apa-apa :)
beary605
Solusi Anda mengembalikan true untuk n <10 yang saya pikir seharusnya salah.
Howard
Kamu benar. Saya harus melihat itu.
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
tmartin
sumber
1

PowerShell: 120 128 123 111 110 97 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 mengambil input dari pengguna, menyimpannya dalam $ i.

$j=(... )-split''|?{$_}memecah digit dari $ i ke dalam array dan menyimpannya dalam $ j.

Terima kasih kepada Rynant untuk menunjukkan bahwa -ne''itu tidak perlu.

While($x-lt$i) menetapkan loop seperti Fibonnaci berikut untuk dijalankan hingga variabel penjumlahan, $ x, mencapai atau melebihi $ i.

$x=0 nol $ x, jadi siap digunakan untuk menjumlahkan (diperlukan ketika loop kembali).

$j|%{$x+=$_} menggunakan ForEach-Object loop untuk menambahkan nilai dari $ j menjadi $ x.

$null,$j=$j+$x menggeser nilai dalam $ j ke kiri, membuang yang pertama, sambil menambahkan $ x.

Yay! Saya akhirnya menemukan cara yang lebih singkat untuk melakukan shift-and-append, dan mendapatkan script ini di bawah 100!

$x-eq$i setelah loop sementara selesai, menguji apakah nilai penjumlahan, $ x, sama dengan nilai awal, $ i - umumnya menunjukkan Nomor Keith.

-and$x-gt9 membatalkan angka satu digit, angka nol, dan angka negatif, yang tidak boleh menjadi Angka Keith.

Script ini agak "berantakan". Ini dapat dengan anggun menangani $ i dan $ j yang tersisa, tetapi Anda harus menghapus $ x di antara run.

Terima kasih kepada Keith Hill dan mjolinor untuk beberapa metode memecah angka menjadi digit yang digunakan dalam versi sebelumnya dari skrip ini. Meskipun mereka tidak ada dalam versi final, mereka menyediakan pengalaman belajar yang hebat.

Iszi
sumber
Anda dapat menghapus -ne''sehingga adil ?{$_}.
Rynant
Terima kasih @Rynant. Terlihat seperti saya juga dapat memotong ke bawah satu lagi dengan mengganti $i=read-host;$j=$i-split''|?{$_}'dengan $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

Tersangka Python adalah alat yang lebih baik untuk yang ini.

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

tes melalui harness:

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

memberi:

14 19 28 47 61 75 197 742 1104 1537 2208 2580 3684 4788 7385 7647 7909
bayi-kelinci
sumber
Anda dapat mengganti i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;dengan i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;dan menyimpan dua karakter.
schnaader
0

R, 116

Rip-off 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
Paolo
sumber
0

Perl, 90

sub k{$-=shift;$==@$=split//,$-;push@$,eval join'+',@$[-$=..-1]while@$[-1]<$-;grep/$-/,@$}

Latihan yang menyenangkan! Saya tahu ini posting lama tapi saya perhatikan perl tidak ada!

Saya yakin saya dapat meningkatkan cara saya membangun ini dari mencerna tanggapan lain lebih menyeluruh, jadi saya kemungkinan akan mengunjungi kembali ini!

Dom Hastings
sumber
0

Smalltalk - 136 char

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

Kirim blok ini value:

Paul Richter
sumber
0

Jawa - 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;
        }
    }
}
mousami
sumber
3
Selamat datang di CodeGolf.SE! Karena pertanyaan ini adalah kode-golf , Anda harus golf kode (remove spasi putih, baris baru ...) Anda
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]

Dan itu adalah fungsi;)

gcq
sumber
0

Python - 116 karakter

Bukan benar-benar ahli codegolf, jadi begitulah - percobaan pertama saya.

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

Buat 2 perubahan untuk suatu fungsi:

  • Ubah printkereturn
  • Tetapkan xsebagai parameter

PS I second @ beary605- menambahkan built-in untuk memisahkan digit / karakter / apa pun.

Dan si Manusia
sumber
0

Ruby (dengan 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)
beginnerProg
sumber