Tính toán siêu logarit


29

Đây phải là một thử thách đơn giản.

Cho một số n >= 0, xuất siêu logarit (hoặc log *, log-star hoặc logarit lặp , tương đương vì nkhông bao giờ âm đối với thử thách này.) Của n.

log * (n): = {0 nếu n <= 1;  1 + log * (log (n)) nếu n> 1}

Đây là một trong hai chức năng nghịch đảo của tetination . Cái khác là siêu gốc , trong một câu hỏi liên quan .

Ví dụ

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

Quy tắc

  • Bạn không cần phải hỗ trợ số thập phân, mặc dù bạn có thể.
  • Bạn cần hỗ trợ đầu vào ít nhất 3814280 = ceiling(e^e^e).
  • Bạn có thể không cứng mã các giá trị như 3814280. (Về mặt lý thuyết, chương trình của bạn phải hỗ trợ số lượng cao hơn.) Tôi muốn một thuật toán được thực hiện.
  • Mã ngắn nhất sẽ thắng.

Liên quan đến OEIS


Câu trả lời:


14

Thạch , 8 byte

ÆlÐĿĊḊi1

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Lý lịch

Chúng tôi bắt đầu bằng cách liên tiếp lấy logarit tự nhiên của đầu vào và kết quả tiếp theo cho đến khi kết quả không còn thay đổi. Điều này hoạt động vì phần mở rộng của logarit tự nhiên đến mặt phẳng phức có một điểm cố định ; if z = e -W (-1) ≈ 0.318 + 1.337i - trong đó W biểu thị hàm Lambert W - chúng ta có log (z) = z .

Đối với đầu vào n , sau khi tính toán [n, log (n), log (log (n)), lỗi, z] , trước tiên chúng ta áp dụng hàm trần cho từng kết quả. Thay vào đó , việc triển khai Jelly ( Ċ) thực sự tính phần ảo của số phức thay vì , nhưng dù sao chúng tôi cũng không quan tâm đến những điều này.

Khi ứng dụng nhật ký thứ k mang lại giá trị nhỏ hơn hoặc bằng 1 , sẽ trả về 1 lần đầu tiên. Chỉ số dựa trên 0 của 1 đầu tiên đó là kết quả mong muốn.Ċ

Việc thực hiện đơn giản (tính toán chỉ số dựa trên 1, giảm) không thành công do trường hợp cạnh 0 , không có số 1 trong danh sách logarit của nó. Trong thực tế, đối với đầu vào 0 , chuỗi logarit là

[0, None]

Điều này là do logarit của Jelly ( Æl) bị quá tải; đầu tiên nó thử math.log(logarit thực), sau đó cmath.log(logarit phức tạp), và cuối cùng "từ bỏ" và trả về None. May mắn thay, Ċbị quá tải tương tự và chỉ đơn giản trả về đối số nếu nó không thể làm tròn hoặc lấy một phần tưởng tượng.

Tương tự, đầu vào 1 trả về

[1, 0, None]

mà có thể tạo ra vấn đề trong các phương pháp khác có hoặc không liên quan Ċ.

Một cách để khắc phục vấn đề này được áp dụng (dequeue; loại bỏ phần tử đầu tiên) cho mảng logarit. Bản đồ này

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

vì vậy không có danh sách nào có 1 bây giờ. Bằng cách này, việc tìm chỉ mục của 1 đầu tiên sẽ trả về 0 (không tìm thấy), đây là đầu ra mong muốn cho các đầu vào 01 .

Làm thế nào nó hoạt động

Æ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).

Đây là một trong những chỉ có ba nguyên tử trong Jelly được quá tải một cách không rõ ràng.




7

Javascript, 45 27 26 byte

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

Đây là bộ thử nghiệm (lần thứ 3)

Cảm ơn @LeakyNun vì đã lưu 1 byte với điều kiện và sau đó chuyển đổi hàm thành lambda và @Neil đã chỉ ra false là giá trị trả về ok cho <= 1 (đã thay đổi kiểm tra thành == thay vì ===)


Tôi đã làm điều đó mà không có es6, nhưng vâng, nó sẽ ngắn hơn 1 byte, cảm ơn.
CShark

Tại sao bạn không sử dụng lambda?
Rò rỉ Nun

không có lý do chính đáng, tôi chỉ không sử dụng nó nhiều, vì vậy đó không phải là bản năng đầu tiên của tôi
CShark

Rõ ràng chúng tôi được phép trả về falsethay vì 0 (vì nó tự động chuyển đổi thành 0 trong một biểu thức số nguyên) trong trường hợp đó bạn có thể loại bỏ |0.
Neil

Điều đó sẽ tiết kiệm 1 byte, nhưng ý của bạn là "nó tự động chuyển đổi thành 0"? Nó là gì"?
CShark

6

Toán học, 21 byte

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

Hàm đệ quy ẩn danh. Lấy một số nguyên làm đầu vào và trả về siêu logarit của nó làm đầu ra. Chỉ cần sử dụng định nghĩa nhất định.


3
Tôi thực sự nhìn về phía trước để xem nếu có tích hợp. Tôi đã rất ngạc nhiên khi không có. : D
mbomb007



5

Haskell, 23 byte

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

Ví dụ sử dụng: l 3814280-> 4.


4

Python 3, 45 byte

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

Đối với x <= 1, điều này trả về False(đó là == 0trong Python).


Có, Falsecó thể được sử dụng cho 0.
mbomb007

Ngoài ra, bạn đánh bại việc thực hiện ngây thơ của tôi (bằng cách sử dụng andchứ không phải if else). Grats.
mbomb007

