Ackermann 기능


34

Ackermann 함수는 원시 재귀 적이 지 않은 계산 가능한 총 함수 중 가장 간단한 예 중 하나로 유명합니다.

우리는 A(m,n)음이 아닌 두 정수 를 취하는 정의를 사용합니다 .

A(0,n) = n+1
A(m,0) = A(m-1,1)
A(m,n) = A(m-1,A(m,n-1))

구현할 수 있습니다

  • 두 개의 정수를 입력으로 사용하여 정수를 반환하는 명명 된 또는 익명 함수
  • STDIN에서 공백 또는 개행으로 구분 된 두 정수를 가져 와서 결과를 STDOUT에 인쇄하는 프로그램.

라이브러리에서 Ackermann 함수 또는 hyperexponentiation 함수 (있는 경우)를 사용할 수 없지만 다른 라이브러리에서 다른 함수를 사용할 수 있습니다. 정기적 인 지수가 허용됩니다.

함수는 A(m,n)1 분 이내에 m ≤ 3 및 n ≤ 10 의 값을 찾을 수 있어야합니다 . 적어도 이론적 으로는 다른 입력에서 끝나야합니다. 무한 스택 공간, 기본 Bigint 유형 및 임의로 긴 기간이 주어지면 답을 반환합니다. 편집 : 언어의 기본 재귀 수준이 너무 제한적인 경우 문자 비용없이 언어를 다시 구성 할 수 있습니다.

문자 수가 가장 적은 제출물이 이깁니다.

답을 확인하기위한 몇 가지 값은 다음과 같습니다.

  A  | n=0     1     2     3     4     5     6     7     8     9    10
-----+-----------------------------------------------------------------
 m=0 |   1     2     3     4     5     6     7     8     9    10    11
   1 |   2     3     4     5     6     7     8     9    10    11    12
   2 |   3     5     7     9    11    13    15    17    19    21    23
   3 |   5    13    29    61   125   253   509  1021  2045  4093  8189
   4 |  13 65533   big   really big...

15
이것은 이전에 어떻게 요청되지 않았습니까?
— Calvin 's Hobbies


22
여기에 도전이 없기 때문에 다운 보팅. 정의에 따라 정확히 순진하게 기능을 구현하는 명백한 답변은 항상 최고의 답변이 될 것입니다. 문제는 "어 커맨의 기능을 명백히 표현할 때 언어가 가장 적은 문자는 무엇입니까?"입니다. 진정한 승자는 프로그래밍 언어이며 명확한 프로그램을 작성한 사람이 아닙니다.
— David Richerby

1
언어의 재귀 제한이 계산하기에 너무 낮고 A(3,8)다른 언어 처럼 순진하게 초과하면 어떻게됩니까? 비 재귀 솔루션을 만들어야합니까, 아니면이 경우 "무한 스택 공간을 가정"할 수 있습니까? 꽤 확신합니다. 1 분 안에 종료됩니다.
— Martin Ender

5
@DavidRicherby "명백한 대답 [...]은 항상 최고의 대답이 될 것입니다." 모든 언어에 해당되는 것은 아닙니다. 나는 모국어로 예를 들어서 조금 더럽다고 느끼지만, Ackermann을 표현하는 방법에는 여러 가지가 있으며 일부 언어에서는 그 사실을 사용하여 저축을 얻을 수 있습니다. 이것이 도전에 대한 나의 의도였다.
— algorithmshark

답변:


7

피 이스 , 19

DaGHR?atG?aGtHH1GhH

aAckermann 함수로 작동하는을 정의합니다 . 오늘까지 계산할 수있는 공식 pyth 컴파일러보다 높은 재귀 깊이가 필요 a 3 10하므로 재귀 깊이를 늘 렸습니다. 이것은 언어의 변화가 아니라 컴파일러의 변화입니다.

테스트:

$ time pyth -c "DaGHR?atG?aGtHH1GhH           ;a 3 10"
8189

real    0m0.092s
user    0m0.088s
sys     0m0.000s

설명:

