给定长度的直链烯烃数量


28

直链烯烃定义为通过单键(烷烃),双键(烯烃)或三键(炔烃)连接的碳原子序列(使用隐式氢。)碳原子只能形成4个键,因此碳原子不得被强制具有四个以上的键。直链烯烃可以表示为其碳-碳键的列表。

这些是有效的直链烯烃的一些例子:

[]       CH4              Methane
[1]      CH3-CH3          Ethane
[2]      CH2=CH2          Ethene
[3]      CH≡CH            Ethyne
[1,1]    CH3-CH2-CH3      Propane
[1,2]    CH3-CH=CH2       Propene
[1,3]    CH3-C≡CH         Propyne
[2,1]    CH2=CH-CH3       Propene
[2,2]    CH2=C=CH2        Allene (Propadiene)
[3,1]    CH≡C-CH3         Propyne 
[1,1,1]  CH3-CH2-CH2-CH3  Butane
...

尽管这些不是,但是至少一个碳原子具有四个以上的键:

[2,3]
[3,2]
[3,3]
...

您的任务是创建一个给定正整数的程序/函数,该程序/函数n输出/返回长度恰好为碳原子的有效直链烯烃的数量n。这是OEIS A077998

规格/说明

  • 您必须1通过返回正确处理1
  • 烷基*喜欢[1,2]并且[2,1]被认为是不同的。
  • 输出是长度给定长度的所有可能的ALK *内斯的列表。
  • 不是要正确处理0。

测试用例:

1 => 1
2 => 3
3 => 6
4 => 14

这是代码高尔夫球,因此最低字节数获胜!


只是为了澄清一下,如果所有连续对都加到上<=4,一条链是有效的,对吗?
Maltysen '16

固定。@Maltysen:是的。
扎卡里

4
为什么所有内容都有OEIS序列?:P
HyperNeutrino,2013年

2
@ZacharyT,恰好有一个碳原子数为零的烃,它也是一个氢原子数为零的烃。这与Pascal三角形的顶部完全为1而不是0完全相同,或者实际上是数百个其他组合序列。
彼得·泰勒

1
@Emigna,这是因为链接了错误的序列。我会改正的。
彼得·泰勒

Answers:


7

绿洲9 7字节

xcd-+3V

在线尝试!

说明

这使用了OEIS中的递归关系:

a(n)= 2 * a(n-1)+ a(n-2)-a(n-3)

x    Multiply a(n-1) by 2: gives 2*a(n-1)
c    Push a(n-2)
d    Push a(n-3)
-    Subtract: gives a(n-2) - a(n-3)
+    Add: gives 2*a(n-1) + a(n-2) - a(n-3)
3    Push 3: initial value for a(n-1)
V    Push 1, 1: initial values for a(n-2), a(n-3)

1
很好地使用初始值!您这次赢得了胜利;)
Emigna '16

是的,可能无法克服这个问题。
扎卡里

4
@ZacharyT仅当有人可以找出使程序包含xkcd在其中的方法时。
hBy2Py

4
@ hBy2Py好吧,xkcd-+311工作正常,因为k目前是空运...
Luis Mendo

10

MATL,10字节

7K5vBiY^1)

在线尝试!

说明

这使用了OEIS中的特征

a(n)是3 X 3矩阵[1,1,1; 1,0,0; 1,0,1]

7    % Push 7
K    % Push 4
5    % Push 5
v    % Concatenate all numbers into a column vector: [7; 4; 5]
B    % Convert to binary: gives 3×3 matrix [1, 1, 1; 1, 0, 0; 1, 0, 1]
i    % Input n
Y^   % Matrix power
1)   % Take the first element of the resulting matrix, i.e. its upper-left corner.
     % Implicitly display

6

绿洲9 8字节

多亏了Adnan,节省了一个字节

xc+d-63T

在线尝试!

说明

a(0) = 0
a(1) = 1
a(2) = 3
a(3) = 6

a(n) = xc+d-

x         # calculate 2*a(n-1)
 c        # calculate a(n-2)
  +       # add: 2*a(n-1) + a(n-2)
   d      # calculate a(n-3)
    -     # subtract: 2*a(n-1) + a(n-2) - a(n-3)

