Saflık numaraları


27

Bugün bir dizi bakacağız a Collatz fonksiyonu ile ilgili, f :

görüntü tanımını buraya girin

Bu şekilde bir dizi arama (f (Z)), f ... z, f (z), bir Collatz sekansı .

İlk rakam eden sekans, bir (1) , bir 0 . Tekrarlanan uygulaması altında f , bu bir kısır döngü içine düşer 0 → 0 → ...

Henüz görmediğimiz en küçük sayı 1, bir (2) = 1 yapıyor . Tekrarlanan uygulaması altında f , bu bir kısır döngü içine düşer 1 → 4 → 2 → 1 → ...

Şimdi yukarıdaki sayıdaki 2 sayısını gördük , bu yüzden sonraki en küçük sayı bir (3) = 3 , 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 → 4 → 2 → 1 döngüsüne düşüyor. →…

Yukarıdaki tüm döngülerde zaten 4 ve 5'i gördük , bu yüzden bir sonraki sayı bir (4) = 6 .

Şimdiye dek fikri anlamalısın. a (n) , tüm a (1),…, a (n - 1) için herhangi bir Collatz sekansının parçası olmayan en küçük sayıdır .

Bir pozitif tamsayı verilen, bir program ya da işlev Yazın , n , döner bir (N) . Bayt cinsinden en kısa kod kazanır.


testcases:

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

