霍夫施塔特Q序列


25

定义

  1. a(1)= 1
  2. a(2)= 1
  3. 对于n> 2的a(n)= a(na(n-1))+ a(na(n-2))其中n是整数

任务

给定正整数n,生成a(n)

测试用例

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

参考



1
我们可以在可以将True用作1的语言中返回True吗?
丹尼斯

1
@Dennis如果在该语言中,true为1,则为yes。
Leaky Nun

4
除了OEIS链接以外,最好参考序列首次出现的GEB。
Martin Ender

Answers:


9

视网膜84 83 79 74字节

字节数假定为ISO 8859-1编码。

.+
$*;1¶1¶
+`;(?=(1)+¶(1)+)(?=(?<-1>(1+)¶)+)(?=(?<-2>(1+)¶)+)
$3$4¶
G3=`
1

在线尝试!(第一行启用换行分隔的测试套件。)

我以后还要打高尔夫球。



8

朱莉娅,29个字节

!n=n<3||!(n-!~-n)+!(n-!~-~-n)

在线尝试!

怎么运行的

我们根据!目的重新定义一元运算符。

如果n12,则n<3返回true,这是我们的返回值。

如果n大于2,则n<3返回false||。分支被执行。这是一个简单的实现的定义,其中的~-n产率N - 1~-~-n产量N - 2


7

Sesos,54个字节

0000000: eefb5b 04f83a a75dc2 36f8d7 cf6dd0 af7b3b 3ef8d7  ..[..:.].6...m..{;>..
0000015: cfed12 f661f0 ae9d83 ee63e6 065df7 ce6183 af7383  ....a.....c..]..a..s.
000002a: 76ef3c 3f6383 7eff9c b9e37f                       v.<?c.~.....

在线尝试

拆解

set numin
set numout
add 1
fwd 1
add 1
fwd 6
get
sub 1
jmp
    jmp
        sub 1
        fwd 1
        add 1
        rwd 1
    jnz
    fwd 1
    sub 1
    rwd 2
    add 2
    jmp
        rwd 4
        jmp
            sub 1
            fwd 3
            add 1
            rwd 3
        jnz
        fwd 4
        jmp
            sub 1
            rwd 3
            add 1
            rwd 1
            add 1
            fwd 4
        jnz
        rwd 3
        jmp
            sub 1
            fwd 3
            add 1
            rwd 3
        jnz
        fwd 4
        add 2
        jmp
            rwd 5
            jmp
                rwd 1
                jmp
                    sub 1
                    fwd 2
                    add 1
                    rwd 2
                jnz
                fwd 1
                jmp
                    sub 1
                    rwd 1
                    add 1
                    fwd 1
                jnz
                rwd 1
                sub 1
            jnz
            fwd 2
            jmp
                sub 1
                rwd 1
                add 1
                rwd 1
                add 1
                fwd 2
            jnz
            fwd 1
            jmp
                rwd 2
                jmp
                    sub 1
                    fwd 1
                    add 1
                    rwd 1
                jnz
                fwd 2
                jmp
                    sub 1
                    rwd 2
                    add 1
                    fwd 2
                jnz
                fwd 1
            jnz
            fwd 3
            sub 1
        jnz
        rwd 2
        jmp
            sub 1
            rwd 3
            add 1
            fwd 3
        jnz
        fwd 1
        sub 1
    jnz
    fwd 2
jnz
rwd 7
put

或使用Brainfuck表示法:

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

6

C,43 42字节

@Dennis节省了1个字节

每个答案都是相同的,我必须做些不同的事情!

在线尝试!

a(n){return n<3?:a(n-a(n-2))+a(n---a(n));}

说明:基本上是这样,a(n-a(n-2))+a(n-a(n-1))但是有一些不确定的行为(可以在我的手机(gcc)和ideone上使用)。


4
1.您还应提及编译器;您的“赃物”是未定义的行为。2.使用GCC,您不需要1介于?和之间:
丹尼斯

@Dennis有趣的是,同样的公式在我的迭代PowerShell答案中也$b+=$b[$_-$b[$_-2]]+$b[$_---$b[$_]]
起作用

@TimmyD一些编译器可能会在n--之前编译a(n),并且没有标准行为(或定义好的行为)。因此,行为不确定。
betseg '16

@betseg是的,我同意。只是指出它不一定独有C.
AdmBorkBork

@TimmyD哦,我误会了。我只是想更改每个人使用的功能,所以我的会有所不同和:草:D
betseg 2016年

5

Mathematica,36个字节

字节数假定使用ISO 8859-1编码,并且Mathematica $CharacterEncoding设置为WindowsANSI(Windows上的默认设置;其他设置也可以使用,但有些设置UTF-8绝对不能使用)。

