1,2,4,8,16,…33?


24

挑战

编写一个函数/程序,以众所周知的数字顺序输出n第一个n元素或第一个元素:

         1, 2, 4, 8, 16 ...

哦,等等...我忘记了前几个数字:

1, 1, 1, 1, 2, 4, 8, 16 ...

哎呀,我会增加一些其他措施:

1, 1, 1, 1, 2, 4, 8, 16, 33, 69, 146, 312, 673, 1463, 3202, 7050, 15605, 34705 ...

这些数字是由(零索引)公式给出的广义加泰罗尼亚语数字:

一种ñ+1个=一种ñ+ķ=2ñ-1个一种ķ一种ñ-1个-ķ

哪里

一种0=一种1个=一种2=一种3=1个

这是OEIS A004149

您可以选择是否要对序列进行零索引或一索引。当然,顺序必须相同,因此,如果对公式进行单索引,则必须重写该公式。


如果我在这里错了,请纠正我,但是对一索引式公式的修改是更改a(n-1-k)a(n-k),对吗?
Sumner18

9
这让我想起了少数
群体

Answers:


22

Python,51字节

f=lambda n,k=2:n<3or k<n and f(k)*f(n-k-2)+f(n,k+1)

在线尝试!

简化公式:

一种ñ=ķ=2ñ-1个一种ķ一种ñ-2-ķ

一种-1个=一种0=一种1个=一种2=1个


8
恭喜!十万!
Stewie Griffin

由于我也是独立到达此解决方案的,所以我必须说,通往该解决方案的道路有点颠簸……
暴民埃里克

10

Perl 6,44个字节

{1,1,1,1,{sum @_[2..*]Z*@_[@_-4...0,0]}...*}

在线尝试!

匿名代码块,它返回值的惰性无限序列。这几乎实现了所描述的顺序,它的快捷方式是zip将所有第二个元素之后的所有元素乘以zip,然后将列表的倒数从第四个元素开始,最后添加一个额外的元素1

说明:

{                                          }  # Anonymous code block
                                       ...*   # Create an infinite sequence
 1,1,1,1,                                     # Starting with four 1s
         {                            }       # Where each new element is:
          sum                                   # The sum of
              @_[2..*]                          # The second element onwards
                      Z*                        # Zip multiplied with
                        @_[@_-4...0  ]          # The fourth last element backwards
                                   ,0           # And 1

10

05AB1E14 13 11字节

$ƒˆ¯Âø¨¨¨PO

在线尝试!

输出第0个索引的第n个元素。

$                # push 1 and the input
 ƒ               # repeat (input+1) times
  ˆ              #  add the top of the stack (initially 1) to the global array
   ¯             #  push the global array
    Â            #  and a reversed copy of it
     ø           #  zip the two together, giving a list of pairs
      ¨¨¨        #  drop the last 3 pairs
         P       #  take the product of each pair (or 1 if the list is empty)
          O      #  take the sum of those products
                 #  after the last iteration, this is implicitly output;
                 #  otherwise, it's added to the global array by the next iteration

7

JavaScript(ES6),42个字节

的端口XNOR的解决方案

0索引。

f=(n,k=2)=>n<3||k<n&&f(k)*f(n+~++k)+f(n,k)

在线尝试!


JavaScript(ES6), 83  75字节

一种更快,递归较少但更长的解决方案。

0索引。

f=(n,i,a=[p=1])=>a[n]||f(n,-~i,[...a,p+=(h=k=>k<i&&a[k]*a[i-++k]+h(k))(2)])

在线尝试!


7

Haskell,49 43 39字节

a n=max(sum[a k*a(n-2-k)|k<-[2..n-1]])1              

在线尝试!

对于n<3sum是0,所以max ... 1提高了它1

编辑:-6字节感谢@Jo King。



6

05AB1E17 13 字节

4Å1λ£₁λ¨Â¦¦s¦¦*O+

不小于现有的05AB1E答案,但是我想尝试新的05AB1E版本的递归功能作为自己的练习。也许可以打几个字节。编辑:确实可以,请参见下面@Grimy的05AB1E答案的递归版本,它是13 个字节

ñ

ñ£è
£

说明:


