Trò chơi chính của Conway


18

Cụ thể, PRIMEGAME của Conway .

Đây là một thuật toán được John H. Conway nghĩ ra để tạo ra các số nguyên tố bằng cách sử dụng một chuỗi gồm 14 số hữu tỷ:

 A   B   C   D   E   F   G   H   I   J   K   L   M   N
17  78  19  23  29  77  95  77   1  11  13  15  15  55
--  --  --  --  --  --  --  --  --  --  --  --  --  --
91  85  51  38  33  29  23  19  17  13  11  14   2   1

Ví dụ, F là phân số 77/29.

Vì vậy, đây là cách thuật toán tìm các số nguyên tố. Bắt đầu với số 2, tìm mục đầu tiên trong chuỗi mà khi nhân với nhau sẽ tạo ra một số nguyên. Ở đây đó là M, 15/2, trong đó sản xuất 15. Sau đó, với số nguyên đó 15, tìm mục đầu tiên trong chuỗi mà khi nhân sẽ tạo ra một số nguyên. Đó là cái cuối cùng N, hoặc 55/1, mang lại 825. Viết trình tự tương ứng. (Những người thông minh trong số bạn có thể nhận ra đây là chương trình FRACTRAN .)

Sau một số lần lặp lại, bạn sẽ nhận được những điều sau:

2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, 910, 170, 156, 132, 116, 308, 364, 68, 4 ...

Lưu ý rằng mục cuối cùng được liệt kê là 4, hoặc 2^2. Kìa số nguyên tố đầu tiên của chúng tôi ( 2số mũ) được tạo bằng thuật toán này! Cuối cùng, chuỗi sẽ như sau:

2 ... 2^2 ... 2^3 ... 2^5 ... 2^7 ... etc.

Do đó, mang lại các số nguyên tố. Đây là OEIS A007542 .

Các thách thức

Cho một số đầu vào n, bằng 0 hoặc một chỉ mục (lựa chọn của bạn), hoặc xuất các nsố đầu tiên của chuỗi này hoặc xuất nsố thứ của chuỗi này.

Ví dụ

Các ví dụ dưới đây đang xuất ra nthuật ngữ thứ tự của chuỗi không có chỉ mục.

 n   output
 5   2275
19   4
40   408

Quy tắc

  • Nếu có thể, bạn có thể giả sử rằng đầu vào / đầu ra sẽ phù hợp với loại Số nguyên gốc của ngôn ngữ của bạn.
  • Đầu vào và đầu ra có thể được cung cấp bởi bất kỳ phương pháp thuận tiện .
  • Một chương trình đầy đủ hoặc một chức năng được chấp nhận. Nếu một chức năng, bạn có thể trả lại đầu ra thay vì in nó.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đây là vì vậy tất cả các quy tắc chơi gôn thông thường đều được áp dụng và mã ngắn nhất (tính bằng byte) sẽ thắng.

11
Có lẽ trò chơi chính của Conway sẽ là một cái tên mô tả cho thử thách này hơn là Chơi một trò chơi . Điều đó sẽ làm cho nó dễ dàng hơn để tìm lại thách thức này trong tương lai.
Lynn

Đầu ra có thể là một float? 408.0thay vì 408ví dụ.
dyl Nam

Thật không may, chúng tôi không có một thử thách (phiên dịch) Fractran "chính tắc". Cái trên Stack Overflow bị khóa.
dùng202729

@dylnan Chắc chắn, điều đó tốt.
admBorkBork

Câu trả lời:


5

Python 3 , 173 165 153 145 144 136 135 127 126 125 108 107 104 byte

f=lambda n:2>>n*2or[f(n-1)*t//d for t,d in zip(b"NM_M\r7",b"[U3&!\r")if f(n-1)*t%d<1][0]

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

  • -30 byte nhờ Jonathan Frech!
  • -3 byte nhờ Lynn!

2>>n*22cho n==00nếu không.

103 byte nếu chúng ta có thể trả lại float.


Sử dụng Python 2; 153 byte .
Jonathan Frech

@JonathanFrech Tuyệt, thủ thuật hay. Cảm ơn!
dylnan

1
Ở trong Python 3, 146 byte !
Jonathan Frech


Cảm ơn một lần nữa, bạn đã làm nhiều hơn tôi bây giờ!
dylnan

5

FRACTRAN , 99 byte

17/2821 78/2635 19/1581 23/1178 29/1023 77/899 95/713 77/589 1/527 11/403 13/341 15/434 15/62 55/31

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

Chương trình lấy 2*31^nlàm đầu vào, được sử dụng làm trạng thái ban đầu.

Tất cả các phân số trong chương trình FRACTRAN ban đầu đã được chia cho 31 (thanh ghi nguyên tố đầu tiên không được sử dụng), vì vậy chương trình dừng lại ở lần lặp thứ n.


Câu trả lời táo tợn. ;-)
admBorkBork