(Bu, OEIS dizisi A061641'dir .)


1
Zorunlu OEIS
FryAmTheEggman

3
Giriş n0 tabanlı olabilir mi?
Luis Mendo,

a(n+1) = a(n) odd: 3*a(n)+1, or a(n) even: a(n)/2
Karl Napf

@LuisMendo Üzgünüz, mesajınızı bir şekilde özledim. Hayır, dizideki gibi kesin diziyi yeniden oluşturun.
orlp

a0 tabanlı değilse , neden burada "0 tabanlı" konuşuyormuş gibi göründüğünüzü anlamıyorum:a(n) is the smallest number that was not part of any Collatz sequences for all a(0), …, a(n − 1).
daniero

Yanıtlar:


5

Jöle , 20 19 bayt

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

Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Nasıl çalışır

Ç¡Ṫ              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.

Sonra n- yineleme, değeri bir (n + 1) dizisinin başında olacaktır. Yeni diziyi eskisinin ters kopyası ile birleştirdiğimizden, bu sonuçta bir (n) olacağı anlamına gelir .


9

Haskell, 93 92 bayt

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

Kullanım örneği: ([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!) 10-> 19.

c xCollatz için xbiraz hile ile döngüsü x == 1. Ana fonksiyonlar tüm tamsayılar döngüsü ve içinde olmayanlar da tutar c xiçin xde [0..y-1]. Hemen hemen tanımın doğrudan bir uygulaması. Haskell index operatörü !!0 tabanlı olduğundan, endeksi -1düzeltmek için (aksi takdirde işe yaramaz) bir numara hazırlamaya başlıyorum .


4

MATL , 46 40 bayt

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

Çevrimiçi deneyin!

açıklama

Kod, her yinelemede olmak üzere Collatz dizileri forüreten bir dış döngüye sahiptir n. Her dizi, do...whileyeni değerleri hesaplayan ve a veya elde edilinceye kadar bir dizi vektöründe saklayan bir iç döngü tarafından üretilir . Dizi ile işimiz bittiğinde, vektör tersine çevrilir ve önceki tüm dizilerin değerlerini içeren global bir vektöre birleştirilir . Bu vektör tekrarlanan değerler içerebilir. Dizi vektörünün tersine çevrilmesi, dış döngünün sonunda istenen sonucun (son dizinin başlangıç ​​değeri) global vektörün sonunda olmasını sağlar.10

Sözde kod :

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

Yorumlanan kod :

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 bayt

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'ün tüm katlarının saf olması gerçeğinden yararlanır . İdeone üzerinde test et .

Nasıl çalışır

İlk satırda s = {-1} (set) ve r = -1 olarakr,=s={-1} ayarlar .

Daha sonra STDIN'den bir tamsayı okuduk, belli bir dizgiyi birçok kez tekrar ettikten sonra çalıştırdık. Bu, aşağıdaki Python koduna eşdeğerdir.

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]

Her yinelemede, s'ye ait olmayan en küçük {r + 1, r + 2, r + 3} üyesini bularak başlarız . İlk tekrarda, bu r'yi 0 olarak başlatır .

Takip eden tüm çalışmalarda, s'nin r + 1 , r + 2 ve r + 3'ten bazılarını içerebilir (ve olacaktır) , ancak bunların hiçbiri hepsini içermez , çünkü 3'ün katları saftır. Bu ifadeyi doğrulamak için, hiçbir çoklu olduğunu gözlemlemek m arasında 3 formunun olduğu 3k + 1 . Bu da 2 metreyi , 3'ün katı olan tek ön görüntü olarak bırakır . Bu nedenle, m daha az olan herhangi bir sayı Collatz sekansında görünemez m ve dolayısıyla saftır.

Belirledikten sonra r ve başlatma n , biz Collatz fonksiyonu uygulamak n=(n/2,3*n+1)[n%2]her ara değer eklenmesi, n grubu ile ler ile s|={n}. Zaten s'de bulunan bir n sayısıyla karşılaştığımızda , boş bir set elde edilir ve yineleme durur.{n}-s

Son değer r sekansının istenen elemanıdır.


1
Buna eklemek için, 3'ün tüm katlarının saf olduğuna dair bir kanıt. Herhangi bir Collatz dizisi modulo 3'e bakın. 3x + 1 kuralının herhangi bir uygulamasından sonra, modulo 1'dir. X / 2 kuralının uygulanmasından sonra, mod 1 2 olur ve mod 2 1 olur. başlangıç ​​değeri zaten yarıya alınmış 3'ün büyük bir katı değilse, Ancak bunlar henüz üretilmemiş daha büyük değerlerdir, bu nedenle n = 0 (mod 3) => n saftır.
orlp


1

Java, 148 bayt

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

Ideone! (Uyarı: sıfır optimizasyon nedeniyle üssel karmaşıklık.)

Bir do...whiledöngüden bir döngüye dönüştürmek daha forgolfcü olurdu, ancak bunu yapmakta zorlanıyorum.

Golf tavsiyesi her zamanki gibi açıktır.


Değiştirerek Pek, ama sen golf 1 bayt kapalı for(b=1,i=1;i<n;i++)etmek for(b=1,i=0;++i<n;). Btw, neden ideonunuzun 50 için test davasını kaybettiğini anlıyorum, ancak neden 10'u da kaçırıyor? Sorunsuz bir şekilde halledebilir.
Kevin Cruijssen

@KevinCruijssen Çünkü biçimlendirme kötü olacak.
Sızdıran Rahibe,

En iyi gelişme değil ama çok fazla zaman 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;}
harcamamıştım

1

Perl6, 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 cevabı dayanarak . Perl6 sözdizimi Perl5 sözdiziminden daha az bağışlayıcı olduğundan biraz daha uzun, ama şimdilik bununla ilgileneceğim.


0

PHP, 233 124 bayt

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

İşlev için +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 bayt

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

Bu oldukça basit bir çözüm. Collatz işlevini değişkene tekrar tekrar uygular ve değerin görüldüğü $adizide saklanır @c, ardından 0 veya 1 değerine ulaştıktan sonra, henüz görülmemiş $abir sayı olana kadar artar . Bu, giriş eksi 2'ye eşit sayıda tekrarlanır ve son olarak değeri $açıkarılır.


0

Mathematica, 134 bayt

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)

Daha kolay okunur format:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.