ในทางทฤษฎีส่งออกหมายเลขของเกรแฮม


44

หมายเลขของ Graham Gถูกกำหนดในลักษณะนี้:

u(3,n,1) = 3^n
u(3,1,m) = 3
u(3,n,m) = u(3,u(3,n-1,m),m-1)
[Knuth's up-arrow notation]
[Conway chained arrow notation]

THEN

g1 = u(3,3,4)
g2 = u(3,3,g1)
g3 = u(3,3,g2)
...
G = u(3,3,g63)

คุณได้รับu(3,3,2)=7625597484987รหัสเพื่อตรวจสอบรหัสของคุณ

งานของคุณคือการเขียนโปรแกรม / ฟังก์ชั่นที่จะส่งออกค่าGกำหนดอย่างแน่นอนกำหนดขนาดจำนวนเต็มและเวลาเพียงพอ

อ้างอิง

ลีดเดอร์บอร์ด


2
ที่เกี่ยวข้อง
Leun Nun

7
การสุ่มอนุญาตหรือไม่ ถ้าฉันเพิ่งส่งออกค่าสุ่มในที่สุดก็จะต้องมีการสร้างหมายเลขเกรแฮม
ไมล์

15
@miles ทำไมบนโลกนี้ไม่ได้เป็นช่องโหว่มาตรฐานอยู่แล้ว? ชี้แจง
Leun Nun

18
คำเตือน: u (3, 3, 2) = u (3, 2, 3) = 7625597484987 ดังนั้นคุณจะต้องทดสอบค่าอื่น ๆ เช่น u (3, 5, 1) = 243 เพื่อให้แน่ใจว่าคุณได้รับ อาร์กิวเมนต์ลำดับถูกต้อง
Anders Kaseorg

คำตอบ:


48

แคลคูลัสแลมบ์ดาไบนารี , 114 bits = 14.25 ไบต์

hexdump:

00000000: 4457 42b0 2d88 1f9d 740e 5ed0 39ce 80    DWB.-...t.^.9..

เลขฐานสอง:

010001000101011101000010101100000010110110001000000111111001110101110100000011100101111011010000001110011100111010

คำอธิบาย

01 00                                           (λx.
│    01 00                                        (λy.
│    │    01 01 01 110                              x
│    │    │  │  └─ 10                               y
│    │    │  └─ 00                                  (λm.
│    │    │       01 01 01 10                         m
│    │    │       │  │  └─ 00                         (λg.
│    │    │       │  │       00                         λn.
│    │    │       │  │         01 01 10                  n
│    │    │       │  │         │  └─ 110                 g
│    │    │       │  │         └─ 00                     (λz.
│    │    │       │  │              10                     z))
│    │    │       │  └─ 00                            (λn.
│    │    │       │       00                            λf.
│    │    │       │         01 111110                    x
│    │    │       │         └─ 01 110                    (n
│    │    │       │            └─ 10                      f))
│    │    │       └─ 1110                             x)
│    │    └─ 10                                     y)
│    └─ 00                                        (λf.
│         00                                        λz.
│           01 110                                   f
│           └─ 01 01 1110                            (x
│              │  └─ 110                              f
│              └─ 10                                  z)))
└─ 00                                           (λf.
     00                                           λz.
       01 110                                      f
       └─ 01 110                                   (f
          └─ 01 110                                 (f
             └─ 10                                   z)))

นี่คือ (λ x . (λ y . x ym . mg . λ n . n g 1)) (λ n . λ f . x ( n f )) x ) y ) (λ f . λ z . f ( x f z ))) 3 ซึ่งตัวเลขทั้งหมดจะแสดงเป็นเลขคริสตจักร. คริสตจักรเลขเป็นตัวแทนแลมบ์ดาแคลคูลัสมาตรฐานของจำนวนธรรมชาติและพวกเขาจะเหมาะกับปัญหานี้เพราะจำนวนคริสตจักรจะถูกกำหนดโดยย้ำฟังก์ชั่น: n กรัมเป็นn TH สำทับของฟังก์ชันกรัม

