n 번째 과다 작동 평가


12

나는 이것이 약간 수학이라는 것을 알고 있지만 여기에 간다.

수학에서 하이퍼 연산 시퀀스는 후속 연산의 단항 연산으로 시작한 다음 산술 연산, 곱셈 및 지수의 이항 연산으로 계속되는 무한 산술 연산 시퀀스입니다 (과잉 연산이라고 함). 오른쪽 연관성을 이용한 지수.

목표는 세 개의 정수 x, y 및 n을 입력으로 사용하고 x 및 y에서 n 번째 하이퍼 연산의 결과를 출력하는 프로그램을 작성하는 것입니다.

예 :

1 1 1 출력 2

2 4 4 출력 65536

3 3 4 출력 7625597484987

  • 프로그램은 가장 짧은 코드로 작성해야합니다.
  • STDIN파일 에서 또는 파일에서 입력을받을 수 있습니다 .
  • 라이브러리 기능이 허용되지 않습니다.
  • 입력 제약 : n은 1 이상입니다.

http://en.wikipedia.org/wiki/Tetration에 머리를 감쌀 수없는 경우에 대한 설명이 있습니다.


무엇입니까 n=1? 그것의 경우 x+yx+1, 1 1 1반환해야합니다2
존 드보락

나는 내가 어딘가에 실수를했다는 것을 알았다.
Soham Chowdhury

1
나는 의사 코드를 작성했고 그것이 실제로 유효한 루비 코드라는 것을 깨달았다. (거의 :-()
John Dvorak

1
아니요, n> = 1 만 해당합니다.
Soham Chowdhury

답변:


4

루비, 천천히 86 84 83 자

def f x,y,n
n>1?(c=x;2.upto(y){c=f(x,c,n-1)};c):x+y
end
p f *gets.split.map(&:to_i)

루비, 빨리 96 94 93 자

def f x,y,n
n>1?(n>2?(c=x;2.upto(y){c=f(x,c,n-1)};c):x*y):x+y
end
p f *gets.split.map(&:to_i)

첫 번째 버전은 방법 내가 버전을 추가, 그래서 마지막 테스트 케이스와 너무 느린 대신 추가의 기본 경우와 사용의 곱셈. 첫 번째 버전은 계산하는 데 시간이 걸립니다 3 3 4. 두 번째는 순식입니다 (기본 IRB 콘솔에서; 웹 버전이 약간 느립니다).

루비의 여러 가지 아름다움이 여기에 표시됩니다.

거의 모든 문장은 루비로 표현됩니다. 따라서 충분한 괄호가 있다면 삼항 연산자 안에 세미콜론을 넣을 수 있습니다. Coffeescript가 그 것을 빌 렸습니다. 또한 루비의 "필요하지 않은"호출 구문을 빌렸다.

암시 적 반환 :이 기능은 멋진 기능이며 이전 기능을 따릅니다. 실제로, return골프가 아닌 경우에도 함수의 마지막 줄을 시작하는 것은 절름발이로 간주됩니다.

숫자는 루비로 된 객체입니다 (물론 null객체 임). 루비에서 정수에는 메소드가 있으며 times, 전달 된 블록을 여러 번 실행합니다. 이것은 루비의 많은 반복자 방법 중 하나입니다. 이 upto방법을 사용하면 우리가 할 수있는 것보다 두 개의 문자를 더 저장할 times수 있습니다.

단항 *은 스 플랫 연산자입니다. 배열을 인수 목록으로 바꿉니다. Javascript와 비슷 Function#apply하지만 더 짧고 좋습니다.

단항 &은 프로 시저를 블록으로 바꿉니다. 하지만 :to_i상징, 그것은 꽤 잘 절차로 변환합니다. 즉, to_i인수 를 호출 하고 결과를 반환 하는 프로 시저로 바뀝니다 . 스택 오버플로에 대한 자세한 내용

n=3기본 사례로 사용하여 더 빨리 얻을 수는 있지만 필요하지 않은 것 같습니다. 하지만 루비의 또 다른 아름다움 인 지수 연산자 덕분에 11 자에 불과 **합니다. 파이썬에는이 연산자가 있지만 첫 번째 연산자는 아닙니다 (@ aka.nice이 지적했듯이-Fortran은 이미이 연산자를 가지고 있습니다).

온라인 루비 인터프리터 : http://repl.it/Ikj/1


좋지만 3 3 4:) 에서 출력을 기다리는 중입니다. :) 매우 느립니다.
Soham Chowdhury

