Câu hỏi ngẫu nhiên


15

Viết một chương trình có khả năng tự tạo ngẫu nhiên.

Nó phải làm điều này dựa trên các mã thông báo được sử dụng trong mã nguồn của nó. Nếu mã nguồn chương trình của bạn bao gồm 50 mã thông báo duy nhất và dài 60 mã thông báo, thì chương trình sẽ tạo ra 60 mã thông báo trong đó mỗi mã thông báo được chọn ngẫu nhiên từ một trong 50 mã thông báo duy nhất.

Ví dụ, chương trình này sẽ có cơ hội một trong 50 ^ 60 để tự tái tạo.

Mã thông báo là gì? Điều đó phụ thuộc vào ngôn ngữ. Ví dụ: mã định danh ( foo_bar), từ khóa ( while) và số ( 42) sẽ được tính là mã thông báo trong hầu hết các ngôn ngữ. Khoảng trắng sẽ không được tính trong hầu hết các ngôn ngữ.

Quy tắc bổ sung:

  • Đầu ra chỉ có thể chứa mã thông báo được tìm thấy trong mã nguồn chương trình, được phân tách bằng dấu phân cách thích hợp
  • Đầu ra phải có cùng độ dài với mã nguồn của chương trình, được tính bằng mã thông báo
  • Chỉ một ngôn ngữ lập trình có thể được sử dụng
  • Mã nguồn phải có ít nhất 3 mã thông báo duy nhất
  • Loại trừ ý kiến ​​từ mã nguồn
  • Chương trình chỉ nên có một cơ hội trong U ^ L để tự tái tạo

Ghi điểm: Chương trình có cơ hội tốt nhất để tái tạo chính nó, chiến thắng.


@MathieuRodic: Bạn đang giả định rằng chương trình rút ra các mã thông báo mà không lặp lại.
user2357112 hỗ trợ Monica

@MathieuRodic: Hãy để tôi viết lại. Bạn đang giả sử chương trình xáo trộn ngẫu nhiên nhiều mã thông báo của nó, thay vì vẽ các mã thông báo L với sự lặp lại từ bộ mã thông báo U được sử dụng trong nguồn của nó.
user2357112 hỗ trợ Monica

@ user2357112: Tôi hiểu rồi. Sai lầm của tôi là coi vấn đề này là một trận hòa mà không cần thay thế.
Mathieu Rodic

1
Quy tắc số 1 và số 5 dường như mâu thuẫn với tôi.
Cruncher

4
Bạn có thể cho rằng các hàm được xây dựng ngẫu nhiên là TRNG không? Việc triển khai điển hình có hạt quá nhỏ để tạo ra tất cả các kết quả đầu ra và do đó có thể không thể tự tái tạo.
CodeInChaos

Câu trả lời:


11

Con trăn 2, 3 ^ -3 = 0,037

execlạm dụng khá tiện dụng để giảm số lượng mã thông báo. Bây giờ cập nhật để không đọc các tập tin nguồn!

exec '' """
s = '''{a}
s = {b}
s = s.format(a='"'*3, b="'"*3+s+"'"*3)
import random
tokens = ['exec', "''", s]
print random.choice(tokens), random.choice(tokens), random.choice(tokens),
{a}'''
s = s.format(a='"'*3, b="'"*3+s+"'"*3)
import random
tokens = ['exec', "''", s]
print random.choice(tokens), random.choice(tokens), random.choice(tokens),
"""

Phần bổ sung ''giữa execvà chuỗi ba trích dẫn khổng lồ chỉ là để tăng số lượng mã thông báo đến mức tối thiểu bắt buộc là 3. Nó được hợp nhất vào chuỗi thứ hai do nối chuỗi theo nghĩa đen.

Phiên bản gốc, tệp nguồn mở:

exec '''
# String literals are one token!
import random
import tokenize

with open(__file__) as f:
    tokens = [x[1] for x in tokenize.generate_tokens(f.readline)][:-1]

''' '''
# Splitting the string into two strings pads the token count to the minimum of 3.

print random.choice(tokens), random.choice(tokens), random.choice(tokens),
'''

Nói một cách chính xác, ngữ pháp Python đặt mã thông báo ENDWORER ở cuối tệp nguồn và chúng tôi không thể tạo tệp nguồn với ENDWORER được đặt ngẫu nhiên. Chúng tôi giả vờ nó không tồn tại.


@Cruncher Đó là xác suất. 3 ^ -3 == 1/3 ^ 3
Austin Henley

