Collatz Conjecture (OEIS A006577)


66

Bu, Collatz Konjeksiyonu'dur ( OEIS A006577 ):

  • N > 1 tamsayısıyla başlayın .
  • Aşağıdaki adımları tekrarlayın:
    • Eğer n bile olduğunu 2'ye bölerek.
    • Eğer n garip, 3 ile çarpın ve 1 ekleyin.

Tüm pozitif tamsayılar için en fazla olduğu kanıtlanmış 5 * 2 60 veya yaklaşık 5764000000000000000 , n sonunda olacak 1 .

Göreviniz 1'e ulaşmak için kaç tekrarlamanın (yarıya veya üçe artı bir tane) geldiğini bulmak .

İlgili xkcd :)

Kurallar:

  • En kısa kod kazanır.
  • Bir sayı <2 ise giriş veya tam sayı olmayan veya sayı olmayan bir çıkış önemli değildir.

Test durumları

2  -> 1
16 -> 4
5  -> 5
7  -> 16

Yanıtlar:



15

C - 50 47 karakter

Zavallı küçük C, ne yazık ki, temel G / Ç için çok fazla miktarda kod gerektiriyor;

b;main(a){return~-a?b++,main(a&1?3*a+1:a/2):b;}

Örneğin ile derleyin gcc -o 1 collatz.c. Giriş, boşlukla ayrılmış basamaklarla aynıdır ve cevabı çıkış kodunda bulabilirsiniz. 17 numaralı bir örnek:

$> ./1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
$> echo $?
12
$>

1
return~-a?Ayrıca hareketli 1. kaydeder b++için ?tasarruf gerektiğini durumda b--.
ugoren

Kuralları çok fazla
zorluyorsunuz

Teşekkürler ugoren! Yazarken sarhoş olmalıyım. :)
Fors

12

Perl 34 (+1) karakter

$\++,$_*=$_&1?3+1/$_:.5while$_>1}{

$\Her zamanki gibi nihai çıktı için kötüye . -pKomut satırı seçeneğiyle çalıştırın , giriş alınır stdin.

Elias Van Ootegem nedeniyle bir bayt kaydedildi . Spesifik olarak, aşağıdaki ikisinin eşdeğer olduğunu gözetleme:

$_=$_*3+1
$_*=3+1/$_

Bir bayt daha uzun olsa da, $_/2sadece kısaltarak iki bayttan tasarruf eder .5.

Örnek kullanım:

$ echo 176 | perl -p collatz.pl
18

PHP 54 bayt

<?for(;1<$n=&$argv[1];$c++)$n=$n&1?$n*3+1:$n/2;echo$c;

Javascript'in Tahta Kaşık Ödülü'nün arşivi, bu mücadelede biraz geriledi. Yine de bu sorunla yaratıcılığa pek yer yok. Giriş bir komut satırı argümanı olarak alınır.

Örnek kullanım:

$ php collatz.php 176
18

1
Eşsiz parantezlerin ne yaptığını
anlamam biraz zaman aldı

1
Tekrarlayan $_üçlü içinde savurgan görünüyor, sen kullanarak başka karakterini tıraş edebilirsiniz *=böyle: $\++,$_*=$_&1?3+1/$_:.5while$_>1}{. Çarpma 1/$_ile aynı etkiye sahiptir +1, bu yüzden $_*=3+1/$_gayet iyi çalışıyor
Elias Van Ootegem

@EliasVanOotegem $_*=3+1/$_mükemmel, teşekkürler!
primo

11

Mathematica (35)

If[#>1,#0@If[OddQ@#,3#+1,#/2]+1,0]&

Kullanımı:

If[#>1,#0[If[OddQ@#,3#+1,#/2]]+1,0]&@16
>> 4

Bu geçerli bir fonksiyon değil, 10.3 sonunda bir hayduttan yakınıyor
CalculatorFeline

@ argüman çağırıyor, neden orada olduğunu bilmiyorum, sadece hızlı bir düzenleme
mil

Dikkatli olmalısın :)
CalculatorFeline

10

Genelde yaptığım gibi, cevapları kendi başıma başlayacağım.

JavaScript, 46 44 karakter (konsolda çalıştırma)

for(n=prompt(),c=1;n>1;n=n%2?n*3+1:n/2,++c)c

Çıktının bir tamsayı olmadığının bir önemi olmadığını söylerseniz, ~~ prompt () 'nin amacı nedir? ~~ kurtularak iki karakter kaydedebilirsiniz.
Resorath

@ Resorat Ah, JS'nin otomatik dökümünü unuttu: P thanks
Doorknob

9

Java, 165, 156, 154,134,131,129,128 , 126 (ayrıntılı dillerin de biraz sevgiye ihtiyacı vardır)

class a{public static void main(String[]a){for(int x=Short.valueOf(a[0]),y=0;x>1;x=x%2<1?x/2:x*3+1,System.out.println(++y));}}

Hepsi için yapılır

for(int x=Short.valueOf(a[0]),y=0;x>1;x=x%2<1?x/2:x*3+1,System.out.println(++y))

Bu garip güzel adam. Pater Taylor'a teşekkürler !!!, ve for döngüsü kullanma fikri ugoren'den çalındı

Tamsayı Kısa için değiştirdim.


1
Uzunluğunu oldukça kolayca kaydedebilirsiniz i(,++y). Sen kullanarak iki tane daha kaydedebilirsiniz <yerine ==.
Peter Taylor

@PeterTaylor haklısın, karşılaştırmalarım <ile daha kısa olacak, ancak ön-artışın bir kısmını anlamadım
jsedano

2
İkinci üçlünüzün iki tarafı yapısal olarak özdeştir; böylece üçlüyü özyinelemeli çağrının ilk argümanına itebilirsiniz.
Peter Taylor

1
OH BENİM TANRI'NIN
ŞAHİN

2
Bunun yaklaşık 3,5 yıl oldu biliyorum ama golf o yine de 5 bayt : class a{public static void main(String[]a){for(int x=new Short(a[0]),y=0;x>1;System.out.println(++y))x=x%2<1?x/2:x*3+1;}}Yapılan değişiklikler: 1) Değiştirilen Short.valueOf(...)ile new Short(...)için -4 byte ve 2) koyduk x=x%2<1?x/2:x*3+1;gövdesinde forkurtulmak için -loop -1 bayt için virgül .
Kevin Cruijssen