±1=±2=1
±n_:=±(n-±(n-1))+±(n-±(n-2))

定义±为一元运算符。

我试图摆脱重复,但最终得到了相同的字节数:

±1=±2=1
±n_:=Tr[±(n-±(n-#))&/@{1,2}]

我可以给你一个+200赏金,如果你在视网膜做到这一点
漏嫩

@LeakyNun好吗?:)
Martin Ender

两天后。
Leaky Nun

@LeakyNun很快,如果您这么轻松地提供赏金,您将没有代表。
mbomb007 '16


4

果冻15 14 字节

2Rạ⁸߀$⁺Sµ1>?2

在线尝试!验证所有测试用例(需要几秒钟)。

怎么运行的

2Rạ⁸߀$⁺Sµ1>?2  Main link. Argument: n (integer)

2R              Yield [1, 2].
      $         Combine the previous three links into a monadic chain.
   ⁸                Yield n.
  ạ                 Take the absolute difference of the return value and n.
    ߀              Recursively call the main link on each result.
       ⁺            Duplicate the chain.
                    The first copy maps [1, 2] to [a(n - 1), a(n - 2)].
                    The second copy maps [a(n - 1), a(n - 2)] to
                    [a(n - a(n - 1)), a(n - a(n - 2))].
        S           Take the sum.
         µ          Combine all links to the left into a chain.
            ?       If...
           > 2          n is greater than 2, call the chain.
          1         Else, return 1.

如果您在Sesos进行,我可能会给您+400的赏金。
Leaky Nun

@LeakyNun似乎有一个Sesos的答案。发表您评论后的一天。
Yytsi'2

4

果冻14 12 11 字节

ịḣ2S;
1Ç⁸¡2ị

这是一种迭代方法。

在线尝试!验证所有测试用例

怎么运行的

1Ç¡2ị   Main link. Argument: n

1       Set the return value to 1.
 Ç¡     Call the helper link n times, updating the return value after each call.
   2ị   Extract the second element of the resulting array.


ịḣ2S;   Helper link. Argument: A (array)

ị       At-index; retrieve the elements of A at the values of A.
 ḣ2     Head 2; extract the first two results.
    S   Take the sum of the result.
     ;  Prepend the sum to A.

3

Python,45 40字节

a=lambda n:n<3or a(n-a(n-1))+a(n-a(n-2))

对挑战的简单天真解释。

@LeakyNun节省了5个字节!


3

Haskell,39 37字节

h n|n<3=1|n>2=h(n-h(n-1))+h(n-h(n-2))

完全像挑战中所述,使用了守卫


抱歉,在发布我的(完全相同)haskell解决方案之前,我没有看到您的解决方案。但是,不是因为要考虑换行而需要计算字节数38吗?
Laikoni'7

而后卫必须n<3h 2 1
Laikoni'7

@Laikoni根据Python的len特性,它是37,带有多行(“”“)字符串,除非您将换行符计为两个字节。是的,我注意到另一件事现在已解决
。– KarlKastor

TIL notepad ++将换行符视为两个字符。
Laikoni '16

@Laikoni摆脱了换行符,现在毫无疑问是37个字节。
KarlKastor '16

3

R,50个字节

a=function(n)ifelse(n<3,1,a(n-a(n-1))+a(n-a(n-2)))

用法:

> a(1)
  1
> a(20)
  12


3

C#,51 44字节

int a(int n)=>n<3?1:a(n-a(n-1))+a(n-a(n-2));

我想知道是否可以通过使它成为匿名名称来缩短 pinkfloydx33!


1
C#6表达式功能强大int a(int n)=>n<3?1:a(n-a(n-a))+a(n-a(n-2));
pinkfloydx33

好像我在手机上键入时输入了错误信息。-a第一组括号中最里面的应该是-1
pinkfloydx33

我也没有注意到它,不适修复它rq
downrep_nation '16

3

JavaScript(ES6),45字节 34字节

ES6中的递归解决方案。任何打高尔夫球的技巧都值得赞赏。

a=n=>n>2?a(n-a(n-1))+a(n-a(n-2)):1

感谢/ u / ismillo进一步缩短时间。




2

APL,20个字节

{⍵≤2:1⋄+/∇¨⍵-∇¨⍵-⍳2}

说明:

{⍵≤2:1⋄+/∇¨⍵-∇¨⍵-⍳2}
 ⍵≤2:1               If argument is 2 or less, return 1
      ⋄              Otherwise:
               ⍵-⍳2  Subtract [1, 2] from the argument
             ∇¨      Recursive call on both
           ⍵-        Subtract both results from the argument     
         ∇¨          Recursive call on both again
       +/            Sum          

2

VBA Excel 87字节

非递归,因为我希望它为n = 100000工作,所以说:

Function A(N):ReDim B(N):For i=3 To N:B(i)=B(i-B(i-1)-1)+B(i-B(i-2)-1)+1:Next:A=B(N)+1

...,然后return在该行的末尾按(字节#87)以获取End Function“ free” 的语句。请注意,B值偏移-1以避免初始化n = 1和2。

正常调用电子表格,例如=A(100000)获取48157

递归版本61字节

Function Y(N):If N<3 Then Y=1 Else Y=Y(N-Y(N-1))+Y(N-Y(N-2))

在n> 30时开始变得异常缓慢,并且不能说在n> 40时完全起作用。


我们不在乎性能。我们关心代码长度。您应该将较短的解决方案移至答案的顶部。
mbomb007 '16

1
@ mbomb007因为我距离赢得高尔夫还差得很远,所以我将根据实际工作情况做出自己的选择。就我而言,即使有一个可以轻松做到的解决方案,就我而言,甚至不能处理单字节整数也不够好。
乔芬'16

2

Ruby,36个字节

直接执行。欢迎任何打高尔夫球的建议。

a=->n{n<3?1:a[n-a[n-1]]+a[n-a[n-2]]}

Afaik,您可以摆脱a =。如果将其发布在此处,则代码以->开头就足够了。然后将其视为匿名函数。
塞姆斯

@Seims不幸的是,由于函数使用a[n-1]诸如此类调用自身,因此需要命名该函数。
Sherlock9年

2

Java 7 68 61 51字节

感谢Leaky Nun保存了17条。

int a(int n){return n<3?1:a(n-a(n-1))+a(n-a(n-2));}

欢迎来到PPCG!
AdmBorkBork '16

欢迎来到PPCG!您可能喜欢Java高尔夫技巧。另一种形式是:int a(int n){return n<3?1:a(n-a(n-2))+a(n---a(n));},但是不幸的是,它使用的字节数与您已经拥有的答案相同。此外,由于Java 8的答案更短,我将指定您的答案在Java 7中:n->return n<3?1:a(n-a(n-1))+a(n-a(n-2))39 bytes) 。
凯文·克鲁伊森

感谢您的欢迎,也感谢Java8的技巧-我没有意识到lambda可以这样被允许-尽管在Python中可以这样允许lambda,所以我想我从来没有考虑过。Lambda是否需要使用分号?
贾斯汀

@JustinTervay我不使用Java 8了很多,但是从我所听到的分号不指望单行表达式,根据评论@DavidConrad@ CAD97自己的Java答案之一
凯文·克鲁伊森

2

Oasis9 7 5字节(无竞争)

禁止竞争,因为该语言推迟了挑战。感谢Kenny Lau节省了4个字节。码:

ece+V

扩展形式(V是的缩写11):

a(n) = ece+
a(0) = 1
a(1) = 1

码:

e        # Stack is empty, so a(n - 1) is used, and it calculates a(n - a(n - 1))
 c       # Calculate a(n - 2)
  e      # Calculate a(n - a(n - 2))
   +     # Add up

在线尝试!。在0.1秒内计算n = 1000。


1

PowerShell v2 +,85 79 69字节

param($n)$b=1,1;2..$n|%{$b+=$b[$_-$b[$_-1]]+$b[$_-$b[$_-2]]};$b[$n-1]

接受输入$n,设置$b为的数组@(1, 1),然后从进入循环2 .. $n。每次迭代,我们都会$b通过序列的简单+=定义来确定序列中的最新计算。然后,我们从中输出适当的数字$b(带有a,-1因为PowerShell中的数组的索引为零)。如果$nis 12因为这两个值$b从一开始就已预先填充到较低的索引中,则此方法有效,因此即使循环在垃圾上定位,也还是会被忽略。


递归解决方案78 76字节

$a={param($k)if($k-lt3){1}else{(&$a($k-(&$a($k-1))))+(&$a($k-(&$a($k-2))))}}

第一次,我使用等效的lambda作为答案,因为通常迭代解决方案更短(如您从所有嵌套的paren中所见)。但是,在这种情况下,嵌套paren在带有嵌套数组调用的迭代解决方案中几乎是重复的,因此递归解决方案更短。不,迭代解决方案的确缩短了(请参见上文)。

通过执行操作符调用它,例如&$a 20。只是一个直接递归调用。


1

JavaScript(ES6),66个字节

n=>[...Array(n+1)].reduce((p,_,i,a)=>a[i]=i<3||a[i-p]+a[i-a[i-2]])

非递归版本以提高速度;递归版本可能会更短,但我将其留给其他人编写。使用时我总是喜欢它reduce。注意:传回of 和时(在整数环境中使用时true会强制转换为1),以节省1个位元组。a(1)a(2)



1

四十六字节

我终于开始工作了!

: Q recursive dup dup 3 < if - 1+ else 2dup 2 - Q - Q -rot 1- Q - Q + then ;

在线尝试

说明:

: Q recursive                           \ Define a recursive function Q
    dup dup 3 <                         \ I moved a dup here to golf 2 bytes
    if                                  \ If n < 3, return 1
        - 1                             \ Golf: n-n is zero, add one. Same as 2drop 1+
    else
        2dup 2 - Q - Q                  \ Copy n until 4 on stack, find Q(n-Q(n-2))
        -rot                            \ Move the result below 2 copies of n
        1- Q - Q +                      \ Find Q(n-Q(n-2)), then add to previous ^
    then ;

在线尝试(上面略有偏离)

不幸的是,相互递归有点过于冗长,无法用于打高尔夫球。


1

枫树,43 41字节

a:=n->`if`(n>2,a(n-a(n-1))+a(n-a(n-2)),1)

用法:

> a(1);
  1
> a(20);
  12

这个问题无疑是一个很好的记忆对象。使用选项缓存,可以大大减少运行时间:

aC := proc(n) 
      option cache; 
      ifelse( n > 2, aC( n - aC(n-1) ) + aC( n - aC(n-2) ), 1 ); 
end proc:

可以使用以下命令查看:

CodeTools:-Usage( aC(50) );

0

J,29 28字节

1:`(+&$:/@:-$:@-&1 2)@.(2&<)

使用递归定义。

用法

额外的命令用于格式化多个输入/输出。

   f =: 1:`(+&$:/@:-$:@-&1 2)@.(2&<)
   (,:f"0) >: i. 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 1 2 3 3 4 5 5 6  6  6  8  8  8 10  9 10 11 11 12

说明

1:`(+&$:/@:-$:@-&1 2)@.(2&<)  Input: n
                        2&<   If n < 2
1:                              Return 1
                              Else
               -&1 2            Subtract [1, 2] from n to get [n-1, n-2]
            $:@                 Call recursively on n-1 and n-2
           -                    Subtract each of the results from n
        /@:                     Reduce using
      $:                          A recursive call on each
    +&                            Then summation
                                Return that value as the result

0

dc,62位元组

?si2sa1dd2:a:a[la1+dsadd1-;a-;alad2-;a-;a+r:ali;a0=A]dsAxli;af

该解决方案利用数组和递归。

?si          # Take input from stdin and store it in register `i'
2sa          # Initialise register `a' with 2, since we'll be putting in the first
             #   two values in the sequence
1dd2         # Stack contents, top-down: 2 1 1 1
:a           # Pop index, then pop value: Store 1 in a[2]
:a           # Ditto:                     Store 1 in a[1]
[            # Open macro definition
 la 1+ dsa   # Simple counter mechanism: Increment a and keep a copy on stack

# The STACK-TRACKER(tm): Top of stack will be at top of each column, under the
#   dashed line. Read commands from left to right, wrapping around to next line.
#   This will be iteration number n.
  dd   1-    ;a       -          ;a            la            d          
#-----------------------------------------------------------------------
# n    n-1   a[n-1]   n-a[n-1]   a[n-a[n-1]]   n             n          
# n    n     n        n          n             a[n-a[n-1]]   n          
# n    n     n                                 n             a[n-a[n-1]]
#                                                            n          
#                                                                       

  2-            ;a            -             ;a            +      r    :a
#-----------------------------------------------------------------------
# n-2           a[n-2]        n-a[n-2]      a[n-a[n-2]]   a[n]   n      
# n             n             a[n-a[n-1]]   a[n-a[n-1]]   n      a[n]   
# a[n-a[n-1]]   a[n-a[n-1]]   n             n                           
# n             n                                                       

 li;a        # Load index of target element, and fetch that element's current value
             #    Uninitialised values are zero
 0=A         # If a[i]==0, execute A to compute next term
]dsAx        # Close macro definition, store on `A' and execute
li;a         # When we've got enough terms, load target index and push value
f            # Dump stack (a[i]) to stdout

总之,如果有人正在为构建IDE dc,请告诉我!

0

Erlang,46个字节

f(N)when N<3->1;f(N)->f(N-f(N-1))+f(N-f(N-2)).

0

Lua,59个字节

function a(n)return n<3 and 1 or a(n-a(n-1))+a(n-a(n-2))end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.