คำนวณ Super-Logarithm


29

นี่ควรเป็นความท้าทายอย่างง่าย

รับจำนวนn >= 0เอาท์พุทซุปเปอร์ลอการิทึม (หรือเข้าสู่ระบบ * การเข้าสู่ระบบดาวหรือซ้ำลอการิทึมซึ่งเทียบเท่าตั้งแต่nไม่เชิงลบสำหรับความท้าทายนี้.) nของ

log * (n): = {0 ถ้า n <= 1;  1 + log * (log (n)) ถ้า n> 1}

นี่คือหนึ่งในสองฟังก์ชันผกผันไปtetration อื่น ๆ ที่เป็นซุปเปอร์รากซึ่งอยู่ในคำถามที่เกี่ยวข้อง

ตัวอย่าง

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 = อี-W (-1) ≈ 0.318 + 1.337i - ที่Wหมายถึงฟังก์ชั่นแลมเบิร์ W - เรามีบันทึก (z) = Z

สำหรับอินพุตnหลังจากคำนวณ[n, log (n), log (log (n)), …, z]เราจะใช้ฟังก์ชั่นเพดานกับผลลัพธ์แต่ละรายการก่อน การใช้งานของ Jelly ( Ċ) คำนวณส่วนจินตภาพของจำนวนเชิงซ้อนแทนแต่เราไม่สนใจสิ่งเหล่านี้

เมื่อk THการประยุกต์ใช้การล็อกผลตอบแทนถัวเฉลี่ยค่าน้อยกว่าหรือเท่ากับ1 , Ċจะกลับ1เป็นครั้งแรก ดัชนีที่ใช้ 0 ของ1แรกนั้นเป็นผลลัพธ์ที่ต้องการ

การดำเนินการที่ตรงไปตรงมา (คำนวณดัชนีที่ใช้ 1 การลดลง) ล้มเหลวเนื่องจาก edge case 0ซึ่งไม่มี1ในรายการลอการิทึม ในความเป็นจริงสำหรับอินพุต0ลำดับลอการิทึมคือ

[0, None]

นี่เป็นเพราะลอการิทึมของเจลลี่ ( Æl) เกินพิกัด มันพยายามครั้งแรกmath.log(ลอการิทึมจริง) แล้วcmath.log(ลอการิทึมที่ซับซ้อน) และในที่สุดก็ "จะให้ขึ้น" Noneและผลตอบแทน โชคดีที่Ċมีการโหลดมากเกินไปในทำนองเดียวกันและส่งคืนอาร์กิวเมนต์หากไม่สามารถปัดเศษขึ้นหรือใช้ส่วนจินตภาพ

เช่นเดียวกันอินพุต1ส่งคืน

[1, 0, None]

ซึ่งอาจสร้างปัญหาในวิธีการอื่น ๆ Ċที่ทำหรือไม่เกี่ยวข้องกับ

วิธีหนึ่งในการแก้ไขปัญหานี้คือการนำไปใช้(dequeue ลบองค์ประกอบแรก) ไปยังอาร์เรย์ของลอการิทึม แผนที่นี้

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

ดังนั้นรายการค่ามี1ในขณะนี้ วิธีนี้การหาดัชนีแรก1จะกลับ0 (ไม่พบ) ซึ่งเป็นผลลัพธ์ที่ต้องการสำหรับปัจจัยการผลิตที่0และ1

มันทำงานอย่างไร

Æ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

Javascript, 45 27 26 ไบต์

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

นี่คือชุดทดสอบ (รอบที่ 3)

ขอบคุณ @LeakyNun สำหรับการบันทึก 1 ไบต์ด้วยเงื่อนไขแล้วแปลงฟังก์ชันเป็นแลมบ์ดาและ @Neil สำหรับการชี้ให้เห็นว่าผิดพลาดคือค่าส่งคืนตกลงสำหรับ <= 1 (เปลี่ยนการทดสอบเป็น == แทน ===)


ฉันทำมันโดยไม่ใช้ ES6 แต่ใช่ว่าจะสั้นลง 1 ไบต์ขอบคุณ
CShark

ทำไมคุณไม่ใช้แลมบ์ดา?
Leun Nun

ไม่มีเหตุผลที่ดีฉันไม่ได้ใช้มันมากนักดังนั้นมันจึงไม่ใช่สัญชาตญาณแรกของฉันเลย
CShark

เห็นได้ชัดว่าเราได้รับอนุญาตให้กลับมาfalseแทน 0 (มันอัตโนมัติแปลงเป็น 0 ในการแสดงออกจำนวนเต็ม) |0ซึ่งในกรณีนี้คุณสามารถวาง
Neil

นั่นจะช่วยประหยัด 1 ไบต์ แต่คุณหมายความว่า "มันแปลงเป็น 0 โดยอัตโนมัติ" มันคืออะไร"?
CShark

6

Mathematica ขนาด 21 ไบต์

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

ฟังก์ชันที่ไม่ระบุชื่อแบบเรียกซ้ำ รับจำนวนเต็มเป็นอินพุตและส่งกลับค่าลอการิทึม super เป็นเอาต์พุต เพียงแค่ใช้คำจำกัดความที่กำหนด


3
จริง ๆ แล้วฉันดูล่วงหน้าเพื่อดูว่ามีในตัว ฉันรู้สึกประหลาดใจเมื่อไม่มี : D
mbomb007


5

Pyth, 10 ไบต์

L&>b1hy.lb

ชุดทดสอบ

สิ่งนี้นิยามฟังก์ชั่น


