Прем'єр-гра Конвей


18

Зокрема, PRIMEGAME Conway .

Це алгоритм, розроблений Джоном Х. Конвеєм для створення простих чисел, використовуючи послідовність 14 раціональних чисел:

 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

Наприклад, F - частка 77/29.

Отже ось як алгоритм знаходить прості числа. Починаючи з числа 2, знайдіть перший запис у послідовності, який при множенні разом утворює ціле число. Ось це M, 15/2, яка виробляє 15. Потім для цього цілого числа 15знайдіть перший запис у послідовності, який при множенні виробляє ціле число. Це останній N, або 55/1, що дає 825. Запишіть відповідну послідовність. (Проникливий серед вас може визнати це програмою FRACTRAN .)

Після деяких ітерацій ви отримаєте наступне:

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

Зауважте, що останнім переліченим пунктом є 4, або 2^2. Ось наше перше просте число ( 2показник), що генерується за допомогою цього алгоритму! Врешті-решт послідовність буде виглядати наступним чином:

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

Таким чином, даючи прості числа. Це OEIS A007542 .

Змагання

З огляду на номер введення n, або нульовий, або одноіндексований (на ваш вибір), або виведіть перші nномери цієї послідовності, або виведіть nчисло номер цієї послідовності.

Приклади

Наведені нижче приклади виводять n- nй член нульової індексації послідовності.

 n   output
 5   2275
19   4
40   408

Правила

  • Якщо можливо, ви можете припустити, що введення / вихід відповідатиме вашому рідному типу Integer.
  • Введення та вихід можуть бути надані будь-яким зручним методом .
  • Прийнятна або повна програма, або функція. Якщо функція, ви можете повернути вихід, а не надрукувати його.
  • Стандартні лазівки заборонені.
  • Це тому застосовуються всі звичайні правила гольфу, і найкоротший код (у байтах) виграє.

11
Можливо , прем’єрна гра Конвея буде більш описовою назвою для цього виклику, ніж Let’s Play a Game . Це полегшило б знайти цю проблему в майбутньому.
Лінн

Чи може вихід бути поплавком? 408.0замість, 408наприклад.
ділнан

На жаль, у нас немає (канонічного) виклику "Тлумачення фрактран". Той, що знаходиться у стеку Overflow , заблокований.
користувач202729

@dylnan Звичайно, це добре.
AdmBorkBork

Відповіді:


5

Python 3 , 173 165 153 145 144 136 135 127 126 125 108 107 104 байт

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]

Спробуйте в Інтернеті!

  • -30 байт завдяки Джонатану Фреху!
  • -3 байти завдяки Лінн!

2>>n*2є 2для n==0і в 0іншому випадку.

103 байти, якщо ми можемо повернути плавці.


Використання Python 2; 153 байт .
Джонатан Фрех

@JonathanFrech Холодний, приємний трюк. Спасибі!
ділнан

1
Перебування в Python 3, 146 байт !
Джонатан Фрех


Ще раз дякую, ти зробив більше, ніж я зараз!
ділнан

5

FRACTRAN , 99 байт

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

Спробуйте в Інтернеті!

Програма приймає 2*31^nяк вхід, який використовується як початковий стан.

Усі фракції в початковій програмі FRACTRAN були розділені на 31 (перший невикористаний основний регістр), тому програма зупиняється на n-й ітерації.


Хитра відповідь. ;-)
AdmBorkBork


3

Python 3 , 107 байт

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

Спробуйте в Інтернеті!

Зашифровує список дробів, використовуючи zipдва бітестрінги, що містять недруковані символи з низьким вмістом ASCII.

Якщо nдорівнює нулю, повертаємо аргумент k; інакше ми повторюємо нові параметри. Наше нове k- це перше значення, яке k*a//bвідповідає деякому дробу (a, b)в списку, таке, що k*a//bє цілим числом, тобто k*a%b<1.



2

J , 116 110 байт

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

Спробуйте в Інтернеті!

