Süper Logaritmayı Hesapla


29

Bu basit bir meydan okuma olmalı.

Bir sayı verildiğinde n >= 0, süper logaritmayı (veya log *, log-star veya yinelenen logaritmayı , çünkü nbu zorluk için hiçbir zaman olumsuz değildir) verin n.

log * (n): = {0, eğer <<1;  N + 1} ise 1 + log * (log (n))

Bu, tetrasyona iki ters fonksiyondan biridir . Diğeri ise ilgili bir soru olan süper kök .

Örnekler

Input       Output
0           0
1           0
2           1
3           2
4           2
...
15          2
16          3
...
3814279     3
3814280     4

kurallar

  • Olsa da, ondalık ayırımları desteklemenize gerek yoktur.
  • En azından girişi desteklemeniz gerekir 3814280 = ceiling(e^e^e).
  • Gibi değerleri zor kodlamayabilirsiniz 3814280. (Programınız teorik olarak daha yüksek sayıları desteklemelidir.) Bir algoritmanın uygulanmasını istiyorum.
  • En kısa kod kazanır.

İlgili OEIS


Yanıtlar:


14

Jöle , 8 bayt

ÆlÐĿĊḊi1

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

Arka fon

Sonuç artık değişmeyene kadar art arda girdilerin doğal logaritmalarını ve ardından gelen sonuçları alarak başlarız. Bu işe yarar çünkü doğal logaritmanın karmaşık düzleme genişletilmesi sabit bir noktaya sahiptir ; Eğer z = E -W (-1) ≈ 0.318 + 1.337i - W belirtmektedir Lambert W işlevi - Elimizdeki log (z) = z .

N girişi için , [n, log (n), log (log (n)),…, z] hesaplamalarından önce, sonuçların her birine tavan fonksiyonunu uygularız. Jelly'in uygulaması ( Ċ) aslında karmaşık sayının hayali kısmını hesaplar. , ancak bunlarla da ilgilenmiyoruz.

Bir kez k inci uygulanması log daha düşük bir değer elde edilir ya da eşit , 1 , Ċdöner 1 ilk kez. İlk 1'in 0-tabanlı endeksi istenen sonuçtur.

Basit uygulama (hesaplama 1 tabanlı dizin, azaltma) , logaritma listesinde 1 bulunmayan uç durum 0 nedeniyle başarısız olur . Aslında, 0 girişi için , logaritma dizisi

[0, None]

Bunun nedeni Jelly'in logaritmasının ( Æl) aşırı yüklenmesidir; önce math.log(gerçek logaritma), sonra cmath.log(karmaşık logaritma) dener ve nihayet "vazgeçer" ve geri döner None. Neyse ki, Ċbenzer şekilde aşırı yüklenmiştir ve basit bir şekilde toplanamaz veya hayali bir rol alamazsa argümanını döndürür.

Aynı şekilde, giriş 1 döndürür

[1, 0, None]

Bu, içermeyen veya içermeyen diğer yaklaşımlarda problem yaratabilir Ċ.