DaGH                     def a(G,H):
    R                    return
    ?          G                (if G:
     atG                              (a(G-1,
        ?    H                               (if H:
         aGtH                                      a(G,H-1)
              1                               else:1)
                hH               else:H+1)

본질적으로, 그것은 먼저 GH + 1을 재귀 또는 반환할지 의 진실 가치에 달려 있습니다. 되풀이되는 경우 첫 번째 인수는 항상 G-1이며 두 번째 인수 H로 사용할지 a(G,H-1)또는 두 번째 인수 로 사용할지의 실제 값에 따라 달라집니다 1.


현대 Pyth에서 내가 할 수있는 더 많거나 적은 변화를 생각한다 (I는이 공격 후 추가 된 가정) DaGHR에 M와 a에 g. ( ?변경에 대한 논쟁의 순서를 했습니까 ?)
— Lynn

@Mauris 예, M대신 사용할 수 있으며 예, ?인수 순서가 변경되었습니다. 이제는 조건입니다. 참, 거짓. 사실, 조건, 거짓이었다.
— isaacg 2016

@Lynn Fun Pyth history facts :이 질문은 실제로 isaacg가 Pyth에 대해 (적어도) 두 가지를 변경하도록 영향을 미쳤습니다 : 재귀 한계 와 로의 변경M !
— FryAmTheEggman

23

하스켈, 35

0%n=1+n
m%n=iterate((m-1)%)1!!(n+1)

이것은 연산자 함수를 정의합니다 %.

이것은 0 이 아닌 에 대한 (ackerman 함수는 m%n어디에 a있습니까) 시간 m이 (m-1)%적용 된다는 것을 알면 작동 n+1합니다 1. 예를 들어, 3%2로 정의 2%(3%1)되는 2%(2%(3%0)), 이는 인2%(2%(2%1))


너무 나쁘다. 우선 순위 때문에 0%n대신 사용할 수 없다n+1
— 자랑스러운 haskeller


와우, 이것은 오랫동안 잘못되었고, 나 자신을 포함하여 아무도 눈치 채지 못했습니까? 잘 했어. 그래서 실수로 잘못되었거나 아마도 효과가 있다고 생각했기 때문에 첫 번째 버전의 답변을 실수로 복사 한 것 같습니다.
— 자랑스런 Haskeller

12

골프 스크립트 (30)

{1$1>{1\){1$(\A}*\;}{+)}if}:A;

온라인 데모

1>(특수한 경우 A(1, n)) 이 없으면 A(3, 10)테스트 한 컴퓨터 에서 계산하는 데 9 분이 걸립니다 . 이 특별한 경우 온라인 데모가 10 초도 걸리지 않을 정도로 빠릅니다.

이것은 정의의 순진한 번역 이 아닙니다 . 재귀 깊이는로 묶습니다 m.

해부

{             # Function boilerplate
  1$          # Get a copy of m: stack holds m n m
  1>{         # (Optimisation): if m is greater than 1
    1         #   Take this as the value of A(m, -1)
    \){       #   Repeat n+1 times:
              #     Stack: m A(m, i-1)
      1$(\    #     Stack: m m-1 A(m, i-1)
      A       #     Stack: m A(m, i)
    }*
    \;        #   Lose that unwanted copy of m
  }{          # Else
    +)        #   A(m in {0, 1}, n) = m + n + 1
  }if
}:A;          # Function boilerplate

CJam에서는 필요하지 않습니다 1>. 제거 (및 변경 한 후 if에 ?), 계산은 3 10 A자바 인터프리터와 온라인 인터프리터 110 초 육초 걸립니다.
— Dennis

7

이진 람다 미적분 , 54 비트 = 6.75 바이트

16 진 덤프 :

00000000: 1607 2d88 072f 68                        ..-../h

이진 :

000101100000011100101101100010000000011100101111011010

이것은 λ m 입니다. m (λ g . λ N . g ( N g 1)) (λ N . λ F . λ X . F ( N F (X) )), 모든 숫자로 표현되는 경우 교회 부호 .


6

자바 스크립트, ES6, 41 34 바이트

f=(m,n)=>m?f(m-1,!n||f(m,n-1)):n+1

최신의 파이어 폭스 콘솔에서이 작업을 실행하고라는 함수를 만듭니다 f당신이 다른 값으로 호출 할 수 있습니다 m와 n같은을

f(3,2) // returns 29

또는

최신 Firefox에서 아래 코드를 사용해보십시오

f=(m,n)=>m?f(m-1,!n||f(m,n-1)):n+1

B.onclick=_=>alert(f(+M.value, +N.value))
#M,#N{max-width:15px;border: 1px solid;border-width:0 0 1px 0}
<div>f(<input id=M />,<input id=N />)</div><br><button id=B>Evaluate</button>


Chrome에서 0.1로 테스트하면 결과가 없습니다.
— Nzall

3
PL 읽기, 이것은 ES6으로 인해 최신 Firefox에서만 작동합니다
— Optimizer

와우 ... 우리는 34 바이트의 4 개의 실질적으로 동일한 JS 솔루션을 가지고 있습니다. 나는 전에 그것을 본 적이 없다.
— ETHproductions

