Kiểm tra nếu cho số nếu một số Keith


14

Vì các số và chuỗi Fibonacci có vẻ như là một chủ đề phổ biến cho môn đánh gôn, tôi nghĩ rằng đó có thể là một thử thách thú vị khi viết mã golf với số Keith .

Vì vậy, tôi đề xuất một thách thức là tạo ra một hàm lấy một số nguyên và trả về một giá trị đúng hay sai tùy thuộc vào số đó có phải là số Keith hay không.

Thông tin thêm về số Keith

Trong toán học giải trí, một số Keith hoặc số kỹ thuật số lặp lại (viết tắt của chữ số giống như Fibonacci lặp đi lặp lại) là một số trong chuỗi số nguyên sau: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208, 2580, Lọ

Numberphile có một video giải thích cách tính số Keith. Nhưng về cơ bản, bạn lấy các chữ số của một số. Cộng chúng lại với nhau và sau đó lấy các chữ số cuối của số ban đầu và thêm chúng vào tổng của phép tính, rửa sạch và lặp lại. Và ví dụ để làm cho nó rõ ràng.

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

Đầu vào

Một số nguyên.

Đầu ra

Đúng nếu số đó là số Keith. Sai nếu không phải là ..


Nói đúng ra, "một số nguyên" có thể bao gồm các số 0 hoặc âm. Tôi khá chắc chắn không thể là số Keith. Chúng ta có cần phải tính đến điều này?
Iszi

Tùy thuộc vào giải pháp của bạn, các số có một chữ số có thể hiển thị là đúng. Vì vậy, bạn nên kiểm tra các lỗi tiềm ẩn trong đầu vào.
Smetad Anarkist

Liệu nó có phải xuất true/ falsehoặc nó có thể là bất cứ điều gì trung thực / falsey không?
Cyoce

Câu trả lời:


7

GolfScript ( 31 25 ký tự)

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

Nhập dưới dạng một số nguyên trên đầu ngăn xếp. Đầu ra là 0 (sai) hoặc 1 (đúng). Bản demo trực tuyến liệt kê các số Keith lên tới 100.


Ý tưởng tốt đẹp với 0>. Thật không may, tôi chỉ có thể +1 một lần.
Howard

7

Con trăn ( 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)]làm tất cả các phép thuật. Nó nhận mọi mục trừ mục đầu tiên n, dán vào tổng của n(với mục đầu tiên), sau đó đặt mục đó thành n.

Tôi ước bạn có thể gọi listmột số nguyên và có các chữ số tách biệt.

Trả Falsevề tất cả các đầu vào dưới 10. Có thể ngắn hơn 8 ký tự nếu trả về True.


Bạn có thể lưu hai ký tự nếu bạn so sánh với n[0]thay vì n[-1].
Howard

Tiết kiệm thêm năm với print 9<a==n[0].
res

n=n[1:]+[sum(n)]có thể trở thànhn=n[1:]+sum(n),
Cyoce

6

GolfScript, 32 29 ký tự

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

Một triển khai GolfScript có thể được kiểm tra trực tuyến . Đầu vào được đưa ra dưới dạng phần tử trên cùng của ngăn xếp và nó trả về 0 (tức là sai) hoặc 1 tương ứng.


@PeterTaylor Hãy nhìn vào liên kết được cung cấp nơi tôi đã làm chính xác điều đó - và nó hoạt động ...
Howard

@PeterTaylor Nhìn vào giải pháp của bạn, tôi thậm chí có thể giảm số lượng ký tự hơn nữa trong phương pháp của mình.
Howard

Tôi phải không được làm mới, bởi vì nhận xét của tôi có thể áp dụng cho phiên bản 1.
Peter Taylor

4

APL, 36 34 39 36 33 29 27

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

Đầu ra 1nếu Keith, 0nếu không

GolfScript đình công một lần nữa !!


Biên tập

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

Sử dụng Quyền giảm ( ⊢/) thay vì Lấy 1 ( ¯1↑), trực tiếp lưu 1 char và gián tiếp lưu 1 từ Tiết lộ ( )

Giải trình

⍎¨⍕x←⎕lấy đầu vào được đánh giá (được coi là một số) và gán nó vào x. Chuyển đổi nó thành một mảng ký tự (còn gọi là "chuỗi" trong các ngôn ngữ khác) và lặp qua từng ký tự (chữ số), chuyển đổi nó thành một số. Vì vậy, điều này dẫn đến một mảng số của các chữ số.

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}là hàm "loop" chính:
+/⍵↑⍨-⍴⍕xlấy các số cuối ⍴⍕x(số chữ số trong x) từ mảng và tính tổng chúng.
⍵,nối nó đến cuối mảng.
(x>⊢/⍵)kiểm tra xem số cuối cùng trên mảng (chưa được +/⍵↑⍨-⍴⍕xnối) chưa nhỏ hơn xvà trả về 1hay0
∇⍣ thực hiện hàm này trên mảng mới nhiều lần. Vì vậy, nếu số cuối cùng nhỏ hơn x, hàm này sẽ tái diễn. Nếu không, chỉ cần trả về mảng mới

Sau khi thực hiện hàm, mảng chứa các tổng đến điểm mà 2 trong số các số lớn hơn hoặc bằng x(ví dụ 14sẽ tạo 1 4 5 9 14 23, 13sẽ tạo 1 3 4 7 11 18 29)
Cuối cùng kiểm tra xem mỗi số có bằng xvà xuất tổng của nhị phân kết quả không mảng.


Biên tập

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