ตัวอย่างเช่นถ้ากรัมเป็นฟังก์ชั่นλ n λ f . 3 ( n ) ที่ 3 คูณด้วยตัวเลขโบสถ์แล้วλ n n g 1 คือฟังก์ชั่นที่ใช้ 3 กับพลังของเลขศาสนจักร ทำซ้ำการดำเนินการนี้ม.ครั้งให้

mg . λ n . n g 1) (λ n . λ f . 3 ( n f )) n = u (3, n , m )

(เราใช้การคูณu (-, -, 0) แทนการยกกำลังu (-, -, 1) เป็นกรณีฐานเนื่องจากการลบ 1 จากตัวเลขในศาสนจักรไม่เป็นที่พอใจ )

แทนn = 3:

mg . λ n . n g 1) (λ n . λ f . 3 ( n f )) 3 = u (3, 3, m )

วนซ้ำการดำเนินการ 64 ครั้งโดยเริ่มที่m = 4

64 (λ . ม.กรัม . λ n . n กรัม 1) (λ n . λ . 3 ( n )) 3) 4 = G

ในการออปติไมซ์นิพจน์นี้ให้แทนที่ 64 = 4 ^ 3 = 3 4:

3 4 (λ . ม.กรัม . λ n . n กรัม 1) (λ n . λ . 3 ( n )) 3) 4 = G

โปรดจำไว้ว่า 4 = Succ 3 = λ ฉ λ Z f (3 f z ) เป็นอาร์กิวเมนต์แลมบ์ดา:

y . 3 ym . mg . λ n . n g 1)) (λ n . λ f . 3 ( n f )) 3) y ) (λ f . λ z . f (3 f Z )) = G

สุดท้ายจำ 3 = λ ฉ λ Z f ( f ( f z )) เป็นอาร์กิวเมนต์แลมบ์ดา:

x . (λ Y . x Y . ม.กรัม . λ n . n กรัม 1) (λ n . λ . x ( n )) x ) Y ) (λ . λ Z F ( x Z ))) 3 = G


เราจะหาล่ามสำหรับภาษานี้ได้ที่ไหน
Dennis

4
@Dennis tromp.github.io/cl/cl.htmlมีสองสามข้อ
Anders Kaseorg

1
นี้เป็นที่น่ากลัว นี่สมควรได้รับรางวัลมากมาย
แมว

1
14.25 bytesดูเหมือนจะเลอะกระดานผู้นำ มันแยกเป็น25 bytesและคุณจะถูกวางไว้เป็นที่สอง
Dan

1
@Dan ฉันแก้ไขส่วนย่อยของกระดานผู้นำฉันคิดว่า
Anders Kaseorg

40

Haskell, 41 ไบต์

i=((!!).).iterate
i(($3).i(`i`1)(*3))4 64

คำอธิบาย:

(`i`1)f n= i f 1 nคำนวณnย้ำ TH ของฟังก์ชั่นเริ่มต้นที่f 1โดยเฉพาะอย่างยิ่ง(`i`1)(*3)n= 3 ^ nและการก่อสร้างนี้ซ้ำmคูณให้i(`i`1)(*3)m n= u (3, n , m ) เราสามารถเขียนว่า(($n).i(`i`1)(*3))m= U (3, n , ม. ) และย้ำการก่อสร้างนี้kครั้งเพื่อให้ได้i(($3).i(`i`1)(*3))4 k= กรัม _ k


16

Haskell, 43 ไบต์

q=((!!).).iterate
g=q(`q`1)(3*)
q(`g`3)4$64

มีวิธีที่ดีกว่าในการพลิกgอินไลน์

46 ไบต์:

i=iterate
n%0=3*n
n%m=i(%(m-1))1!!n
i(3%)4!!64

48 ไบต์:

n%1=3^n
1%m=3
n%m=(n-1)%m%(m-1)
iterate(3%)4!!64

เพียงแค่เขียนคำจำกัดความ

เคสพื้นฐานเป็นบิตที่สะอาดกว่าสำรองถึง 0 แม้ว่าจะไม่มีการบันทึกไบต์ บางทีมันอาจจะทำให้การเขียนคำจำกัดความทางเลือกง่ายขึ้น

