Número de Alk de cadeia reta * nes de determinado comprimento

28

Um alcalino de cadeia linear é definido como uma sequência de átomos de carbono conectados por ligações simples (alcano), duplas (alceno) ou triplas (alcino), (são usados ​​hidrogênios implícitos.) Os átomos de carbono podem formar apenas 4 ligações, portanto nenhum átomo de carbono pode ser forçado a ter mais de quatro ligações. Um alcalino de cadeia linear pode ser representado como uma lista de suas ligações carbono-carbono.

Estes são alguns exemplos de alcoóis de cadeia linear válidos:

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

Enquanto estes não são, como pelo menos um átomo de carbono teria mais de 4 ligações:

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

Sua tarefa é criar um programa / função que, dado um número inteiro positivo n, produz / retorne o número de alcos de cadeia linear válidos com exatamente nátomos de carbono de comprimento. Este é o OEIS A077998 .

Especificações / Esclarecimentos

  • Você deve manipular 1corretamente retornando 1.
  • Alk * nes gostam [1,2]e [2,1]são considerados distintos.
  • Saída é o comprimento de uma lista de todos os alcinos possíveis de um determinado comprimento.
  • Você não precisa manipular 0 corretamente.

Casos de teste:

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

Isso é código de golfe, então a contagem de bytes mais baixa ganha!

Zacharý
fonte
só para esclarecer, uma cadeia é válida se todos os pares consecutivos forem somados <=4, certo?
Maltysen
Fixo. @ Maltysen: sim.
Zacharý
4
Por que existe uma sequência OEIS para tudo? : P
HyperNeutrino
2
@ ZacharyT, existe precisamente um hidrocarboneto com zero átomos de carbono, e é aquele que também tem zero átomos de hidrogênio. É exatamente o mesmo argumento que o triângulo de Pascal tem um 1 no topo, em vez de um 0, ou literalmente centenas de outras seqüências combinatórias.
Peter Taylor
1
@ Emigna, é porque a sequência errada foi vinculada. Eu vou corrigir isso.
Peter Taylor

Respostas:

7

Oasis , 9 7 bytes

xcd-+3V

Experimente online!

Explicação

Isso usa o relacionamento de recorrência no 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)
Luis Mendo
fonte
1
Bom uso dos valores iniciais! Você venceu desta vez;)
Emigna
Sim, provavelmente não há como superar isso.
Zacharý
4
@ZacharyT Somente se alguém puder descobrir uma maneira de fazer com que o programa tenha xkcdnele.
Hby2Py
4
@ hBy2Py Bem, xkcd-+311funciona , porque katualmente é um não ...
Luis Mendo
10

MATL , 10 bytes

7K5vBiY^1)

Experimente online!

Explicação

Isso usa a caracterização encontrada em OEIS

a (n) é a entrada superior esquerda da n-ésima potência da matriz 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
Luis Mendo
fonte
6

Oásis , 9 8 bytes

Guardou um byte graças a Adnan

xc+d-63T

Experimente online!

Explicação

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
fonte
1
Agradável! Além disso, xé a abreviação de 2*:).
Adnan
1
Beat ya :-P (eu não tinha visto uma resposta do OASIS) #
Luis Mendo
@Adnan Existe uma maneira de dizer ao Oasis que você deseja alterar o índice de sequência de saída em 1? Quer dizer, subtrair um para o argumento de entrada (em vez de utilizar um inicial 0aqui)
Luis Mendo
1
@LuisMendo Ah, isso ainda não foi implementado. Mas é uma boa ideia para o próximo lançamento :).
Adnan
Para referência futura, isso agora está implementado
Luis Mendo
4

Gelatina, 10 bytes

745DBæ*µḢḢ

Experimente online!

Usa o algoritmo de Luis Mendo .

Explicação

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

Gelatina, 15 bytes

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

Experimente online!

Usa força bruta.

Explicação

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
fonte
4

MATL , 14 bytes

q3:Z^TTZ+!5<As

Experimente online!

Explicação

Isso gera o poder cartesiano de [1 2 3]"elevado" ao número de átomos menos 1 e, em seguida, usa a convolução para verificar se não há dois números contíguos em cada tupla cartesiana somando mais de 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
Luis Mendo
fonte
3

Mathematica, 48 bytes

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

Como Luis Mendo apontou , este é o A006356 no OEIS. Aqui estão as minhas tentativas originais:

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

Para uma entrada n, Tuples[{1,2,3},n-1]é a lista de todos os (n-1)pares de elementos que {1,2,3}representam todas as sequências possíveis de ligações simples, duplas ou triplas para nátomos de carbono. +##<5&é uma função pura que retorna se a soma de seus argumentos é menor que 5, portanto, Split[#,+##<5&]&divide uma lista em sublistas que consistem em elementos consecutivos cujas somas em pares são menores que 5. Descrever um alc * ne válido é equivalente a que esta lista tenha comprimento 0(no caso em que n=1) ou 1, portanto, apenas Counto número de (n-1)-tuplas em que o comprimento dessa lista corresponde 0|1.

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