Đã thêm 2 ký tự :-( để tạo đầu ra 0nếu đầu vào là một chữ số


Một chỉnh sửa khác

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

Giải trình

Hàm bây giờ bỏ số đầu tiên ( 1↓) khỏi mảng thay vì lấy số cuối ⍴⍕x( ↑⍨-⍴⍕x).
Tuy nhiên, cách tiếp cận này làm cho 1=không đủ để xử lý các số có một chữ số. Vì vậy, bây giờ nó giảm số cuối cùng từ mảng trước khi kiểm tra đẳng thức x, thêm 1 char


Bạn đã đoán ra: EDIT

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

So sánh xvới mục mới được thêm vào thay vì mục cuối cùng cũ, vì vậy hãy bỏ mục đầu tiên (thay vì cuối cùng) trước khi kiểm tra tính bằngx là đủ, lưu dấu trừ. Lưu thêm 3 bằng cách sử dụng một dạng khác của toán tử Power ( )

Và một câu trả lời 25 char gs xuất hiện (Orz)


Chỉnh sửa lần cuối

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

Không thể tin rằng tôi đã bỏ lỡ điều đó.
Không thể đánh gôn được nữa.


1
Bạn có thể nhận được điều này xuống còn 24 ký tự : x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕. Trong hàm power, là giá trị "sau".
bến

2

Lisp thường gặp, 134

CL có thể khá khó đọc đôi khi.

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

Một số định dạng để tránh cuộn ngang:

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

Kiểm tra:

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

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

1

F # - 184 ký tự

Tôi hy vọng nó sẽ ổn khi tôi tham gia vào thử thách của riêng mình.

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

Chỉnh sửa Đã sửa một lỗi liên quan đến số lượng nhỏ.


Nó hoàn toàn ổn :)
beary605

Giải pháp của bạn trả về true cho n <10 mà tôi nghĩ là sai.
Howard

Bạn đúng rồi. Tôi nên nhìn vào đó.
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 lấy đầu vào từ người dùng, lưu trữ nó trong $ i.

$j=(...)-split''|?{$_} chia các chữ số từ $ i thành một mảng và lưu nó trong $ j.

Cảm ơn Rynant đã chỉ ra rằng-ne'' là không cần thiết.

While($x-lt$i) thiết lập vòng lặp giống như Fibonnaci sau để chạy cho đến khi biến tổng, $ x, đạt hoặc vượt quá $ i.

$x=0 bỏ ra $ x, vì vậy nó sẵn sàng được sử dụng để tính tổng (cần thiết khi vòng lặp quay lại).

$j|%{$x+=$_} sử dụng vòng lặp ForEach-Object để cộng các giá trị từ $ j vào $ x.

$null,$j=$j+$x thay đổi các giá trị trong $ j còn lại, loại bỏ giá trị đầu tiên, trong khi nối thêm $ x.

Yay! Cuối cùng tôi đã tìm ra một cách ngắn hơn để thực hiện thay đổi và nối thêm, và có kịch bản này dưới 100!

$x-eq$i sau khi vòng lặp while hoàn thành, kiểm tra xem giá trị tổng, $ x, bằng với giá trị ban đầu, $ i - thường biểu thị cho Số Keith.

-and$x-gt9 làm mất hiệu lực các số có một chữ số, số 0 và số âm, không thể là số Keith.

Kịch bản này hơi "lộn xộn". Nó có thể xử lý duyên dáng $ i và $ j còn sót lại, nhưng bạn sẽ cần xóa $ x giữa các lần chạy.

Cảm ơn Keith Hillmjolinor cho một số phương pháp chia số thành chữ số được sử dụng trong các phiên bản trước của tập lệnh này. Mặc dù chúng không có trong phiên bản cuối cùng, nhưng chúng đã mang lại trải nghiệm học tập tuyệt vời.


Bạn có thể loại bỏ -ne''để nó chỉ là ?{$_}.
Rynant

Cảm ơn @Rynant. Có vẻ như tôi cũng có thể cắt nó xuống thêm một lần nữa bằng cách thay thế $i=read-host;$j=$i-split''|?{$_}'bằng $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

Nghi ngờ Python là một công cụ tốt hơn cho cái này.


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

kiểm tra thông qua khai thác:

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

cho:

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

Bạn có thể thay thế i=(i+n-1)%n;t=g[i];g[i]=s;s=s*2-t;bằng i+=n-1;t=g[i%n];g[i%n]=s;s+=s-t;và lưu hai ký tự.
schnaader

0

R, 116

Trích xuất 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/$-/,@$}

Một bài tập thú vị! Tôi biết đó là một bài viết cũ nhưng tôi nhận thấy perl đã bị mất!

Tôi chắc chắn rằng tôi có thể cải thiện cách tôi xây dựng điều này từ việc tiêu hóa các phản hồi khác kỹ lưỡng hơn, vì vậy tôi có thể sẽ xem xét lại điều này!


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

Gửi khối này 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
Chào mừng bạn đến với CodeGolf.SE! Vì câu hỏi này là golf-code , bạn nên đánh golf mã của mình (xóa các khoảng trắng, các dòng mới ...)
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]

Và nó là một chức năng;)


0

Python - ký tự 116

Không thực sự là một chuyên gia về codegolf, vì vậy bạn có nó - lần thử đầu tiên của tôi.

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

Thực hiện 2 thay đổi cho một chức năng:

  • Thay đổi printthànhreturn
  • Chỉ định xlà tham số

PS I second @ beary605- thêm một tích hợp để tách các chữ số / ký tự / bất cứ thứ gì.


0

Ruby (với 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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.