수퍼 로그 계산


29

이것은 간단한 도전이어야합니다.

숫자 감안할 때 n >= 0, 출력 슈퍼 로그 (로그 - 스타 또는 로그 *를, 또는 로그 반복 하기 때문에 동일, n이 문제에 대한 부정적인 결코합니다.)의 n.

log * (n) : = {n <= 1 인 경우 0;  n> 1 인 경우 1 + log * (log (n))}

이것은 tetratation 에 대한 두 가지 역함수 중 하나입니다 . 다른 하나는 관련 질문 에있는 수퍼 루트 입니다.

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

규칙

  • 소수를 지원할 필요는 없지만 가능할 수도 있습니다.
  • 의 입력을 지원해야합니다 3814280 = ceiling(e^e^e).
  • 과 같은 값을 하드 코딩 할 수 없습니다 3814280. (귀하의 프로그램은 이론적으로 더 높은 숫자를 지원 해야합니다 .) 알고리즘을 구현하고 싶습니다.
  • 가장 짧은 코드가 승리합니다.

관련 OEIS


답변:


14

젤리 , 8 바이트

ÆlÐĿĊḊi1

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

배경

우리는 결과가 더 이상 변하지 않을 때까지 입력의 자연 로그와 연속 결과를 연속적으로 취함으로써 시작합니다. 이것은 복잡한 대수에 대한 자연 로그의 확장이 고정 된 점을 갖기 때문에 작동 합니다 . 만약 Z = E -W (-1) ≈ 0.318 + 1.337i 곳 - W가 나타낸다 램버트 W 함수 - 우리가 로그인 (z) = Z .

입력 n의 경우 [n, log (n), log (log (n)),…, z]를 계산 한 후 먼저 천장 함수를 각 결과에 적용합니다. 젤리의 구현 ( Ċ)은 실제로 대신 복소수 의 허수 부분을 계산 하지만, 우리는 이것에 관심이 없습니다.

일단 K 번째 의 애플리케이션 로그가 보다 작은 값을 산출하거나 동일 하나 , Ċ반환 1 처음. 첫 번째 1 의 0 기반 인덱스 가 원하는 결과입니다.

간단한 경우 (계산 1 기반 인덱스, 감소)는 대소 문자 케이스 0으로 인해 실패 하며, 로그 목록에 1 이 없습니다 . 실제로 입력 0 의 경우 로그 시퀀스는 다음과 같습니다.

[0, None]

Jelly의 로그 ( Æl)가 오버로드 되기 때문입니다 . 먼저 math.log(실제 대수)를 시도한 다음 cmath.log(복소수 대수) 를 시도 하고 마지막으로 "포기"하고를 반환합니다 None. 다행스럽게도 Ċ비슷하게 오버로드되어 있으며 반올림하거나 가상의 부분을 취할 수없는 경우 단순히 인수를 반환합니다.

마찬가지로 입력 1

[1, 0, None]

다른 접근 방식에서 문제가 발생할 수 있습니다 Ċ.

이 문제를 해결하는 한 가지 방법은 (배열, 첫 번째 요소 제거) 로그 배열에 적용하는 것입니다. 이지도

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

따라서 어느 목록에도 1 이 없습니다 . 이런 식으로 첫 번째 1 의 인덱스를 찾으면 0 (찾을 수 없음)을 반환 하며, 이는 입력 01에 대해 원하는 출력입니다 .

작동 원리

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

이것은 젤리에서 명백하지 않은 방식으로 과부하 된 유일한 세 원자 중 하나입니다.




7

자바 스크립트, 45 27 26 바이트

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

다음은 테스트 스위트입니다 (3 차 개정판)

조건부로 1 바이트를 저장 한 다음 함수를 람다로 변환 한 @LeakyNun에게 감사 드리며 false를 지적하는 @Neil은 <= 1의 ok 반환 값입니다 (테스트는 === 대신 ==로 변경)


나는 es6없이 그것을하고 있었지만, 그래도 1 바이트 더 짧을 것입니다. 감사합니다.
CShark

왜 람다를 사용하지 않습니까?
Leaky Nun

아무 이유도없이, 나는 그것을 그렇게 많이 사용하지 않았기 때문에 그것은 나의 첫 번째 본능이 아닙니다
CShark

분명히 우리는 false0 대신에 반환 할 수 있습니다 (정수 표현식에서 0으로 자동 변환되므로) |0.
Neil

1 바이트를 절약 할 수 있지만 "0으로 자동 변환"이란 무엇입니까? "그것"은 무엇입니까?
CShark

6

수학, 21 바이트

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

재귀 익명 기능. 정수를 입력으로 취하고 수퍼 로그를 출력으로 리턴합니다. 주어진 정의 만 사용하십시오.


3
실제로 내장 기능이 있는지 미리 살펴 보았습니다. 없을 때 놀랐습니다. : D
mbomb007



5

하스켈, 23 바이트

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

사용 예 : l 3814280-> 4.


4

파이썬 3, 45 바이트

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

의 경우 ( Python에 있음)을 x <= 1반환합니다 .False== 0


예,에 False사용할 수 있습니다 0.
mbomb007

