Hofstadter H-sequence


15

คำนิยาม

  • a(0) = 0
  • a(n) = n-a(a(a(n-1))) สำหรับจำนวนเต็ม n > 0

งาน

ได้รับจำนวนเต็มไม่เป็นลบออกna(n)

Testcases

n     a(n)
0     0
1     1
2     1
3     2
4     3
5     4
6     4
7     5
8     5
9     6
10    7
11    7
12    8
13    9
14    10
15    10
16    11
17    12
18    13
19    13
20    14
10000 6823

อ้างอิง


ความท้าทายที่เกี่ยวข้องกับลำดับของ Hofstadter: 1 , 2 , 3
Martin Ender

4
และฉันก็ยังคิดว่าคุณควรอ้างอิง GEB ...
Martin Ender

1
วิธีการคือหมายเลขทฤษฎีที่เกี่ยวข้องที่นี่?
ข้อบกพร่อง


1
@StigHemmer ที่จริง facepalm มีอิโมจิเป็นของตัวเองแล้วตอนนี้: 🤦
Tobias Kienzler

คำตอบ:


20

Haskell, 23 22 ไบต์

f 0=0
f n=n-f(f$f$n-1)

เพียงใช้คำจำกัดความของลำดับ เทียบเท่ากับf(f$f$n-1)f (f (f (n-1)))

ทดสอบ:

main = putStrLn . show $ map f [0..20]
-- => [0,1,1,2,3,4,4,5,5,6,7,7,8,9,10,10,11,12,13,13,14]

ขอบคุณAnders Kaseorgสำหรับ byte!


(f$f$f$n-1)= f(f$f$n-1)บันทึกไบต์
Anders Kaseorg

9

เยลลี่ 8 ไบต์

’ßßßạµṠ¡

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบที่มีขนาดเล็ก

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

’ßßßạµṠ¡  Main link. Argument: n

     µṠ¡  Execute the preceding chain sign(n) times.
’         Decrement n, yielding n - 1.
 ßßß      Recursively call the main link thrice.
    ạ     Take the absolute difference of n and the result.

9
ตัวแยกวิเคราะห์ Jelly สามารถจัดการโปรแกรมที่มีขนาดใหญ่กว่า 10 ไบต์ได้หรือไม่
steenbergh

9

Mathematica ขนาด 20 ไบต์

นับไบต์ถือว่า ISO 8859-1 (หรือเข้ากันได้) การเข้ารหัสและตั้งค่าการจับคู่เหมือนเริ่มต้นของ$CharacterEncoding WindowsWindowsANSI

±0=0
±n_:=n-±±±(n-1)

±นี้กำหนดผู้ประกอบการเอก


คุณจะอธิบายว่า±ทำงานอย่างไรหรือทำงานอย่างไร? Btw ขอแสดงความยินดีกับ 100k
DavidC

1
@DavidC ขอบคุณ :) PlusMinusมันเป็นเพียงแค่ในตัวซึ่งเป็นผู้ประกอบการจดชวเลขสำหรับฟังก์ชั่นที่ไม่ได้ใช้ ดูโพสต์นี้เพื่อดูรายละเอียด
Martin Ender

1
น่าสนใจมาก. จะทำยังไงกับ@หรือ[ ]มากเกินไป
DavidC

9

J, 14 12 ไบต์

-$:^:3@<:^:*

ที่บันทึกไว้ 2 ไบต์ขอบคุณที่ @ รั่วนูน

คำนวณผลโดยการเรียกตัวเองซ้ำเมื่อn > 0 สามครั้งในn -1 และลบผลจากที่n มีสถานการณ์ที่แตกต่างกันสำหรับกรณีฐานเมื่อn = 0 จะคำนวณn - nซึ่งเท่ากับ 0

a(n) = n - n = 0           if n = 0
       n - a(a(a(n-1)))    if n > 0

ลองที่นี่

คำอธิบาย

-$:^:3@<:^:*  Input: n
           *  Get the sign of n (n = 0 => 0, n > 0 => 1)
         ^:   Execute that many times
                (0 times means it will just be an identity function)
       <:       Decrement n
 $:             Call itself recursively
   ^:3          three times
      @         on n-1
-             Subtract that result from n and return

ฉันไม่คิดว่าจำเป็นต้องใส่วงเล็บ
Leun Nun

6

จูเลีย 16 ไบต์

!n=n>0&&n-!!!~-n

ลองออนไลน์!

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

เรากำหนดผู้ประกอบการเอก!สำหรับวัตถุประสงค์ของเรา

ถ้าn = 0การเปรียบเทียบn>0จะคืนค่าเท็จและจะเป็น!เช่นนั้น

