Trình tự H


15

Định nghĩa

  • a(0) = 0
  • a(n) = n-a(a(a(n-1))) cho số nguyên n > 0

Bài tập

Cho số nguyên không âm n, đầu ra a(n).

Tủ thử

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

Người giới thiệu


Những thách thức liên quan về trình tự của Hofstadter: 1 , 2 , 3
Martin Ender

4
Và tôi vẫn nghĩ bạn nên tham khảo GEB ...
Martin Ender

1
Làm thế nào là lý thuyết số có liên quan ở đây?
flawr

1
@flawr facepalm Hãy để tôi thử lại lần nữa: Gôdel, Escher, Bach: Một
Stig Hemmer

1
@StigHemmer Thực tế facepalm có Biểu tượng cảm xúc của riêng mình ngay bây giờ:
Tobias

Câu trả lời:


20

Haskell, 23 22 byte

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

Đơn giản chỉ cần sử dụng định nghĩa của chuỗi. f(f$f$n-1)tương đương với f (f (f (n-1))).

Kiểm tra:

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]

Cảm ơn Anders Kaseorg cho một byte!


(f$f$f$n-1)= f(f$f$n-1)lưu một byte.
Anders Kaseorg

9

Thạch , 8 byte

’ßßßạµṠ¡

Hãy thử trực tuyến! hoặc xác minh các trường hợp thử nghiệm nhỏ hơn .

Làm thế nào nó hoạt động

’ßßßạµṠ¡  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
Trình phân tích cú pháp Jelly thậm chí có thể xử lý các chương trình lớn hơn 10 byte không?
steenbergh

9

Toán học, 20 byte

Số lượng byte giả định mã hóa ISO 8859-1 (hoặc tương thích) và $CharacterEncodingđược đặt thành giá trị khớp, như mặc định của Windows WindowsANSI.

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

Điều này định nghĩa một toán tử đơn nguyên ±.


Bạn sẽ giải thích những gì ± làm hoặc làm thế nào nó hoạt động? Btw, chúc mừng trên 100k.
DavidC

1
@DavidC Cảm ơn. :) Nó chỉ là một toán tử tích hợp, là tốc ký cho hàm không được sử dụng PlusMinus. Xem bài này để biết chi tiết.
Martin Ender

1
Rất thú vị. Tranh chấp với @hoặc [ ]quá.
DavidC

9

J, 14 12 byte

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

Đã lưu 2 byte nhờ @ Leaky Nun .

Tính kết quả bằng cách gọi chính nó đệ quy khi n > 0 ba lần trên n -1 và trừ kết quả đó khỏi n . Có một tình huống khác nhau cho trường hợp cơ sở khi n = 0. Ở đó nó tính toán n - n bằng 0.

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

Hãy thử nó ở đây.

Giải trình

-$:^: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

Tôi không nghĩ rằng dấu ngoặc đơn là cần thiết.
Leaky Nun

6

Julia, 16 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Chúng tôi xác định lại toán tử đơn nguyên ! cho mục đích của chúng tôi.

Nếu n = 0 , phép so sánh n>0trả về false và cũng vậy! .

Mặt khác, mã sau khi &&được thực thi. ~-ntương đương với (n-1)phần bù của hai, !!!gọi đệ quy !ba lần trên n - 1 và giá trị kết quả được trừ từ n .


Tâm thêm một lời giải thích? Tôi không biết chuyện gì đang xảy ra với -!!~-._.
Hạ cấp

1
Không có gì lạ mắt. !chỉ đơn giản là tên của hàm.
Dennis

5

Python, 31 byte

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

Giới hạn đệ quy và các ràng buộc thời gian làm cho chức năng trên không thực tế, nhưng trên lý thuyết nó sẽ hoạt động (và không hoạt động đối với n nhỏ).


4

JavaScript (ES6), 52 byte

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

Tôi có thể đã nhàm chán và viết phiên bản đệ quy nhưng phiên bản này nhanh hơn nhiều (dễ dàng đối phó với trường hợp thử nghiệm cuối cùng) và cũng sử dụng reducevì vậy đó là một điểm cộng!




3

R, 42 41 byte

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

Sử dụng:

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

Cách tiếp cận đệ quy này không mở rộng tốt cho các giá trị lớn hơn nmặc dù.


Bạn sẽ có thể mất một byte (và một số lỗi w / đầu vào xấu) nếu bạn thay đổi điều kiện của mình thành n<1. Dù là một chuỗi, nó chỉ thực sự được xác định cho các số nguyên không âm.
dùng5957401

a=function(n)"if"(n,n-a(a(a(n-1))),0)sẽ làm việc cho một vài byte tắt.
Giuseppe

3

Ốc đảo , 6 byte

Mã số:

nbaa-0

Phiên bản mở rộng:

a(n) = nbaa-
a(0) = 0

Mã số:

n      # Push n
 b     # Calculate a(n - 1)
  a    # Calculate a(a(n - 1))
   a   # Calculate a(a(a(n - 1)))
    -  # Subtract a(a(a(n - 1))) from n

Hãy thử trực tuyến!


2

Sesos , 58 55 byte

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..

Xử lý đầu vào lên tới 400 hợp lý tốt, nhưng thời gian chạy tăng đáng kể sau thời điểm đó.

Hãy thử trực tuyến! Kiểm tra gỡ lỗi để xem mã SBIN được tạo.

Sesos lắp ráp

Tệp nhị phân ở trên đã được tạo bằng cách lắp ráp mã SASM sau.

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