2
+1 cho hack tuyệt vời của các quy tắc. Ý tưởng tương tự được thực hiện trong J : ".]';(?3 3 3){]`".;~({:,],{:,],6#{:)'';(?3 3 3){]`".;~({:,],{:,],6#{:)'''''''.
thuật toán

5

Javascript, 102 mã thông báo, 33 độc đáo, 7,73 × 10 -154

Lưu ý, đây là một quine thực sự. Nó không đọc tệp hoặc sử dụng evalhoặcFunction.toString

meta = "meta = ; out = '' ; tokens = meta . split ( '\\u0020' ) ; tokens . push ( '\"' + meta + '\"' ) ; length = tokens . length ; tmp = length ; unique = { } ; while ( tmp -- ) unique [ tokens [ tmp ] ] = unique ; unique = Object . keys ( unique ) ; tmp = unique . length ; while ( length -- ) out += tokens [ ~~ ( Math . random ( ) * tmp ) ] + '\\u0020' ; console . log ( out )"; 
out = '';
tokens = meta.split('\u0020');
tokens.push('"' + meta + '"');
//console.log(tokens);
length = tokens.length;
tmp = length;
unique = { };
while(tmp--) unique[tokens[tmp]] = unique;
unique = Object.keys(unique);
//console.log(unique);
tmp = unique.length;
while(length--)
    out += unique[~~(Math.random() * tmp)] + '\u0020';
console.log(out)

4

Python: P (tạo chương trình trong 1 bản dùng thử) = 3.0317 * 10 ^ -123

34 mã thông báo độc đáo, tổng số 80 mã thông báo. Lưu ý rằng có một khoảng trắng ở cuối mỗi dòng.

import tokenize , random 
tokens = [ x [ 1 ] for x in tokenize . generate_tokens ( open ( __file__ , 'r' ) . readline ) ] [ : -1 ] 
s = '' 
for x in tokens : s += random . choice ( list ( set ( tokens ) ) ) ; s += [ ' ' , '' ] [ s [ -1 ] == '\n' ] 
print s 

Đầu ra mẫu:

' ' random len set 'r' , for ( list , import ] ] tokens : random [ for '\n' import readline readline 'r' tokens [ len 'r' import '' choice '' '' for in ( readline ( = open readline , list 1 list s += for s 1 , '' : 1 += list len - __file__ ; open __file__ print . - ] 'r' for import [ print . , 

; . [ [ print print __file__ generate_tokens ] ; open ] , readline 

Cảm ơn giải pháp Python khác của user2357112 đã nhắc nhở tôi loại bỏ mã thông báo cuối cùng và sử dụng __file__mà trước đây tôi không biết gì.


3

J - 1 trong 11 17 = 1.978 x 10 -18

;(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''

J có một loạt các công cụ nhỏ tiện dụng để hoàn thành các công việc này.

  • Trước hết, bất kỳ chuỗi số nào được phân tách bằng dấu cách là một mã thông báo . Nó có nghĩa là một mảng một chiều của những con số đó. Đây là cách mà lexer của J hoạt động. Nhân tiện, đó là mười bảy 11s, nếu có ai tò mò.

  • (,,,{:,{:)'QUINE'''là một thủ thuật quine phổ biến trong J, được thực hiện để sử dụng càng ít mã thông báo càng tốt: {:có nghĩa là Tail , do đó, nó nối thêm chuỗi vào chính nó, và sau đó thêm hai bản sao của ký tự cuối cùng vào cuối đó. Vì ký tự cuối cùng là một trích dẫn (J sử dụng chuỗi kiểu Pascal), kết quả là QUINE'QUINE'''.

  • ;:là một mã thông báo và phá vỡ một chuỗi đầu vào như thể đó là mã J, trả về một danh sách các hộp. Độ dài của kết quả này là 17.

  • ~.có tất cả các yếu tố duy nhất của mảng này. Độ dài của kết quả này là 11.

  • ?được gọi là cuộn . Đối với mỗi số nguyên trong đối số của nó, nó chọn một số dương ngẫu nhiên lớn hơn hoặc bằng 0, nhỏ hơn số đó. Vì vậy, ở đây J sẽ tạo ra 17 số từ 0 đến 10.

  • { sử dụng các chỉ mục ngẫu nhiên để chọn các mục trong danh sách các mã thông báo duy nhất của chúng tôi.

  • ; mở tất cả các hộp và chạy kết quả cùng nhau.

Một số ví dụ sau. Các dòng thụt lề là lời nhắc đầu vào và các dòng tuôn ra với bên trái là đầu ra của trình thông dịch.

   ;(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''
~.~.(?;;:11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''(){11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){(;:;
   ;(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''
{';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)''',?{:;:{:';(?11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11){~.;:(,,,{:,{:)'''11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11{:{;(;:{:,~.

2

Bản thảo

Đây là một niềm vui

/cvx /cvx cvx /exec /exec cvx /dup /rand /mod /get /== /array /astore /realtime
/srand /repeat 6 17 54 17 /array cvx exec /astore cvx exec 54 /dup cvx /rand
cvx 17 /mod cvx /get cvx /== cvx 6 /array cvx exec /astore cvx exec cvx /realtime
cvx exec /srand cvx exec /repeat cvx exec

Có 17 mã thông báo duy nhất và tổng số 54 mã thông báo cho khoảng 1 trong 3,6e-67 cơ hội.


2

Khoảng trắng, 3 ^ -205 3 ^ -189 3 ^ -181 3 ^ -132 ~ = 10 ^ -63

Đây là chương trình Whitespace, khi được tạo mầm với các ký tự ngẫu nhiên, có cơ hội 1 trong 3 ^ 132 tự tái tạo (3 mã thông báo riêng biệt, lặp lại 132 lần). Nó phải được thêm ít nhất 132 ký tự ngẫu nhiên khi chạy, (Khoảng trắng không có chức năng ngẫu nhiên hoặc ngày tháng tích hợp để tạo hạt giống), vd some_whitespace_interpreter my_quine.ws <some_random_source >quine_output.ws. Điểm số sẽ được cải thiện nếu chương trình có thể được chơi gôn nữa, nhưng đây là chương trình Whitespace "thực sự" đầu tiên của tôi, vì vậy tôi sẽ chỉ để lại số tiền chơi golf ít ỏi của mình.

Mã Plain Whitespace hoặc xem nó chạy : (để thử, nhấp vào "chỉnh sửa", sao chép nội dung bên trong các thẻ <pre>; phải là 132 ký tự với EOL kiểu Unix)

    

























Mã được chú thích với lệnh nào là gì (về mặt kỹ thuật không phải là câu hỏi, vì nó sẽ không tái tạo các ý kiến):

ngăn xếp stack_number + 0 kết thúc
ngăn xếp chồng số + 1 0 0 1 kết thúc
heap stack stack Push_number + 1 end
ngăn xếp stack_number + 1 0 0 0 0 0 kết thúc
heap store stack Push_number + 1 0 end
ngăn xếp chồng số + 1 0 1 0 kết thúc
heap store stack push_number + 1 0 0 0 0 0 1 1 end
lưu lượng
make_label loop_begin  
stack Push_number + 1 1 end
Tôi  
đọc ngăn xếp ký tự Push_number + 1 1 kết thúc
heap lấy stack push_number + 1 1 end
đống modulo số học lấy IO  
in char stack stack_number + 1 end
phép trừ số học trùng lặp
 lưu lượng
jump_if_zero end_prog
lưu lượng
nhảy_to 
loop_begin  
lưu lượng
make_label end_prog
lưu lượng
chương trình kết thúc

Nếu hạt giống chỉ tương đương (các ký tự được lấy mod 3 để được chuyển đổi thành mã thông báo), thì nó sẽ thành công:

CCCCACCCBCCBABBCCCCBACCCBCCCCCABBCCCCBCACCCBCBCABBCCCCBCCCCCBBAACCBACCCBBABABCCCCBBABBBCCCBBABCBBBBBBACCCCCBABCCBCACABBAACABAACCAAA

Đây là một chương trình khá đơn giản, gần tương đương với chương trình Ruby này:

i = 131
while true
    print '\t \n'[STDIN.getc.ord % 3]
    i = i - 1
    break if i < 0
end

1

Perl, 27 mã thông báo, P = 1.4779 x 10 -34

@ARGV=$0;print$W[rand@W]for@W=split/(\W)/,readline

Chỉnh sửa lần cuối: sử dụng @ARGV=$0thay vì open*ARGV,$0lưu mã thông báo.

  • 15 mã thông báo độc đáo
  • 4 thẻ xuất hiện 2 lần ( =, /, @, $)
  • 1 mã thông báo xuất hiện 4 lần ( W)

Vì vậy, tôi nghĩ rằng điều đó làm cho xác suất (pow (2,2 * 4) * pow (4,4)) / pow (27,27), khoảng 1,48E-34.

Nếu mã nguồn nằm trong một tệp được gọi ARGV, thì bạn có thể sử dụng giải pháp mã thông báo 26 này với P = ~ 2.193 x 10 -31 :

@ARGV=ARGV;print$ARGV[rand@ARGV]for@ARGV=split/(\W)/,readline

Trên thực tế, P = (4 * 2! + 4!) / 27!đó là khoảng 1.7632684538487448 x 10 ^ -26
Mathieu Rodic

0

Perl 6 ,1 trong 33 = = 0,037037 ...

(Tôi biết đây không phải là môn đánh gôn, nhưng ...)

q[say |roll <<~~"q[$_]".EVAL>>: 3]~~.EVAL

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

Giống như câu trả lời của Python, trong đó mã thông báo đầu tiên là một chuỗi ký tự được đánh giá. Các mã thông báo là

q[say |roll <<~~"q[$_]".EVAL>>: 3]   String literal
~~                                   Smartmatch operator
.EVAL                                Function call

Giải trình:

q[say |roll <<~~"q[$_]".EVAL>>: 3]         # Push as string literal
                                  ~~       # Smartmatch by setting $_ to the string literal
                                    .EVAL  # Eval the string
            <<~~"q[$_]".EVAL>>             # From the list of tokens
       roll                   : 3          # Pick 3 times with replacement
  say |                                    # Join and print
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.