9

Rebmu : 28

u[++jE1 AeEV?a[d2A][a1M3a]]j

Bu kısa ve özlü bir problemde GolfScript, Rebmu'ya karşı yüzde bir oranında kazanacak (eğer gerekli değilse, internetten dosya okuyacak veya JPG dosyaları oluşturacak). Yine de çoğu Golfscript'in mantığının takip edilmesi kolay bir yerde olmadığı ve onu çalıştıran toplam çalıştırılabilir yığının daha büyük olduğu konusunda hemfikir olacağını düşünüyorum.

Her ne kadar Rebol'ün yaratıcısı Carl Sassenrath , Rebmu'yu "okunamadığını" bulduğunu söylemesine rağmen, meşgul ve ezme yoluyla domuz-latin benzeri dönüşümü gerçekten uygulama zamanı gelmedi . Bu gerçekten sadece dönüştürülür:

u [
    ++ j
    e1 a: e ev? a [
        d2 a
    ] [
        a1 m3 a
    ]
]
j

Uzay bir almak için gerekli olduğunu unutmayın : a yerine ait a . Bu bir "kelime" dir! ve değerlendirici, bu sembol tipini atamayı tetiklemek için uyarır.

Kısaltılmamış bir şekilde yazılmışsa (ancak garip bir şekilde yazılmış Rebol),

until [
    ++ j
    1 == a: either even? a [
        divide a 2
    ] [
        add 1 multiply 3 a
    ]
 ]
 j

