Độ dài chương trình Fibonacci


14

Viết chương trình có độ dài n dẫn ra một chương trình khác có độ dài là số Fibonacci tiếp theo sau n. Chương trình mới phải thực hiện điều tương tự - xuất ra một chương trình khác có độ dài là số Fibonacci tiếp theo, v.v.
(chính độ dài của chương trình ban đầu) không phải là số Fibonacci, mặc dù nó sẽ rất tốt nếu có.

Mã ngắn nhất sẽ thắng.

Không có tài nguyên bên ngoài, chỉ ASCII, yêu cầu trình biên dịch / trình thông dịch miễn phí.
Nếu đầu ra của bạn kết thúc trong một dòng mới, nó cũng được tính.


Điều này có cần phải tiếp tục mãi mãi? ( inthoặc BigInteger)
Justin

1
@Quincunx sẽ ổn nếu nó ngừng hoạt động ở giới hạn int hoặc giới hạn của trình biên dịch / trình thông dịch, tùy theo điều kiện nào đến trước. Tôi hy vọng nó sẽ đạt được hơn 10000.
aditsu

1
Có hạn chế nào trong việc sử dụng khoảng trắng hoặc nhận xét hoặc tên biến / hàm / lớp tùy ý dài trong các chương trình gốc hoặc sản xuất sau đó không?
Jonathan Pullano

1
Chương trình có thể đọc mã nguồn riêng của nó không, hoặc bạn đang tìm kiếm một quine-quine thực sự?
lịch sử

@JonathanPullano không hạn chế, họ chỉ cần là chương trình hợp lệ
aditsu

Câu trả lời:


5

CJam, 26 23

Tôi vừa thử với ngôn ngữ của bạn.