มิฉะนั้นรหัสหลังจาก&&ได้รับการดำเนินการ ~-nเทียบเท่ากับ(n-1)ในส่วนประกอบที่สองของ!!!ซ้ำเรียกร้อง!สามครั้งในn - 1และความคุ้มค่าที่เกิดขึ้นถูกลบออกจากn


ต้องการเพิ่มคำอธิบายหรือไม่ ฉันไม่รู้ว่าเกิดอะไรขึ้นกับ-!!~-.
Downgoat

1
ไม่มีอะไรแฟนซี !เป็นเพียงชื่อของฟังก์ชัน
Dennis

5

Python ขนาด 31 ไบต์

a=lambda n:n and n-a(a(a(n-1)))

การ จำกัด การเรียกซ้ำและข้อ จำกัด ด้านเวลาทำหน้าที่ดังกล่าวไม่ได้ แต่ในทางทฤษฎีแล้วมันควรจะทำงานได้ (และทำงานให้กับ n ขนาดเล็ก)


4

JavaScript (ES6), 52 ไบต์

n=>[0,...Array(n)].reduce((p,_,i,a)=>a[i]=i-a[a[p]])

ฉันน่าเบื่อและเขียนเวอร์ชันซ้ำ แต่รุ่นนี้เร็วกว่ามาก (รับมือกับกรณีทดสอบครั้งสุดท้ายได้ง่าย) และยังใช้reduceเช่นกันนั่นเป็นข้อดี!




3

R, 42 41 ไบต์

a=function(n)ifelse(n<1,0,n-a(a(a(n-1))))

การใช้งาน:

> a(1)
1
> a(10)
7

วิธีแบบเรียกซ้ำนี้ไม่ได้ปรับขนาดสำหรับค่าที่nมากขึ้น


คุณควรจะสามารถที่จะสูญเสียไบต์ (และจำนวนข้อผิดพลาด w / ปัจจัยการผลิตไม่ดี) n<1ถ้าคุณเปลี่ยนสภาพของคุณจะ เป็นลำดับมันถูกกำหนดจริงๆเท่านั้นสำหรับจำนวนเต็มไม่เป็นลบ แต่อย่างใด
user5957401

a=function(n)"if"(n,n-a(a(a(n-1))),0)จะทำงานได้หลายไบต์
Giuseppe


2

Sesos , 58 55 ไบต์

0000000: 16e0d7 bdcdf8 8cdf1b e6cfbb 840d3f bf659b 38e187  ..............?.e.8..
0000015: f8639b 39dc37 fc893f 666c05 7e7ed9 b88b3f ae0d3f  .c.9.7..?fl.~~...?..?
000002a: 676ed8 bd9940 7fdc3b 36619e f1                    gn...@..;6a..

จัดการอินพุตได้สูงสุด400ด้วยดี แต่เวลารันเพิ่มขึ้นอย่างมากหลังจากจุดนั้น

ลองออนไลน์! ตรวจสอบ Debugเพื่อดูรหัส SBIN ที่สร้างขึ้น

ประกอบน้ำมัน

ไฟล์ไบนารีข้างต้นถูกสร้างขึ้นโดยการรวบรวมรหัส SASM ต่อไปนี้

set numin, set numout

get
jmp
    jmp
        rwd 3, add 1, rwd 1, add 1, fwd 4, sub 1
    jnz
    rwd 3, sub 1
jnz
rwd 3, add 1, fwd 2
jmp
    rwd 1, sub 1, fwd 3, sub 1, fwd 2, add 3
    jmp
        rwd 2
        jmp
            rwd 3
        jnz
        fwd 6, get, rwd 4, sub 1
        jmp
            fwd 1, sub 1
            jmp
                rwd 3
            jnz
            sub 1
            jmp
                fwd 3
            jnz
            rwd 4, sub 1
        jnz
        fwd 1
        jmp
            rwd 1, add 1, fwd 1, add 1
        jnz
        sub 1, fwd 3, sub 1
        jmp
            fwd 3
        jnz
        rwd 1, sub 1
    jnz
    rwd 2, get
    nop
        rwd 3
    jnz
    fwd 3, get, rwd 2
    jmp
        fwd 2, add 1
        jmp
            fwd 3
        jnz
        rwd 1, add 1, rwd 2
        jmp
            rwd 3
        jnz
        fwd 1, sub 1
    jnz
    fwd 2
    jmp
        rwd 2, add 1, fwd 2, sub 1
    jnz
    nop
        get, fwd 3
    jnz
    rwd 1, add 1, fwd 2
jnz
rwd 2, sub 1
jmp
    rwd 1, sub 1, fwd 1, sub 1
jnz
rwd 1, put


1

Java 7, 42 ไบต์

int c(int n){return n>0?n-c(c(c(n-1))):0;}

กรณีที่ไม่ได้รับการทดสอบ &:

ลองที่นี่