Rebol, Ruby gibi, blokları son değerleriyle değerlendirir. UNTIL döngüsü, herhangi bir döngü koşulu gerektirmeyen meraklı bir döngü şeklidir, bloğu YANLIŞ veya YOK olmayan bir şey olarak değerlendirildiğinde döngülemeyi durdurur. Bu nedenle, 1 ==A (rebmu argümanı) koşulunun Collatz koşuluna (ya da seçtiği dalı değerlendiren bir IF-ELSE'dir) sonucuna atanmasının sonucu ... döngü kopar.

J ve K, Rebmu'da sıfır tamsayı değerine sıfırlanır. Ve daha önce de belirtildiği gibi, her şey son değere göre değerlendirilir. Yani programın sonunda bir J referansı, yineleme sayısını aldığın anlamına gelir.

Kullanımı:

>> rebmu/args [u[++jE1 AeEV?a[d2A][a1M3a]]j] 16
== 4

8

Python temsilcisi, 48

Daha kısa bir ifade olmadığına ikna olmadım n=3*n+1;n/=1+n%2*5;. Muhtemelen aynı uzunluktaki bir düzine farklı ifadeyi buldum.

i=0
n=input()
while~-n:n=3*n+1;n/=1+n%2*5;i+=1
i

düzenleme: Ben asla mücadele etmeyecek başka bir çözüm buldum ama paylaşmak için çok eğlenceli.

s='s'
i=s
n=i*input()
while 1:
 while n==n[::2]+n[::2]:i+=s;n=n[::2]
 if n==s:i.rindex(s);break
 n=3*n+s
 i+=s

1
Beynim şimdi ağrıyor.
daniero

1
@ daniero ikinci çözüm tam size göre.
stand

Vay vay. Onur duydum!
daniero

4
(n//2,n*3+1)[n%2]daha kısa.
Evpok

1
@Evpok n/2bile bildiğimiz kadar iyi çalışmaz mı?
george

7

APL (31)

A←0⋄A⊣{2⊤⍵:1+3×⍵⋄⍵÷2}⍣{⍺=A+←1}⎕

eski cevap, henüz, 27:{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
Uriel,

1
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
ngn

7

J, 30 karakter

<:#-:`(1+3&*)`]@.(2&|+1&=)^:a:

İstenenden biraz daha uzun çıktı

kullanımı:

   <:#-:`(1+3&*)`]@.(2&|+1&=)^:a:2
1
   <:#-:`(1+3&*)`]@.(2&|+1&=)^:a:16
4
   <:#-:`(1+3&*)`]@.(2&|+1&=)^:a:5
5
   <:#-:`(1+3&*)`]@.(2&|+1&=)^:a:7
16
   <:#-:`(1+3&*)`]@.(2&|+1&=)^:a:27
111
  • -:`(1+3&*)`]üç defa kullanılan üç fiilden oluşan bir fiildir. -:"yarım" anlamına gelir (1+3&*)veya (1+3*])çarpma adımını kodlar ve ](kimlik) sonlandırmaya yardımcı olur.

  • 2&|+1&=gerund için bir dizin oluşturur. Kelimenin tam anlamıyla, "ikiye bölündükten sonra kalan artı bir tanesine eşit mi".

  • #verb^:a:işlevi, sonuç kararlı oluncaya kadar (burada açıkça zorlanır), adımları toplarken tekrar eder ve ardından bunları sayar. @JB'den çalınmış . <:Soru gereksinimlerine göre adım sayısını bir azaltır.


6
Ne zaman bir J teslimi görsem, ifadeleri sayarım. Bu seferki oldukça iyi yapar: <:, #-:, :`(, &*), =), )^:.
Primo

3
@primo nice; açıklamalarını ister misin? :-) <:"azaltma" veya "daha az veya eşit", #"" veya "n kere" sayımı, -:"yarı" veya "epsilon-eşitlik" :`(anlamına gelir; bir firada iki fiil ve bir sol parantez (gruplama için kullanılır). &*)"çarpıma bağlanmış sth" anlamına gelir (çarpma ile bağlanmış 3, "üç kez" operatörünü oluşturur) ve gruplamanın sona ermesini sağlar. =Eşitlik kontrolü veya tekdüze bir şekilde kendi kendini sınıflandırma yapar. ^:güç birleşimidir (fiil yineleme). J fiillerinin birçoğu bir kolonla sona erdiğinden, ... :-)
John Dvorak

Yıllar sonra ... Geliştirilmiş döngü bloğu: '- & 2 # (> & 1 * -: + 2 & | * +: +>: @ -:) ^: a:' -> -1 karakter. : P
rastgele

Yıllar sonra ... <:#a:2&(<*|+|6&*%~)19 bayt (-11)
mil

6

Gambit düzeni, 106 98 karakter, 40 parantez

