Количество прямых цепей Alk * nes заданной длины

28

Прямой цепной алк * ne определяется как последовательность атомов углерода, соединенных одинарной (алкан), двойной (алкен) или тройной связью (алкин) (используются неявные атомы водорода). Атомы углерода могут образовывать только 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
...

Хотя это не так, по крайней мере, один атом углерода будет иметь более 4 связей:

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

Ваша задача состоит в том, чтобы создать программу / функцию, которая при заданном натуральном числе nвыдает / возвращает количество действительных прямолинейных алкенов nс длиной атомов углерода. Это OEIS A077998 .

Спецификации / Разъяснения

  • Вы должны 1правильно обращаться , возвращаясь 1.
  • Алки * нравятся [1,2]и [2,1]считаются различными.
  • Выход - длина списка всех возможных вариантов * данной длины.
  • Вы не должны обрабатывать 0 правильно.

Тестовые случаи:

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

Это кодовый гольф, поэтому выигрывает меньшее количество байтов !

Zachary
источник
просто чтобы уточнить, цепочка действительна, если все последовательные пары суммируются <=4, верно?
Maltysen
Исправлена. @Maltysen: да.
Захари
4
Почему есть последовательность OEIS для всего? : P
HyperNeutrino
2
@ZacharyT, есть точно один углеводород с нулевыми атомами углерода, и это тот, который также имеет нулевые атомы водорода. Это тот же аргумент, что и для треугольника Паскаля, имеющего 1 вверху, а не 0, или для буквально сотен других комбинаторных последовательностей.
Питер Тейлор
1
@ Emigna, это потому, что неправильная последовательность была связана. Я исправлю это.
Питер Тейлор

Ответы:

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
Да, вероятно, нет способа победить это.
Захари
4
@ZacharyT Только если кто-то может найти способ заставить программу иметь xkcdэто.
hBy2Py
4
@ hBy2Py Ну, xkcd-+311работает , потому что kв настоящее время не работает ...
Луис Мендо
10

MATL , 10 байт

7K5vBiY^1)

Попробуйте онлайн!

объяснение

Это использует характеристику, найденную в OEIS

a (n) - верхний левый элемент 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 байт

Сохранил байт благодаря Аднану

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)
Emigna
источник
1
Ницца! Кроме того, xэто сокращение от 2*:).
Аднан
1
Beat ya :-P (я не видел, там уже был ответ OASIS)
Луис Мендо
@Adnan Есть ли способ сообщить Oasis, что вы хотите сместить индекс выходной последовательности на 1? Я имею в виду, вычтите 1 из входного аргумента (вместо использования начального 0здесь)
Луис Мендо
1
@ LuisMendo Ах, это еще не реализовано. Но это хорошая идея для следующего релиза :).
Аднан
Для дальнейшего использования теперь это реализовано
Луис Мендо,
4

Желе, 10 байт

745DBæ*µḢḢ

Попробуйте онлайн!

Использует алгоритм Луиса Мендо .

объяснение

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
PurkkaKoodari
источник
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]]&

Как отметил Луис Мендо , это A006356 в OEIS. Вот мои оригинальные попытки:

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

Для ввода n, Tuples[{1,2,3},n-1]список всех (n-1)-кортежей элементов в {1,2,3}представляющих все возможные последовательности одно-, двух-, или тройных связей для nатомов углерода. +##<5&является чистой функцией, которая возвращает значение меньше, чем сумма ее аргументов 5, поэтому Split[#,+##<5&]&разбивает список на подсписки, состоящие из последовательных элементов, попарные суммы которых меньше 5. Описание действительного alk * ne эквивалентно тому, что этот список имеет длину 0(в случае, где n=1) или 1, поэтому я просто Countколичество (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)-туплей, которым применение этого оператора не дает 4. Случай, где n=1рассматривается, так как Foldостается неоцененным, когда его вторым аргументом является пустой список {}.

ngenisis
источник
1
Будет ли это работать? (Вид сорвал прямо из OEIS с настройками) LinearRecurrence[{2,1,-1},{1,3,6},#][[#]]&?
Захари
Часть того, почему я люблю этот сайт, изучает все возможности, которые Mathematica может предложить :)
ngenisis
К this site, вы имеете в виду OEIS или PPCG?
Захари
PPCG. Я взял много Mathematica из предложений людей.
ngenisis
3

Python, 51 байт

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

Это прямая реализация рекуррентного отношения. Спасибо Тиму Педерику за 3 байта. Выходные данные - это число с плавающей точкой в ​​Python 3 и целое число в Python 2.

Попробуйте онлайн!

Mego
источник
(n*n+n)/2короче чем [1,3,6][n-1]. И если вы используете Python 3 и вам не нравится заканчивать выводом с плавающей запятой, (n*n+n)//2все равно будет короче.
Тим Педерик
2

Pyth - 16 байт

Использует грубую силу.

lf.AgL4+VTtT^S3t

Тестовый пакет .

Maltysen
источник
1
Было бы неплохо дать описание для тех из нас, кто не "питает" Пит.
Захари
2

Рубин, 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]
Уровень реки St
источник
2

Рубин, 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больше элементов в последовательность, а затем возвращает элемент 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]
Уровень реки St
источник
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 :

Соответствует преобразованию INVERT (1, 2, 1, 1, 1, ...), эквивалентному 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). - Гэри В. Адамсон, 27 апреля 2009 г.

но с соответствующим смещением, что устраняет необходимость в финале, + 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
     ^

Состояние стеков теперь так же , как это было в начале цикла , за исключением , что текущий стек теперь имеет следующие значения u, vи wна нем.

0 '
источник
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поэтому выигрывает итеративное решение.

bb94
источник
2

Дьялог АПЛ, 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.
Zachary
источник
1

Дьялог АПЛ, 29 байт

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

Работает с использованием рекурсивного определения целочисленной последовательности OEIS A006356.

Zachary
источник
1

Питон с Numpy, 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))
rturnbull
источник
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формулу в любой другой ячейке.

Выкопайте старые идентификационные данные Трига, чтобы увидеть, может ли это быть полезным. Теперь у меня болит голова.

Wernisch
источник
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))))
)
Andrakis
источник