一种ñ=一种ñ-1个+ķ=2ñ-1个一种ķ一种ñ-1个-ķ

一种0=一种1个=一种2=一种3=1个

   λ               # Create a recursive environment,
    £              # to output the first (implicit) input amount of results after we're done
4Å1                # Start this recursive list with [1,1,1,1], thus a(0)=a(1)=a(2)=a(3)=1
                   # Within the recursive environment, do the following:
      λ            #  Push the list of values in the range [a(0),a(n)]
       ¨           #  Remove the last one to make the range [a(0),a(n-1)]
        Â          #  Bifurcate this list (short for Duplicate & Reverse copy)
         ¦¦        #  Remove the first two items of the reversed list,
                   #  so we'll have a list with the values in the range [a(n-3),a(0)]
           s       #  Swap to get the [a(0),a(n-1)] list again
            ¦¦     #  Remove the first two items of this list as well,
                   #  so we'll have a list with the values in the range [a(2),a(n-1)]
              *    #  Multiply the values at the same indices in both lists,
                   #  so we'll have a list with the values [a(n-3)*a(2),...,a(0)*a(n-1)]
               O   #  Take the sum of this list
               +  #  And add it to the a(n-1)'th value
                   # (afterwards the resulting list is output implicitly)

@Grimy的 13 字节版本(如果您还没有,请确保对他的回答进行投票!):

1λ£λ1šÂ¨¨¨øPO

ñ

可以再次更改为基于0的索引或无限列表:
1λèλ1šÂ¨¨¨øPO
λλ1šÂ¨¨¨øPO一种0=1个

说明:


一种ñ=ķ=2ñ-1个一种ķ一种ñ-2-ķ

一种-1个=一种0=一种1个=一种2=1个

 λ             # Create a recursive environment,
  £            # to output the first (implicit) input amount of results after we're done
1              # Start this recursive list with 1, thus a(0)=1
               # Within the recursive environment, do the following:
   λ           #  Push the list of values in the range [a(0),a(n)]
    1š         #  Prepend 1 in front of this list
      Â        #  Bifurcate the list (short for Duplicate & Reverse copy)
       ¨¨¨     #  Remove (up to) the last three value in this reversed list
          ø    #  Create pairs with the list we bifurcated earlier
               #  (which will automatically remove any trailing items of the longer list)
           P   #  Get the product of each pair (which will result in 1 for an empty list)
            O  #  And sum the entire list
               # (afterwards the resulting list is output implicitly)

1
有趣的是,这可以在tio上的40秒内解决a(1200),而其他递归方法对于n大于100的值会超时...
Stewie Griffin

1
我还制作了(但未发布)递归版本。这是针对前n项13个字节,或为无限名单11个字节。特殊大小的a(n-1)占用大量字节,因此不需要(例如,参见xnor的公式)。
肮脏的

@Grimy您介意我是否将您的递归解决方案添加到我的答案中(当然会给您信用)?我也将保留原始答案。但是很高兴看到原始公式与xnor的字节节省公式之间的差异。:)
凯文·克鲁伊森

1
当然可以!
Grimmy

@StewieGriffin是的,这些递归无穷函数的速度也给我留下了深刻的印象。也许是Elixir的长处之一,并且肯定是由于内置的​​延迟加载功能。它的计算n=100时间为0.65秒,但是当我禁用延迟加载时,它会在60秒后超时,即使是n=25
凯文·克鲁伊森





2

Japt19 17 16 字节

输出n第1个索引的th项。

@Zí*Zz2)Ťx}g4Æ1

试试吧

@Zí*Zz2)Ťx}g4Æ1     :Implicit input of integer U
@                    :Function taking an array as an argument via parameter Z
 Zí                  :  Interleave Z with
    Zz2              :  Z rotated clockwise by 180 degrees (simply reversing would be a bye shorter but would modify the original array)
   *                 :  Reduce each pair by multiplcation
       )             :  End interleave
        Å            :  Slice off the first element
         ¤           :  Slice off the first 2 elements
          x          :  Reduce by addition
           }         :End function
            g        :Pass the following as Z, push the result back to it and repeat until it has length U
             4Æ1     :Map the range [0,4) to 1s
                     :Implicit output of the last element