(let((f(lambda(x)(cond((= x 1) 0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))))(f(read)))

91 89 karakterle doğrudan tanımlı

(define(f x)(cond((= x 1)0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))(f(read))


Uzun zamandır buralarda değildim, ancak insanların genellikle programlama dili başına 1 cevap yazdıklarını fark ettim.
jsedano

Üzgünüm, bunun farkında değildim :)
Valentin CLEMENT

Python'u kaldırmak için düzenlenmiştir.
Valentin CLEMENT

1
Doğru değil! İnsanlar programlama dili başına bir cevap gönderme eğilimindedirler , ancak bunun nedeni, daha kısa cevaplı bir başkasıyla doğrudan rekabet etmemeye çalışmaktır. Fakat aynı dilde farklı bir cevap gönderirseniz kimse şikayetçi olmayacak.
breadbox 19

@breadbox doğru değil. Her çözüm diğerine göre kendi başına ilginçse, her dil için bir cevap gönderirim. Her iki çözüm de her ikisi de birlikte olduğu kadar ilginçse (aynı algoritma, ilginç dil püf noktaları yok), bunları tek bir yayınladım. Normalde çoklu çözümler göndermem, çünkü önce bir dili seçerim, sonra sorunu o dilde çözerim - sonra aynı dili farklı bir dilde yazmak için çok tembelim - veya başka bir programlama öğrenmek için bir yolculuğa çıkarım dil.
John Dvorak

6

PowerShell: 77 74 71 70 61

Golf kodu:

for($i=(read-host);$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x

Notlar:

Başlangıçta bir tam sayıya zorlamadan kullanıcı girdisini almaya çalıştım, ancak bu ilginç bir şekilde kırdı. Herhangi bir garip girdi yanlış işlenir, ancak girdiler bile iyi çalışır. Neler olduğunu anlamak benim için bir dakika sürdü.

Çarpma veya toplama işlemi yaparken, PowerShell yazılmamış girişi ilk olarak bir dize olarak kabul eder. Böylece, '5'*3+116 yerine '5551' olur. Çift girişler bile iyi davranır, çünkü PowerShell dizelere karşı bölmek için varsayılan bir eylemde bulunmaz. Tek sayılarla ilerleyen çift girdiler bile iyi çalıştı, çünkü PowerShell döngüde tek bir sayıya geldiğinde değişken zaten matematik işlemleri tarafından bir tam sayıya zorlandı.

Danko Durbic'e işaret ettiği için teşekkürler , çarpma işlemini tersine çevirebildim ve read-hostPowerShell işlemlerini ilk nesneye dayandırdığı için int'e basmak zorunda kalmamıştım .

PowerShell Golfçü İpucu: Bu gibi bazı senaryolar için, switchatıyor if/else. Burada fark 2 karakterdi.

Danko Durbic'in nezaketinde bulunma : Bu özel senaryoda, switch8 karakter daha kazanmak için bir dizi kullanılabilir !

Tamsayı olmayan değerleri veya ikiden küçük olan tamsayıları kontrol ederken hata yoktur.

Komut dosyasını denetlemek istiyorsanız, komut dosyasındaki ;$ison yakın kümeden hemen önce koyun .

PowerShell'in çok büyük değerlere ilerleyen sayıları ne kadar iyi kullandığından emin değilim, ancak kesinliğin bir noktada kaybolmasını bekliyorum. Ne yazık ki, senaryoyu ciddi şekilde şişirmeden bu konuda yapılacak çok şey olmadığını da bekliyorum.


Ungolfed kod, yorumlarla:

# Start for loop to run Collatz algorithm.
# Store user input in $i.
# Run until $i reaches 1.
# Increment a counter, $x, with each run.
for($i=(read-host);$i-ne1;$x++)
{
    # New $i is defined based on an array element derived from old $i.
    $i=(
        # Array element 0 is the even numbers operation.
        ($i/2),
        # Array element 1 is the odd numbers operation.
        (3*$i+1)
    # Array element that defines the new $i is selected by $i%2.
    )[$i%2]
}

# Output $x when the loop is done.
$x

# Variable cleanup. Don't include in golfed code.
rv x,i

Test durumları:

Aşağıda, denetimin etkin olduğu bazı örnekler verilmiştir. Girdi ve son sayıya etiketler ekleyerek ve Collatz değerlerini ayırmak için boşluk bırakarak çıktıyı biraz netleştirmek için de düzenledim.

---
Input: 2

1

Steps: 1

---
Input: 16

8
4
2
1

Steps: 4

---
Input: 5

16
8
4
2
1

Steps: 5

---
Input: 7

22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1

Steps: 16

---
Input: 42

21
64
32
16
8
4
2
1

Steps: 8

---
Input: 14

7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1

Steps: 17

---
Input: 197

592
296
148
74
37
112
56
28
14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1

Steps: 26

---
Input: 31

94
47
142
71
214
107
322
161
484
242
121
364
182
91
274
137
412
206
103
310
155
466
233
700
350
175
526
263
790
395
1186
593
1780
890
445
1336
668
334
167
502
251
754
377
1132
566
283
850
425
1276
638
319
958
479
1438
719
2158
1079
3238
1619
4858
2429
7288
3644
1822
911
2734
1367
4102
2051
6154
3077
9232
4616
2308
1154
577
1732
866
433
1300
650
325
976
488
244
122
61
184
92
46
23
70
35
106
53
160
80
40
20
10
5
16
8
4
2
1

Steps: 106

---
Input: 6174

3087
9262
4631
13894
6947
20842
10421
31264
15632
7816
3908
1954
977
2932
1466
733
2200
1100
550
275
826
413
1240
620
310
155
466
233
700
350
175
526
263
790
395
1186
593
1780
890
445
1336
668
334
167
502
251
754
377
1132
566
283
850
425
1276
638
319
958
479
1438
719
2158
1079
3238
1619
4858
2429
7288
3644
1822
911
2734
1367
4102
2051
6154
3077
9232
4616
2308
1154
577
1732
866
433
1300
650
325
976
488
244
122
61
184
92
46
23
70
35
106
53
160
80
40
20
10
5
16
8
4
2
1

Steps: 111

---
Input: 8008135

24024406
12012203
36036610
18018305
54054916
27027458
13513729
40541188
20270594
10135297
30405892
15202946
7601473
22804420
11402210
5701105
17103316
8551658
4275829
12827488
6413744
3206872
1603436
801718
400859
1202578
601289
1803868
901934
450967
1352902
676451
2029354
1014677
3044032
1522016
761008
380504
190252
95126
47563
142690
71345
214036
107018
53509
160528
80264
40132
20066
10033
30100
15050
7525
22576
11288
5644
2822
1411
4234
2117
6352
3176
1588
794
397
1192
596
298
149
448
224
112
56
28
14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1

Steps: 93
---

Sorunun test durumlarında bulunmayan girdi numaraları hakkında ilginç bitler:


2
Güzel! Hala değiştirerek, biraz kısaltın olabilir switchile$i=(($i/2),($i*3+1))[$i%2]
Danko Durbić

2
Ayrıca, dönüştürmek gerekmez read-host, sadece değiştirmek - sayıya $i*3kadar 3*$i.
Danko Durbić

Anahtar yerine bir dizi? Parlak! Ve takas etme $i*3- neden bunu zaten düşünmedim?
Iszi

1
param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x- 56 bayt almak için okuma ana bilgisayarını bir parametre için değiştirin . Deneyin Online link
TessellatingHeckler

6

80386 derleme, 16 bayt

Bu örnek AT&T sözdizimini ve fastcall çağırma kuralını kullanır, argüman şöyle olur ecx:

collatz:
        or $-1,%eax              # 3 bytes, eax = -1;
.Loop:  inc %eax                 # 1 byte,  eax += 1;
        lea 1(%ecx,%ecx,2),%edx  # 4 bytes, edx = 3*ecx + 1;
        shr %ecx                 # 2 bytes, CF = ecx & 1;
                                 #          ecx /= 2;
                                 #          ZF = ecx == 0;
        cmovc %edx,%ecx          # 3 bytes, if (CF) ecx = edx;
        jnz .Loop                # 2 bytes, if (!ZF) goto .Loop;
        ret                      # 1 byte,  return (eax);

İşte 16 byte'lık makine kodu:

83 c8 ff 40 8d 54 49 01 d1 e9 0f 42 ca 75 f4 c3

6

Brachylog , 16 bayt

1b|{/₂ℕ|×₃+₁}↰+₁

Çevrimiçi deneyin!

açıklama

         Either:
  1        The input is 1.
  b        In which case we unify the output with 0 by beheading the 1
           (which removes the leading digit of the 1, and an "empty integer"
           is the same as zero).
|        Or:
  {        This inline predicate evaluates a single Collatz step on the input.
           Either:
    /₂       Divide the input by 2.
    ℕ        And ensure that the result is a natural number (which is
             equivalent to asserting that the input was even).
  |        Or:
    ×₃+₁     Multiply the input by 3 and add 1.
  }
  ↰        Recursively call the predicate on this result.
  +₁       And add one to the output of the recursive call.

Aynı byte sayısında alternatif bir çözüm:

;.{/₂ℕ|×₃+₁}ⁱ⁾1∧

Çevrimiçi deneyin!

;.          The output of this is a pair [X,I] where X is the input and
            I will be unified with the output.
{/₂ℕ|×₃+₁}  This is the Collatz step predicate we've also used above.
ⁱ⁾          We iterate this predicate I times on X. Since we haven't actually
            specified I, it is still a free variable that Brachylog can backtrack
            over and it will keep adding on iterations until the next
            constraint can be satisfied.
1           Require the result of the iteration to be 1. Once this is
            satisfied, the output variable will have been unified with
            the minimum number of iterations to get here.
∧           This AND is just used to prevent the 1 from being implicitly
            unified with the output variable as well.


5

F # - 65 karakter

let rec c n=function 1->n|i->c(n+1)(if i%2=0 then i/2 else i*3+1)

5

Python 68 58 54 52 karakter

f=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())

Bakuriu ve püf noktaları için standby sayesinde :)