ฉันไม่เห็นผลลัพธ์ใด ๆ ในชุดทดสอบของคุณ เพียงบรรทัดว่างในผลลัพธ์
mbomb007

@ mbomb007 แก้ไขแล้ว
Leun Nun

Way cooler: tl.u?>N1.l;-)
Jakube

@Jakube คุณสามารถโพสต์ได้!
Leun Nun


4

Python 3, 45 ไบต์

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

สำหรับx <= 1สิ่งนี้จะส่งคืนFalse(ซึ่งอยู่== 0ใน Python)


ใช่สามารถใช้สำหรับการFalse 0
mbomb007

นอกจากนี้คุณยังชนะการดำเนินการที่ไร้เดียงสาของฉัน (โดยใช้andมากกว่าif else) Grats
mbomb007


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 ไบต์

บันทึก 2 ไบต์ถึง Leaky Nun, 1 ไบต์ถึง Galen Ivanov และ 2 ไบต์ถึง FrownyFrog!

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:(ผมเริ่ม sovling สิ่งที่จะกลายเป็น dup ของปัญหานี้.)
เลน Ivanov

2#@}.(0>.^.)^:a:ดูเหมือนว่าจะทำงาน
FrownyFrog

ไม่แน่ใจว่ามันเทียบเท่าหรือไม่
FrownyFrog


2

MATLAB / Octave, 44 ไบต์

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

พยายามทำมันทั้งหมดเป็นฟังก์ชั่นนิรนาม แต่ฉันลืมไปว่า MATLAB / Octave ยังคงประเมินนิพจน์แม้ว่ามันจะถูกคูณด้วยค่าบูลีน false (ศูนย์):

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

ฉันคิดว่าคุณสามารถบันทึกไบต์โดยใช้ตัวอักษรถ้าคำสั่งอื่น ie if(x>1)1+f(log(x))else 0สั้นลงหนึ่งไบต์
user5957401


2

Java 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 ตอบกลับในอีกสามปีต่อมาฮ่า ๆ .. (ในขณะที่ฉันเป็นเพียงโค้ดกอล์ฟใน Java 7) แต่ยังคงตอบคำถามของคุณ: ไม่น่าเสียดายที่ Java 8 แลมบ์ดานั้นมีความยาวมากกว่าวิธีแบบเรียกซ้ำ ฉันได้เพิ่มมันเข้าไปในคำตอบของฉันแล้วและฉันก็เพิ่มคำอธิบายด้วย
Kevin Cruijssen

ดังนั้นคุณไม่สามารถกลับมาทำ lambdas ซ้ำอีกได้?
mbomb007

@ mbomb007 ไม่ใน Java ไม่น่าเสียดาย ใน Python, JavaScript, และฉันคิดว่า C # .NET เช่นกัน, lambdas แบบเรียกซ้ำมีความเป็นไปได้, แต่ใน Java ไม่ได้ด้วยเหตุผลบางอย่าง ..
Kevin Cruijssen


1

เยลลี่ขนาด 8 ไบต์

-Ælß$Ị?‘

การใช้คำจำกัดความตรงไปตรงมา ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

มันทำงานอย่างไร

-Æ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 ไบต์

ง่ายมากต้องการ-M5.016(ซึ่งฟรี) เพื่อเปิดใช้งาน__SUB__คำหลักสำหรับการเรียกซ้ำแบบไม่ระบุชื่อ

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

อีกทางเลือกหนึ่งคือ

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

ซึ่งคือ 34 ไบต์และให้เอาต์พุตเดียวกันสำหรับอินพุตทั้งหมด> 1 แต่ส่งกลับค่าเท็จพิเศษสำหรับอินพุต <= 1 เท็จมีค่าตัวเลขเท่ากับศูนย์ แต่พิมพ์เป็น "" (สตริงว่าง) ดังนั้นจึงอาจไม่ได้ ไม่มีคุณสมบัติ


คำตอบที่ดี คุณสามารถชนะ 1 ไบต์โดยทำsub{($_=pop)>1?1+__SUB__->(log):0}แม้ว่า
Dada

1

CJam (16 ไบต์)

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

การสาธิตออนไลน์

ง่าย ๆ ในขณะที่วนรอบพร้อมเงื่อนไขล่วงหน้า (สิ่งที่ฉันต้องการจริงๆที่นี่คือการดำเนินการตีแผ่แบบ Golfscript แต่ CJam ไม่มีหนึ่งจุดและจุดลอยตัวใน GolfScript นั้นยุ่งและไม่วุ่นวายเลย)


นอกจากนี้นี่คือคำตอบที่ 80 ของฉันในวิชาคณิตศาสตร์และทำให้ฉันได้รับป้ายแท็กที่สองของฉันในวันนี้
Peter Taylor



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

Mathematica, 29 ไบต์

ง่ายเหมือนนรกทั้งหมดและใช้ได้กับอินพุตที่มีขนาดใหญ่และเชิงลบ:

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

enter image description here



0

Perl 6 , 21 ไบต์

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

ลองออนไลน์!

นิพจน์วงเล็บคือลำดับ $_อาร์กิวเมนต์ของฟังก์ชันเป็นองค์ประกอบแรก *.logสร้างแต่ละองค์ประกอบต่อเนื่องโดยการบันทึกขององค์ประกอบก่อนหน้า ลำดับจะดำเนินต่อไปจนกระทั่งเงื่อนไขสิ้นสุด1 >= *เป็นจริง: 1 มากกว่าหรือเท่ากับองค์ประกอบปัจจุบัน การลบ 1 จากลำดับจะรวมเป็นจำนวน: ความยาว

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