6

파이썬 2.7.8-80 , 54, 48, 46 45

A=lambda m,n:m and A(m-1,n<1or A(m,n-1))or-~n

xnor에게 크레딧!

더 읽기 쉽지만 1 문자가 더 있습니다.

A=lambda m,n:n+(m<1or A(m-1,n<1or A(m,n-1))-n)

에 sys.setrecursionlimit(10000)대한 결과를 얻기 위해 설정 해야하는 것은 아닙니다 A(3,10). 재귀 깊이가 급격히 증가하여 논리적 인덱싱을 사용한 추가 골프는 작동하지 않았습니다.


에 구문 오류가 발생합니다 1else. e숫자는 다음과 같이 쓸 수 있기 때문에 시작 문자 는 파서에 문제를 일으 킵니다 1e3.
— xnor

다음으로 전환하는 몇 가지 문자를 저장했습니다 and/or.A=lambda m,n:m and A(m-1,n<1or A(m,n-1))or-~n
— xnor

@ xnor : 팁 주셔서 감사합니다! 구문 분석 문제 문제에 대해서는 이 토론 을 참조하십시오 . Python 2.7.8은을 허용 1else하지만 대부분의 다른 버전은 허용 하지 않습니다.
— Falko

에 대한 포인터 주셔서 감사합니다 1else; 여기 와 다른 곳 에서 숯을 짜낼 수 있습니다. 그러나 버전마다 다릅니다! 파이썬 2.7.4는 그것을 허용하지 않습니다. 2.7.8의 온라인 버전을 사용 중입니까, 아니면 다운로드해야합니까?
— xnor

@xnor : 오프라인 설치입니다. 예를 들어 ideone.com도 구문 분석에 실패합니다 1else.
— Falko

6

J-26 자