1
真好!另外,x2*:)的缩写。
阿德南

1
Beat ya :-P(我还没有看到OASIS的答案)
Luis Mendo 2016年

@Adnan是否可以告诉Oasis您要将输出序列索引移位1?我的意思是,在输入参数中减去1(而不是在0此处使用
缩写

1
@LuisMendo啊,还没有实现。但这是下一个版本的好主意:)。
阿德南

供将来参考,该方法现已实施
Luis Mendo

4

果冻,10个字节

745DBæ*µḢḢ

在线尝试!

使用Luis Mendo算法

说明

745DBæ*µḢḢ    Main link. Argument: n
745D          Get the digits of 745
    B         Convert each to binary
     æ*       Matrix power
        ḢḢ    First element of first row

果冻,15个字节

3Rṗ’µ+2\<5PµÐfL

在线尝试!

使用蛮力。

说明

3Rṗ’µ+2\<5PµÐfL    Main link. Argument: n
3R                 Start with [1, 2, 3]
   ’               Take the (n-1)'th
  ṗ                Cartesian power
            Ðf     Filter on:
     +2\             Sums of overlapping pairs
        <5           1 for sums < 5, 0 otherwise
          P          Product: 1 if all pairs < 5
              L    Length

4

MATL,14个字节

q3:Z^TTZ+!5<As

在线尝试!

说明

这将产生[1 2 3]“提高”到小于1的原子数的笛卡尔乘方,然后使用卷积来检查每个笛卡尔元组中的两个连续数之和不大于4

q    % Take number of atoms n implicitly
3:   % Push [1 2 3]
Z^   % Cartesian power. Gives a matrix with each (n-1)-tuple on a row
TT   % Push [1 1]
Z+   % 2D convolution. For each tuple this gives the sum of contiguous numbers
5<   % For each entry, gives true if less than 5
!    % Transpose
A    % True if all elements of each column are true. Gives a row vector
s    % Sum of true results. Implicitly display

3

Mathematica,48个字节

