ทดสอบว่าได้รับหมายเลขถ้าเป็นหมายเลขคี ธ


14

เนื่องจากตัวเลข Fibonacci และลำดับดูเหมือนว่าเรื่องที่นิยมสำหรับการเล่นกอล์ฟรหัสผมคิดว่ามันอาจจะเป็นความท้าทายที่สนุกกับการเล่นกอล์ฟรหัสที่มีตัวเลขคี

ดังนั้นฉันเสนอความท้าทายที่จะสร้างฟังก์ชั่นที่ใช้จำนวนเต็มและคืนค่าจริงหรือเท็จขึ้นอยู่กับจำนวนนั้นเป็นจำนวนคี ธ หรือไม่

เพิ่มเติมเกี่ยวกับตัวเลขของคี ธ

ในคณิตศาสตร์เชิงนันทนาการหมายเลข Keith หรือหมายเลข repfigit (ย่อมาจากหลัก Fibonacci ซ้ำเหมือนเดิม) เป็นตัวเลขในลำดับจำนวนเต็มต่อไปนี้: 14, 19, 28, 47, 61, 75, 197, 742, 1104, 1537, 2208 2580, ...

Numberphileมีวิดีโออธิบายวิธีการคำนวณหมายเลข Keith แต่โดยทั่วไปคุณจะใช้ตัวเลขของตัวเลข เพิ่มเข้าด้วยกันจากนั้นนำตัวเลขสุดท้ายของหมายเลขเดิมและเพิ่มลงในผลรวมของการคำนวณล้างและทำซ้ำ และตัวอย่างเพื่อให้ชัดเจน

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

อินพุต

จำนวนเต็ม

เอาท์พุต

จริงถ้าตัวเลขเป็นจำนวนคี ธ เท็จถ้าไม่ใช่ ..


การพูดอย่างเคร่งครัด "จำนวนเต็ม" อาจรวมถึงจำนวนศูนย์หรือจำนวนลบ ฉันค่อนข้างแน่ใจว่าไม่สามารถเป็น Keith Number ได้ เราจำเป็นต้องพิจารณาเรื่องนี้หรือไม่?
Iszi

ตัวเลขหลักเดียวขึ้นอยู่กับโซลูชันของคุณอาจแสดงว่าเป็นจริง ดังนั้นคุณควรตรวจสอบข้อผิดพลาดที่อาจเกิดขึ้นในอินพุต
Smetad Anarkist

มันจะต้องมีการส่งออกtrue/ falseหรือมันจะเป็นอะไรจริง / เท็จ ?
Cyoce

คำตอบ:


7

GolfScript ( 31 25 ตัวอักษร)

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

อินพุตเป็นจำนวนเต็มด้านบนของสแต็ก เอาต์พุตคือ 0 (false) หรือ 1 (true) การสาธิตออนไลน์ซึ่งแสดงหมายเลข Keith ได้สูงสุด 100


0>ความคิดที่ดีกับ น่าเสียดายที่ฉันสามารถ +1 ได้เพียงครั้งเดียว
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)]ทำทุกสิ่งมหัศจรรย์ มันต้องใช้เวลาทุกรายการ แต่รายการแรกของnไม้ผลรวมของn(กับรายการแรก) nแล้วกำหนดว่า

ฉันหวังว่าคุณจะสามารถเรียกlistจำนวนเต็มและแยกตัวเลข

ผลตอบแทนFalseในปัจจัยการผลิตทั้งหมดด้านล่าง 10. สามารถเป็น 8 Trueตัวอักษรที่สั้นลงถ้ามันกลับมา


คุณสามารถบันทึกตัวอักษรสองถ้าคุณเปรียบเทียบกับแทนn[0] n[-1]
Howard

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 (เช่นเท็จ) หรือ 1 ตามลำดับ


@PeterTaylor ดูลิงค์ที่ให้ไว้ซึ่งฉันทำอย่างนั้น - และใช้งานได้ ...
Howard

@ PeterTaylor กำลังมองหาวิธีการแก้ปัญหาของคุณฉันยังสามารถลดจำนวนตัวอักษรเพิ่มเติมในแนวทางของฉัน
โฮเวิร์ด

ฉันต้องไม่รีเฟรชเพราะความคิดเห็นของฉันใช้ได้กับเวอร์ชัน 1
Peter Taylor

4

APL, 36 34 39 36 33 29 27

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

เอาท์พุท1ถ้าคี ธ0มิฉะนั้น

GolfScript นัดหยุดงานอีกครั้ง !!


แก้ไข

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

ใช้ Right-Reduction ( ⊢/) แทน Take ลบ 1 ( ¯1↑), ประหยัด 1 char โดยตรงและอ้อม 1 บันทึกจาก Disclose ( )

คำอธิบาย

⍎¨⍕x←⎕ใช้เวลาการประเมินการป้อนข้อมูล (ถือว่าเป็นตัวเลข) xและกำหนดให้ แปลงเป็นอาร์เรย์อักขระ (aka "string" ในภาษาอื่น ๆ ) และวนซ้ำอักขระแต่ละตัว (หลัก) แปลงเป็นตัวเลข ดังนั้นนี่จะส่งผลให้มีตัวเลขที่เป็นตัวเลข

