Özyinelemeli Collatz Conjecture


21

Collatz varsayım Eğer herhangi bir olumlu tamsayı almak, o zaman aşağıdaki algoritma yeterli kez tekrar o varsayımları:

if number is odd, then multiply by three and add one
if number is even, then divide by two

sonunda 1'de sona ereceksin. Her zaman işe yarıyor gibi gözüküyor, ama asla her zaman işe yaradığı ispatlanmadı.

Zaten 1'e ne kadar zaman alacağını hesaplamak için golf oynadın , bu yüzden işleri biraz değiştiririm diye düşündüm.

Belirli bir pozitif tamsayı ile başlayarak, 1'e ("durma süresi") ne kadar süre alacağını hesaplayın. O zaman bu numaranın durma zamanını bulun .

1 olana kadar veya 100 yinelemenin tamamen isteğe bağlı sınırına ulaşana kadar tekrarlayın. Eski durumda, kaç tane yineleme yaptığını yazdırın. İkinci durumda, bir tamsayı olmadığı sürece, "Başarısız" veya seçtiğiniz bir başka tutarlı çıktıyı yazdırın 1≤n≤100. Bu seçenek için boş bir dize çıkarmayabilirsiniz. Bununla birlikte, aralığın dışındaki bir tamsayı çıktısına [1, 100] izin verilir.

Örnekler:

Input: 2
2->1
Output: 1

Input: 5
5->5->5->5->5->...
Output: Fail

Input: 10
10->6->8->3->7->16->4->2->1
Output: 8

Input: 100
100->25->23->15->17->12->9->19->20->7->16->4->2->1
Output: 13

Input: 10^100
10^100->684->126->108->113->12->9->19->20->7->16->4->2->1
Output: 13

Input: 12345678901234567890
12345678901234567890->286->104->12->9->19->20->7->16->4->2->1
Output: 11

Input: 1
--Depending on your code, one of two things may happen. Both are valid for the purposes of this question.
1
Output: 0
--Or:
1->3->7->16->4->2->1
Output: 6

Ben hesaplandığı gibi 10^100ve 12345678901234567890dil o farklı sonuçlar alabilirsiniz daha doğru ise sadece, söz konusu boyutta real destekleyen bir dil kullanarak.

puanlama

Bu olduğu için, en kısa bayt sayısına sahip olan cevap kazanır.


Yanıtlar:




6

Ataşesi , 40 bayt

`-&3@`#@PeriodicSteps[CollatzSize@Max&1]

Çevrimiçi deneyin!

Bu yaptığım yeni bir dil. Düzgün bir giriş dili yapmak için etrafta dolaşmak istedim ve sonuç şu: matematiği bozma. Yaşasın?

açıklama

Bu birkaç fonksiyonun bileşimidir. Bu işlevler:

  • PeriodicSteps[CollatzSize@Max&1]Bu, sonuçlar yinelenen bir öğe içerene kadar argümanını uygulayan bir işlev sunar. Bu fonksiyon, CollatzSize@Max&1, uyguladığı CollatzSizegiriş büyük ve 1geçersiz giriş önlemek için, 0CollatSize için.
  • `#alıntı bir operatördür; tek taraflı olarak bu anlamda uygulandığında, argümanının boyutunu alır.
  • `-&3argümanı "eksi 3" olarak okuyan 3fonksiyona bağlayan bir bağlı fonksiyondur `-. Bunun nedeni PeriodicSteps uygulamasının 0hesaba katılması gereken s verimidir. (Aynı zamanda 5, hangi haritaya eşleştirileceği gibi sayıları da dışarıda tutar -1.)

1
Kendi dilini kullanmana gerçekten izin var mı? Sadece her bayt için sadece bir kaç bayt kullanan bir kordon oluşturabilir misiniz?
Tweakimp

2
@Tweakimp Elbette kendi dilinizi yaratmanıza (ve kullanmanıza) izin verilir. Ancak bir görevi tek bir komut olacak şekilde değiştirmek (zorluk gönderildikten sonra) standart bir boşluktur.
caird coinheringaahing

2
@Tweakimp daha iyi hissettiriyorsa, bu zorluğu görmeden önce bu işlevi tasarlamıştım. Ben bir dil tasarımcısıyım, yani yaptığım şey bu.
Conor O'Brien,

Kendi dillerini kullanmana izin veren olumsuz bir ifade değil, kişisel dillere izin verilip verilmeyeceği daha genel bir soruydu.
Tweakimp

4

J , 49 45 bayt

Buraya @ randomra'dan yapılan yorumdan daha kısa Collatz Dizi kodu sayesinde -4 byte .

(2-~[:#(>&1*-:+2&|*+:+>:@-:)^:a:)^:(<101)i.1:

101Geçersiz sonuçlar için çıktılar .

Çevrimiçi deneyin!

açıklama

Şaşırtıcı olmayan bir şekilde, bu açıklama hızla eski hale geldi. Aşağıda verdiğim eski 49 baytlık cevap ile bırakacağım. Bir güncelleme istiyorsanız, sadece bana bildirin. Özyinelemeli dizinin uzunluğunu bulma şekli aynı kalır, sadece daha kısa bir Collatz Dizisi yöntemi kullandım.

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)^:(<101)i.1:

Collatz Dizisinin uzunluğunu bulma

Kodun bu bölümü aşağıdaki gibidir

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)

İşte açıklama:

(1 -~ [: # %&2`(1+3&*)@.(2&|) ^: (1&<) ^: a:)  Given an input n
                                       ^: a:   Apply until convergence, collecting
                                                each result in an array.
                              ^: (1&<)         If n > 1 do the following, else
                                                return n.
                        (2&|)                  Take n mod 2.
           %&2                                 If n mod 2 == 0, divide by 2.
               (1+3&*)                         If n mod 2 == 1, multiply by 3 
                                                and add 1.
         #                                     Get the length of the resulting
                                                array.
 1 -~                                          Subtract 1.