@SohamChowdhury 기본 케이스는 추가입니다. 기본 곱셈의 경우 매우 느릴 것입니다. 대신 지수로 테스트하는 것이 좋습니다 ;-)
John Dvorak

그것은 사용 메모이 제이션에 시간을 절약 할 수 있지만, 어떤 바이트 (꽤) 비용이
존 드보락

다음 버전을 추가하십시오 :)
Soham Chowdhury

1
운영자는 ** 이미 이하의 1 개 문자를 화살표 것이 50 년대와 ALGOL에서 FORTRAN 존재
aka.nice

6

APL, 62

{1=3⌷⍵:2⌷+\⍵⋄0=2⌷⍵:(⍵[3]⌊3)⌷⍵[1],0,1⋄∇⍵[1],(∇⍵-0 1 0),3⌷⍵-1}⎕

{...}⎕: 평가 된 입력 (공백으로 구분 된 숫자는 숫자 형 배열로 평가됨)을 취하고 함수를 적용합니다.

1=3⌷⍵:다음과 같은 경우, n은 1 ... 같다
2⌷+\⍵: 제 2 개 요소 (X + Y)의 환원 액을 ...
⋄0=2⌷⍵:: y는 0 일 경우 그렇지 ...
(⍵[3]⌊3)⌷⍵[1],0,1: 숫자 배열 [X, 0, 1]과 리턴 인덱스를 생성 min(n,3)...
⋄∇⍵[1],(∇⍵-0 1 0),3⌷⍵-1: 그렇지 않으면 ∇ (x, ∇ (x, y-1, n), n-1)을 반환합니다. (∇는 자기 참조입니다)


나는 "하이퍼 라이저"연산자를 가지고 있는데,이 함수는 함수를 취해 다음 과다 동작을 반환합니다.

{⍺⍺/⊃⍴/⌽⍵}

예를 들어, +{⍺⍺/⊃⍴/⌽⍵}곱셈 함수와 +{⍺⍺/⊃⍴/⌽⍵}5 3출력 15입니다.

그러나 재귀 할 수는 없습니다. 다른 사람이 할 수 있습니다.


아, APL. 간단하게 파이썬을 이길 수 있습니다. </ sarcasm> 어떻게 실행합니까?
Soham Chowdhury

2

파이썬, 83

( flornquake의 답변을 기반으로 )

def h(x,y,n):r=n>2;exec"r=h(x,r,n-1);"*y*(n>1);return(x+y,r)[n>1]
print h(*input())

큰 결과는 매우 느립니다.

들면 2, 4, 4출력이다 65536.


"매우 느리다"는 나의 86 자 솔루션이 나쁜 것으로 간주 된 이유입니다.
John Dvorak

1
@ JanDvorak : 왜 그것이 나쁜 것으로 간주됩니까? Soham Chowdhury는 속도가 느리고 솔루션을 교체하지 않고 다른 버전을 추가해야한다고 말했다. (그러나 어쩌면 나는 그것을 오해했을 것입니다.)
Monica Monica Reinstate

네가 옳아; 짧은 버전을 복원했습니다. 이제 나는 당신보다 더 긴 문자입니다.
John Dvorak

@WolframH 정확하게. 버전이 항상 좋습니다.
Soham Chowdhury

2

파이썬, 96 92

def h(x,y,n):r=1;exec(n>2)*y*"r=h(x,r,n-1);";return(r,(x+y,x*y)[n>1])[n<3]
print h(*input())

입력 : 3, 3, 4
출력 :7625597484987

@WolframH의 아이디어를 사용하여 단축했습니다 .


2