1

Haskell,65个字节

f a|a<4=1|z<-g[2..a]=sum$zipWith(*)z$reverse(1:g[0..a-4])
g=map f

在线尝试!

您可以使用f获取序列中的单个元素,也可以将值列表传递至g并获取该列表的所有索引。


1

第四(gforth)99 81字节

: f recursive dup 4 > if 0 over 3 do over 1- i - f i f * + loop else 1 then nip ;

在线尝试!

输出是n项,输入是1索引

编辑:通过切换到xnor的公式保存了17个字节。通过使用1索引保存了另外1个字节

代码说明

: f                     \ start a new word definition
  recursive             \ mark that this word will be recursive
  dup 4 >               \ duplicate the input and check if it is greater than 4
  if                    \ if it is:
    0 over              \ create an accumulator and copy n to top of stack
    3 do                \ start counted loop from 3 to n-1
      over 1- i - f     \ recursively calculate f(n-1-i)
      i f               \ recursively calculate f(i)
      * +               \ multiply results and add to accumulator
    loop                \ end the counted loop        
  else                  \ otherwise, if n < 5
    1                   \ put 1 on the stack
  then                  \ end the if block
  nip                   \ drop n from the stack
;                       \ end the word definition

1

木炭,26字节

F⁵⊞υ¹FN⊞υΣ✂E⮌υ×κ§υλ³→I§υ±⁴

在线尝试!链接是详细版本的代码。尽管在内部使用1索引进行计算,但打印0索引的第n个数字。说明:

F⁵⊞υ¹

从开始a[0] = a[1] = a[2] = a[3] = a[4] = 1。是的,这是1索引的,但是还有一个额外的第零值。这就是您的高尔夫代码。

FN

计算附加n条件。这是过分的,但是当时,它使找到所需的术语更加容易n<5

⊞υΣ✂E⮌υ×κ§υλ³

对于每个术语,将下一个术语计算为到目前为止的术语总和乘以到目前为止的术语的反向,不包括三个术语。

这是一个禁止操作的方法,用于诱使Charcoal解析的2参数形式Slice,否则我将不得不使用一种不太复杂的方法来删除三个术语。

I§υ±⁴

输出第四项。


1

Pyth,30个字节

J*4]1VQ=+J+eJsPP*M.t,PJ_PJ0;<J

在线尝试!

ñ

J*4]1VQ=+J+eJsPP*M.t,PJ_PJ0;<JQ # Full program, last Q = input (implicitly added)
J*4]1                  # J = 4 * [1] (=[1,1,1,1])
VQ                     # for N in range(Q):
  =+J                  #  J +=
     +eJ               #   J[-1] + 
        s              #    sum(                           )
           *M          #     map(__operator_mul,          )
             .t      0 #      transpose(          , pad=0)
               ,       #       [       ,         ]
                PJ     #         J[:-1] 
                  _PJ  #                 J[1::-1]
<JQ                    # J[::Q]

<@ñ



1

八度,73字节

g=(1:4).^0;for(i=3:(n=input('')))g(i+2)=g(4:i+1)*g(i-(2:i-1))';end;g(end)

在线尝试!

-2个字节,感谢Stewie Griffin。命令式方法再次胜过函数式递归方法。如下所示。

八度,75字节

f(f=@(a)@(n){@()sum(arrayfun(@(k)a(a)(k)*a(a)(n-2-k),2:n-1)),1}{2-(n>3)}())

在线尝试!

Captcha在发布此信息时想验证我是人类。老实说,我不太确定


我看不到任何明显的方法可以缩短循环方法...看起来不错!另外,我很少在八度中看到基于零的索引:)
Stewie Griffin

@StewieGriffin由于递归有一些偏移它并不真正的问题,如果你选择零或一个索引。我认为,如果我进行了2索引编制,也许可以剃掉一些字节,但这似乎是作弊行为。无论如何,您的直觉是正确的-以某种方式,以匿名递归的方式确实缩短了时间。我认为主要的优点是它可以很好地创建四个初始值,因为它只返回1 n<4
桑契斯

1
@StewieGriffin当然,好的旧矩阵乘法。做得好!
桑契斯


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.