n%2and 3*n+1or n/25 karakter kaydetmek için kullanabilirsiniz . Ayrıca python2'de intboyutu 58 bayta düşürerek çağrıyı kaldırabilirsiniz .
Bakuriu,

Ah, sen bile daha kısa alabilirsiniz: [n/2,3*n+1][n%2].
stant

Çok şık!
Valentin CLEMENT

Bu piton 2.7 mı? 3.5.1 bir hata alıyorum? unsupported operand type(s) for -: 'str' and 'int'
george

5

Retina , 43 bayt

11
2
(2+)1
$1$1$0$0$0$0
2.*
$0x
)`2
1
1?x
1

Girdiyi alır ve çıktıları aynı anda yazdırır.

Her satır kendi dosyasına gitmelidir. Bayt sayısına eklenen her bir dosya için 1 bayt.

Kodu -sbayrakla bir dosya olarak çalıştırabilirsiniz . Örneğin:

> echo -n 1111111|retina -s collatz
1111111111111111

Algoritma, unary sayı ile bir Collatz adımı atma xve sayı 1 değilse dizgenin sonuna yeni bir adım işareti ekleme döngüsünü oluşturur .

Döngü sona erdiğinde 1, işaretleyicileri 1istenen çıktı olan tek bir sayıya (öncüyü kaldırarak ) dönüştürürüz.


5

Jöle , rakipsiz

12 bytes Bu cevap yarışmacı değil, çünkü zorluk Jelly'in yaratılmasından önce geldi.

×3‘$HḂ?ß0’?‘

Çevrimiçi deneyin!

Nasıl çalışır

×3‘$HḂ?ß0’?‘  Main link. Argument: n (integer)

     Ḃ?       Yield the last bit of n is 1:
   $            Evaluate the three links to the left as a monadic chain:
×3                Multiply n by 3.
  ‘               Increment the product by 1.
    H           Else, halve n.
         ’?   If n-1 is non-zero:
       ß        Recursively call the main link.
        0     Else, yield 0.
           ‘  Increment the result by 1.

4

dc, 27 karakter

Booth'un kara büyüsünü uygulamak :

?[d3*1+d2%5*1+/d1<x]dsxxkzp

Nasıl çalıştığını - ya da bunun - nasıl çalıştığını anladığımdan emin değilim .

Kullanımı:
$ dc collatz.dc <<< 7
16

dc, 36 karakter

Kendi yaratım; biraz daha geleneksel bir yaklaşım olsa bile, bir ifadenin bir elsekısmının eksikliğinin üstesinden gelmek için diline adil bir parça sokmak zorunda kaldım bile if:

?[2/2Q]se[dd2%[0=e3*1+]xd1<x]dsxxkzp

Dahili olarak, dizinin tüm sayılarını üretir ve bunları yığında depolar, sonra finali çıkar 1ve yığın yüksekliğini görüntüler.


1
Parite kara büyü değildir .
Ağustos'ta

1
Hayır, ama orada çok temiz bir numara! Aslında kendim de benzer şeyler yaptım, sadece bu durumda düşünmedim. Bir saniye için beni tökezledi bölümdü, ama anladım: Parite yanlıştıysa, ilk işlemi geri alarak (* = 3, + = 1), ikinciyle böldünüz, ve parite yanlışsa, toplama tamsayı nedeniyle uzakta da ve temelde / = 2 yaptık. Çok zekice :)
daniero,

1
+1. Bu mücadeleyi dc ile ezeceğimi sanıyordum, ama sadece 40'a kadar çıktı. 27 cevabını gördüm. Oh iyi.
Dijital Travma

Bu zorluğu görmemiştim, ancak bir süre önce Collatz sırasını DC'de basmakla ilgili blog yazdım. Benim yaklaşımım seninkine benziyor ama byte ile kaybediyor, bu yüzden onu göndermek için bir neden göremiyorum. Ancak, her adımın basılmasından adımların basımına kadar kolayca nasıl gidileceğini görmek için madene baktığımda, sizden bir bayt golf yapabilen bir şey buldum ... Collatz dizisi her zaman 2'den 1'e gideceği için, koşulunuzu değiştirebilir 2<xve ondan kurtulabilirsiniz k. Sadece dört yıl sonra bir byte istemeniz durumunda. : D
brhfl

4

brainfuck , 59 56 bayt

,-[<->[[>]+<[-<]>>]>[-<<[++>+<]>->]<<[+>+++<]<<+>>>]<<<.

Çevrimiçi deneyin! (Kullanım kolaylığı için biraz değiştirilmiş)

Karakter kodları olarak giriş ve çıkış. Bu, isteğe bağlı olarak boyutlandırılmış hücrelerde daha kullanışlıdır, ancak sınırlı hücre boyutlarında küçük değerlerle çalışabilir.

Nasıl çalışır

Tape Format:
Counter 0 Copy Number Binary...
^End           ^Start

,-[ Get input, decrement by 1 and start loop
  <->                  Initialises the copy of the value at -1
  [[>]+<[-<]>>]        Converts the input to binary while preserving a negative copy
  <+>>[-<<[++>+<]>->] If the last digit of the binary is 1 (n-1 is odd), divide by 2 and decrement
  <<[+>+++<]            If the last digit of the binary is 0 (n-1 is even), multiply by 3
  <<+>>>               Increment counter and end on n-1
]<<<.                 End loop and print counter

4

Altıgen , 48 44 bayt

?(]$_)"){{?{*')}/&!/={:<$["/>&_(.<@2'%<>./>=

Çevrimiçi deneyin!

Expanded:

     ? ( ] $ _
    ) " ) { { ?
   { * ' ) } / &
  ! / = . { < $ [
 " / > & _ ( . < @
  2 ' % < > : / >
   = . . . . . .
    . . . . . .
     . . . . .

Bu konuda başarısız olduğunu unutmayın 1... ahh için sebepler . Açıkçası, bunun artık nasıl çalıştığından emin değilim. Tek bildiğim tek sayılar için olan kodun çift sayılar için geriye doğru çalıştırıldığı mı? Bir şekilde?

Yeni sürüm öncekinden daha temiz, ancak kıyaslandığında birkaç yön daha var ve ayrıca sıfıra bölme hatasıyla sonuçlanıyor. Hata yapmadığı tek durum, gerçekten 1doğru bir şekilde işlemesidir.


If a number < 2 is input ... output does not matter.: o)
Sok

@Sok Yep, bunu düzeltmeye çalışırken delirmek yerine onu yolladım
Jo King

3

C, 70 69 karakter

Oldukça basit, numara yok.
Stdin'den girişi okur.

a;
main(b){
    for(scanf("%d",&b);b-1;b=b%2?b*3+1:b/2)a++;
    printf("%d",a);
}


3

Yakut 1.9, 49 karakter

Stabil lambda sözdizimini kullanarak Rubyfied Valentin CLEMENT'in Python cevabı . Okunamayanlık eklemek için onu bir ifadeye sıkıştırdı.

(f=->n{n>1&&1+f[[n/2,3*n+1][n%2]]||0})[gets.to_i]

Bazı ek yükler, çünkü Python'dan farklı olarak Ruby, sayıları booleanlarla karıştırmaktan memnun değil.


3

C ++ ( 51 48)

Bu, bunu yapan özyinelemeli bir işlevdir; giriş okuması ayrı gelir.

int c(n){return n==1?0:1+(n%2?c(n*3+1):c(n/2));}

Bir == 0şeyler "ve / veya" hile yapabilirim eminim ama nasıl yapacağımı bilemiyorum .


Koşulları kaldırabilir ==0ve yanlarını değiştirebilirsiniz
Doorknob

Ayrıca, gerek yok n==1çünkü her zaman sayının 1'den büyük olduğu
sorusunda belirtmiştim

Sorun şu ki n==1, temel özyinelemeli durum budur. n==2Oraya koymak , skoru iyileştiremezdi.
Joe Z.

Ah, o zaman sadece bununla değiştirebilirsin: return~-n?ve koşullu tarafları değiştirebilirsin
Doorknob

. n==1== n<2.
CalculatorFeline

3

~ - ~! (Yorum Yok) - 71 53

Bu dil, çok fazla yerel işlevsellikten yoksun olduğu için, golf oynamak için en iyisi değil, ama güzelliği bu.

'=|*;~~[*,~~~-~]*/~~|:''=|'''==~[*]'''='&''':''&*+~|:

İlk '''önce girişinize ayarlayın . İşlev ''daha sonra %girişi olduğu gibi çağrılabilir ve cevabı şöyle döndürür:

'''=~~~~~:''&%:

Bu geri dönecek ~~~~~. Aslında n==1bunun için çalışır (sonsuza dek döngüye girer n==0).

Her zaman olduğu gibi bu dilde, denenmemiş.


3

JavaScript (ES6) - 29 Karakterler

f=x=>x>1?f(x%2?x*3+1:x/2)+1:0

fTek bir argümanı kabul eden ve yineleme sayısını döndüren bir işlev oluşturur .

JavaScript - 31 Karakterler

for(c=0;n>1;n=n%2?n*3+1:n/2)++c

Girişin değişkende olduğunu nve cyinelemelerin sayısını içeren bir değişken yarattığını varsayar (ve ayrıca cson komut olarak konsola da çıkacaktır ).



3

Perl 6, 40 bayt

Valentin CLEMENT ve daniero'ya göre özyinelemeli fonksiyon yöntemi : 40 karakter

sub f(\n){n>1&&1+f n%2??3*n+1!!n/2}(get)

Tembel liste yöntemi: 32 karakter

+(get,{$_%2??$_*3+1!!$_/2}...^1)

3

> <>, 27 26 23 bayt

\ln;
\::2%:@5*1+2,*+:2=?

Diğer> <> cevapları gibi, bu da istif üzerindeki sırayı oluşturur. Dizi 2'ye ulaştığında, yığının boyutu atılan adımların sayısıdır.

@Hohmannfan sayesinde, bir sonraki değeri doğrudan hesaplamak için çok akıllı bir yöntemle 3 bayt tasarruf etti. Sıradaki bir sonraki değeri hesaplamak için kullanılan formül:

f(n)=n5(nmod2)+12+(nmod2)

Kesir sayıları 0,5'e, tek sayıları 3'e eşleştirir. Çarpma nve ekleme n%2, hesaplamayı tamamlar - bir sonraki değeri seçmenize gerek yok!

Düzenleme 2: İşte ön @ Hohmannfan versiyonu:

\ln;
\:::3*1+@2,@2%?$~:2=?

Burada hile hem olmasıdır 3n+1ve n/2dizi sonradan seçilir gelen dizisindeki her adım ve bir de hesaplanır rafa kaldırıldı. Bu, kodun 1'e ulaşana kadar dallanması gerekmediği ve dizinin hesaplanmasının tek bir kod satırında yaşayabileceği anlamına gelir.

Düzenleme: 1'e yol açabilecek tek pozitif tamsayının 2 olduğunu anladıktan sonra başka bir karakterin dışında durdu. Programın çıktısı <2 girişi için önemli olmadığı için, sıra üretme işlemi 2'ye ulaştığında sona erebilir, yığın boyutu bırakılarak Gerekli olan adımların tam sayısı.

Önceki sürüm:

\~ln;
\:::3*1+@2,@2%?$~:1=?

1
İkinci çizgiyi daha da \::2%:@5*1+2,*+:2=?
açmadan
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.