($:^:(<:@[`]`1:)^:(0<[)>:)

Ackermann에 대한보다 기능적인 대체 정의가 있습니다.

Ack 0 n = n+1
Ack m n = Iter (Ack (m-1)) n
Iter f 0 = f 1
Iter f n = f (Iter f (n-1))

너무 그렇게 IterJ는 전달의 방법이 있기 때문에, J에서 쓰기에 매우 쉽습니다 m-1에를 Ack또한의 초기 값 정의 Iter폭발로 설명 1. 일하기를 :

(                      >:)  NB. increment n
                ^:(0<[)     NB. if m=0, do nothing to n+1; else:
   ^:                       NB. iterate...
($:                      )  NB.   self ($: is recursion)
     (<:@[     )            NB.   with left arg m-1
          `]                NB.   n+1 times
            `1:             NB.   starting on 1

이것은 J가 gerund 형식이라고 부르는 것에 의존합니다. ^:기본적으로 모든 경계를 암묵적인 (무점) 방식으로 더 많이 제어 할 수있는 방법입니다.

REPL에서 :

   3 ($:^:(<:@[`]`1:)^:(0<[)>:) 3
61
   ack =: ($:^:(<:@[`]`1:)^:(0<[)>:)
   (i.4) ack"0 table (i.11)
+-----+------------------------------------------+
|ack"0|0  1  2  3   4   5   6    7    8    9   10|
+-----+------------------------------------------+
|0    |1  2  3  4   5   6   7    8    9   10   11|
|1    |2  3  4  5   6   7   8    9   10   11   12|
|2    |3  5  7  9  11  13  15   17   19   21   23|
|3    |5 13 29 61 125 253 509 1021 2045 4093 8189|
+-----+------------------------------------------+
   6!:2 '3 ($:^:(<:@[`]`1:)^:(0<[)>:) 10'  NB. snugly fits in a minute
58.5831

우리 ack는 테이블에 넣을 수 있도록 이름 으로 정의해야 합니다. 왜냐하면 $:끔찍하고 못생긴 짐승이며 그것을 이해하려고 시도하는 사람에게 속이기 때문입니다. self-reference는 self가 그것을 포함하는 가장 큰 동사구로 정의됩니다. table는 부사이므로, 기회를 주면 동사구의 일부가되기를 원하므로, $:그것을 사용하기 위해 명명 된 정의에 갇혀 있어야합니다.


편집 : 24 문자?

몇 년 후, 나는 두 글자가 더 짧은 해결책을 발견했습니다.

(0&<~(<:@#~$:/@,1:^:)>:)

그래도 속도가 훨씬 느립니다 3 ack 8. 내 컴퓨터에서 1 분 이상이 걸립니다. (1) 나는 배를 사용하기 때문입니다 /반복 대신 J 아마 평소보다 일을 기억해야하므로, (2)이 때, 0&<~수행과 같은 계산 (0<[), 실제로 실행 도착 n+1시간을 재귀 단계를 복용하기 전에 호출 m ack n-가 0&<발생 dem 등원이므로 계산을 망치지 않지만 n빨리 커지고 ack재귀 적입니다.

이전 코드 3 ack 10가 15 초 이내에 발견 될 수있는 컴퓨터이기 때문에 더 강력한 머신이 1 분 안에 새로운 코드를 푸시 할 수 있을지 의심 됩니다.


5

C-41 바이트

아무것도 아님-작은 한계는 함수 정의에 따라 순식간에 모든 필수 값을 1 초 이내에 계산할 수 있음을 의미합니다.

A(m,n){return!m?n+1:A(m-1,n?A(m,n-1):1);}


int main()
{
    int m,n;
    for(m = 0; m <= 3; m++)
    for(n = 0; n <= 10; n++)
    printf("%d %d %d\n", m,n,A(m,n));
    return 0;
}

5

자바 스크립트 ES6 (34)

a=(m,n)=>m?a(m-1,n?a(m,n-1):1):n+1

이행:

a=(m,n)=>m?a(m-1,n?a(m,n-1):1):n+1
td[colspan="2"] input{width: 100%;}
<table><tbody><tr><td>m=</td><td><input id="m" type="number" value="0" /></td></tr><tr><td>n=</td><td><input id="n" type="number" value="0" /></td></tr><tr><td colspan="2"><input type="button" value="Calculate!" onclick="document.getElementById('out').value=a(document.getElementById('m').value, document.getElementById('n').value)" /></td></tr><tr><td colspan="2"><input id="out" disabled="disabled" type="text" /></td></tr></tbody></table>


4

자바 스크립트 (ES6)-34

A=(m,n)=>m?A(m-1,!n||A(m,n-1)):n+1

그리고 테스트 :

> A=(m,n)=>m?A(m-1,!n||A(m,n-1)):n+1;s=new Date().getTime();console.log(A(3,10),(new Date().getTime() - s)/1000)
8189 16.441

3

코크, 40

nat_rec _ S(fun _ b n=>nat_iter(S n)b 1)

이것은 유형의 함수입니다 nat -> nat -> nat. Coq는 전체 기능의 구성 만 허용하므로 Ackermann의 재발이 잘 이루어 졌다는 공식적인 증거이기도합니다.

데모:

Welcome to Coq 8.4pl6 (November 2015)

Coq < Compute nat_rec _ S(fun _ b n=>nat_iter(S n)b 1) 3 10.
     = 8189
     : nat

참고 :이 도전 이후에 릴리스 된 Coq 8.5는로 이름이 변경 nat_iter되었습니다 Nat.iter.



2

수학, 46 바이트

0~a~n_:=n+1
m_~a~n_:=a[m-1,If[n<1,1,a[m,n-1]]]

에 대해 정확히 1 분이 걸립니다 a[3,10]. Mathematica의 기본 재귀 제한은 너무 작 a[3,8]거나 (적어도 내 컴퓨터에서는) 초과하지만 구성을 통해 수정할 수 있습니다.

$RecursionLimit = Infinity

1
와우, JS가 Mathematica보다 25 배 이상 빠르다는 말씀이신가요?
— Optimizer

@Optimizer 적어도 재귀에 관해서는 ... 사용할 정의를 매번 알아 내야 If하고 함수가되는 것이 더 느리다 면 부분을 추측 합니다.
— Martin Ender

1
메모를 사용하면 0.07 초가 걸립니다. 즉 m_~a~n_:=m~a~n=...
— 마크 아들러

@MarkAdler Mathematica에서 메모를하는 정말 좋은 방법입니다!
— Martin Ender

2

람다가있는 자바 스크립트, 34

A=(m,n)=>m?A(m-1,n?A(m,n-1):1):n+1

간단한 대답은 더 짧은 것을 만들 수 없습니다.


2

Haskell, 48 44 문자 (목록은 36 자)

다른 Haskell 솔루션만큼 짧지는 않지만 Ackermann 기능을 무한 목록으로 표현하기 때문에 주목할 만합니다. 결과는 [m, n] 위치 에 값 A (m, n)을 보유 하도록 무한리스트 (무한리스트 ) 입니다.

무한 목록 자체 :

iterate(tail.(`iterate`1).(!!))[1..]

기능으로 (사양을 준수하기 위해) :

i=iterate;m%n=i(tail.(`i`1).(!!))[1..]!!m!!n

Ackermann 함수의 일반적인 / 일반적인 경우는 왼쪽의 값을 위의 행에서 색인으로 사용한다는 것을 관찰하여 공식을 도출했습니다. 이 재귀의 기본 경우 (즉, 행의 가장 왼쪽 열, 즉 A (m, 0) )는 위 행에서 두 번째로 가장 왼쪽에있는 값을 사용하는 것입니다. 대 기부 경우 그 재귀가있다 = N + 1 A (0, n)의 경우, 즉 첫 번째 행이다 [1..].

따라서 우리는

let a0 = [1..]
let a1 = tail $ iterate (a0 !!) 1  -- 'tail' because iterate starts by applying
let a2 = tail $ iterate (a1 !!) 1  -- the function 0 times
-- etc

그런 다음 해당 패턴을 기반으로 다른 수준의 반복을 추가하고 무의미한 저글링을 수행합니다.


당신은 별칭 수 iterate즉, 단일 문자 이름i=iterate;ack=i ...
— 자랑 haskeller

@ proudhaskeller 오 예, 그것에 대해 생각하지 않았습니다. 감사! 운영자 이름 사용도 차용합니다.
— FireFly

2

작은 리스프 , 70 (경쟁에서 제외)

언어가 질문보다 새로운 언어이기 때문에 경쟁에서 벗어날 (A 3 10)수 있으며 스택 오버플로로 인해 질문에 필요한대로 실행하지 못합니다 .

(d A(q((m n)(i m(i n(A(s m 1)(A m(s n 1)))(A(s m 1)1))(s n(s 0 1))))))

이것은 AAckermann 함수를 계산 하는 함수 를 정의 합니다. 형식화 :

(d A
   (q( (m n)
       (i m
          (i n
             (A (s m 1)
                (A m
                   (s n 1)
                 )
              ) 
             (A (s m 1)
                1
              )
           )
          (s n
             (s 0 1)
           )
        )
    ) )
 )

여기서는 모든 내장 매크로 ( d(정의) 및 q(따옴표) 및 i(if))와 하나의 내장 함수 ( s– 빼기)를 사용하고 있습니다.

i 조건이 숫자> 0 일 때 (그리고 그렇지 않은 경우) 실제 부분을 실행하므로 여기서 명시 적으로 비교할 필요가 없습니다.

s유일한 연산이 가능하며, 우리는 그것을 사용 n-1/ m-1뿐만 아니라 등 (s n (s 0 1))을위한 n+1.

작은 리스프는 꼬리 재귀 최적화를 사용하지만 A결과 에 대한 외부 호출 에만 도움이 A(m, n-1)되고 매개 변수에 사용되는 호출에는 도움이 되지 않습니다 .

JVM의 Ceylon에서 작은 lisp 구현 을 사용하면 작동 (A 3 5) = 253하지만 (A 2 125)직접 계산하려고 할 때 고장 나는 것처럼 보입니다 (동일한 결과를 제공해야 함). 이후에 계산 (A 3 4) = 125하면 JVM이 내 인터프리터에서 일부 중간 함수 호출을 인라인 할 수있을만큼 함수를 최적화하여 더 많은 재귀 깊이를 허용하는 것으로 보입니다. 이상한.

레퍼런스 구현 에 일어나서 (A 3 5) = 253도 (A 2 163) = 329하지만, 성공하지 못한 (A 2 164)더 적은 따라서 및 (A 3 6) = (A 2 253).


이것은 공백과 괄호를 위해 경쟁 절약이 될 수 있습니다;)
— cat

2

이동, 260 243 240 122 바이트

나는 그 질문에 anon funcs가 허용되는 것을 보지 못했다.

경쟁력이 없지만 나는이 언어를 배우고 있으며 그것을 테스트하고 싶었습니다.

func (m,n int)int{r:=0
switch{case m==0&&n!=0:r=n+1
case m!=0&&n==0:r=a(m-1,1)
case m!=0&&n!=0:r=a(m-1,a(m,n-1))}
return r}

처럼 사용 go run ack.go하고 두 숫자을 공급 m하고 n. m> 4 또는 n> 30 인 경우 실행 시간이 반분을 초과 할 수 있습니다.

에 대한 m=3 n=11:

$ time go run ack
16381
real    0m1.434s
user    0m1.432s
sys     0m0.004s

편집 : switch오버 if/else및 도트 가져 오기 로 전환하여 총 17 바이트 저장


1
더 잘할 수 있습니다! switch 0 {case m:r=n+1 case n:r=a(m-1,1) default:r=a(m-1,a(m,n-1))}Go의 switch진술은 매우 유연합니다!
— EMBLEM

@EMBLEM 고마워, Go 줄을 쓴 지 너무 오래되었지만, 다른 Go-golfers가 있다는 것을 알게되어 기쁩니다. : D
— cat

1

하스켈 : 81 69 바이트

a::Int->Int->Int
a 0 n=n+1
a m 0=a (m-1) 1
a m n=a (m-1) a m (n-1)

a 3 10 약 45 초가 걸립니다.


1
이것은 코드 골프이므로 가능한 가장 짧은 코드를 사용해야합니다. 예를 들어 불필요한 공간과 명시 적 유형을 제거하십시오
— 자랑스러운 haskeller

당신은 또한 네 번째 줄에 괄호를 놓치고 있습니다
— 자랑스런 Haskeller




1

R - 54 52

나는 이것을 R 주위에 내 머리를 잡으려고하는 변명으로 사용 했으므로 아마도 실제로는 잘못되었습니다.)

a=function(m,n)"if"(m,a(m-1,"if"(n,a(m,n-1),1)),n+1)

예제 실행

> a(3,8)
[1] 2045

그 이상으로 스택 오버플로가 발생합니다.

T-SQL-222

T-SQL도 그렇게 할 것이라고 생각했습니다. SQL에서는 재귀가 그리 좋지 않기 때문에 다른 방법을 사용했습니다. 4,2 이상은 폭탄을 공격합니다.

DECLARE @m INT=4,@n INT=1;WITH R AS(SELECT 2 C, 1 X UNION ALL   SELECT POWER(2,C),X+1FROM R)SELECT IIF(@m=0,@n+1,IIF(@m=1,@n+2,IIF(@m=2,2*@n+3,IIF(@m=3,POWER(2,@n+3)-3,IIF(@m=4,(SELECT TOP(1)C FROM R WHERE x= @n+3)-3,-1)))))

R에 {}TCO가 없기 때문에 스택 오버 플로우 제한을 돕는 것은 없지만 R 서브 미션의 경우에는 필요하지 않은 것처럼 보입니다 .
— Giuseppe

@ 주세페 감사합니다 ... 내 방어에, 나는 그때 처음이었다 :)
— MickyT

1

brainfuck , 90 바이트

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

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

IO를 숫자로 사용하여 임의 크기의 셀 크기로 구현을 가정합니다. 음수 셀을 사용하지 않아도되는 경우 -6 바이트

올바른 설정을 선택하면 연결된 인터프리터에서 3,8 초 동안 약 30 초 안에 완료됩니다. 앞에 \s가 붙은 입력 번호 ( 예 : 3,9is) \3\9.


1

Tcl , 67 바이트

proc tcl::mathfunc::A m\ n {expr {$m?A($m-1,$n?A($m,$n-1):1):$n+1}}

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


Tcl , 77 바이트

proc A m\ n {expr {$m?[A [expr $m-1] [expr {$n?[A $m [expr $n-1]]:1}]]:$n+1}}

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

온라인 컴파일러에서는 시간 초과로 인해 실행되지 않지만 로컬 Tcl 인터프리터에서는 잘 실행됩니다. 각 루트 호출을 프로파일 링 A하여 각 쌍의 {m,n}피험자가 테스트 하는 데 걸리는 시간 을 확인했습니다.

m=0, n=0, A=1, time=3.5e-5 seconds
m=0, n=1, A=2, time=2e-6 seconds
m=0, n=2, A=3, time=8e-6 seconds
m=0, n=3, A=4, time=1e-6 seconds
m=0, n=4, A=5, time=2e-6 seconds
m=0, n=5, A=6, time=1e-6 seconds
m=0, n=6, A=7, time=1e-6 seconds
m=0, n=7, A=8, time=1e-6 seconds
m=0, n=8, A=9, time=1e-6 seconds
m=0, n=9, A=10, time=0.0 seconds
m=0, n=10, A=11, time=1e-6 seconds
m=1, n=0, A=2, time=4e-6 seconds
m=1, n=1, A=3, time=6e-6 seconds
m=1, n=2, A=4, time=1e-5 seconds
m=1, n=3, A=5, time=1.2e-5 seconds
m=1, n=4, A=6, time=1.5e-5 seconds
m=1, n=5, A=7, time=2e-5 seconds
m=1, n=6, A=8, time=2e-5 seconds
m=1, n=7, A=9, time=2.6e-5 seconds
m=1, n=8, A=10, time=3e-5 seconds
m=1, n=9, A=11, time=3e-5 seconds
m=1, n=10, A=12, time=3.3e-5 seconds
m=2, n=0, A=3, time=8e-6 seconds
m=2, n=1, A=5, time=2.2e-5 seconds
m=2, n=2, A=7, time=3.9e-5 seconds
m=2, n=3, A=9, time=6.3e-5 seconds
m=2, n=4, A=11, time=9.1e-5 seconds
m=2, n=5, A=13, time=0.000124 seconds
m=2, n=6, A=15, time=0.000163 seconds
m=2, n=7, A=17, time=0.000213 seconds
m=2, n=8, A=19, time=0.000262 seconds
m=2, n=9, A=21, time=0.000316 seconds
m=2, n=10, A=23, time=0.000377 seconds
m=3, n=0, A=5, time=2.2e-5 seconds
m=3, n=1, A=13, time=0.000145 seconds
m=3, n=2, A=29, time=0.000745 seconds
m=3, n=3, A=61, time=0.003345 seconds
m=3, n=4, A=125, time=0.015048 seconds
m=3, n=5, A=253, time=0.059836 seconds
m=3, n=6, A=509, time=0.241431 seconds
m=3, n=7, A=1021, time=0.971836 seconds
m=3, n=8, A=2045, time=3.908884 seconds
m=3, n=9, A=4093, time=15.926341 seconds
m=3, n=10, A=8189, time=63.734713 seconds

{m,n}={3,10}1 분 이상 걸리므로 마지막 쌍에 실패합니다 .

값이 높을수록 값 m을 늘려야합니다 recursionlimit.


나는 그것을 65 바이트로 더 짧게 얻었지만 질문의 요구 사항을 충족시키지 못할 것입니다. 포함하지 않는 {}이 TIO에 시간 제한과 마지막 두 항목의 데모를하지 않습니다.

Tcl , 65 바이트

proc tcl::mathfunc::A m\ n {expr $m?A($m-1,$n?A($m,$n-1):1):$n+1}

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


0

J : 50

>:@]`(1$:~<:@[)`(<:@[$:[$:_1+])@.(0>.[:<:@#.,&*)M.

0 ... 3 vs 0 ... 10에 대해 1 초 단위로 반환합니다.

   A=:>:@]`(1$:~<:@[)`(<:@[$:[$:_1+])@.(0>.[:<:@#.,&*)M.
   timespacex 'res=:(i.4) A"0 table (i.11)'
0.0336829 3.54035e6
   res
┌───┬──────────────────────────────────────────┐
│A"0│0  1  2  3   4   5   6    7    8    9   10│
├───┼──────────────────────────────────────────┤
│0  │1  2  3  4   5   6   7    8    9   10   11│
│1  │2  3  4  5   6   7   8    9   10   11   12│
│2  │3  5  7  9  11  13  15   17   19   21   23│
│3  │5 13 29 61 125 253 509 1021 2045 4093 8189│
└───┴──────────────────────────────────────────┘

PS : "0은 왼쪽과 오른쪽 배열을 움직이지 않고 길이 오류를 생성하는 대신 각 단일 요소에 대해 A를 작동시키는 역할을합니다. 그러나 9 = 2 A 3과 같은 경우에는 필요하지 않습니다.



0

APL, 31

{⍺=0:⍵+1⋄⍵=0:1∇⍨⍺-1⋄(⍺-1)∇⍺∇⍵-1}

꽤 직설적 인. ⍨ 문자를 한 번 사용하여 인수를 반대로하여 1 바이트를 저장합니다. m을 왼쪽 인수로, n을 오른쪽 인수로 사용합니다.

TryAPL.org


0

루비, 65

h,a={},->m,n{h[[m,n]]||=m<1?(n+1):(n<1?a[m-1,1]:a[m-1,a[m,n-1]])}

설명

이것은 문제 설명에 주어진 알고리즘을 매우 간단하게 번역 한 것입니다.

  • 입력은 람다에 대한 인수로 사용됩니다. 두 가지 Integer가 예상됩니다.
  • 속도와 스택 오버플로 오류를 피하기 위해에 답변이 메모에 표시 Hash h됩니다. ||=운전자는 이전에 계산되지 않은 값을 계산하는데 사용된다.

a[3,10] 내 컴퓨터에서 ~ 0.1 초로 계산됩니다.

골 판이없는 버전입니다

h = {}
a = lambda do |m,n|
  h[[m,n]] ||= if m < 1 
    n + 1
  elsif n < 1
    a[m-1,1]
  else
    a[m-1,a[m,n-1]]
  end
end

a[3,10]내 컴퓨터에 SystemStackError 발생 ...
— TuxCrafting 2016 년

골프 nitpicks : 당신은 변경 될 수 있습니다 m<1?(n+1):(n<1?a[m-1,1]:a[m-1,a[m,n-1]])에m<1?n+1:a[m-1,n<1?1:a[m,n-1]]
— 간단하게 아름다운 예술

0

Mouse-2002 , 99 83 바이트

$Y1%j:j.0=m:2%k:k.0=n:m.n.>[k.1+!|m.n.<[#Y,j.1-,1;|m.n.*0=[#Y,j.1-,#Y,j.,k.1+;;]]]@

0

자바, 274 바이트

import java.math.*;class a{BigInteger A(BigInteger b,BigInteger B){if(b.equals(BigInteger.ZERO))return B.add(BigInteger.ONE);if(B.equals(BigInteger.ZERO))return A(b.subtract(BigInteger.ONE),BigInteger.ONE);return A(b.subtract(BigInteger.ONE),A(b,B.subtract(BigInteger.ONE)));}}

이 계산 A(3,10)몇 초에서 무한 메모리 스택 공간 감안할 때의 임의의 조합을 산출 할 수 b와 B한 결과가 2 이하로 2147483647 -1.


나는 그것이 import java.math.*;BigInteger A(BigInteger b,BigInteger B){return b.equals(B.ZERO)?B.add(B.ONE):B.equals(B.ZERO)?A(b.subtract(B.ONE),B.ONE):A(b.subtract(B.ONE),A(b,B.subtract(B.ONE)));}
— 오래

0

실론, 88 87 85

alias I=>Integer;I a(I m,I n)=>m<1then n+1else(n<1then a(m-1,1)else a(m-1,a(m,n-1)));

이것은 간단한 구현입니다. 형식화 :

alias I => Integer;
I a(I m, I n) =>
        m < 1
        then n + 1
        else (n < 1
            then a(m - 1, 1)
            else a(m - 1, a(m, n - 1)));

별칭은 1 바이트 만 저장하고 ( Integer대신 쓰기 사용 I) 86 바이트가됩니다. 다른 2 바이트는 두 번 대체 == 0하여 저장할 수 있습니다 < 1.

의 기본 설정으로 ceylon run, 그것까지 작동합니다 A(3,12) = 32765(그리고 A(4,0) = 13),하지만 A(3,13)(따라서도 A(4,1)) 스택 오버플로 오류가 발생합니다. ( 내 컴퓨터 A(3,12)에서는 약 5 초, A(3,11)약 3 초가 걸립니다 .)

사용 ceylon run-js을 많이 느 (필요에 1 분 19의 (즉 Node.js를 자바 스크립트로 컴파일의 결과를 실행) A(3,10)이미), 및 휴식을위한 A(3, 11)1 실행 후»최대 호출 스택의 크기를 초과와«(기본 설정을 사용하여) 최소 30 초


재귀없는 실론, 228

보너스로, 여기에는 비 재귀 버전이 있습니다 (물론 더 길지만 스택 오버플로에 영향을받지 않습니다. 어느 시점에서 메모리 부족 오류가 발생할 수 있습니다).

import ceylon.collection{A=ArrayList}Integer a(Integer[2]r){value s=A{*r};value p=s.addAll;while(true){if(exists m=s.pop()){if(exists n=s.pop()){if(n<1){p([m+1]);}else if(m<1){p([n-1,1]);}else{p([n-1,n,m-1]);}}else{return m;}}}}

형식화 :

import ceylon.collection {
    A=ArrayList
}

Integer a(Integer[2] r) {
    value s = A { *r };
    value p = s.addAll;
    while (true) {
        if (exists m = s.pop()) {
            if (exists n = s.pop()) {
                if (n < 1) {
                    p([m + 1]);
                } else if (m < 1) {
                    p([n - 1, 1]);
                } else {
                    p([n - 1, n, m - 1]);
                }
            } else {
                // stack is empty
                return m;
            }
        }
    }
}

내 컴퓨터에서는 재귀 버전보다 속도가 느립니다. A(3,11)9.5 초, A(3,12)34 초, A(3,13)2:08 분, A(3,14)8:25 분이 걸립니다. (나는 원래 내가 가지고있는 튜플 대신 게으른 iterables를 사용하는 버전을 가지고 있었는데, 같은 크기로 훨씬 느 렸습니다.)

조금 더 빠른 (21 초 A(3,12)) (그러나 1 바이트 더 큼 )은 s.push대신을 사용하는 버전 s.addAll이지만 여러 개의 숫자를 추가하려면 각각 단일 정수가 필요하기 때문에 여러 번 호출해야했습니다. ArrayList 대신 LinkedList를 사용하면 속도가 훨씬 느려집니다.

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