3

Python 3 , 107 byte

f=lambda n,k=2:n and f(n-1,[k*a//b for a,b in zip(b"NM_M\r7",b"[U3&!\r")if k*a%b<1][0])or k

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

Mã hóa danh sách các phân số bằng cách nhập ziphai chuỗi phụ có chứa các ký tự ASCII thấp không thể in được.

Nếu nbằng 0, chúng ta trả về đối số k; nếu không, chúng tôi tái diễn với các tham số mới. kGiá trị mới của chúng tôi là giá trị đầu tiên k*a//btương ứng với một số phân số (a, b)trong danh sách, ví dụ như k*a//blà một số nguyên k*a%b<1.



2

J , 116 110 byte

g=.3 :0
((1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x)([:({.@I.@(=<.){[)*)])^:y 2
)

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

Chỉ số 0; trả về số thứ n

Một số byte có thể được lưu bằng cách tạo động từ ngầm, nhưng tôi gặp vấn đề khi thực hiện ^:công việc.

Giải trình:

J mô tả các số hữu tỷ ở dạng NrD, trong đó N là tử số và D là mẫu số, ví dụ 17r91 78r85 19r51 23r38...tôi đã tạo 2 danh sách riêng cho tử số và mẫu số và tạo 2 số cơ sở 96 từ chúng.

1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x chuyển đổi các số cơ sở 96 thành danh sách và xây dựng danh sách các phân số bằng cách chia hai danh sách.

   1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x
17r91 78r85 19r51 23r38 29r33 77r29 95r23 77r19 1r17 11r13 13r11 15r14 15r2 55

2 bắt đầu với 2

^:ylặp lại động từ vào nthời gian bên trái của nó (y là đối số của hàm)

] đối số đúng (bắt đầu từ 2, và sau đó sử dụng kết quả của mỗi lần lặp)

* nhân danh sách các phân số với đối số đúng

(=<.) là số nguyên kết quả (so sánh mỗi số với sàn của nó)

{.@I.@tìm chỉ số I.của {.số nguyên đầu tiên

{[ sử dụng chỉ mục để lấy số


1
62 byte:('0m26<l~l *,..V'%&(31x-~3&u:)'ztRE@<620,*-! ')&(0{*#~0=1|*)2:
dặm

@miles Cảm ơn, tôi nghĩ bạn phải đăng giải pháp của mình, nó tốt hơn của tôi.
Galen Ivanov

2

05AB1E ,  44  43 byte

Chỉ số 0

2sF•Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•тв2ä`Š*s‰ʒθ_}нн

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

Giải trình

2                                             # initialize stack with 2
 sF                                           # input times do:
   •Ë₁ǝßÌ?ƒ¥"h2ÔδD‡béαA5À>,•                  # push a base-255 compressed large number
                            тв                # convert to a list of base-100 digits
                              2ä`             # split in 2 parts to stack
                                 Š            # move denominators to bottom of stack
                                  *           # multiply the last result by the numerators
                                   s‰         # divmod with denominators
                                     ʒθ_}     # filter, keep only those with mod result 0
                                         нн   # get the div result

Số lượng lớn đẩy là 17781923297795770111131515559185513833292319171311140201



1

JavaScript (Node.js) , 106 95 byte

  • cảm ơn @Arnauld và @Neil vì đã giảm 11 byte
(n,N=2,I=13,B=Buffer(`[U3&!\rNM_M\r7`))=>n--?f(n,N/B.find(x=>N%x<!!++I)*B[I]):N

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


Quản lý để vắt kiệt một vài byte nhưng không thể nghĩ rằng tôi đang thiếu một cái gì đó: Hãy thử trực tuyến!
Neil

1
@Neil Không cần sử dụng toán tử lây lan trên Buffer. Ngoài ra, tôi nghĩ an toàn khi đặt tất cả dữ liệu vào một bộ đệm: 95 byte .
Arnauld

@Arnauld OP đã sử dụng toán tử lây lan (Tôi không quen với Bộ đệm nên tôi không biết gì hơn) nhưng đó là một bước đi tuyệt vời với Bộ đệm duy nhất!
Neil

@Arnauld chính xác, được cập nhật :)
DanielIndie

1

Võng mạc , 213 byte

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2
\d+
*
"$+"+`((_+)/(_+)¶(.+¶)*)(\3)+$
$1$#5*$2
r`_\G

Hãy thử trực tuyến! Giải trình:

K`17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶17/91¶78/85¶19/51¶23/38¶29/33¶77/29¶95/23¶77/19¶1/17¶11/13¶13/11¶15/2¶1/7¶55/1¶2

Thay thế đầu vào bằng một danh sách tất cả các phân số, cộng với số nguyên ban đầu.

\d+
*

Chuyển đổi mọi thứ để unary.

"$+"+`

Lặp lại thay thế số lần được đưa ra bởi đầu vào ban đầu.

((_+)/(_+)¶(.+¶)*)(\3)+$

Tìm mẫu số chia đều số nguyên.

$1$#5*$2

Thay số nguyên bằng kết quả của phép chia nhân với tử số.

r`_\G

Chuyển đổi số nguyên thành số thập phân và xuất kết quả.


1

Tùy viên , 81 byte

Nest<~{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]},2~>

Hãy thử trực tuyến! Xuất ra một phân số trên 1. Ví dụ, 5trả về đầu vào 2275/1. Điều này có thể được sửa với cộng 2 byte bằng cách thêm vào N@chương trình.

Giải trình

Đây là một hàm được xử lý, Nest có hai đối số được xác định trước:

{Find[Integral,_*&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]}

2. Đối số cuối cùng này chỉ đơn giản là hạt giống ban đầu và đối số được truyền cho hàm này là số lần lặp để lồng hàm đã cho.

Sau đây được sử dụng để mã hóa PRIMEGAME:

&`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]]

Điều này được đánh giá như vậy:

A> "0zmt2R6E<@l<~6l2 0*,,*.-.!V "
"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "
[48, 122, 109, 116, 50, 82, 54, 69, 60, 64, 108, 60, 126, 54, 108, 50, 32, 48, 42, 44, 44, 42, 46, 45, 46, 33, 86, 32]
A> Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31
[17, 91, 78, 85, 19, 51, 23, 38, 29, 33, 77, 29, 95, 23, 77, 19, 1, 17, 11, 13, 13, 11, 15, 14, 15, 2, 55, 1]
A> Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
 17 91
 78 85
 19 51
 23 38
 29 33
 77 29
 95 23
 77 19
  1 17
 11 13
 13 11
 15 14
 15  2
 55  1
A> &`//=>Chop[Ords!"0zmt2R6E<@l<~6l2 0*,,*.-.!V "-31,2]
[(17/91), (78/85), (19/51), (23/38), (29/33), (77/29), (95/23), (77/19), (1/17), (11/13), (13/11), (15/14), (15/2), (55/1)]

Hãy thay thế biểu thức này bằng Gtrong lời giải thích. Chức năng đầu tiên của chúng tôi trở thành:

{Find[Integral,_*G]}

Điều này thực hiện một lần lặp mã FRACTRAN duy nhất _, đầu vào cho hàm. Nó Findlà một Integralthành viên (một số nguyên) của mảng _*G, là đầu vào _nhân với mỗi thành viên của G. Nestchỉ cần áp dụng phép biến đổi này với số lần đã cho.

Tùy viên, 42 byte

Tôi đã thực hiện các phần của $langsthư viện, được truyền cảm hứng từ thử thách này, vì vậy tôi đánh dấu phần này không cạnh tranh.

Needs[$langs]2&FRACTRAN_EXAMPLES.prime.run

Điều này chỉ đơn giản là truy vấn danh sách của FRACTRAN_EXAMPLEStôi có. Mỗi ví dụ là một FractranExamplethể hiện, gọi FRACTRANhàm inbuilt . Các primeví dụ là PRIMEGAME Conway.



0

PHP, 183 byte (189 với thẻ "php")

Chơi gôn

$t=2;for(;@$i++<$argv[1];){foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1]as$n){$a=$t*$n;if(preg_match('/^\d+$/',$a)){$t=$a;break;}}}echo$t;

Ung dung:

<?php 
$t=2;
for(;@$i++<$argv[1];){
    foreach([17/91,78/85,19/51,23/38,29/33,77/29,95/23,77/19,1/17,11/13,13/11,15/14,15/2,55/1] as $n){
        $a=$t*$n;
        if(preg_match('/^\d+$/',$a)){
            $t=$a;break;
        }
    }
}
echo $t;

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

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.