เครื่องกำเนิดไฟฟ้าสำคัญที่เกิดขึ้นตามธรรมชาติ


42

มีฟังก์ชั่นการสร้างที่สำคัญจำนวนมาก ค่อนข้างทั้งหมดของพวกเขาถูกสร้างขึ้นและอยู่บนพื้นฐานของ Eratosthenes, ฟังก์ชั่นMöbiusหรือทฤษฎีบทของวิลสันและโดยทั่วไปจะไม่สามารถคำนวณได้ในทางปฏิบัติ แต่ยังมีเครื่องกำเนิดไฟฟ้าที่มีโครงสร้างที่ง่ายมากและถูกค้นพบโดยบังเอิญ

ในปี 2003 Stephen Wolfram ได้สำรวจสมการการเกิดซ้ำแบบซ้อนในการทดสอบคอมพิวเตอร์สดที่ NKS Summer School กลุ่มคนรอบ ๆ Matthew Frank ติดตามการทดลองเพิ่มเติมและค้นพบคุณสมบัติที่น่าสนใจของการกลับเป็นซ้ำ

a(n) = a(n-1) + gcd(n,a(n-1))

a(1) = 7ที่มีค่าเริ่มต้นของ ความแตกต่างa(n) - a(n-1) = gcd(n,a(n-1))มักจะเป็น 1 หรือนายก ความแตกต่างแรก ๆ คือ ( OEIS A132199 ):

1, 1, 1, 5, 3, 1, 1, 1, 1, 11, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 3, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 47, 3, 1, 5, 3, ...

หากเราไม่ใช้ 1s เราจะได้รับลำดับต่อไปนี้ ( OEIS A137613 ):

5, 3, 11, 3, 23, 3, 47, 3, 5, 3, 101, 3, 7, 11, 3, 13, 233, 3, 467, 3, 5, 3, 
941, 3, 7, 1889, 3, 3779, 3, 7559, 3, 13, 15131, 3, 53, 3, 7, 30323, 3, ...

Eric S. Rowlandพิสูจน์ความเป็นอันดับหนึ่งของแต่ละองค์ประกอบในรายการนี้ไม่กี่ปีต่อมา อย่างที่คุณเห็นช่วงเวลาต่าง ๆ และบางส่วนก็ปรากฏขึ้นหลายครั้ง มันยังได้รับการพิสูจน์แล้วว่าลำดับนั้นรวมถึงช่วงเวลาที่แตกต่างกันมากมาย ยิ่งไปกว่านั้นมันคือการคาดเดาว่าทุกช่วงเวลาแปลก ๆ ปรากฏขึ้น

เนื่องจากตัวสร้างหลักนี้ไม่ได้ถูกสร้างขึ้น แต่ค้นพบโดยบังเอิญโดยที่ตัวสร้างหลักเรียกว่า "เกิดขึ้นตามธรรมชาติ" แต่ขอให้สังเกตว่าในทางปฏิบัติเครื่องกำเนิดไฟฟ้านี้ยังไม่สามารถคำนวณได้ เมื่อปรากฎออกมาไพรม์ p จะปรากฏขึ้นหลังจาก(p–3)/21s ติดต่อกันเท่านั้น อย่างไรก็ตามการนำเครื่องมือสร้างสำคัญนี้ไปใช้จะเป็นงานของคุณ

ท้าทาย:

เขียนฟังก์ชั่นหรือโปรแกรมที่พิมพ์nองค์ประกอบแรกของลำดับA137613(ลำดับที่ไม่มี 1s) คุณสามารถอ่านหมายเลขอินพุตn >= 0ผ่านทาง STDIN, อาร์กิวเมนต์บรรทัดคำสั่ง, พรอมต์หรือฟังก์ชันอาร์กิวเมนต์ เอาท์พุทnองค์ประกอบแรกในรูปแบบที่อ่านได้ไปยัง STDOUT หรือส่งกลับอาร์เรย์หรือรายการที่มีค่าเหล่านี้

นี่คือรหัสกอล์ฟ ดังนั้นรหัสที่สั้นที่สุดชนะ

ลีดเดอร์บอร์ด:

นี่คือ Stack Snippet เพื่อสร้างทั้งกระดานผู้นำปกติและภาพรวมของผู้ชนะตามภาษา เพื่อให้แน่ใจว่าคำตอบของคุณปรากฏขึ้นโปรดเริ่มคำตอบด้วยหัวข้อโดยใช้เทมเพลต Markdown ต่อไปนี้:

# Language Name, N bytes

โดยที่ N คือขนาดของการส่งของคุณ หากคุณปรับปรุงคะแนนของคุณคุณสามารถเก็บคะแนนเก่าไว้ในบรรทัดแรกโดยการตีพวกเขาผ่าน ตัวอย่างเช่น

# Ruby, <s>104</s> <s>101</s> 96 bytes


1
ในขณะที่ตัวสร้างนายกไม่ได้ถูกสร้างขึ้นมาคุณกำลังใช้งานแผนกทดลองโดยใช้การสอบถามซ้ำอย่างมีประสิทธิภาพ
orlp

หาก a (1) = 7 ทำไมลำดับไม่เริ่มต้นด้วย 7
feersum

3
@feersum เพราะลำดับที่เราเกี่ยวข้องคือa(n)-a(n-1)
Maltysen

สามารถnเป็นศูนย์ได้หรือไม่
Sp3000

1
@jrenk ไม่แน่ใจ อาจนับเป็น 2 ไบต์ (เนื่องจากคุณลบ 2 ตัวอักษร//) และอธิบายในการส่งของคุณ หากใครไม่เห็นด้วยกับคุณคุณสามารถแก้ไขโพสต์ของคุณได้ตลอดเวลา
Jakube

คำตอบ:



7

Python 3.5.0b1 +, 95 93 ไบต์

ลิงก์ไปยังPython เวอร์ชัน 3.5.0b1 +

import math
def f(k,n=2,a=7,L=[]):x=math.gcd(n,a);return k and f(k-1%x,n+1,a+x,L+1%x*[x])or L

การนำไปปฏิบัติโดยตรงของการเกิดซ้ำซึ่งมี:

  • เพื่อนที่ดีของเรา1%xและ
  • math.gcdfractions.gcdเมื่อเทียบกับ

อะไร1%xทำอย่างไร คำถามด้าน: ฉันจะหาเอกสารของประวัติการแก้ไขของ Python ที่มี betas ได้ที่ไหน แก้ไข: ไม่เป็นไรพบได้ที่ด้านล่างของประวัติการแก้ไข
mbomb007

@ mbomb007 ตั้งแต่x >= 1, 1%xส่งกลับค่า 0 ถ้าx == 1, 1 เป็นอย่างอื่น (ใช้เพื่อตัดสินใจว่าจะเพิ่มxในรายการหรือไม่)
Sp3000

5

Julia, 110 ไบต์

n->(a(n)=(n1&&(n==1?7:a(n-1)+gcd(n,a(n-1))));i=2;j=0;while j<n x=a(i)-a(i-1);x>1&&(j+=1;println(x));i+=1end)

Ungolfed:

function a(n::Int)
    n  1 && (n == 1 ? 7 : a(n-1) + gcd(n, a(n-1)))
end

function f(n::Int)
    i = 2;
    j = 0;
    while j < n
        x = a(i) - a(i-1)
        if x > 1
            j += 1
            println(x)
        end
        i += 1
    end
end

ว้าว 8k สมบูรณ์ดี: D
Beta Decay

1
ใช้แทนn<2 n==1นอกจากนี้ถ้าคุณมองไปข้างหน้าแทนไปข้างหลังคุณสามารถใช้i=1และx=a(i)-a(i+=1)แล้วprintln(-x)และการที่ถูกต้องสำหรับคัดค้านจึงหลีกเลี่ยงความจำเป็นในการเพิ่มขึ้นของการแยกจากกัน-x>1 iและคือสามไบต์ในขณะที่>=สอง ... แต่แล้วคุณสามารถใช้n<1||()มากกว่าn>=1&&()... และยังไม่จำเป็นแม้แต่ในตอนแรก (วางเงื่อนไข n จะไม่น้อยกว่า 1) คุณไม่จำเป็นต้องใช้วงเล็บนอกสุดเมื่อกำหนด (n) ด้วยการเปลี่ยนแปลงเหล่านี้อย่างน้อยคุณควรลดลงเหลือ 97 ไบต์
เกลน O

5

PHP, 101 96 99 98 77 72 ไบต์

<?for(;2>$t=gmp_strval(gmp_gcd(~++$i,7+$e+=$t))or$argv[1]-=print"$t ";);


การใช้งาน:
โทรหาสคริปต์พร้อมอาร์กิวเมนต์: php -d error_reporting=0 script.php 30
หากคุณต้องการทดสอบคุณต้องยกเลิกการคอมเม้นต์;extension=php_gmp.dllใน php.ini ของคุณ
-> extension=php_gmp.dll
ฉันควรเพิ่มส่วนขยายไปยังจำนวนไบต์ของฉันหรือไม่ ความคิดใด ๆ


บันทึก:
บันทึกแล้ว 3 ไบต์ขอบคุณ Ismael Miguel
บันทึก 26 ไบต์ขอบคุณ primo


1
คุณสามารถร่นแท็กเปิดของคุณไปและเอาความหมายของ<? $j
Ismael Miguel

1
ใช่มันนับ แต่คุณสามารถลบบรรทัดใหม่นั้นได้ ซึ่งจะบันทึก 1-2 ไบต์ขึ้นอยู่กับว่าคุณนับขนาดรหัสของคุณอย่างไร
Ismael Miguel

1
การปรับปรุงเล็กน้อย: ใช้<ใน$j<=$argv[1](พิมพ์หนึ่งมากเกินไป) (-1) ปล่อยให้$eไม่เตรียมใช้งาน$e+7แทน (-3) ใช้for(;;)แทนwhile()ใช้ประโยชน์จาก pre- และ post-expressions (-2) แทนที่echo$t.' ';$j++ด้วย$j+=print"$t "ปล่อยวงเล็บ (-3) แทนที่if($t>1)ด้วย2>$t||(-2) รวมการบ้านเข้า$tกับเงื่อนไขสลับ||เพื่อorปล่อยวงเล็บ (-5) ย้าย$argv[1]ไปที่ส่วน$jเพิ่มย้ายนิพจน์ทั้งหมดไปที่forเงื่อนไข (-2) เปลี่ยน>=$j+=printเป็น-=print(-3) ทีละขั้นตอน: codepad.org/s6LNSPSM
primo

1
@primo ขอบคุณสำหรับคำอธิบายที่ดี! ไม่รู้ว่าฉันสามารถทำสิ่งนั้นได้ทั้งหมด
jrenk

1
อีกไม่กี่: รวม$e+7กับ$e+=$t(-2) ปล่อยให้$iไม่เตรียมใช้งาน~++$iแทน (-3) codepad.org/fDIImajp
primo

4

Haskell, 51 ไบต์

d=zipWith gcd[2..]$scanl(+)7d
f=($filter(>1)d).take

โปรดทราบว่าfเป็นฟังก์ชั่นที่จะคืนองค์ประกอบnแรก

มากกว่าการคำนวณa(n)แล้วการทำงานออกความแตกต่างที่เราคำนวณความแตกต่างและรวมพวกเขาร่วมกันที่จะได้รับd(n) a(n)(ผู้ที่ไม่คุ้นเคยกับ Haskell อาจประท้วงว่าเราต้องการa(n)ก่อนเพื่อให้ได้d(n)แต่แน่นอนว่าการประเมินผลที่ขี้เกียจทำให้เราได้รับปัญหานี้!)

Ungolfed:

a = scanl (+) 7 d        -- yielding a(n) = 7 + d(1) + d(2) + ... + d(n-1)
d = zipWith gcd [2..] a  -- yielding d(n) = gcd(n+1, a(n))

f n = take n $ filter (> 1) d -- get rid of 1s and take the first n

4

Pyth, 30 ไบต์

กอล์ฟที่แย่มากสามารถลดได้อย่างมาก กำหนดฟังก์ชั่นวนซ้ำที่ด้านหน้าตัวกรอง.first-n จากนั้นจับคู่ความแตกต่าง

L?tb+KytbibK7m-yhdyd.ft-yhZyZQ

ลองมันนี่เกมออนไลน์


สิ่งนี้ให้เอาต์พุตที่ไม่ถูกต้องสำหรับn = 0
Sp3000

2
@ Sp3000 ที่เป็นข้อบกพร่องใน Pyth ฉันจะส่งคำขอดึง
Maltysen

พบข้อผิดพลาดและได้รับการแก้ไข - แพทช์จะดำเนินการเมื่อ github หยุดเป็น DDoS'd
isaacg

1
นี่มันคือmeta.codegolf.stackexchange.com/questions/5318/... โดยส่วนตัวฉันจะพิจารณาการแก้ไขข้อบกพร่องในภาษาการเขียนโปรแกรมเป็นคำตอบ
Thomas Weller

2
@ThomasWeller เป็นภาษาที่ประสบความสำเร็จทั้งภาษา ...
isaacg

4

Julia, 69 67 ไบต์

n->(i=1;a=7;while n>0 x=gcd(i+=1,a);a+=x;x>1&&(n-=1;println(x))end)

นี่เป็นวิธีแก้ปัญหาแบบวนซ้ำที่ง่ายสำหรับปัญหา xคือความแตกต่าง (ซึ่งเป็นgcd) และการปรับปรุงแล้วฉันโดยการเพิ่มax


ฉันคิดว่ามันพิมพ์A231900
alephalpha

@alephalpha - ฉันคิดว่าฉันเห็นข้อผิดพลาด แก้ไขได้อย่างง่ายดาย แม้แต่การโกนสองไบต์ในกระบวนการ
เกลน O

3

JavaScript (ES6), 91

gcd แบบเรียกซ้ำ, ฟังก์ชั่นหลักซ้ำ ไม่เร็วนัก

หมายเหตุปกติ: ทดสอบการเรียกใช้ตัวอย่างข้อมูลบนเบราว์เซอร์ที่สอดคล้องกับ EcmaScript 6 (ไม่ใช่ Chrome ไม่ใช่ MSIE โดยเฉพาะอย่างยิ่งฉันทดสอบบน Firefox, Safari 9 แล้ว)

F=m=>{
  for(G=(a,b)=>b?G(b,a%b):a,o=[],p=7,n=1;m;d>1&&(o.push(d),--m))
    p+=d=G(++n,p);
  return o
}

O.innerHTML=F(+I.value)
<input id=I value=10><button onclick='O.innerHTML=F(+I.value)'>-></button>
<pre id=O></pre>


3

Haskell, 74 71 66 ไบต์

f=($filter(>1)$tail>>=zipWith(-)$scanl(\x->(x+).gcd x)7[2..]).take

ใช้เคล็ดลับที่นี่: https://codegolf.stackexchange.com/a/39730/43318และทำให้ไม่มีจุด

(ก่อนหน้า: 71 ไบต์)

a=scanl(\x->(x+).gcd x)7[2..]
f m=take m$filter(>1)$zipWith(-)(tail a)a

ก่อนอื่นให้สร้างลำดับของ a แล้วจึงหาความแตกต่าง

(ก่อนหน้า: 74 ไบต์)

f m=take m$filter(>1)$map snd$scanl(\(x,d)->(\y->(x+y,y)).gcd x)(7,1)[2..]

ฟังก์ชั่นรายการมาตรฐานรวมถึงการใช้ฟังก์ชั่นแลมบ์ดาอย่างชาญฉลาด โปรดทราบว่านี่คือ 1 ไบต์สั้นกว่าที่ชัดเจนยิ่งขึ้น

g m=take m$filter(>1)$map snd$scanl(\(x,d)n->(x+gcd x n,gcd x n))(7,1)[2..]

หากเราไม่นับการนำเข้าฉันสามารถทำให้มันลดลงเหลือ 66

import Data.List
h m=take m$filter(>1)$snd$mapAccumL(\x->(\y->(x+y,y)).gcd x)7[2..]

3

PARI / GP, 60 ไบต์

a(n)=a=7;i=1;while(n,if(1<d=gcd(i+=1,a),n-=1;print(d));a+=d)

ถ่ายภาพโดยตรงจากคำนิยามa (n) - a (n-1) = gcd (n, a (n-1))

เอาท์พุทสำหรับa(20):

5
3
11
3
23
3
47
3
5
3
101
3
7
11
3
13
233
3
467
3

2

C ++, 193 182 180 172 ไบต์

ขอบคุณ @Jakube - บันทึก 8 ไบต์กับเอาต์พุต

int g(int a,int b){return a==b?a:a>b?g(b,a-b):g(a,b-a);}void f(int *r,int n){int m=1,i=0,a=7,b;while(i<n){b=g(a,++m);if(b>1){r[i]=b;++i;}a+=b;}}int main(){int r[6];f(r,6);}

คุณสามารถบันทึกได้สองสามไบต์โดยการกำหนดฟังก์ชั่นfที่ส่งกลับอาร์เรย์พร้อมผลลัพธ์ วิธีนี้คุณสามารถลบการรวม scanf และการพิมพ์
Jakube

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