7{9\@5mq)2/*')*\"_~"}_~

9 là (22*0.618 + 0.5 - 1)/1.618 + 1.

Nó tính toán độ dài của chính nó *1.618thay vì liên tục thêm hai số. Trong phiên bản đầu tiên, nó sẽ điền vào đầu ra trước khi {thích 1))))))))), tính chính các ký tự đó. Nói kết quả n. Tổng chiều dài là n+22và chiều dài mới trước đó {phải được (n+22)*1.618-22làm tròn. Giảm nó xuống một để đếm số lượng ). Sau đó, nó sẽ xấp xỉ bằng (n+8)*1.618.

Phiên bản cũ hơn:

-3{1\@5mq)2/*E+')*\"_~"}_~

Số 14 là 24*0.618 + 0.5 - 1.


Rất ấn tượng!
Dennis

Tôi nghĩ chúng ta có một người chiến thắng mới :)
aditsu

7

Python 2, 160 byte

s='s=%s;c=s;l=len(s%%c)+4;a,b=1,1\nwhile b<l:a,b=b,a+b\nc+="1"*(b-l-1);print s%%`c`;a=1'
c=s
l=len(s%c)+4
a,b=1,1
while b<l:a,b=b,a+b
c+="1"*(b-l-1)
print s%`c`

Đây là một quine-quine thực sự; nó không đọc nguồn của chính nó, nhưng nó tạo ra nó. Đầu ra đầu tiên (có dòng mới):

s='s=%s;c=s;l=len(s%%c)+4;a,b=1,1\nwhile b<l:a,b=b,a+b\nc+="1"*(b-l-1);print s%%`c`;a=111111111111111111111111111111111111111111111111111111111111111111111';c=s;l=len(s%c)+4;a,b=1,1
while b<l:a,b=b,a+b
c+="1"*(b-l-1);print s%`c`;a=1

Thứ hai:

s='s=%s;c=s;l=len(s%%c)+4;a,b=1,1\nwhile b<l:a,b=b,a+b\nc+="1"*(b-l-1);print s%%`c`;a=1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111';c=s;l=len(s%c)+4;a,b=1,1
while b<l:a,b=b,a+b
c+="1"*(b-l-1);print s%`c`;a=111111111111111111111111111111111111111111111111111111111111111111111

Chỉnh sửa: Rất tiếc. Quên thay đổi chuỗi khi tôi thay đổi từ ;s thành 1s, vì vậy đầu ra thứ hai là xuất ra dấu chấm phẩy bổ sung (mà Python không hỗ trợ). đã sửa


Tôi sợ nó ngừng hoạt động sau khoảng 3 lần lặp lại ...
aditsu

@aditsu Gì? Python có giới hạn về kích thước của một số nguyên?! (hoặc có phải số đếm không phải là một Wikipedia / bỏ qua / cái gì khác không?) Đợi đã. Tât nhiên. Tôi quên thay đổi chuỗi XD
Justin

7

CJam, 41 31 byte

{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~

Hãy thử trực tuyến.

Đầu ra

$ cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~'); echo
{1$+S@]_1=4+1$`,-S*"2$~"}34 21 2$~
$ cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~') | wc -c
34
$ cjam <(cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~')); echo
{1$+S@]_1=4+1$`,-S*"2$~"}55 34                      2$~
$ cjam <(cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~')) | wc -c
55
$ cjam (cjam <(cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~'))); echo
bash: syntax error near unexpected token `cjam'
$ cjam <(cjam <(cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~'))); echo
{1$+S@]_1=4+1$`,-S*"2$~"}89 55                                                        2$~
$ cjam <(cjam <(cjam <(echo '{1$+S@]_1=4+1$`,-S*"2$~"}21D2$~'))) | wc -c
89

Làm thế nào nó hoạt động

{       "                                                   {…} 21 13                     ";
  1$+   " Duplicate the higher number and add.              {…} 21 34                     ";
  S@    " Push a space and rotate the lower number on top.  {…} 34 ' ' 21                 ";
  ]     " Wrap the stack into an array.                     [ {…} 34 ' ' 21 ]             ";
  _1=   " Push the second element of the array.             [ {…} 34 ' ' 21 ] 34          ";
  4+    " Add 4 to it.                                      [ {…} 34 ' ' 21 ] 38          ";
  1$`,  " Push the length of the stringified array.         [ {…} 34 ' ' 21 ] 38 37       ";
  -S*   " Subtract and push that many spaces.               [ {…} 34 ' ' 21 ] ' '         ";
  "2$~" " Push the string '2$~'.                            [ {…} 34 ' ' 21 ] ' ' '2$~'   ";
}       "                                                   {…}                           ";

21D     " Push 21 and 13.                                   {…} 21 13                     ";
2$~     " Copy the code block an evaluate.                  [ {…} 34 ' ' 21 ] ' ' '2$~'   ";

2
Thật tuyệt, được xác nhận lên tới 1 triệu :) Tôi nghĩ rằng đó là 37 thay vì 39 mặc dù trong phần giải thích.
aditsu

@aditsu: Không nhận thấy bạn đã chỉnh sửa nhận xét của mình cho đến bây giờ. Nó thực sự phải là 37, cảm ơn.
Dennis

6

Con trăn - 89

g="%(s,b,a+b);print o.ljust(b-1)";s,a,b="s,a,b=%r,%i,%i;o=s%"+g,89,144;exec("o=s"+g)#####

Số lượng nhân vật hoàn hảo của tôi đã biến mất . ; _; Cảm ơn TheRare đã chỉ ra điều mới và Quincunx đã gợi ý tôi sử dụng Python 2, cạo sạch 2 ký tự.

EDIT : Bây giờ chỉ sử dụng nhiều #s thay vì 1s; 12 ký tự ngắn hơn.

EDIT 2 : 94 ký tự! Loại bỏ một số sự lặp lại. > 3

EDIT 3 : Thay thế repr ngắn hơn cho Python 2.

EDIT 4 : Đầu ra là một ký tự ngắn hơn bây giờ.

EDIT 5 : Việc sử dụng %rđể rút ngắn nó được lấy từ một câu trả lời cho một câu hỏi khác của @primo.

EDIT 6 : Ngắn hơn. : D

Đây là phiên bản Python 3:

g="%(s,b,a+b);print(o.ljust(b-1))";s,a,b="s,a,b=%r,%i,%i;o=s%"+g,89,144;exec("o=s"+g)####

Câu trả lời này tương tự như câu trả lời của @Quincunx.


printluôn luôn thêm một dòng mới, trừ khi bạn chỉ định end=''đối số.
xem

Tại sao không sử dụng Python 2?:s,a,b="s,a,b=%s,%i,%i;o=s%%(`s`,b,a+b)+'#';print o+(b-len(o)-1)*'1'",89,144;o=s%(`s`,b,a+b)+'#';print o+(b-len(o)-1)*'1'
Justin

@Quincunx tôi sẽ! Cảm ơn: D
cjfaure

Chương trình 90 char của bạn không hoạt động với python 3 và có đầu ra 145 char (không phải là số Fibonacci)
aditsu

@aditsu Đã sửa. : 3
cjfaure

2

JavaScript, 94

(function q(w,e){return ('('+q+')('+e+','+(s=w+e)+')'+Array(s).join('/')).substr(0,s)})(55,89)

Dựa trên một Quine JavaScript nổi tiếng , hàm này trả về gần như cùng một hàm, chỉ được theo sau bởi số lượng dấu gạch chéo, sao cho tổng của nó là 144, là số Fibonacci tiếp theo sau N. Và cứ thế ...

N không phải là một số Fibonacci, nhưng nó chỉ là "tốt đẹp để có".


Nó dường như không hoạt động chính xác khi vượt qua 1000
aditsu

1000 cái gì? Lặp lại?
Jacob

Không, thời lượng chương trình
aditsu

Hmm ... Tôi đã thử nghiệm nó trong Bảng điều khiển của Chrome, sử dụng p = (my answer)và sau đó p = eval(p)một vài lần và đến năm 196418 ... sau thời gian xử lý đó là> 1 giây nên tôi bỏ thử nghiệm: P Nhưng tôi đoán nó có thể tiếp tục nhiều hơn nữa.
Jacob

Bạn không hiểu .. Tôi đã không nói rằng nó ngừng hoạt động hoặc nó quá chậm. Tôi nói nó không hoạt động chính xác. Đừng chỉ làm p=eval(p), cũng kiểm tra p.length. Sau khi lên tới 987, tôi nhận được độ dài 1598, không phải là số Fibonacci.
aditsu

0

Toán học

({0};
 With[{n = Ceiling[ InverseFunction[Fibonacci]@LeafCount@#0 ], l = Length[#0[[1, 1]]]},
    #0 /. {0..} -> ConstantArray[0, Fibonacci[n+1] - LeafCount[#0] + l]
 ]) &

Đây là một thực hiện rất đơn giản (tức là không có obfuscation ở đây). Đây là một hàm ẩn danh tự trả về với một chút phần đệm để đạt được độ dài chính xác. Mathematica là homoiconic: mã và dữ liệu đều được biểu diễn dưới dạng biểu thức Mathicala, giúp dễ dàng sửa đổi / tạo mã khi đang di chuyển. Điều này cũng có nghĩa là số lượng ký tự không phải là thước đo tự nhiên của độ dài mã. Kích thước epxression ( "đếm lá" ) là. Phiên bản này dựa trên số lượng lá như thước đo chiều dài mã.

Nếu chúng ta gán hàm ẩn danh này cho một biến f(để tôi có thể hiển thị những gì xảy ra theo cách có thể đọc được) và tiếp tục gọi nó là 1, 2, 3, ... lần, mỗi lần đo độ dài của giá trị trả về, đây là những gì chúng tôi nhận được:

In[]:= f // LeafCount
Out[]= 42

In[]:= f[] // LeafCount
Out[]= 89

In[]:= f[][] // LeafCount
Out[]= 144

In[]:= f[][][] // LeafCount
Out[]= 233

Về yêu cầu thông dịch viên miễn phí: Mathematica miễn phí cho Raspberry Pi. Mặt khác, mã này phải đơn giản để chuyển sang Mathics (mã nguồn mở) . Điều duy nhất còn thiếu từ Mathics là InverseFunction, có thể thay thế như ở đây (nhưng tôi lười biếng :).


Ồ, tôi không biết Mathicala là miễn phí cho Pi, tôi nên kiểm tra nó. Tuy nhiên, chương trình được cho là in các ký tự đến đầu ra tiêu chuẩn và đó là những gì cần được tính.
aditsu

@aditsu Thật ra tôi đã làm điều này vì niềm vui hơn là cạnh tranh trong thử thách và sử dụng LeafCountcó vẻ thú vị hơn nhiều so với sử dụng số lượng ký tự (điều này có nghĩa là thao tác mã nhàm chán như thao tác chuỗi). :-) Tôi sẽ không thay đổi nó để sử dụng số lượng ký tự, nhưng tôi có thể xóa nó mà không có bất kỳ cảm giác xấu nào nếu bạn muốn.
Szabolcs

Ồ, tôi hiểu rồi. Chỉ cần để lại nó, không cần phải xóa.
aditsu

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.