{(∇⍣(x>⊢/⍵))⍵,+/⍵↑⍨-⍴⍕x}เป็นฟังก์ชั่น "loop" หลัก:
+/⍵↑⍨-⍴⍕xใช้ตัวเลข⍴⍕x(ไม่ใช่ของตัวเลขx) ตัวสุดท้ายจากอาร์เรย์และสรุปผลรวม
⍵,เชื่อมต่อกับส่วนท้ายของอาร์เรย์
(x>⊢/⍵)ตรวจสอบว่าหมายเลขสุดท้ายของอาร์เรย์ (ซึ่งยังไม่ได้+/⍵↑⍨-⍴⍕xต่อกันอยู่) มีขนาดเล็กกว่าxและส่งกลับ1หรือ0
∇⍣เรียกใช้ฟังก์ชันนี้ในอาร์เรย์ใหม่ที่หลายต่อหลายครั้ง ดังนั้นหากจำนวนสุดท้ายมีขนาดเล็กกว่าxฟังก์ชั่นนี้จะเกิดขึ้นอีก มิฉะนั้นเพียงส่งคืนอาร์เรย์ใหม่

หลังจากที่ดำเนินการฟังก์ชันอาร์เรย์มีผลบวกขึ้นไปยังจุดที่ 2 ของตัวเลขที่มีค่ามากกว่าหรือเท่ากับx(เช่น14จะสร้าง1 4 5 9 14 23, 13จะสร้าง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เพียงพอแล้วบันทึกเครื่องหมายลบ บันทึกอีก 3 โดยใช้รูปแบบอื่นของตัวดำเนินการพลังงาน ( )

และคำตอบ 25-char gs ปรากฏขึ้น (Orz)


แก้ไขล่าสุด

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

ไม่อยากเชื่อเลยว่าฉันพลาดไป
ไม่สามารถเล่นกอล์ฟได้อีกต่อไป


1
คุณสามารถได้รับการลงนี้ถึง 24 x∊{1↓⍵,+/⍵}⍣{x≤⊃⍺}⍎¨⍕x←⎕ตัวอักษร: ในฟังก์ชั่นเพาเวอร์คือค่า "after"
marinus

2

เสียงกระเพื่อมสามัญ, 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 ซึ่งฉันคิดว่าควรเป็นเท็จ
โฮเวิร์ด

คุณพูดถูก ฉันควรมองเข้าไปในนั้น
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 รับอินพุตจากผู้ใช้เก็บไว้ใน $ i

$j=(... )-split''|?{$_}แยกตัวเลขจาก $ i เป็นอาร์เรย์และเก็บไว้ใน $ j

ขอบคุณที่ Rynant ที่ชี้ให้เห็นว่า-ne''ไม่จำเป็น

While($x-lt$i) ตั้งค่าการวนรอบเหมือน Fibonnaci ต่อไปนี้ให้ทำงานจนกว่าตัวแปรผลรวม, $ x, ถึงหรือเกินกว่า $ i

$x=0 เป็นศูนย์ $ x ดังนั้นมันจึงพร้อมที่จะใช้สำหรับการรวม (จำเป็นสำหรับเมื่อวงวนกลับมา)

$j|%{$x+=$_} ใช้ ForEach-Object loop เพื่อเพิ่มค่าจาก $ j เป็น $ x

$null,$j=$j+$x เลื่อนค่าเป็น $ j ไปทางซ้ายละทิ้งสิ่งแรกในขณะที่เพิ่ม $ x

เย้! ในที่สุดฉันก็พบวิธีที่สั้นกว่าในการทำ shift-and-append และรับสคริปต์นี้ต่ำกว่า 100!

$x-eq$i หลังจากห่วงในขณะที่เสร็จสิ้นการทดสอบว่ามูลค่ารวม, $ x, เท่ากับค่าเริ่มต้น, $ i - โดยทั่วไปบ่งบอกถึงจำนวน Keith

-and$x-gt9 ทำให้ตัวเลขตัวเลขศูนย์และลบเป็นโมฆะซึ่งไม่สามารถใช้เป็นหมายเลข Keith ได้

สคริปต์นี้ค่อนข้าง "ยุ่ง" มันสามารถจัดการ $ i และ $ j ที่เหลือได้อย่างงดงาม แต่คุณจะต้องล้าง $ x ระหว่างการวิ่ง

ขอบคุณKeith Hillและmjolinorสำหรับวิธีการแบ่งตัวเลขเป็นตัวเลขซึ่งใช้ในสคริปต์รุ่นก่อนหน้านี้ แม้ว่าพวกเขาจะไม่ได้อยู่ในรุ่นสุดท้าย แต่พวกเขาก็ให้ประสบการณ์การเรียนรู้ที่ยอดเยี่ยม


คุณสามารถลบเพื่อที่ว่ามันเป็นเพียง-ne'' ?{$_}
Rynant

ขอบคุณ @Rynant ดูเหมือนว่าฉันยังสามารถตัดมันลงมาอีกครั้งหนึ่งโดยการแทนที่ด้วย$i=read-host;$j=$i-split''|?{$_}' $j=($i=read-host)-split''|?{$_}
Iszi

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


0

Perl, 90

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

การออกกำลังกายที่สนุก! ฉันรู้ว่ามันเป็นโพสต์เก่า แต่ฉันสังเกตเห็นว่า Perl หายไป!

ฉันแน่ใจว่าฉันสามารถปรับปรุงวิธีที่ฉันสร้างได้จากการแยกย่อยคำตอบอื่น ๆ ให้ละเอียดยิ่งขึ้นดังนั้นฉันจะกลับมาทบทวนอีกครั้ง!



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! เนื่องจากคำถามนี้เป็นโค้ดกอล์ฟคุณควรตีกอล์ฟโค้ดของคุณ (ลบช่องว่างบรรทัดใหม่ ... )
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 อย่างสำหรับฟังก์ชั่น:

  • เปลี่ยนprintเป็นreturn
  • กำหนดxให้เป็นพารามิเตอร์

PS I second @ beary605- เพิ่ม built-in เพื่อแยกตัวเลข / ตัวอักษร / อะไรก็ตาม


0

ทับทิม (กับ 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.