class Main{
  static int c(int n){
    return n > 0
              ? n - c(c(c(n-1)))
              : 0;
  }

  public static void main(String[] a){
    for(int i = 0; i < 21; i++){
      System.out.println(i + ": " + c(i));
    }
    System.out.println("1000: " + c(1000));
  }
}

เอาท์พุท:

0: 0
1: 1
2: 1
3: 2
4: 3
5: 4
6: 4
7: 5
8: 5
9: 6
10: 7
11: 7
12: 8
13: 9
14: 10
15: 10
16: 11
17: 12
18: 13
19: 13
20: 14
 (last case takes too long..)

1

Ruby, 27 ไบต์

การใช้งานที่ชัดเจน

a=->n{n<1?0:n-a[a[a[n-1]]]}

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

->n{r=[0];i=0;(i+=1;r<<i-r[r[r[i-1]]])while i<n;r[n]}



1

ค, 35 32 ไบต์

บันทึก 3 ไบต์ด้วย @PeterTaylor!

a(n){return n?n-a(a(a(n-1))):0;}

ลองใช้กับ Ideone!


2
ใน C คุณสามารถใช้จำนวนเต็มเป็นเงื่อนไขได้โดยตรงโดยให้การประหยัดแบบสามไบต์:a(n){return n?n-a(a(a(n-1))):0;}
Peter Taylor

1
@betseg - คุณมี:รหัสผิดพลาดเช่นกัน ?คุณควรจะออกจากหนึ่งหลัง
owacoder


1

VBA, 69 ไบต์

Function H(N):ReDim G(N):For j=1To N:G(j)=j-G(G(G(j-1))):Next:H=G(N)

ใช้งานได้ในพริบตาบนชุดทดสอบชะลอตัวลงเล็กน้อยเหนือ n = 1000000 วิ่งเข้าไปในผนังหน่วยความจำน้อยกว่า n = 25 ล้านเล็กน้อย


1

Pyth, 10 ไบต์

L-WbbyFtb3

yกำหนดฟังก์ชั่น ลองใช้งานออนไลน์: การสาธิต

สิ่งนี้ใช้คุณสมบัติใหม่ที่เกี่ยวข้องของ Pyth คุณสามารถใช้ฟังก์ชั่นได้หลายครั้งโดยใช้ fold-syntax จริงๆแล้วมันไม่ได้บันทึกไบต์ใด ๆ ฉันใช้มันเพื่อการสาธิตเท่านั้น

คำอธิบาย:

L-WbbyFtb3
L            define function y(b), that returns:
    b           b
 -Wb            and subtract the following if b>0
     yF  3      y applied three times to
       tb       b - 1

1

เมเปิ้ล28 28ไบต์

`if`(n=0,0,n-a(a(a(n-1))))

การใช้งาน:

> a:=n->ifelse(n=0,0,n-a(a(a(n-1))));
> seq(a(i),i=0..10);
0, 1, 1, 2, 3, 4, 4, 5, 5, 6, 7

1

dc, 34 ไบต์

dsn[zdddd1-;a;a;a-r:aln!=L]dsLx;ap

อินพุตถูกนำมาจากด้านบนของสแต็ก ต้องเป็นรายการเดียวในสแต็กเนื่องจากใช้ความลึกของสแต็กเป็นตัวนับ ตัวอย่างการใช้งาน:

$ dc
10000dsn[zdddd1-;a;a;a-r:aln!=L]dsLx;ap

นี่เป็นการดำเนินการตามลำดับของคำนิยามอย่างตรงไปตรงมา:

dsn               # Store n as `n', and keep a copy as a depth buffer (see below)
[                 # Open loop definition
 z                # Push stack depth i for i-th term
 dddd             # Duplicate stack depth four times, for a total of five copies
 1-               # Get i-1 for use as index to previous term
                  #   Note that if we hadn't duplicated n above, or left something else
                  #   on the stack, 0-1 would be -1, which is not a valid array index
 ;a;a;a           # Fetch a(a(a(i-1)))
 -                # Calculate i-a(a(a(i-1)))
 r                # Arrange stack to store i-th term: TOS |  i  (i-a(a(a(i-1))))
 :a               # Store i-th term in array `a'
 ln!=L            # Load n. If n!=i, we're not done calculating terms yet, so execute loop
]                 # Close loop definition. Note that we started with five copies of i:
                  #   i-1 was used to get last term
                  #   i-a(...) was used to calculate current term
                  #   ... i :a was used to store current term
                  #   i ln !=L was used to check loop exit condition
                  # One copy of i is left on the stack to increment counter
dsLx              # Duplicate loop macro, store it, and execute copy
;a                # Last i stored on stack from loop will equal n, so use this to get a(n)
p                 # Print a(n)

อย่างไรก็ตามมันเริ่มตรงไปตรงมา ... จากนั้นการเล่นกอล์ฟก็เกิดขึ้น