n%0=3*n
0%m=1
n%m=(n-1)%m%(m-1)
z=iterate(3%)2!!1

คุณสามารถใช้ฟังก์ชั่นอื่นที่มีความสำคัญต่ำกว่า+เพื่อลบวงเล็บระหว่างกันได้m-1หรือไม่?
Leun Nun

ฉันนับ 44 ไบต์และเกิดอะไรขึ้นกับ 4 และ 64
Leun Nun

โอ๊ะฉันคัดลอกในการทดสอบพารามิเตอร์ขนาดเล็กลงแล้ว ฉันไม่คิดว่าฉันจะเปลี่ยนลำดับความสำคัญของโอเปอเรเตอร์ได้เพราะฉันกำหนดฟังก์ชั่นใหม่ ฉันไม่สามารถเขียนทับฟังก์ชันที่มีอยู่ได้
xnor

ฉันหมายถึงฉันนับ 44 ไบต์หลังจากที่คุณเปลี่ยนกลับเป็น 64
Leun Nun

ฉันคิดว่าคุณหมายถึงไม่ได้(`g`3) (3`g`)
Anders Kaseorg

10

Pyth, 25 ไบต์

M?H.UgbtH*G]3^3Gug3tG64 4

ส่วนแรกกำหนดวิธีการM?H.UgbtH*G]3^3Gg(G,H) = u(3,G,H+1)

เพื่อทดสอบส่วนแรกตรวจสอบว่า7625597484987=u(3,3,2)=g(3,1): g3 1.

ส่วนที่สองug3tG64 4เริ่มต้นจากr0 = 4นั้นคำนวณrn = u(3,3,r(n-1)) = g(3,r(n-1))64 ครั้งออกผลลัพธ์สุดท้าย ( rเลือกแทนgเพื่อหลีกเลี่ยงความสับสน)

ส่วนหนึ่งในการทดสอบนี้เริ่มต้นจากr0=2และคำนวณแล้ว:r1ug3tG1 2


ถ้า g (G, H) = u (3, G, H + 1) คุณควรมี r (n) = u (3, 3, r (n - 1)) = g (3, r (n - 1) ) - 1) ไม่ใช่ g (3, r (n - 1)) ฉันคิดว่ารหัสของคุณถูกต้อง แต่คำอธิบายของคุณไม่มี - 1
Anders Kaseorg

คุณสามารถบันทึกไบต์โดยใช้ข้อโต้แย้งยู unoffsetted ( ^3*3, tGG) และไบต์อื่นที่มี↦.UgbtH*G]3 e.ugNtHG1
Anders Kaseorg

อีกทางหนึ่งที่จะบันทึกว่าไบต์ที่สองคือ↦*G]3 ShG
Anders Kaseorg

8

Sesosขนาด 30 ไบต์