0-індексований; повертає n-е число

Деякі байти можна зберегти, зробивши дієслово мовчазним, але у мене проблеми з ^:роботою.

Пояснення:

J описує раціональні числа у формі NrD, де N - це чисельник, а D - знаменник, наприклад, 17r91 78r85 19r51 23r38...я створив 2 окремі списки для чисельників і знаменників і зробив з них 2 базових-96 чисел.

1047856500267924709512946135x%&(96#.inv])5405040820893044303890643137x перетворює базові числа-96 в списки і будує список дробів шляхом поділу двох списків.

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

2 почніть з 2

^:yповторіть дієслово в лівому nчасі (y - аргумент функції)

] правильний аргумент (починається з 2, а потім використовує результат кожної ітерації)

* перемножити список дробів на правильний аргумент

(=<.) ціле число результатів (порівняйте кожне число з його рівнем)

{.@I.@знаходить індекс I.першого {.з цілих чисел

{[ використовує індекс для отримання числа


1
62 байти:('0m26<l~l *,..V'%&(31x-~3&u:)'ztRE@<620,*-! ')&(0{*#~0=1|*)2:
миль

@miles Спасибі, я думаю, ви повинні розмістити своє рішення, це краще, ніж моє.
Гален Іванов

2

05AB1E ,  44  43 байт

0-індексований

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

Спробуйте в Інтернеті!

Пояснення

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

Велика кількість штовхнуто є 17781923297795770111131515559185513833292319171311140201



1

JavaScript (Node.js) , 106 95 байт

  • завдяки @Arnauld та @Neil за зменшення на 11 байт
(n,N=2,I=13,B=Buffer(`[U3&!\rNM_M\r7`))=>n--?f(n,N/B.find(x=>N%x<!!++I)*B[I]):N

Спробуйте в Інтернеті!


Вдалося вичавити пару байтів, але не можу не думати, що я щось пропускаю: Спробуйте в Інтернеті!
Ніл

1
@Neil Немає необхідності використовувати оператор розповсюдження Buffer. Крім того, я думаю, що безпечно розміщувати всі дані в одному буфері: 95 байт .
Арнольд

@Arnauld ОП використовував оператор розповсюдження (я не знайомий з Buffer, тому я не знав нічого кращого), але це чудовий крок з одним буфером!
Ніл

@Arnauld правильний, оновлений :)
DanielIndie

1

Сітківка , 213 байт

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

Спробуйте в Інтернеті! Пояснення:

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

Перетворіть ціле число в десятковий і виведіть результат.


1

Attache , 81 байт

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

Спробуйте в Інтернеті! Виводить дріб більше 1. Наприклад, вхід 5повертається 2275/1. Це можна виправити плюс 2 байти, попередньо додавши N@до програми.

Пояснення

Це curried функція, яка curries Nest з двома заздалегідь заданими аргументами:

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

і 2. Цей останній аргумент є просто початковим початком, і аргумент, який передається цій функції, - це кількість повторень для введення даної функції.

Для кодування PRIMEGAME використовується наступне:

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

Це оцінюється як таке:

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)]

Замінимо цей вираз на Gу поясненні. Нашою першою функцією стає:

{Find[Integral,_*G]}

Це виконує єдину ітерацію коду FRACTRAN _, вхід до функції. Це Findів в Integralелемент (один , який являє собою ціле число) масив _*G, який є вхідним _множиться з кожним членом G.Nestпросто застосовує це перетворення задану кількість разів.

Attache, 42 байти

Я реалізував частини $langsбібліотеки, надихаючись цим викликом, тому відзначаю цей розділ неконкурентним.

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

Це просто запитує список у FRACTRAN_EXAMPLESмене. Кожен приклад - це FractranExampleекземпляр, який викликає вбудовану FRACTRANфункцію. primeПриклад PRIMEGAME Конвея.



0

PHP, 183 байти (189 з тегом "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;

Безголовки:

<?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;

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.