1

C ++ (MSVC ส่วนใหญ่)

รุ่นปกติ: 40 ไบต์

int a(int n){return n?n-a(a(a(n-1))):0;}

เวอร์ชันการเขียนโปรแกรมเทมเพลตเมตา: 130 ไบต์

#define C {constexpr static int a(){return
template<int N>struct H C N-H<H<H<N-1>::a()>::a()>::a();}};template<>struct H<0>C 0;}};

การใช้งาน:

std::cout << a(20) << '\n';       // Normal version
std::cout << H<20>::a() << '\n';  // Template version

เทมเพลตเวอร์ชันเป็นรหัสที่เร็วที่สุดเนื่องจากไม่มีอะไรเร็วไปกว่าการย้ายค่าไปยัง register => พร้อมการเพิ่มประสิทธิภาพH<20>::a()รวบรวมเป็น:

mov esi, 14

สำหรับ 10000 เวอร์ชันซ้ำเกิดปัญหาเนื่องจากข้อผิดพลาดล้นสแตกและรุ่นแม่แบบล้มเหลวในเวลารวบรวมเนื่องจากความลึกอินสแตนซ์ของแม่แบบ GCC ไปที่ 900 (614)


ฉันคิดว่าคุณไม่ต้องการช่องว่างระหว่างCและ{ในเวอร์ชันการเขียนโปรแกรมเมตาเทมเพลต
Zacharý

@ Zacharý MSVC ปฏิเสธที่จะรวบรวมโดยไม่มีช่องว่างนั้น
HatsuPointerKun

Ahh ฉันเห็นแล้วว่าทำไมสิ่งนั้นจึงเกิดขึ้นต่อไป
Zacharý

@ Zacharýมันขึ้นอยู่กับประเภทของมาโคร หากมีพารามิเตอร์ฉันสามารถลบช่องว่างได้ แต่ที่นี่ไม่มี
HatsuPointerKun


1

APL (Dyalog Unicode) , 18 17 ไบต์

{⍵=0:0⋄⍵-∇⍣3⊢⍵-1}

ลองออนไลน์!

น่าแปลกที่ไม่มีคำตอบของ APL สำหรับความท้าทายนี้ นี่คือการดำเนินการตามตัวอักษรของฟังก์ชั่นใน OP

TIO หมดเวลา n>90.

บันทึกเป็นไบต์ด้วย @ Zacharý


1
{⍵=0:0⋄⍵-∇⍣3⊢⍵-1}
Zacharý


0

PowerShell v2 +, 56 ไบต์

$a={$n=$args[0];if($n){$n-(&$a(&$a(&$a($n-1))))}else{0}}

PowerShell เทียบเท่าแลมบ์ดาเพื่อจัดทำนิยามแบบวนซ้ำ ดำเนินการได้ผ่านทางผู้ประกอบการเรียกร้องเช่น& &$a(5)ใช้เวลานานในการดำเนินการ - แม้50บนเครื่องของฉัน (i5 ล่าสุดที่มี 8GB RAM) ใช้เวลาประมาณ 90 วินาที

โซลูชันที่วนซ้ำได้เร็วขึ้น 59 ไบต์

param($n)$o=,0;1..$n|%{$o+=$_-$o[$o[$o[$_-1]]]};$o[-1]*!!$n

อีกต่อไปเพียงเพราะเราจำเป็นต้องบัญชีสำหรับการป้อนข้อมูล0(นั่นคือ*!!$nในตอนท้าย) มิฉะนั้นเราก็ซ้ำสร้างอาร์เรย์ถึงการเพิ่มองค์ประกอบใหม่ในแต่ละครั้งและเอาท์พุทเป็นคนสุดท้ายที่สิ้นสุด$n $o[-1]Super-speedy - การคำนวณ10000บนเครื่องของฉันใช้เวลาประมาณ 5 วินาที


0

> <> , 55 + 2 = 57 ไบต์

^~n;
.~-]{:0$
v>1-}32[
v/  /:1-32[
>$:?/$~]{:0$.
/30@2[

คาดว่าอินพุตจะแสดงบนสแต็กเมื่อเริ่มต้นโปรแกรมดังนั้นจึงมีค่า 2 ไบต์สำหรับ-vแฟล็ก ลองออนไลน์!

นี่คือ hecka ช้าเนื่องจากใช้การสอบถามซ้ำเพื่อคำนวณผลลัพธ์ ใช้ TIO h(50)ใช้เวลามากกว่าหนึ่งนาที มันส่งคืนผลลัพธ์ที่ถูกต้อง <= 30 ดังนั้นฉันจึงมั่นใจว่ามันจะได้ผลh(10000)ฉันแค่ไม่ได้วิ่งออกไปหา!

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