Числа чистоти


27

Сьогодні ми розглянемо послідовність a , пов'язану з функцією Collatz f :

введіть тут опис зображення

Ми називаємо послідовність виду г, ф (г), F (F (Z)), ... в послідовності Коллатц .

Перше число в нашій послідовності, (1) , дорівнює 0 . При повторному застосуванні f вона потрапляє в цикл 0 → 0 →…

Найменше число, якого ми ще не бачили, - це 1, що складає (2) = 1 . При повторному застосуванні f вона потрапляє в цикл 1 → 4 → 2 → 1 →…

Тепер ми побачили число 2 у циклі вище, тому наступне найменше число - це (3) = 3 , потрапляючи в цикл 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 → 4 → 2 → 1 →…

У всіх вище циклах ми вже бачили 4 і 5 , тому наступне число - це (4) = 6 .

На даний момент ви повинні отримати ідею. a (n) - найменше число, яке не входило до жодної послідовності Колатца для всіх a (1),…, a (n - 1) .

Напишіть програму або функцію, яка за заданим цілим числом n повертає a (n) . Найкоротший код у байтах виграє.


Тести:

1  -> 0
2  -> 1
3  -> 3
4  -> 6
5  -> 7
6  -> 9
7  -> 12
8  -> 15
9  -> 18
10 -> 19
50 -> 114

(Це послідовність OEIS A061641 .)


1
Обов’язковий OEIS
FryAmTheEggman

3
Чи може вхід nбазуватися на 0?
Луїс Мендо

a(n+1) = a(n) odd: 3*a(n)+1, or a(n) even: a(n)/2
Карл Напф

@LuisMendo Вибачте, я якось пропустив ваше повідомлення. Ні, відтворюйте точну послідовність, як у виклику.
orlp

Якщо aнемає на основі 0, я не розумію, чому ви, здається, тут "розмовляєте на базі 0":a(n) is the smallest number that was not part of any Collatz sequences for all a(0), …, a(n − 1).
Даніеро

Відповіді:


5

Желе , 20 19 байт

ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ
Ç¡Ṫ

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

Ç¡Ṫ              Main link. No explicit arguments. Default argument: 0
 ¡               Read an integer n from STDIN and do the following n times.
Ç                  Call the helper link.
  Ṫ              Tail; extract the last element of the resulting array.


ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ  Helper link. Argument: A (array)

  J              Yield all 1-based indices of A, i.e., [1, ..., len(A)]. Since 0
                 belongs to A, there is at least one index that does belong to A.
ḟ@               Filter-false swapped; remove all indices that belong to A.
   Ḣ             Head; extract the first index (i) that hasn't been removed.
           ÐĿ    Call the quicklink to the left on i, then until the results are no
                 longer unique. Collect all unique results in an array.
         Ḃ?      If the last bit of the return value (r) is 1:
       $           Apply the monadic 3-link chain to the left to r.
    ×3‘              Yield 3r + 1.
        H        Else, halve r.
              Ṛ  Yield A, reversed.
             ;   Concatenate the results array with reversed A.

Після n ітерацій значення a (n + 1) буде на початку масиву. Оскільки ми з'єднуємо новий масив із зворотною копією старого, це означає, що a (n) буде в кінці.


9

Haskell, 93 92 байт