MatrixPower[{{1,1,1},{1,0,0},{1,0,1}},#][[1,1]]&

正如Luis Mendo 指出的那样,这是OEIS中的A006356。这是我最初的尝试:

Count[Length@Split[#,+##<5&]&/@Tuples[{1,2,3},#-1],0|1]&

对于输入nTuples[{1,2,3},n-1]是表示碳原子的单键,双键或三键所有可能序列的(n-1)元素的所有元组的列表。是一个纯函数,它返回其参数的和是否小于,因此将一个列表分成子列表,子列表由逐对和小于的连续元素组成。描述有效的alk * ne等效于此列表的长度(在情况下为)或,因此我只是该列表的长度与-tuples相匹配的数量。{1,2,3}n+##<5&5Split[#,+##<5&]&50n=11Count(n-1)0|1

Count[Fold[If[+##>4,4,#2]&]/@Tuples[{1,2,3},#-1],Except@4]&

If[+##>4,4,#2]&返回4如果它的参数的总和大于4否则返回第二个参数。使用此功能在其输入Fold[If[+##>4,4,#2]&]的左侧Fold。所以在这里,我没有应用此运算符Count(n-1)-tuple 数4n=1覆盖的情况,因为Fold当它的第二个参数为空列表时仍未评估{}


1
这行得通吗?(从OEIS处直接获得调整的种类)LinearRecurrence[{2,1,-1},{1,3,6},#][[#]]&
扎卡里

我喜欢这个网站的部分原因是学习Mathematica必须提供的所有功能:)
ngenisis

通过this site,你的意思OEIS或PPCG?
扎卡里

PPCG。我从人们的建议中摘取了许多Mathematica。
ngenisis '16

3

Python,51个字节

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

这是递归关系的直接实现。感谢Tim Pederick提供的3个字节。输出为Python 3中的浮点数和Python 2中的整数。

在线尝试!


(n*n+n)/2比短[1,3,6][n-1]。而且,如果您使用的是Python 3,并且不喜欢以浮点输出结束,那么(n*n+n)//2它会更短。
蒂姆·佩德里克


2

Ruby,62个字节

->n{c=0
(10**n/10).times{|i|"#{i}#{i*11}"=~/[3-9]/||c+=1}
c}

效率极低的10级暴力破解方法。可以改进为以5为基数的其他字节。

生成数字,其中每个数字代表一个键(n-1个数字。)0代表一个键序1,2代表一个键序3。超过2的数字无效。

我们将此乘以11即可得出相邻数字对的和。再次超过3的数字无效。

我们将两个数字组合成一个字符串,并执行正则表达式来搜索无效数字。如果没有找到,我们增加计数器。

在测试程序中

f=->n{c=0
(10**n/10).times{|i|"#{i}#{i*11}"=~/[3-9]/||c+=1}
c}

p f[gets.to_i]

2

Ruby,51个字节

->n{a=[1,1,3]
n.times{a<<2*a[-1]+a[-2]-a[-3]}
a[n]}

基于每个OEIS A006356的重复关系。

从一个数组开始,该数组分别包含序列的元素0,1和2,分别为1(由我计算,使其起作用),1和3。

迭代n地向序列中添加更多元素,然后返回element n。它总是计算比实际需要更多的2个元素,但是它仍然是线性时间,这比我以前的答案要有效得多。

在测试程序中

f=->n{a=[1,1,3]
n.times{a<<2*a[-1]+a[-2]-a[-3]}
a[n]}

p f[gets.to_i]

2

Mathematica,42个 40字节

字节数假定使用兼容的单字节编码,例如CP-1252(Windows安装中的默认设置)。

±0=±1=1;±2=3;±n_:=±(n-1)2+±(n-2)-±(n-3);

这只是将OEIS上的重复执行为一元运算符。


2

CJam(19个字节)

{2,{__-2=+1b+}@*W=}

在线测试套件。这是一个匿名块(函数),它在堆栈上保留一项,而在堆栈上保留一项。请注意,测试套件包括a(0) = 1

所使用的重复基于对相关OEIS序列A006356的观察:

等于(1、2、1、1、1、1 ...)的INVERT变换等于a(n)= a(n-1)+ 2 * a(n-2)+ a(n-3)+ a(n-4)+ ... +1。a(6)= 70 =(31 + 2 * 14 + 6 + 3 +1 + 1)。-Gary W.Adamson,2009年4月27日

但具有适当的偏移量,从而消除了对+ 1现在所涉及的决赛的需求a(0)

解剖

{         e# Define a block
  2,      e#   Take starting sequence [0 1] (beginning at index -1 for golfiness)
  {       e#   Loop...
    _     e#     Copy sequence so far
    _-2=+ e#     Append an extra copy of a(n-2)
    1b    e#     Sum
    +     e#     Append
  }@*     e#   ...n times
  W=      e#   Take the final value from the sequence
}

2

Brain-Flak,56个字节

使用OEIS页面上第一个注释中详述的算法。

在线尝试!

({}[()]<(((())))>){({}[()]<{({}<>({}))<>}<>>)}{}({}<>{})

说明

序列可以这样定义:

For u(k), v(k), and w(k) such that
u(1) = v(1) = w(1) = 1
u(k+1) = u(k) + v(k) + w(k)
v(k+1) = u(k) + v(k)
w(k+1) = u(k)
u(k) is the number of straight-chain alk*nes with length k

程序开始于1并重复应用此重复进行计算u(k)

带注释的代码(即将提供实际注释)

# Setup: decrement the input by one and push three 1's to the stack under it
({}[()]<(((())))>)

# Calculation:
{                          }           # While the input is not zero (main loop)
 ({}[()]                  )            # Pop the counter decrement it by one and push it
        <                >             # Before the counter gets pushed back to the stack...
         {            }                # Loop while the top of the stack is not zero (subloop)
          (        )                   # Push...
           {}                          # The top of the stack (popped)...
             <>                        # to the other stack...
               ({})                    # plus the top of the other stack (peeked)
                    <>                 # Switch back to the first stack.
                       <>              # Switch to the other stack
                            {}         # Pop the input (now zero)
                              (      ) # Push...
                               {}      # The top of the stack (u(k))...
                                 <>    # to the other stack...
                                   {}  # plus the top of the other stack (zero).

堆栈可视化

在主循环的一次迭代中,这是发生的事情(请注意,零可能会或可能不会出现,但无论哪种方式都没有关系):

Start of main loop iteration/subloop first iteration:
A    B

u
v
w
0    0
^

After first subloop iteration:
A    B

v
w    u
0    0
^

After second subloop iteration:
A    B

    u+v
w    u
0    0
^

After third subloop iteration (top of stack is zero so subloop terminates):

A    B

   u+v+w
    u+v
     u
0    0
^

End of main loop iteration:
A    B

   u+v+w
    u+v
     u
0    0
     ^

堆叠的状态是现在同样的,因为它是在循环的不同之处在于当前堆栈现在有下一个值开始uv以及w在其上。


2

Perl 6,48

{my @a=1,0,0;@a=reverse [\+] @a for 1..$_;@a[0]}

本来

sub f {$_>2??2*f($_-1)+f($_-2)-f($_-3)!!(1,1,3)[$_]}

但是我忘了我需要sub f这样,所以迭代解决方案会成功。


2

Dyalog APL,30个字节

{⍵<3:⍵⌷1 3⋄+/∧/¨4≥2+/¨,⍳1↓⍵/3}

使用蛮力。说明(至少是我的最佳尝试):

⍵<3:⍵⌷1 3 - if ⍵ (function arg) is 1 (case 1) or 2 (case 2), return 1 (case 1) or 3 (case 2)
⋄ - separate statements
⍵/3 - otherwise, 3 repeated ⍵ times
1↓ - without the first element
⍳ - the matrix of possible indices of a matrix of that size
,  - ravel, return a list of all the elements of the matrix
2+/¨ - sum of each contiguous pair on each element
4≥ - tests whether each element is less than or equal to 4
∧/¨ - all elements are true, applied to each item.
+/ - Sum.

1

Dyalog APL,29个字节

{⍵<4:⍵⌷1 3 6⋄+/2 1 ¯1×∇¨⍵-⍳3}

通过使用整数序列OEIS A006356的递归定义来工作。


1

带有Numpy的Python,62个字节

我必须尝试一下,但是看起来纯Python和递归比numpy和OEIS页面上基于矩阵的显式计算要短。

from numpy import*
lambda n:(mat('1 1 1;1 0 0;1 0 1')**n)[0,0]

1

R,61 58 55 51 50字节

从标准输入中获取输入,使用矩阵求幂来确定精确结果。

el(expm::`%^%`(matrix(!-3:5%in%2^(0:2),3),scan()))

如果您喜欢递归解决方案,则可以使用OEIS中列出的55个字节的递归关系直接实现。

f=function(n)`if`(n<4,(n*n+n)/2,2*f(n-1)+f(n-2)-f(n-3))

1

Excel,123字节

实现OEIS中的公式:

=4*(SIN(4*PI()/7)^2*(1+2*COS(2*PI()/7))^A1+SIN(8*PI()/7)^2*(1+2*COS(4*PI()/7))^A1+SIN(2*PI()/7)^2*(1+2*COS(8*PI()/7))^A1)/7

与往常一样,A1在其他任何单元格中输入,公式。

挖掘旧的Trig身份,看是否有帮助。现在我的头很痛。


0

Lithp,79个字节

#N:(((if(< N 4)((/(+ N(* N N))2))((-(+(* 2(f(- N 1)))(f(- N 2)))(f(- N 3)))))))

实现OEIS中列出的递归整数序列。

可读的实现和测试套件。

% alkaline.lithp
% run with: ./run.js alkaline.lithp
(
    (def f #N : ((
        (if (< N 4) (
            (/ (+ N (* N N)) 2)
        ) (else (
            (- (+ (* 2 (f (- N 1))) (f (- N 2))) (f (- N 3)))
        )))
    )))

    % Test cases 1 to 4
    (import lists)
    (each (seq 1 4) #I :: ((print (f I))))
)
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.