If[+##>4,4,#2]&retorna 4se a soma de seus argumentos for maior que 4e retorna o segundo argumento caso contrário. Fold[If[+##>4,4,#2]&]faz uma esquerda Foldde sua entrada com esta função. Então aqui estou Counto número de (n-1)-tuples aos quais a aplicação desse operador não fornece 4. O caso em que n=1é abordado Foldpermanece sem avaliação quando seu segundo argumento é a lista vazia {}.

ngenisis
fonte
1
Isso funcionaria? (Tipo rasgado do OEIS com ajustes) LinearRecurrence[{2,1,-1},{1,3,6},#][[#]]&?
Zacharý
Parte da razão pela qual eu amo este site é aprender todos os recursos Mathematica tem para oferecer :)
ngenisis
Por this site, você quer dizer OEIS ou PPCG?
Zacharý 14/12/16
PPCG. Eu peguei um monte de Mathematica nas sugestões das pessoas.
Ngenisis
3

Python, 51 bytes

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

Essa é uma implementação direta da relação de recorrência. Obrigado a Tim Pederick por 3 bytes. A saída é um float no Python 3 e um número inteiro no Python 2.

Experimente online!

Mego
fonte
(n*n+n)/2é mais curto que [1,3,6][n-1]. E se você estiver usando Python 3 e não gostar de terminar com saída de ponto flutuante, (n*n+n)//2é ainda mais curto.
Tim Pederick
2

Pitão - 16 bytes

Usa força bruta.

lf.AgL4+VTtT^S3t

Conjunto de Teste .

Maltysen
fonte
1
Seria bom fornecer uma descrição para aqueles que não "criticam" Pyth.
Zacharý
2

Ruby, 62 bytes

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

Abordagem de força bruta de base 10 horrivelmente ineficiente. Pode ser aprimorado para a base 5 para bytes adicionais.

Os números são gerados onde cada dígito representa uma ligação (n-1 dígitos.) 0Representa uma ordem de ligação de 1, 2representa uma ordem de ligação de 3. Os dígitos acima de 2 são inválidos.

Nós multiplicamos por 11 para somar o par de dígitos adjacente. Novamente, dígitos acima de 3 são inválidos.

Combinamos os dois números em uma sequência e executamos uma regex para procurar dígitos inválidos. Se nenhum for encontrado, incrementamos o contador.

no programa de teste

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

p f[gets.to_i]
Level River St
fonte
2

Ruby, 51 bytes

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

Com base na relação de recorrência de acordo com OEIS A006356.

Começa com uma matriz para os elementos 0,1 e 2 da sequência que são 1 (conforme calculado por mim, para fazê-lo funcionar), 1 e 3, respectivamente.

Adiciona iterativamente nmais elementos à sequência e retorna o elemento n. Ele sempre calcula 2 elementos a mais do que realmente precisa, mas ainda é tempo linear, o que é muito mais eficiente que a minha resposta anterior.

no programa de teste

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

p f[gets.to_i]
Level River St
fonte
2

Mathematica, 42 40 bytes

A contagem de bytes assume uma codificação compatível de um byte, como o CP-1252 (o padrão nas instalações do Windows).

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

Isso simplesmente implementa a recorrência dada no OEIS como um operador unário.

Martin Ender
fonte
2

CJam (19 bytes)

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

Conjunto de testes online . Este é um bloco anônimo (função) que pega um item na pilha e deixa um na pilha. Observe que o conjunto de testes inclui a(0) = 1.

A recorrência usada é baseada na observação para a sequência OEIS relacionada A006356 :

É igual à transformação INVERT de (1, 2, 1, 1, 1, ...) equivalente a 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, 27 de abril de 2009

mas com o deslocamento apropriado, o que elimina a necessidade da final, + 1como agora coberta a(0).

Dissecação

{         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
}
Peter Taylor
fonte
2

Brain-Flak, 56 bytes

Usa o algoritmo detalhado no primeiro comentário na página OEIS.

Experimente online!

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

Explicação

A sequência pode ser definida como tal:

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

O programa inicia 1e aplica repetidamente essa recorrência para calcularu(k)

Código anotado (anotação real por vir)

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

Visualização das pilhas

Em uma iteração do loop principal, é o que acontece (observe que os zeros podem ou não estar presentes, mas isso não importa de qualquer maneira):

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
     ^

O estado das pilhas é agora o mesmo que era no início do ciclo, excepto que a pilha corrente agora tem os seguintes valores para u, ve wsobre ele.

0 '
fonte
2

Perl 6, 48

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

Originalmente

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

mas esqueci que precisava da sub fsolução iterativa para vencer.

bb94
fonte
2

Dyalog APL, 30 bytes

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

Usa força bruta. Explicação (minha melhor tentativa, pelo menos):

⍵<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.
Zacharý
fonte
1

Dyalog APL, 29 bytes

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

Funciona usando a definição recursiva da sequência inteira OEIS A006356.

Zacharý
fonte
1

Python com Numpy, 62 bytes

Eu tive que tentar, mas parece puro Python e a recursão é mais curta que numpy e o cálculo explícito baseado em matriz na página OEIS.

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

R, 61 58 55 51 50 bytes

Recebe informações de stdin, usa exponenciação de matriz para determinar o resultado exato.

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

Se você preferir uma solução recursiva, aqui está uma implementação direta da relação de recorrência listada no OEIS, por 55 bytes .

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

Excel, 123 bytes

Implementa a fórmula do 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

Como sempre, insira a A1fórmula em qualquer outra célula.

Desenterre identidades antigas do Trig para ver se isso pode ser útil. Agora minha cabeça dói.

Wernisch
fonte
0

Lithp , 79 bytes

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

Implementa a sequência inteira recursiva listada no OEIS.

Implementação legível e suíte de testes.

% 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
fonte