c x|x<2=[[0,2]!!x]|odd x=x:c(3*x+1)|1<2=x:c(div x 2)
([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!)

Приклад використання: ([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!) 10-> 19.

c x- це цикл Колатца, який xмає трохи обману x == 1. Основні функції перебирає всі цілі числа і зберігає ті, які не c xдля xв [0..y-1]. Насправді пряма реалізація цього визначення. Оскільки оператор індексу Haskell !!базується на 0, я починаю -1вводити номер (інакше марний), щоб фіксувати індекс.


4

MATL , 46 40 байт

Oiq:"tX>Q:yX-X<`t0)to?3*Q}2/]h5M1>]Pv]0)

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

Пояснення

Код має зовнішню forпетлю, яка генерує nпослідовності Collatz, по одному в кожній ітерації. Кожна послідовність породжується внутрішнім do...whileконтуром , який не вирахував нові значення і зберігає їх в векторної послідовності доти , 1або 0виходить. Коли ми закінчимо послідовність, вектор обертається і приєднується до глобального вектора, який містить значення з усіх попередніх послідовностей. Цей вектор може містити повторювані значення. Зворотний вектор послідовності забезпечує, що в кінці зовнішньої петлі бажаний результат (початкове значення останньої послідовності) буде в кінці глобального вектора.

Псевдокод :

1  Initiallization
2  Generate n sequences (for loop):
3    Compute initial value for the k-th sequence
4    Generate the k-th sequence (do...while loop)
5      Starting from latest value so far, apply the Collatz algorithm to get next value
6      Update sequence with new value 
7      Check if we are done. If so, exit loop. We have the k-th sequence
8    Update vector of seen values
9  We now have the n sequences. Get final result

Коментований код :

O           % Push 0                                                          1
iq:         % Input n. Generate [1 2 ... n-1]                                 ·
"           % For loop: repeat n-1 times. Let k denote each iteration         2
  t         %   Duplicate vector of all seen values                           · 3
  X>Q       %   Take maximum, add 1                                           · ·
  :         %   Range from 1 to that: these are potential initial values      · ·
  y         %   Duplicate vector of all seen values                           · ·
  X-X<      %   Set difference, minimum: first value not seen                 · ·
  `         %   Do...while: this generates the k-th Collatz sequence          · 4
    t0)     %     Duplicate, push last value of the sequence so far           · · 5
    to      %     Duplicate, parity: 1 if odd, 0 if even                      · · ·
    ?       %     If odd                                                      · · ·
      3*Q   %       Times 3, plus 1                                           · · ·
    }       %     Else                                                        · · ·
      2/    %       Half                                                      · · ·
    ]       %     End if                                                      · · ·
    h       %     Concatenate new value of the sequence                       · · 6
    5M      %     Push the new value again                                    · · 7
    1>      %     Does it exceed 1? This is the loop condition                · · ·
  ]         %   End do...while. The loops ends when we have reached 0 or 1    · ·
  P         %   Reverse the k-th Collatz sequence                             · 8
  v         %   Concatenate with vector of previously seen values             · ·
]           % End for                                                         ·
0)          % Take last value. Implicitly display.                            9


3

Python 2, 97 96 байт

r,=s={-1}
exec'n=r=min({r+1,r+2,r+3}-s)\nwhile{n}-s:s|={n};n=(n/2,3*n+1)[n%2]\n'*input()
print r

Користується тим, що всі кратні 3 є чистими. Перевірте це на Ideone .

Як це працює

На першому рядку, r,=s={-1}встановлює S = {-1} (безліч) і г = -1 .

Далі ми читаємо ціле число з STDIN, повторюємо певний рядок, який багато разів, а потім виконуємо його. Це еквівалентно наступному коду Python.

for _ in range(input())
    n=r=min({r+1,r+2,r+3}-s)
    while{n}-s:
        s|={n}
        n=(n/2,3*n+1)[n%2]

У кожній ітерації ми починаємо з пошуку найменшого члена {r + 1, r + 2, r + 3} , який не належить до s . У першій ітерації це ініціалізує r як 0 .

У всіх наступних запусках s може містити деякі r + 1 , r + 2 і r + 3 , але ніколи не всі, оскільки всі кратні 3 є чистими. Щоб перевірити це твердження, зауважимо , що не кратне т з 3 не має вид 3k + 1 . Це залишає 2 м як єдине можливе попереднє зображення, яке також є кратним 3 . Таким чином, m не може відображатись у послідовності Колатца жодного числа, меншого від m , і тому є чистим.

Після ідентифікації r та ініціалізації n ми застосовуємо функцію Collatz з n=(n/2,3*n+1)[n%2], додаючи кожне проміжне значення n до набору s з s|={n}. Як тільки ми зустрінемо число n, яке вже знаходиться в s , {n}-sвийде порожній набір, і ітерація припиниться.

Останнє значення r - бажаний елемент послідовності.


1
Додамо до цього доказ того, що всі кратні 3 є чистими. Подивіться на будь-який модуль послідовності Collatz 3. Після будь-якого застосування правила 3x + 1 модуль дорівнює 1. Після застосування правила x / 2 mod 1 стає 2, а mod 2 стає 1. Жодне правило не може генерувати множину 3, якщо початкове значення вже не було кратним кратним 3, яке зменшилося вдвічі. Але це більші значення ще не сформовані, тому n = 0 (mod 3) => n чисте.
orlp


1

Java, 148 байт

int a(int n){if(n<2)return 0;int f=a(n-1),b,i,c;do{f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}while(b<1);return f;}

Ідей це! (Попередження: експоненціальна складність через нульову оптимізацію.)

Перетворення його з do...whileциклу в forцикл було б гольфістом, але у мене виникають проблеми з цим.

Рада з гольфу - як завжди.


Не так багато, але ви можете перейти for(b=1,i=1;i<n;i++)на 1 байт, перейшовши на for(b=1,i=0;++i<n;). До речі, я розумію, чому вашому ідеону не вистачає тестового випадку на 50, але чому він також пропускає 10? З цим можна впоратися без проблем.
Kevin Cruijssen

@KevinCruijssen Тому що форматування було б поганим.
Leaky Nun

Не найкраще вдосконалення, але я не витратив надто багато часу ... (147 байт)int a(int n){if(n<2)return 0;int f=a(n-1),b=0,i,c;for(;b<1;){f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}return f;}
Poke

1

Перл6, 96

my @s;my $a=0;map {while ($a=@s[$a]=$a%2??3*$a+1!!$a/2)>1 {};while @s[++$a] {}},2..slurp;$a.say;

На основі відповіді Perl 5 . Трохи довше, оскільки синтаксис Perl6 менш прощає, ніж синтаксис Perl5, але я зараз вирішуся з цим.


0

PHP, 233 124 байт

<?$n=$argv[1];for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}echo$v;

+4 для функції:

function a($n){for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}return$v;}

0

Perl 5 - 74 байти

map{0 while 1<($a=$c[$a]=$a%2?$a*3+1:$a/2);0 while$c[++$a]}2..<>;print$a+0

Це досить просте рішення. Він неодноразово застосовує функцію Collatz до змінної $aі зберігає в масиві, @cщо значення було видно, потім після досягнення 0 або 1 збільшується $aдо тих пір, поки це число, яке ще не було помічено. Це повторюється кілька разів, що дорівнює входу мінус 2, і, нарешті, значення $aвиводиться.


0

Математика, 134 байти

f=If[EvenQ@#,#/2,3#+1]&;a@n_:=(b={i=c=0};While[i++<n-1,c=First[Range@Max[#+1]~Complement~#&@b];b=b~Union~NestWhileList[f,c,f@#>c&]];c)

Простіший для читання формат:

f = If[EvenQ@#, #/2, 3#+1] &;                        Collatz function
a@n_ := (                                            defines a(n)
  b = {i = c = 0};                                   initializations
                                                       b is the growing sequence
                                                       of cycles already completed
  While[i++ < n - 1,                                 computes a(n) recursively
    c = First[Range@Max[# + 1]~Complement~# & @b];   smallest number not in b
    b = b~Union~NestWhileList[f, c, f@# > c &]       apply f to c repeatedly
                                                       until the answer is smaller
                                                       than c, then add this new
                                                       cycle to b
    ]
  ; c)                                                 output final value of c
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.