Ne yazık ki, ^:sonuçları saklamak için söylendiğinde uygulanan fiil ( ), ilk değeri de depolar, bu nedenle (her zaman olduğu gibi) tek tek olduğumuz anlamına gelir. Bu yüzden neden 1'i çıkardık.

Özyinelemeli dizinin uzunluğunu bulma

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:) ^: (< 101) i. 1:  Given an input n.
                                      ^: (< 101)        Apply 100 times,
                                                         collecting results
                                                         in an array.
(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)                   Collatz sequence length.
                                                 i. 1:  Index of first 1 (returns
                                                         101, the length of the
                                                         array if 1 not found).

1
Başlık bölümünü kullanmak sakıncası yoksa, bu belki de cevabınızı daha doğru bir şekilde gösterir
Conor O'Brien

@ ConorO'Brien Hiç bilmiyorum - bu şekilde nasıl biçimlendirileceğini gerçekten bilmiyordum (ama bundan sonra seninkini çalıyorum). Teşekkürler
cole

1
Bir n y t, i e m!
Conor O'Brien,

1
38 bayt ile *i.~(<101)1&(#@}.a:2&(<*|{%~,*+1+])])]eşdeğer olmalıdır
mil


3

JavaScript (ES6), 57 bayt

İade truebaşarısız olduğunda. İade 0için 1.

f=(n,k=i=0)=>n>1?f(n&1?n*3+1:n/2,k+1):k?i>99||f(k,!++i):i

Test durumları


Eğer programınız taşma / yanlışlık dışında doğru sonucu hesaplarsa ya da OP sonuçları benzer sayıda uygulamalı bir dil kullanarak elde edilmişse şüphelenirim (sanırım tüm sınav durumlarını el ile hesaplamadıklarını sanıyorum).
Jonathan Frech

@JonathanFrech Gerçekten. Her iki sonucun da eşit olmadığı ortaya çıktı.
Arnauld

3

APL (Dyalog Unicode) , 39 60 53 52 49 bayt

@Ngn sayesinde -3 bayt

0∘{99<⍺:⋄1=⍵:01+(⍺+1)∇{1=⍵:01+∇⊃⍵⌽0 1+.5 3×⍵}⍵}

Çevrimiçi deneyin!

Collatz için @ngn kodunu kullanır, ancak önceden @ Uriel'in kodunu kullandı.

İşte şartnameye uymayan eski sürüm:

{1=⍵:01+∇{1=⍵:02|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}⍵}

2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2->1+∇⊃⍵⌽0 1+.5 3×⍵
ngn


2

Kabuğu , 21 bayt

←€1↑101¡ȯ←€1¡?½o→*3¦2

Çevrimiçi deneyin! İade -1başarısızlık üzerine, 0girişi 1.

açıklama

←€1↑101¡ȯ←€1¡?½o→*3¦2  Implicit input (a number).
             ?½o→*3¦2  Collatz function:
             ?     ¦2   if divisible by 2,
              ½         then halve,
               o→*3     else multiply by 3 and increment.
        ȯ←€1¡?½o→*3¦2  Count Collatz steps:
            ¡           iterate Collatz function and collect results in infinite list,
          €1            get 1-based index of 1,
        ȯ←              decrement.
       ¡               Iterate this function on input,
   ↑101                take first 101 values (initial value and 100 iterations),
←€1                    get index of 1 and decrement.


2

Temiz , 146 ... 86 bayt

Ørjan Johansen sayesinde -11 bayt

import StdEnv
?f l n=hd[u\\1<-iterate f n&u<-l]

?(?(\b|isOdd b=3*b+1=b/2)[0..])[0..99]

Kısmi bir işlev olarak değişmez.

Çevrimiçi deneyin!

hd of []Yineleme sayısı 100'ü aşarsa, iptal eder . Daha büyük bir yığın boyutu belirtmezseniz, yukarıdaki ~ girişleri
ile çıkar .Heap Full2^23


1
Temiz sözdizimini (Haskell'den farklı olarak) cevaplarınızdan anlamaya başladım ... bunu bir yardımcı fonksiyonla kısaltabilirsiniz j f l n=hd[u\\1<-iterate f n&u<-l].
Ørjan Johansen

@ ØrjanJohansen Teşekkürler!
Büyük

\a=...aParçaya ihtiyacın yok , köri. (Veya eta azalır.)
Ørjan Johansen

@ ØrjanJohansen oh, bunu özledim, teşekkürler!
Büyük

1

Python 2 , 99 98 97 bayt

  • Kullanarak bir byte Kaydedilen c and t or fyerine t if c else f.
  • Kesintisiz girişler -1yerine fveya çıkışsız olarak bir bayt kaydedildi 'f'.
exec"f,F="+"lambda n,i=0:n<2and i or %s"*2%("f([n/2,3*n+1][n%2],-~i),","i>99and-1or F(f(n),-~i)")

Çevrimiçi deneyin!


1

BiwaScheme , 151 karakter

(define(f n i s)(if(= s 0) 'F(if(= n 0)i(f(letrec((c(lambda(m k)(if(= m 1)k(c(if(=(mod m 2)0)(/ m 2)(+(* m 3)1))(+ k 1))))))(c n 0))(+ i 1)(- s 1)))))

Burada deneyebilirsiniz .


1

R , 119 107 bayt

Kısmen buradan Jarko Dubbeldam'ın collatz kodunu kullanıyor . İade 0> 100 tekrarlamalar (başarısızlık) için.

pryr::f(x,{N=n=0
while(x-1){while(x-1){x=`if`(x%%2,3*x+1,x/2);n=n+1}
x=n
n=0
N=N+1
if(N==100)return(0)}
N})

Çevrimiçi deneyin!


1

APL NARS, 115 bayt, 63 karakter

{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}

Muhtemelen döngüler kullanıldığında daha açık olacaktır ... 4 fonksiyon vardır, 2 iç içe ve ricorsive ve ilk sadece 2. değişkenden global değişken sayacı olarak görülen d değişkeni = 0 olarak tanımlanır ve ilklendirilir.

q←{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}

Bu 3'üncü işlev, Collatz varsayımını argümanına göre çözmek için kaç çağrı yapıldığını gösteren işlev olacaktır.

{⍵=1:d⋄99<d+←1:¯1⋄∇q⍵}

Bu, 2. fonksiyondur, eğer arg = 1 ise, özyinelemeyi durdur ve d 'e kendi adı verilen süreyi döndür; eğer kendisi 99 defadan daha fazla denirse özyinelemeyi durdurur ve -1 (başarısız) ile döner, aksi halde argümanına göre Collatz varsayımını hesaplar ve kendisini Collatz sıra uzunluğu değeri için çağırır. Programcı sadece yerel bir değişken olarak gördüğünde, benim için bütün bunlar koşulu görünse bile, aynı değişkende global bir değişken ve bir değişkende tanımlanmışsa büyük bir problem olabilir.

  f←{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}     
  f 2
1
  f 3
5
  f 5
¯1
  f 10
8
  f 100
13
  f 12313
7
  f 1
0

1

(Emacs, Common, ...) Lisp, 105 bayt

100 yineleme için döndürür

(defun f(n k c)(or(> c 100)(if(= n 1)(if(= k 0)c(f k 0(1+ c)))(f(if(oddp
n)(+ n n n 1)(/ n 2))(1+ k)c))))

Expanded:

(defun f (n k c)
  (or (> c 100)
      (if (= n 1)
          (if (= k 0) c
            (f k 0 (1+ c)))
        (f (if (oddp n) (+ n n n 1) (/ n 2))
           (1+ k) c))))
(f (read) 0 0)
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.