또한, 당신은 내 순진한 구현을 이겼습니다 ( and보다는 오히려 사용하여 if else). Grats.
mbomb007

4

05AB1E, 16 13 바이트

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

설명

              # 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

온라인으로 사용해보십시오


3

MATL , 15 12 바이트

0`ZetG>~}x@q

온라인으로 사용해보십시오!또는 모든 테스트 사례를 확인하십시오 (여러 입력을 처리하기 위해 약간 수정 된 버전).

작동 원리

0부터 시작하여 입력을 초과 할 때까지 반복 지수를 적용하십시오. 출력은 반복 횟수에서 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 바이트

Leaky Nun에 2 바이트, Galen Ivanov에 1 바이트, FrownyFrog에 2 바이트를 저장했습니다!

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

온라인으로 사용해보십시오!

테스트 사례

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

여기 내 18 바이트 솔루션입니다 : 2#@}.^.^:(0<])^:a:(나는이 문제의 DUP으로 밝혀졌다 무엇 sovling 시작했다.)
갈렌 이바노프

2#@}.(0>.^.)^:a:작동하는 것 같습니다.
FrownyFrog

그래도 같은지 확실하지 않습니다.
FrownyFrog


2

MATLAB / 옥타브, 44 바이트

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

모든 것을 하나의 익명 함수로 시도했지만 MATLAB / Octave는 부울 false (0) 값을 곱해도 표현식을 계속 평가한다는 것을 잊었습니다.

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


그렇습니다, 단락 제품이있는 것이 좋을 것입니다 :-)
Luis Mendo

2

R, 38 37 바이트

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

여분의 바이트에 대해 @ user5957401 에게 감사드립니다 !

테스트 사례 :

> 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

리터럴 if, else 문을 사용하여 바이트를 저장할 수 있다고 생각합니다. 즉, if(x>1)1+f(log(x))else 01 바이트 더 짧습니다.
user5957401


2

자바 7, 47 바이트

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

온라인으로 사용해보십시오.

위의 재귀 Java 7 스타일 메소드는 반복 Java 8 스타일 람다보다 2 바이트 짧습니다.

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

온라인으로 사용해보십시오.

설명:

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 람다를 사용하면 더 짧아 질 수 있습니다.
mbomb007

@ mbomb007 3 년 후 haha ​​.. (Java 7에서 코드 골프 만했을 때) 응답했지만 여전히 질문에 대답하기 위해 : 불행히도 Java 8 람다는 재귀 방법보다 2 바이트 더 깁니다. 내 답변에 추가하고 설명도 추가했습니다.
케빈 크루이 ssen

재귀 람다를 할 수 없습니까?
mbomb007

@ mbomb007 아니요, 불행히도 Java에서는 그렇지 않습니다. 파이썬, 자바 스크립트, 그리고 C # .NET에서도 재귀 적 람다는 가능하지만 Java에서는 어떤 이유로 든 가능하지 않다고 생각합니다.
Kevin Cruijssen

1

이맥스 리스프, 38 바이트

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

테스트 케이스 :

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


1

펄 5, 35 바이트

익명 재귀에 키워드 -M5.016를 사용 하려면 매우 간단하고 (무료) 필요합니다 __SUB__.

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

다른 대안은

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

이는 34 바이트이며 모든 입력> 1에 대해 동일한 출력을 제공하지만 입력 <= 1에 대해 특수한 false 값을 반환합니다. False는 숫자 0과 동일하지만 ""(빈 문자열)로 인쇄되므로 아마도 ' 자격이 없습니다.


좋은 대답입니다. sub{($_=pop)>1?1+__SUB__->(log):0}그래도 1 바이트를 이길 수 있습니다
Dada

1

CJam (16 바이트)

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

온라인 데모

사전 조건이있는 간단한 while 루프. (내가 정말로 원하는 것은 Golfscript 스타일의 펼치기 작업이지만 CJam에는 하나가 없으며 GolfScript의 부동 소수점은 지저분하며 전혀 골프 색이 아닙니다).


옆으로, 이것은 수학 에서 80 번째 답변이며 오늘 두 번째 태그 배지를 받았습니다.
피터 테일러


1

라켓, 61 바이트

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

1

메이플, 32,30 29 바이트

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

테스트 사례 :

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

1

R, 36 바이트

Plannapus와 약간 다른 접근법

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

코드를 실행하기 위해 올바른 할당을 사용하므로 원하는 숫자가 앞에 와야합니다. 즉

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

0

매스 매 티카, 29 바이트

모든 지옥처럼 간단하고 음의 입력뿐만 아니라 코믹하게 큰 작업에도 효과적입니다.

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

여기에 이미지 설명을 입력하십시오



0

펄 6 , 21 바이트

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

온라인으로 사용해보십시오!

괄호로 묶은 표현식은 시퀀스입니다. $_함수의 인수 인 첫 번째 요소입니다. *.log이전 요소의 로그를 가져 와서 각 연속 요소를 생성합니다. 순서는 종료 조건, 1 >= *true가 될 때까지 계속됩니다 . 1은 현재 요소보다 크거나 같습니다. 시퀀스에서 1을 빼면 숫자로 길이를 강제합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.