느린 골프 스크립트, 39 자

 ~{\(.{3${[4$\2$4$.~}4$(*}{;;+}if])\;}.~

(라이브 링크)

이것은 기본 대 / 소문자가 n = 1 (더하기) 인 표준 재귀 알고리즘입니다 (즉, 느림). Ruby 솔루션 에서 사용한 것과 동일

내 주석이있는 버전이 있습니다 (주로 스택 유지). 나중에 추가 한 최적화는 포함되어 있지 않습니다.

~{            #read the input and do (x y n f)
 \(.{         #(x y f n-1); if(n-1)
  3${         #(x y f n-1 c)
   4$\2$4$.~  #(x y f n-1 x c n-1 f); call
  }3$(*       #y-1 times
  {\;}4*
 }{           #else
  ;;+         #return (x+y)
 }if
}.~           #once

~평가 연산자입니다. 문자열의 경우 문자열을 GolfScript 프로그램으로 취급합니다. 다행히 공백으로 구분 된 정수 목록은 해당 정수를 스택에 푸시하는 유효한 GolfScript 프로그램입니다. 이것과 비교하여 이전 버전의 입력 루틴 (" "/{~}/ , 공간으로 나눔과 평가)은 상당히 절름발이입니다. 함수의 경우 함수를 호출합니다. .(클론) 이 앞에 오면 , 첫 번째 인수로 함수를 호출합니다.

Golfscript는 재귀 알고리즘을 만드는 데 적합하지 않은 것 같습니다. 꼬리 호출에 최적화 할 수없는 재귀 알고리즘을 원한다면 변수를 보존하기 위해 스택 프레임을 생성하고 파괴해야합니다. 대부분의 언어에서이 작업은 자동으로 수행됩니다. 골프 스크립트에서는 실제로 변수를 복제하고 (실제로 스택 항목) 더 이상 필요없는 스택 항목을 제거해야합니다. Golfscript에는 스택 프레임 개념이 없습니다. GolfScript가 스택 기반 언어라고 말했습니까?

첫 번째 요구 사항은 이해할 수 있습니다. 어떻게 든 인수를 지정해야합니다. 그들이 원래 위치를 유지하는 경우에만 좋습니다. 두 번째 요구 사항은 불행히도, 특히 반환 값이 스택의 맨 위에 있고 golfscript에는 스택 요소 만 삭제할 수있는 기능이 없기 때문입니다. 스택을 회전시키고 새로운 상단 요소를 버릴 수는 있지만 빠르게 쌓입니다. \;괜찮습니다. \;\;\;\;\;그렇지 않습니다. \;루프에서 수행 할 수 있습니다 ( {\;}9*; 비용 : 최대 9 개의 요소를 버리는 6 자 또는 최대 99 개의 요소를 버리는 7 자). 우리는 더 잘 할 수 있습니다.

Golfscript에는 일류 어레이가 있습니다. 또한 배열 리터럴 구문이 [1 2 3 4]있습니다. 어떤 예기치 않은 것은 것입니다 [및이 ]실제로 구문의 일부가 아닙니다. 그들은 단지 두 개의 연산자 일뿐입니다 : [스택에서 현재 위치를 표시하고] 배열 시작 마크를 찾거나 스택이 다 떨어질 때까지 모든 요소를 ​​수집하고 마크를 버립니다. 이 두 가지를 찢어서 어떤 일이 일어나는지 볼 수도 있습니다. 글쎄, 꽤 흥미로운 점은 :

golfscript에 스택 프레임 개념이 없다고 말했습니까? 나는 거짓말했다. 이것은 스택 프레임 [입니다. 한 번에 모두 버릴 수 있습니다 ];.. 그러나 반환 값을 유지하려면 어떻게해야합니까? :, 또는 우리는 스택 프레임을 닫고 완전히 폐기의 마지막 요소를 대신 취할 수 - 당신은 (하지 흥미로운 개념을 우리가 통과별로 배열의 약간 난도질 버전이 다음) 함수 항목의 스택 프레임을 닫을 수 있습니다 ]-1=또는 우리 대신 마지막 요소를 제외 하고 프레임 버릴 수 ])\;있습니다. 그것들은 길이는 같지만 후자는 약간 더 시원하므로 사용하고 있습니다.

정리를 위해 6 ~ 7 자 대신 5로 할 수 있습니다. 여전히 골프를 더 많이 할 수 있다고 생각하지만 문자를 저장했습니다.


"재귀에 대한 첫 번째 주장으로 함수를 호출한다"-재귀에 대한 흥미로운 아이디어
SE가 EVIL이기 때문에 아디 츠는 종료

1

스몰 토크 스 퀴크 4.x 맛 많은 바이트!

71 문자로 Integer에서 재귀 양식 중 하나를 구현할 수 있습니다.

f:y n:n n=1or:[^(2to:y)inject:self into:[:x :i|self f:x n:n-1]].^self+y

그런 다음 파일이나 FileStream stdin에서 읽는 데 비용이들 것입니다 ... Squeak은 분명히 스크립팅 언어로 설계되지 않았습니다. 따라서 문제와 관련이없는 범용 유틸리티를 만드는 데 많은 바이트를 소비합니다.

스트림에서 21 개의 char 메소드 구현 (시파 레이터 건너 뛰기)

s self skipSeparators