Bu sorunu çözmenin bir yolu logaritma dizisine uygulanır (dequeue; first element'i kaldırır). Bu haritalar

0ÆlÐĿ -> [0, None]    -> [None]
1ÆlÐĿ -> [1, 0, None] -> [0, None]

yani hiçbir liste şimdi 1’e sahip değil . Bu şekilde, ilk 1'in endeksini bulmak geri dönecektir. 0 ve 1 girişleri için istenen çıktı olan 0 (bulunamadı) .

Nasıl çalışır

ÆlÐĿĊḊi1  Main link. Argument: n (non-negative integer)

  ÐĿ      Apply the following link until the results are no longer unique.
Æl          Natural logarithm.
          Return the array of all unique results.
    Ċ     Round all resulting real numbers up to the nearest integer. This takes
          the imaginary part of complex numbers and does nothing for non-numbers.
     Ḋ    Dequeue; remove the first item (n) of the array of results.
      i1  Find the first index of 1 (0 if not found).

Bu, Jelly'de belirgin olmayan bir şekilde aşırı yüklenmiş olan sadece üç atomdan biridir.


11

Jöle , 9 bayt

Æl>1$пL’

Çevrimiçi deneyin!

Test odası.(Hafifçe değiştirilmiş.)

açıklama

Æl>1$пL’
     п    while loop, collect all intermediate results.
  >1$      condition: z>1
Æl         body: natural logarithm.
       L   length of the array containing all intermediate results,
           meaning number of iterations
        ’  minus one.


7

Javascript, 45 27 26 bayt

l=a=>a>1&&1+l(Math.log(a))

İşte test paketi (3. rev)

1 bayt'ı koşullu ve daha sonra lambda'ya dönüştüren fonksiyonu kaydettiği için teşekkürler @LeakyNun ve yanlış olarak işaret etmek için @Neil, <= 1 (= = = yerine) olarak değiştirildi.


Es6 olmadan yapıyordum, ama evet bu 1 byte daha kısa olurdu, teşekkürler.
CShark

Neden lambda kullanmıyorsun?
Leaky Nun

iyi bir sebep yok, sadece bu kadar kullanmadım, bu yüzden ilk
içgüdüm

Görünüşe göre false0 yerine geri dönmemize izin veriyoruz (bir tamsayı ifadesinde otomatik olarak 0 değerine dönüştüğü için) |0.
Neil

Bu 1 byte tasarruf eder, ancak "0'a otomatik dönüştürür" ile ne demek istiyorsunuz? Bu ne"?
CShark

6

Mathematica, 21 bayt

If[#>1,1+#0@Log@#,0]&

Özyinelemeli anonim işlev. Girdi olarak bir tamsayı alır ve süper logaritmasını çıktı olarak döndürür. Sadece verilen tanımı kullanır.


3
Yerleşik olup olmadığını görmek için vaktinden önce baktım. Olmadığında şaşırdım. : D
mbomb007



5

Haskell, 23 bayt

l x|x>1=1+l(log x)|1<2=0

Kullanım örneği: l 3814280-> 4.


4

Python 3, 45 bayt

import math
s=lambda x:x>1and-~s(math.log(x))

Çünkü x <= 1, bu False( == 0Python'da olan) döndürür .


Evet, Falseiçin kullanılabilir 0.
mbomb007

Ayrıca, saf uygulamamı yendin ( andyerine if else). Grats.
mbomb007

4

05AB1E, 16 13 bayt

[Dî2‹#¼žr.n]¾

açıklama

              # implicit input n
[          ]  # infinite loop
 Dî2‹#        # break if n rounded up is less than 2
      ¼       # else, increase counter
       žr.n   # set next n = log(n)
            ¾ # push counter and implicitly print

Çevrimiçi deneyin


3

Matl , 15 12 bayt

0`ZetG>~}x@q

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın (birkaç girişi işlemek için biraz değiştirilmiş versiyon).

Nasıl çalışır

0 ile başlayarak, girişi aşıncaya kadar yinelenmiş üstel uygulayın. Çıkış, eksi 1 eksi sayısıdır.

0       % Push 0
`       % Do...while loop
  Ze    %   Exponential
  t     %   Duplicate
  G     %   Push input
  >~    %   Is current value less than or equal to the input? If so: next iteration
}       % Finally (code executed at the end of the last iteration)
  x     %   Delete
  @q    %   Iteration index minus 1
        % Implicitly end loop
        % Implicitly display stack

3

J , 21 19 18 16 bayt

Sızdıran Rahibe'ye 2 bayt, Galen Ivanov'a 1 bayt ve FrownyFrog'a 2 bayt kaydedildi!

2#@}.(0>.^.)^:a:

Çevrimiçi deneyin!

Test durumları

ls =: >:@$:@^.`0:@.(<:&1)
   ls 0
0
   ls 1
0
   ls 2
1
   ls 3
2
   ls 4
2
   ls 15
2
   ls 16
3
   ls 3814280
4

İşte 18 baytlık çözümüm: 2#@}.^.^:(0<])^:a:(Bu sorunun bir kopyası olduğu ortaya çıkanı yumuşatmaya başladım.)
Galen Ivanov

2#@}.(0>.^.)^:a:iş gibi görünüyor.
FrownyFrog

Yine de eşdeğer olup olmadığından emin değilim.
FrownyFrog


2

MATLAB / Octave, 44 bayt

function a=g(n);a=0;if n>1;a=1+g(log(n));end

Hepsini bir anonim işlev olarak yapmaya çalıştım, ancak MATLAB / Octave'un bir boolean false (sıfır) değeriyle çarpılsa bile ifadeleri değerlendirmeye devam ettiğini unuttum:

f=@(n)(n>1)*(1+f(log(n)))


Evet, kısa devre yapan bir ürüne sahip olmak güzel olurdu :-)
Luis Mendo

2

R, 38 37 bayt

f=function(x)if(x>1)1+f(log(x))else 0

@ User5957401 adlı kullanıcıya teşekkür ederiz.Ekstra bayt için !

Test durumları:

> f(0)
[1] 0
> f(1)
[1] 0
> f(2)
[1] 1
> f(3)
[1] 2
> f(4)
[1] 2
> f(3814279)
[1] 3
> f(3814280)
[1] 4

Bence bir ifadesi kullanarak bir bayt kurtarabilirsin, else ifadesi. yani if(x>1)1+f(log(x))else 0bir bayt daha kısa.
user5957401

2

R , 34 bayt

f=pryr::f(`if`(n>1,1+f(log(n)),0))

Çevrimiçi deneyin!

Özyinelemeli olmayan bir yaklaşım mümkündür: 36 bayt ve stdin'den girdi alır.

n=scan()
while((n=log(n))>0)F=F+1
+F

2

Java 7, 47 bayt

int c(double n){return n>1?1+c(Math.log(n)):0;}

Çevrimiçi deneyin.

Yukarıdaki özyinelemeli Java 7 tarzı yöntem, yinelemeli Java 8 tarzı lambda'dan 2 byte daha kısadır:

n->{int c=0;for(;n>1;c++)n=Math.log(n);return c;}

Çevrimiçi deneyin.

Açıklama:

int c(double n){      // Method with double parameter and integer return-type
  return n>1?         //  If the input is larger than 1:
    1+                //   Return 1 +
      c(Math.log(n))  //   A recursive call with log(input)
   :                  //  Else:
    0;                //   Return 0 instead

n->{                  // Method with double parameter and integer return-type
  int c=0;            //  Create a counter, starting at 0
  for(;n>1;           //  Loop as long as the input is still larger than 1:
    c++)              //   Increase the counter by 1
    n=Math.log(n);    //   And update the input to log(input)
  return c;}          //  After the loop: return the counter as result

Java 8 lambda ile kısaltabilirsiniz.
mbomb007

@ mbomb007 üç yıl sonra cevap veriyor, haha ​​.. (o zamanlar sadece Java 7'de sadece kod golfü yapıyordum), ama yine de sorunuzu cevaplamak için: hayır, maalesef bir Java 8 lambda özyinelemeden 2 bayt daha uzun. Cevabımı ekledim ve bir açıklama da ekledim.
Kevin Cruijssen

Yani özyinelemeli lambda yapamazsın?
mbomb007

@ mbomb007 Hayır, Java ne yazık ki değil. Python'da JavaScript ve C # .NET'in de olduğunu düşünüyorum, özyinelemeli lambdalar mümkün, fakat Java'da bir sebepten dolayı değil ..
Kevin Cruijssen

1

Emacs Lisp, 38 bayt

(defun l(n)(if(> n 1)(1+(l(log n)))0))

testcases:

(mapcar 'l '(0 1 2 3 4 15 16 3814279 3814280))
;; (0 0 1 2 2 2 3 3 4)

1

Jöle , 8 bayt

-Ælß$Ị?‘

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

Nasıl çalışır

-Ælß$Ị?‘  Main link. Argument: x

     Ị    Insignificant; test if |x| ≤ 1.
      ?   If the result is 1:
-           Return -1.
          Else:
   $        Execute the monadic chain formed by the two links to the left.
Æl            Apply natural logarithm to x.
  ß           Recursively call the main link.
       ‘  Increment the result.

1

Perl 5, 35 bayt

Çok basit, anahtar kelimeyi anonim özyinelemede -M5.016etkinleştirmek için (ücretsiz olan) gerekir __SUB__.

sub{$_[0]>1?1+__SUB__->(log pop):0}

Başka bir alternatif

sub{$_[0]>1?1+__SUB__->(log pop):0}

bu, 34 bayttır ve tüm girişler> 1 için aynı çıktıyı verir, ancak <= 1 girişleri için özel yanlış değeri döndürür. Yanlış, sayısal olarak sıfıra eşittir, ancak "" (boş dize) olarak yazdırır, bu nedenle büyük olasılıkla " Kalifiye değil.


Mükemmel cevap. sub{($_=pop)>1?1+__SUB__->(log):0}Yine de yaparak 1 byte kazanabilirsiniz
Dada

1

CJam (16 bayt)

rd{_1>}{_ml}w],(

Çevrimiçi demo

Ön koşulu ile döngü sırasında basit. (Burada gerçekten istediğim bir Golfscript tarzı açılma işlemidir, ancak CJam'da bir tane yoktur ve GolfScript'teki kayan nokta dağınıktır ve hiç golf değildir).


Bir kenara, bu matematikteki 80. cevabım ve bugün bana ikinci rozeti kazandı.
Peter Taylor


1

Raket, 61 bayt

(λ(x)(letrec([a(λ(b)(if(> b 1)(+ 1 (a(log b)))0))])(a x)))

1

Akçaağaç, 32,30 29 bayt

f:=x->`if`(x>1,1+f(log(x)),0)

Test durumları:

> f(0.);
  0
> f(1.);
  0
> f(2.);
  1
> f(3.);
  2
> f(4.);
  2
> f(3814279.);
  3
> f(3814280.);
  4

1

R, 36 bayt

Plannapus'tan biraz farklı yaklaşım

->n;a=0;while(n>1){a=a+1;n=log(n)};a

Kodu çalıştırmak için doğru bir atama kullanır - bu yüzden istenen numara ondan önce gelmelidir. yani

10->n;a=0;while(n>1){a=a+1;n=log(n)};a

0

Mathematica, 29 bayt

Tüm cehennem kadar basit ve komik ve negatif girdiler için komik olarak çalışır:

f[x_]:=If[x>1,1+f[Log[x]],0]

enter image description here



0

Perl 6 , 21 bayt

{($_,*.log...1>=*)-1}

Çevrimiçi deneyin!

Parantez içindeki ifade bir dizidir. $_, fonksiyonun argümanı, ilk elemandır. *.logönceki her bir öğenin günlüğünü alarak her başarılı öğeyi oluşturur. Sıra, bitiş koşulu, 1 >= *doğru olduğunda devam eder : 1, geçerli öğeye eşit veya ondan büyük. Sekanstan 1 çıkartmak onu bir sayıya zorlar: uzunluğu.

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.