2

LISP, 61 byte

(defun H(N)(if(= N 0)(return-from H 0)(- N(H(H(H(- N 1)))))))

Có lẽ không phải là giải pháp tối ưu, nhưng nó hoạt động.


1

Java 7, 42 byte

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

Các trường hợp bất ngờ & thử nghiệm:

Hãy thử nó ở đây.

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));
  }
}

Đầu ra:

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 byte

Việc thực hiện rõ ràng.

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

Đây là một câu trả lời dài hơn, nhanh hơn lưu trữ các mục trước đó trong chuỗi. Cả hai câu trả lời chỉ hoạt động cho các phiên bản sau 1.9, vì đó là khi ->lambda cứng nhắc, được giới thiệu cho Ruby.

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



1

C, 35 32 byte

Đã lưu 3 byte nhờ @PeterTaylor!

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

Hãy thử nó trên Ideone!


2
Trong C, bạn có thể sử dụng một số nguyên trực tiếp làm điều kiện, tiết kiệm ba byte:a(n){return n?n-a(a(a(n-1))):0;}
Peter Taylor

1
@betseg - Bạn cũng có một lỗi :trong mã của mình. Bạn nên lấy ra một cái sau ?.
owacoder

1

Javascript ES6, 22 byte

a=n=>n&&n-a(a(a(n-1)))

Tôi sẽ nhàm chán và làm phiên bản đệ quy: P


1

VBA, 69 byte

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

Hoạt động trong chớp mắt trên bộ thử nghiệm, chậm lại một chút trên n = 1000000, chạy vào một bức tường bộ nhớ một chút trên n = 25 triệu.


1

Bình thường, 10 byte

L-WbbyFtb3

Xác định một hàm y. Dùng thử trực tuyến: Trình diễn

Điều này sử dụng một tính năng mới tương đối của Pyth. Bạn có thể áp dụng một hàm nhiều lần bằng cú pháp gập. Nó không thực sự lưu bất kỳ byte nào, tôi đã sử dụng nó chỉ cho mục đích trình diễn.

Giải trình:

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

Maple, 28 26 byte

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

Sử dụng:

> 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 byte

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

Đầu vào được lấy từ đỉnh ngăn xếp. Đây phải là mục duy nhất trên ngăn xếp, vì độ sâu của ngăn xếp được sử dụng làm bộ đếm. Ví dụ về cách sử dụng:

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

Đây là một triển khai khá đơn giản của định nghĩa trình tự:

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)

Dù sao, nó bắt đầu đơn giản ... sau đó việc đánh gôn đã xảy ra.



1

C ++ (MSVC, chủ yếu)

Phiên bản thường: 40 byte

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

Phiên bản lập trình meta mẫu: 130 byte

#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;}};

Sử dụng :

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

Phiên bản mẫu là mã nhanh nhất, vì không có gì nhanh hơn việc chuyển một giá trị vào một thanh ghi => với tối ưu hóa, H<20>::a()biên dịch thành:

mov esi, 14

Đối với 10000, phiên bản đệ quy gặp sự cố do lỗi tràn ngăn xếp và phiên bản mẫu gặp sự cố tại thời gian biên dịch do độ sâu khởi tạo mẫu. GCC đi đến 900 (614)


Tôi nghĩ rằng bạn không cần khoảng trống giữa C{trong phiên bản lập trình meta mẫu
Zacharý

@ Zacharý MSVC từ chối biên dịch mà không có khoảng trống đó
HatsuPulumKun

Ahh, tôi hiểu tại sao điều đó dường như tiếp tục xảy ra
Zacharý

@ Zacharý Nó phụ thuộc vào loại macro. Nếu nó có các tham số, thì tôi có thể xóa khoảng
trắng


1

APL (Dyalog Unicode) , 18 17 byte

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

Hãy thử trực tuyến!

Đáng ngạc nhiên, không có câu trả lời APL cho thách thức này. Đây là một triển khai thực hiện chức năng trong OP.

TIO hết thời gian cho n>90.

Đã lưu một byte nhờ @ Zacharý.


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


0

PowerShell v2 +, 56 byte

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

PowerShell tương đương với lambda để tạo thành định nghĩa đệ quy. Thực hiện nó thông qua các &cuộc gọi, ví dụ &$a(5). Mất nhiều thời gian để thực thi - ngay cả 50trên máy của tôi (một i5 gần đây có RAM 8GB) mất khoảng 90 giây.

Giải pháp lặp nhanh hơn, 59 byte

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

Chỉ dài hơn vì chúng ta cần tính đến đầu vào 0(đó là *!!$nphần cuối). Mặt khác, chúng tôi chỉ lặp đi lặp lại việc xây dựng mảng lên $n, thêm một phần tử mới mỗi lần và xuất ra phần cuối cùng ở cuối $o[-1]. Siêu tốc độ - tính toán 10000trên máy của tôi mất khoảng 5 giây.


0

> <> , 55 + 2 = 57 byte

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

Đầu vào dự kiến ​​sẽ có mặt trên ngăn xếp khi bắt đầu chương trình, vì vậy +2 byte cho -vcờ. Hãy thử trực tuyến!

Đây là hecka chậm, vì nó sử dụng đệ quy để tính kết quả. Sử dụng TIO, h(50)mất hơn một phút. Nó trả về kết quả chính xác <= 30, vì vậy tôi tự tin rằng nó sẽ hoạt động h(10000), tôi chỉ không chạy nó để tìm hiểu!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.