0000000: 286997 2449f0 6f5d10 07f83a 06fffa f941bb ee1f33  (i.$I.o]...:....A...3
0000015: 065333 07dd3e 769c7b                              .S3..>v.{

ถอดชิ้นส่วน

set numout
add 4
rwd 2
add 64
jmp
    sub 1
    fwd 3
    add 3
    rwd 1
    add 1
    jmp
        sub 1
        jmp
            fwd 1
            jmp
                jmp
                    sub 1
                    fwd 1
                    add 1
                    rwd 1
                jnz
                rwd 1
                jmp
                    sub 1
                    fwd 3
                    add 1
                    rwd 3
                jnz
                fwd 3
                jmp
                    sub 1
                    rwd 2
                    add 1
                    rwd 1
                    add 1
                    fwd 3
                jnz
                rwd 1
                sub 1
            jnz
            rwd 1
            jmp
                sub 1
            jnz
            add 1
            rwd 1
            sub 1
        jnz
        fwd 1
        jmp
            sub 1
            rwd 1
            add 3
            fwd 1
        jnz
        rwd 2
    jnz
    rwd 1
jnz
fwd 2
put

หรือในรูปแบบ Brainfuck:

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

การทดสอบ

การคำนวณยู (3, n , U (3, n ... U (3, n , ม. ) ... )) กับkซ้อนโทรไปยังยูแทนที่สามคนแรกaddคำแนะนำadd 4, add 64, add 3กับadd m, add k, add nตามลำดับ เนื่องจาก Sesos ไม่สามารถสร้างตัวเลขได้เร็วกว่าเวลาเชิงเส้นคุณจึงถูก จำกัด ให้มีค่าน้อยเช่นu (3, 2, 2) = 27, u (3, 5, 1) = 243 และu (3, 1 , u (3, 1, … u (3, 1, m ) …)) = 3


คุณสามารถแทนที่[-]ด้วย,ตั้งแต่ EOF 0คือ
mbomb007

6

JavaScript (ES7), 63 ไบต์

u=(n,m)=>n>1&m>1?u(u(n-1,m),m-1):3**n
g=n=>n?u(3,g(n-1)):4
g(64)

@AndersKaseorg Ugh ในกรณีนั้นฉันก็อาจยกเลิกการเปลี่ยนแปลงนั้นได้เช่นกัน
Neil

สิ่งนี้ทำให้เกิดการโอเวอร์โฟลว์ของสแต็กอาจจำเป็นต้องตรวจสอบรูปแบบการตรวจสอบซ้ำของคุณอีกครั้ง
NodeNodeNode

นี่ไม่ใช่ ES7 ธรรมดา นี่คือ ES7 ที่ไม่ได้ จำกัด (ตัวแปรในจินตนาการของ ES7 แต่มี bignum, สามารถพยากรณ์ได้อย่างไม่ จำกัด และใช้ทศนิยมด้วย / # xE ^ เป็นชวเลข)
user75200

5

Brachylog , 57 ไบต์

4:64:1iw
:3{[1:N],3:N^.|t1,3.|hM:1-X,?t:1-:Mr:2&:Xr:2&.}.

STDOUTคาดว่าจะไม่มีการป้อนข้อมูลหรือขาออกและเขียนผลให้ สิ่งนี้จะสร้างสแต็คโอเวอร์โฟลว์ ณ จุดหนึ่ง

หากต้องการตรวจสอบว่างานนี้ได้ค่าขนาดเล็ก (เช่นu(3,3,2)) คุณสามารถแทนที่4ด้วยค่าของmและมี641

คำอธิบาย

นี่เป็นการใช้งานที่ตรงไปตรงมาของวิธีการคำนวณตัวเลข

  • ภาคแสดงหลัก:

    4:64:1i                    Call Predicate 1 64 times with 4 as initial input (the second
                               call takes the output of the first as input, etc. 64 times).
           w                   Write the final output to STDOUT
    
  • คำกริยาที่ 1:

    :3{...}.                   Call predicate 2 with input [Input, 3]. Its output is the 
                               output of predicate 1.
    
  • คำกริยาที่ 2:

    [1:N],                     M = 1
          3:N^.                Output = 3^N
    |                          Or
    t1,                        N = 1
       3.                      Output = 3
    |                          Or
    hM:1-X,                    X is M - 1
           ?t:1-:Mr:2&         Unify an implicit variable with u(3,N-1,M)
                      :Xr:2&.  Unify Output with u(3,u(3,N-1,M),X)
    

5

คาราเมล , 38 ไบต์

(64 ((f->(f,1)),(n f->(3 (n f))),3) 4)

นี่คือ syntactic sugar สำหรับแลมบ์ดานิพจน์นิพจน์ 64 (λ m . mf . λ n . n f 1)) (λ n . λ f . 3 ( n f )) 3) 4 ซึ่งตัวเลขทั้งหมดถูกแทนด้วยคริสตจักร เลข


(n f->3 (n f))ไม่ควรอ่านn-1หรือ
Leun Nun

@LeakyNun ฉบับที่(n f->3 (n f))เป็นฟังก์ชั่นสำหรับการคูณด้วยสามในตัวเลขคริสตจักร
Anders Kaseorg