4

05AB1E, 16 13 byte

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

Giải trình

              # 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

Dùng thử trực tuyến


3

MATL , 15 12 byte

0`ZetG>~}x@q

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm (phiên bản sửa đổi một chút để xử lý một số đầu vào).

Làm thế nào nó hoạt động

Bắt đầu bằng 0, áp dụng lũy ​​thừa lặp cho đến khi vượt quá đầu vào. Đầu ra là số lần lặp trừ đi 1.

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 byte

Đã lưu 2 byte vào Leaky Nun, 1 byte cho Galen Ivanov và 2 byte cho FrownyFrog!

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

Hãy thử trực tuyến!

Các trường hợp thử nghiệm

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

Đây là giải pháp 18 byte của tôi: 2#@}.^.^:(0<])^:a:(Tôi đã bắt đầu giải quyết vấn đề hóa ra vấn đề này.)
Galen Ivanov

2#@}.(0>.^.)^:a:dường như làm việc
FrownyFrog

Không chắc chắn nếu nó tương đương mặc dù.
FrownyFrog


2

MATLAB / Octave, 44 byte

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

Đã thử làm tất cả dưới dạng một hàm ẩn danh, nhưng tôi quên rằng MATLAB / Octave tiếp tục đánh giá các biểu thức ngay cả khi chúng được nhân với giá trị boolean false (zero):

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


Vâng, thật tuyệt khi có một sản phẩm ngắn mạch :-)
Luis Mendo

2

R, 38 37 byte

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

Cảm ơn @ user5957401 cho byte thêm!

Các trường hợp thử nghiệm:

> 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

Tôi nghĩ rằng bạn có thể lưu một byte bằng cách sử dụng một câu lệnh if, other. tức if(x>1)1+f(log(x))else 0là ngắn hơn một byte.
dùng5957401

2

R , 34 byte

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

Hãy thử trực tuyến!

Một cách tiếp cận không đệ quy là có thể: 36 byte và lấy đầu vào từ stdin.

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

2

Java 7, 47 byte

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

Hãy thử trực tuyến.

Phương thức kiểu Java 7 đệ quy ở trên ngắn hơn 2 byte so với lambda kiểu Java 8 lặp:

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

Hãy thử trực tuyến.

Giải trình:

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

Bạn có thể làm cho nó ngắn hơn với lambda Java 8.
mbomb007

@ mbomb007 trả lời ba năm sau, haha ​​.. (tại thời điểm đó tôi chỉ chơi golf trong Java 7), nhưng vẫn trả lời câu hỏi của bạn: không, thật không may, lambda Java 8 dài hơn 2 byte so với phương thức đệ quy. Tôi đã thêm nó vào câu trả lời của mình và tôi cũng đã thêm một lời giải thích.
Kevin Cruijssen

Vì vậy, bạn không thể làm lambdas đệ quy?
mbomb007

@ mbomb007 Không, trong Java không may. Trong Python, JavaScript và tôi nghĩ C # .NET cũng vậy, lambdas đệ quy là có thể, nhưng trong Java không phải vì một số lý do ..
Kevin Cruijssen

1

Emacs Lisp, 38 byte

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

Testcase:

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

1

Thạch , 8 byte

-Ælß$Ị?‘

Thực hiện đơn giản định nghĩa. Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

-Æ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 byte

Rất đơn giản, yêu cầu -M5.016(miễn phí) để kích hoạt __SUB__từ khóa cho đệ quy ẩn danh.

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

Một cách khác là

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

có 34 byte và cho cùng một đầu ra cho tất cả các đầu vào> 1, nhưng trả về giá trị sai đặc biệt cho các đầu vào <= 1. Sai bằng số bằng 0, nhưng in dưới dạng "" (chuỗi trống), vì vậy có lẽ nó không ' t đủ điều kiện.


Câu trả lời chính xác. Bạn có thể giành chiến thắng 1 byte bằng cách thực hiện sub{($_=pop)>1?1+__SUB__->(log):0}mặc dù
Dada

1

CJam (16 byte)

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

Bản demo trực tuyến

Vòng lặp while đơn giản với điều kiện trước. (Điều tôi thực sự muốn ở đây là một hoạt động mở ra theo kiểu Golfscript, nhưng CJam không có, và điểm nổi trong GolfScript là lộn xộn và hoàn toàn không phải là golf).


Bên cạnh đó, đây là câu trả lời thứ 80 của tôi trong toán học và mang lại cho tôi huy hiệu thẻ thứ hai của tôi ngày hôm nay.
Peter Taylor


1

Vợt, 61 byte

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

1

Maple, 32,30 29 byte

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

Các trường hợp thử nghiệm:

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

1

R, 36 byte

Cách tiếp cận hơi khác với Plannapus

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

Sử dụng một quyền gán để chạy mã - vì vậy số mong muốn phải đi trước nó. I E

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

0

Toán học, 29 byte

Đơn giản như tất cả địa ngục, và hoạt động cho đầu vào lớn cũng như tiêu cực:

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

nhập mô tả hình ảnh ở đây



0

Perl 6 , 21 byte

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

Hãy thử trực tuyến!

Biểu thức ngoặc đơn là một chuỗi. $_, đối số cho hàm, là phần tử đầu tiên. *.logtạo ra từng phần tử liên tiếp bằng cách lấy nhật ký của phần tử trước đó. Trình tự tiếp tục cho đến khi điều kiện kết thúc 1 >= *là đúng: 1 lớn hơn hoặc bằng phần tử hiện tại. Trừ 1 từ chuỗi cưỡng chế nó thành một số: chiều dài của nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.