이 20 문자 메소드를 Behavior에서 구현합니다 (Stream에서 인스턴스를 읽기 위해).

<s^self readFrom:s s

그런 다음 문자열에 28 문자 (파일 핸들 만들기)

f^FileDirectory default/self

그런 다음 FileDirectory에 59 개의 문자 (readStream을 작성하기 위해)

r^FileStream concreteStream readOnlyFileNamed:self fullName

그런 다음 BlockClosure에서 33 문자 (n 번 평가하기 위해)

*n^(1to:n)collect:[:i|self value]

그런 다음 Array에서 63 개의 문자 (수신자를 사용하여 인수와 Array에서 가져온 인수를 평가)

`s^self first perform:s asSymbol withArguments:self allButFirst

그런 다음 x라는 파일에서 읽을 수있는이 31 문자 조각을 평가하여 문제를 해결하십시오.

|s|s:='x'f r.[0class<s]*3`#f:n:

유틸리티를 세지 않아도 71 + 31 = 102 문자입니다 ...

이제 codeGolf를 잃어 버릴 것이므로 Integer에서 더 재미있는 구현이 있습니다.

doesNotUnderstand:m
    (m selector allSatisfy:[:c|c=$+])or:[^super doesNotUnderstand:m].
    self class compile:
        m selector,'y y=0or:[^(2to:y)inject:self into:[:x :i|self'
        ,m selector allButLast,'x]].^'
        ,(Character digitValue:()asBit)
        ,(m selector size-2min:1)hex last.
    thisContext sender restart

이 메소드는 존재하지 않는 경우 (메시지 m의 수신자가 이해할 수없는) n +로 작성된 2 진 메시지를 정의 (컴파일)하고 송신자 컨텍스트의 시작에서 실행을 다시 시작합니다. 가독성을 위해 추가 캐리지 리턴과 공백을 삽입했습니다.

(m selector size-2min:1)hex last의 단락 된 형태이다 (m selector size>2)asBit printString.

스몰 토크 사악한 초강대국을 보여주지 않는다면, 마지막 진술은 더 짧고 간단한 것으로 대체 될 수 있습니다

^m sendTo:self

이제 문자로 28 문자 유틸리티를 구현하십시오 (문자열에서 n 번 반복하십시오)

*n^String new:n withAll:self

그런 다음이 43 자 표현식을 평가하십시오.

|i s|i:=0class.s:='x'f r.[i<s]*2`($+*(i<s))

Integer로 구현하여 10 개 이상의 문자로 가속화 할 수 있습니다.

++y^self*y

우리가 대체 할 수 있기 때문에이 경우 우리는 또한 짧은 코드가 ^',(m selector size-2min:1)hex last함께^1'

이러한 높은 가격의 경우 코드는 두 번째 정수 = 0으로 작동합니다.


0

그루비-77

h={x,y,n->n<2?x+y:y<2?x:h(x,h(x,y-1,n),n-1)}
print h(args.collect{it as int})

참고 : 작지 않은 인수에는 음란 한 양의 스택 (및 시간)이 필요합니다.


0

AXIOM 컴퓨터 대수 시스템, 바이트 69

p(x,y,n)==(n<=1=>y+x^n;n=2=>y*x;n=3=>x^y;y<=0=>1;p(x,p(x,y-1,n),n-1))

테스트:

(2) -> p(1,1,1)
   (2)  2
                                                 Type: Expression Integer
                                   Time: 0.05 (IN) + 0.03 (OT) = 0.08 sec
(3) -> p(2,4,4)
   (3)  65536
                                                 Type: Expression Integer
                                                              Time: 0 sec
(4) -> p(3,3,4)
   (4)  7625597484987
                                                 Type: Expression Integer
                                                              Time: 0 sec

이것은 재귀를 제거 할 것입니다 ... 일부 반환에서 x와 y를 바꿀 수 있습니다 ... 다른 테스트 값이 있습니까?


0

APL (NARS), 문자 61, 바이트 122

{(x y n)←⍵⋄n≤1:y+x*n⋄n=2:x×y⋄n=3:x*y⋄y≤0:1⋄∇x,(∇x(y-1)n),n-1}

테스트:

  h←{(x y n)←⍵⋄n≤1:y+x*n⋄n=2:x×y⋄n=3:x*y⋄y≤0:1⋄∇x,(∇x(y-1)n),n-1}
  h 1 1 1
2
  h 2 4 4
65536
  h 3 4 4
∞
  h 3 3 4
7625597484987
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.