2
ความท้าทายนี้ดูเหมือนจะง่ายเกินไปในแคลคูลัสแลมบ์ดา ทำไม?
แมว

3

Prolog (SWIPL), 129/137 ไบต์

g(1,R):-u(3,4,R).
g(L,R):-M is L-1,g(M,P),u(3,P,R).
u(N,1,R):-R is 3**N.
u(1,_,3).
u(N,M,R):-K is N-1,L is M-1,u(K,M,Y),u(Y,L,R).

ในการส่งออกหมายเลขของ Graham ให้ทำการค้นหาg(64,G).(ถ้านับจำนวน 8 ไบต์ของแบบสอบถามนี้ความยาวคือ 137 ไบต์):

?- g(64, G).
ERROR: Out of local stack

แต่อย่างที่ควรจะเป็น

ทดสอบ

?- u(3, 2, X).
X = 7625597484987

การย้อนรอยทำให้เกิดการซ้อนทับกัน:

?- u(3, 2, X).
X = 7625597484987 ;
ERROR: Out of local stack

Ungolfed

เวอร์ชันที่ไม่ได้รับการเสริมจะเพิ่มสัญกรณ์ลูกศรขึ้นโดยทั่วไปไม่ใช่เฉพาะสำหรับ 3 และใช้การตัดและตรวจสอบเพื่อหลีกเลี่ยงการย้อนรอยและสถานการณ์ที่ไม่ได้กำหนด

% up-arrow notation
u(X, 1, _M, X) :- !.
u(X, N, 1, R) :-
    R is X**N, !.
u(X, N, M, R) :-
    N > 1,
    M > 1,
    N1 is N - 1,
    M1 is M - 1,
    u(X, N1, M, R1),
    u(X, R1, M1, R).

% graham's number
g(1,R) :- u(3, 3, 4, R), !.
g(L,R) :-
    L > 1,
    L1 is L - 1,
    g(L1,G1),
    u(3, G1, R).

คุณจัดการได้อย่างไรโดยไม่ต้องมีหมายเลข64ในรหัสของคุณ?
Leun Nun

@LeakyNun ฉันแก้ไขเพื่อชี้แจง; ดีขึ้นหรือไม่
SQB

จากนั้นเพิ่มลงในรหัสของคุณเช่นเดียวกับการนับไบต์ของคุณ
Leun Nun

3

C, 161 ไบต์

u(int a, int b){if(a==1)return 3;if(b==1)return pow(3,a);return u(u(a-1,b),b-1);}
g(int a){if(a==1)return u(3,4);return u(3,g(a-1));}
main(){printf("%d",g(64));}

แก้ไข: บันทึก 11 ไบต์โดยลบแท็บและบรรทัดใหม่ แก้ไข: ขอบคุณ auhmann บันทึกอีกไบต์และแก้ไขโปรแกรมของฉัน


1
คุณสามารถลบออกได้g(int a){if(a==1)return u(3,4);return g(a-1);}เนื่องจากไม่ได้ใช้งานเลย ... หรือคุณลืมอะไรไปหรือเปล่า
auhmaan

@auhmaan อุ๊ปส์ฉันใช้หมายเลขนั้นในการทดสอบและลืมเปลี่ยนกลับ ขอบคุณ !!
thepiercingarrow

คุณควรจะเป็นreturn g(a-1) return u(3,g(a-1))
Anders Kaseorg

1
ฉันไม่รู้ว่าฉันควรตอบคำถามหรือแสดงความคิดเห็นในเรื่องนี้หรือไม่ แต่คุณสามารถหาวิธีแก้ปัญหานี้ได้ถึง 114 ไบท์ได้อย่างง่ายดายโดยการตระหนักว่าบรรทัดใหม่ระหว่างฟังก์ชั่นสามารถถูกละเว้นได้ การละเว้นประเภทสำหรับ argumens ทั้งหมดจะทำให้ค่าเริ่มต้นเป็น int (คิดว่า K&R) หากงบเช่นนี้สามารถเขียนด้วย ops ประกอบไปด้วยหลายระดับ รหัส:u(a,b){return a<2?3:b<2?pow(3,a):u(u(a-1,b),b-1);}g(a){return a<2?u(3,4):u(3,g(a-1));}main(){printf("%d",g(64));}
algmyr

@algmyr ว้าวน่าทึ่งมาก! คุณควรไปโพสต์คำตอบของคุณเอง XD
thepiercingarrow

2

Mathematica, 59 ไบต์

n_ ±1:=3^n
1 ±m_:=3
n_ ±m_:=((n-1)±m)±(m-1)
Nest[3±#&,4,64]

ใช้ตัวดำเนินการมัดที่ไม่ได้กำหนด±ซึ่งต้องการเพียง 1 ไบต์เมื่อเข้ารหัสใน ISO 8859-1 ดูโพสต์ของ @ Martin สำหรับข้อมูลเพิ่มเติม ฟังก์ชั่น Mathematica รองรับการจับคู่รูปแบบสำหรับอาร์กิวเมนต์ของพวกเขาเช่นนั้นทั้งสองกรณีฐานสามารถกำหนดแยกต่างหาก


1
Mathematica ใช้ ISO 8859-1 ตั้งแต่เมื่อใด
Leun Nun

n_ ±m_:=Nest[#±(m-1)&,3,n]
Leun Nun

2

C, 114 109 ไบต์

จากคำตอบโดย @thepiercingarrow ( ลิงก์ ) ฉันเล่นกอล์ฟกับคำตอบลงไปเล็กน้อย การประหยัดส่วนใหญ่เกิดจากการใช้การพิมพ์อาร์กิวเมนต์เริ่มต้นเมื่อใช้ฟังก์ชั่นสไตล์ K&R และการแทนที่คำสั่งที่มีตัวดำเนินการแบบไตรภาค เพิ่มบรรทัดใหม่เผื่อเลือกระหว่างฟังก์ชั่นเพื่อให้อ่านง่าย

ปรับปรุงเป็น 109 ด้วย @LeakyNun

u(a,b){return a<2?3:b<2?pow(3,a):u(u(a-1,b),b-1);}
g(a){return u(3,a<2?4:g(a-1));}
main(){printf("%d",g(64));}

g(a){return u(3,a<2?4:g(a-1));}
Leun Nun

@LeakyNun นั่นเป็นสิ่งที่ดีจริงๆ ขอบคุณ
algmyr

1

Python ขนาด 85 ไบต์

v=lambda n,m:n*m and v(v(n-1,m)-1,m-1)or 3**-~n
g=lambda n=63:v(2,n and g(n-1)-1or 3)

vฟังก์ชั่นกำหนดฟังก์ชั่นเดียวกับที่พบในคำตอบที่เดนนิสv(n,m) = u(3,n+1,m+1) : ฟังก์ชั่นเป็นรุ่นที่เป็นศูนย์การจัดทำดัชนีของการทำซ้ำแบบดั้งเดิม:g g(0) = v(2,3), g(n) = v(2,g(n-1))ดังนั้นจึงg(63)เป็นหมายเลขของเกรแฮม โดยการตั้งค่าเริ่มต้นของnพารามิเตอร์ของgฟังก์ชัน63เป็นผลลัพธ์ที่ต้องการสามารถรับได้โดยการเรียกg()(ไม่มีพารามิเตอร์) ดังนั้นจึงตอบสนองความต้องการของเราสำหรับการส่งฟังก์ชั่นที่ไม่มีอินพุต

ตรวจสอบv(2,1) = u(3,3,2)และv(4,0) = u(3,5,1)ทดสอบเคสออนไลน์: Python 2 , Python 3


1
เป็นการยากที่จะตรวจสอบ แต่ฟังก์ชั่นของคุณgดูเหมือนจะปิดอยู่ ไม่ควรv(2,n-1)จะเป็นg(n-1)หรือสิ่งที่คล้ายกัน?
Dennis

@ เดนนิสจับที่ดี ฉันจะแก้ไขมัน
Mego

ที่จริงชดเชยระหว่างuและวิธีการที่มันควรจะเป็นv g(n-1)-1
Anders Kaseorg

@AndersKaseorg ฉันไม่ควรเขียนโปรแกรมในขณะที่ง่วงนอน ฉันต้องเรียนรู้สิ่งนี้ใหม่ทุกสองสามวัน
Mego

@AndersKaseorg ในอนาคตโปรดอย่าแก้ไขข้อมูลที่ส่งโดยคนอื่นแม้ว่าจะเป็นการแก้ไขข้อผิดพลาดในการปรับปรุง / แก้ไขข้อผิดพลาดที่คุณแนะนำ
Mego

1

Dyalog APL, 41 ไบต์

u←{1=⍺:3⋄1=⍵:3*⍺⋄(⍵∇⍨⍺-1)∇⍵-1}
3u 3u⍣64⊣4

กรณีทดสอบ:

      3u 2
7625597484987

คุณควรแปลง1=⍺:3⋄1=⍵:3*⍺เป็นเพียง1=⍵:3*⍺( 3=3*1)
Zacharý

1

Ruby, 64 ไบต์

การกู้ยืมเงินจากอัลกอริทึมทฤษฎีการคำนวณจำนวนของเกรแฮม

def f(a,b=3)b<2?3:a<1?3*b:f(a-1,f(a,b-1))end;a=4;64.times{a=f a};p a

ใส่เพียงf a = u(3,3,a)และมันใช้ 64 ครั้งนี้


คำอธิบายที่ดีเกี่ยวกับสาเหตุและวิธีการทำงานของรหัสนี้จะดี
Manish Kundu

มันเป็นโปรแกรมที่ตรงไปตรงมาของคำจำกัดความของหมายเลขของเกรแฮม
ศิลปะที่สวยงามเรียบง่าย

0

J, 107 ไบต์

u=:4 :0
if.y=1 do.3^x
elseif.x=1 do.3
elseif.1 do.x:(y u~<:x)u<:y
end.
)
(g=:(3 u 4[[)`(3 u$:@<:)@.(1&<))64

ฉันกำลังทำงานuเพื่อเปลี่ยนเป็นวาระ แต่ตอนนี้มันจะทำ


บางอย่างเช่นu=:3^[`[:(3$:])/[#<:@]@.*@](ไม่ผ่านการทดสอบ)
Leun Nun

0

F #, 111 108 ไบต์

แก้ไข

นี่คือการใช้ฟังก์ชั่นด้านล่างเพื่อคำนวณหมายเลขของ Graham

let rec u=function|b,1->int<|3I**b|1,c->3|b,c->u(u(b-1,c),c-1)
and g=function|1->u(3.,4.)|a->u(3.,g (a-1))
g 63

นี่คือคำตอบก่อนหน้าของฉันซึ่งไม่ได้:

ตรงไปตรงมาสวย เพียงแค่นิยามของuฟังก์ชั่น

let rec u=function|a,b,1->a**b|a,1.,c->a|a,b,c->u(a,u(a,b-1.,c),c-1)

การใช้งาน:

u(3.,3.,2)
val it : float = 7.625597485e+12

ถ้าฉันคิดว่า 3 เป็นค่าสำหรับ a ฉันสามารถตัดมันเป็น 60:

let rec u=function|b,1->3.**b|1.,c->3.|b,c->u(u(b-1.,c),c-1)

การใช้งาน:

u(3.,2)
val it : float = 7.625597485e+12

uความท้าทายคือการเขียนหมายเลขของเกรแฮมไม่ แน่นอนคุณสามารถรวมฟังก์ชั่นกลางที่คุณต้องการเช่นuมีหรือไม่มีข้อโต้แย้งแรกของการแก้ไขที่ 3
Anders Kaseorg

@AndersKaseorg แก้ไขว่าขอบคุณ ความคิดเห็นก่อนหน้าของฉันดูเหมือนจะหายไป
asibahi

0

R, 154 142 128 126 118 ไบต์

u=function(n,b)return(if(n&!b)1 else if(n)u(n-1,u(n,b-1))else 3*b)
g=function(x)return(u(if(x-1)g(x-1)else 4,3))
g(64)

ฉันใช้นิยามวิกิพีเดียของฟังก์ชั่นวนซ้ำนี้เนื่องจากเหตุผลแปลก ๆ ข้อเสนอแนะที่ไม่ได้ผล ... หรือฉันแค่ดูดที่สนามกอล์ฟ R

UPD: โกน 12 + 14 = 26 ไบต์ขอบคุณที่ปลายจากรั่วนูน รุ่นก่อนใช้ขนาดใหญ่และมีประสิทธิภาพน้อยลง

u=function(n,b)if(n==0)return(3*b)else if(n>0&b==0)return(1)else return(u(n-1,u(n,b-1)))
g=function(x)if(x==1)return(u(4,3))else return(u(g(x-1),3))

UPD: ลบออกอีก 2 + 6 + 2 ไบต์ (อีกครั้ง, รุ่งโรจน์ไปยังLeaky Nun ) เนื่องจากการแทนที่อันชาญฉลาดด้วย“ if (x)” แทน“ if (x == 0)” เพราะ x <0 ไม่เคยถูกป้อนเข้า ฟังก์ชั่น ... ใช่มั้ย


@LeakyNun ขอขอบคุณอัปเดตคำตอบด้วยการตอบรับ
Andreï Kostyrka

เพียงไม่กี่วินาที ... วันนี้เป็นวันแรกของการเล่นกอล์ฟรหัสมีมากที่จะเรียนรู้!
Andreï Kostyrka

คุณได้รับเชิญให้เข้าร่วมการแชทของเรา
Leun Nun

กอล์ฟมากขึ้นโปรดดูการปรับปรุง
Andreï Kostyrka

Ta-dam เสร็จแล้วเปลี่ยนฟังก์ชั่นuในคีย์เดียวกับของคุณgและบันทึกอีก 6 ไบต์ - ยอดเยี่ยม!
Andreï Kostyrka

0

PHP, 114 ไบต์

ละเว้นการแบ่งบรรทัด พวกเขามีไว้สำหรับการอ่านเท่านั้น

function u($n,$m){return$m>1&$n>1?u(u($n-1,$m),$m-1):3**$n;}
function g($x){return u(3,$x>1?g($x-1):4);}
echo g(63);

มันเป็นไปได้ที่จะบูรณาการกรณีที่สองเข้ามาเป็นคนแรก: สำหรับn=1, เท่ากับ3^n สิ่งนี้จะช่วยประหยัดสองสามไบต์ - เท่าที่ฉันเห็น - คำตอบทั้งหมดที่มีอยู่ บันทึกสองไบต์ในของฉัน3

รุ่นก่อนหน้า 62 + 43 + 11 = 116 ไบต์

function u($n,$m){return$m>1?$n>1?u(u($n-1,$m),$m-1):3:3**$n;}

การเชื่อมโยงที่เหลืออยู่ของ PHP ของไตรภาคต้องใช้วงเล็บ ... หรือคำสั่งทดสอบเฉพาะ
สิ่งนี้บันทึกสองไบต์บนนิพจน์วงเล็บเหลี่ยม


อาจมีวิธีการวนซ้ำซึ่งอาจอนุญาตให้เล่นกอล์ฟต่อไป ...
แต่ฉันไม่สามารถใช้เวลาได้ในตอนนี้


หวังว่าฉันจะรู้ว่า Sesos หรือมีเวลาที่จะเรียนรู้มันและแปลตอนนี้
ติตัส

@Leaky Nun: ฉันทำลายมันลงไปที่ลูปและเพิ่มเท่านั้น มีวิธีใน Sesos เพื่อเพิ่มมูลค่าของเซลล์หนึ่งไปยังอีกเซลล์หนึ่งหรือไม่?
ติตัส

@AndersKaseorg: คุณอาจจะถูกต้อง ... ฉันมีแผลที่ดวงตาของฉันจากการดูอัลกอริทึมนั้น จะมองมันอีกครั้งในไม่ช้า
ติตัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.