Liczba alkaliów o prostych łańcuchach * o podanej długości

28

Prostołańcuchowy alk * ne jest zdefiniowany jako sekwencja atomów węgla połączonych wiązaniami pojedynczymi (alkan), podwójnymi (alken) lub potrójnymi (alkin), (stosowane są ukryte atomy wodoru). Atomy węgla mogą tworzyć tylko 4 wiązania, więc żaden atom węgla nie może być zmuszony do posiadania więcej niż czterech wiązań. Prostołańcuchowy alk * ne może być reprezentowany jako lista jego wiązań węgiel-węgiel.

Oto kilka przykładów prawidłowych alk * nów o łańcuchach prostych:

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

Chociaż tak nie jest, ponieważ co najmniej jeden atom węgla miałby więcej niż 4 wiązania:

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

Twoim zadaniem jest stworzenie programu / funkcji, która przy dodatniej liczbie całkowitej nwyprowadza / zwraca liczbę prawidłowych alkinów o łańcuchach prostych o długości dokładnie natomów węgla. To jest OEIS A077998 .

Dane techniczne / Wyjaśnienia

  • Musisz 1poprawnie postępować , zwracając 1.
  • Alk * nes lubią [1,2]i [2,1]są uważane za odrębne.
  • Dane wyjściowe to długość listy wszystkich możliwych alk * nów o danej długości.
  • Zdajesz nie muszą obsługiwać 0 poprawnie.

Przypadki testowe:

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

To jest golf golfowy, więc wygrywa najmniej bajtów !

Zacharý
źródło
dla wyjaśnienia, łańcuch jest ważny, jeśli wszystkie kolejne pary są sumowane <=4, prawda?
Maltysen
Naprawiony. @Maltysen: tak.
Zacharý
4
Dlaczego istnieje sekwencja OEIS dla wszystkiego? : P
HyperNeutrino,
2
@ZacharyT, jest dokładnie jeden węglowodór z zerowymi atomami węgla i ten, który ma również zero atomów wodoru. Jest to dokładnie ten sam argument, co w przypadku trójkąta Pascala, który ma 1 na górze, a nie 0, lub dosłownie setki innych sekwencji kombinatorycznych.
Peter Taylor,
1
@Emigna, ponieważ połączono niewłaściwą sekwencję. Poprawię to.
Peter Taylor,

Odpowiedzi:

7

Oaza , 9 7 bajtów

xcd-+3V

Wypróbuj online!

Wyjaśnienie

Wykorzystuje to relację powtarzalności w 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
źródło
1
Dobre wykorzystanie wartości początkowych! Tym razem wygrywasz;)
Emigna
Tak, prawdopodobnie nie ma sposobu na pokonanie tego.
Zacharý
4
@ZacharyT Tylko wtedy, gdy ktoś może wymyślić, jak sprawić, by program miał xkcdw tym udział.
hBy2Py
4
@ hBy2Py Cóż, xkcd-+311działa , ponieważ kobecnie nie można tego zrobić ...
Luis Mendo,
10

MATL , 10 bajtów

7K5vBiY^1)

Wypróbuj online!

Wyjaśnienie

Wykorzystuje to charakterystykę znalezioną w OEIS

a (n) jest lewym górnym wpisem n-tej potęgi macierzy 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
źródło
6

Oaza , 9 8 bajtów

Oszczędność bajtu dzięki Adnanowi

xc+d-63T

Wypróbuj online!

Wyjaśnienie

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
źródło
1
Miły! Również xjest skrótem od 2*:).
Adnan
1
Beat ya :-P (nie widziałem, że już tam była odpowiedź OASIS)
Luis Mendo
@Adnan Czy istnieje sposób, aby powiedzieć Oasis, że chcesz przesunąć indeks sekwencji wyjściowej o 1? Mam na myśli, odejmij 1 od argumentu wejściowego (zamiast 0tu inicjału )
Luis Mendo,
1
@LuisMendo Ah, które nie zostało jeszcze zaimplementowane. Ale to dobry pomysł na następne wydanie :).
Adnan
Do wglądu w przyszłości jest to teraz zaimplementowane
Luis Mendo
4

Galaretka, 10 bajtów

745DBæ*µḢḢ

Wypróbuj online!

Wykorzystuje algorytm Luisa Mendo .

Wyjaśnienie

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

Galaretka, 15 bajtów

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

Wypróbuj online!

Używa brutalnej siły.

Wyjaśnienie

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
źródło
4

MATL , 14 bajtów

q3:Z^TTZ+!5<As

Wypróbuj online!

Wyjaśnienie

Generuje to kartezjańską moc [1 2 3]„podniesionej” do liczby atomów minus 1, a następnie używa splotu, aby sprawdzić, czy nie ma więcej niż dwóch sąsiadujących liczb w każdej krotce kartezjańskiej więcej niż 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
źródło
3

Mathematica, 48 bajtów

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

Jak zauważył Luis Mendo , jest to A006356 w OEIS. Oto moje oryginalne próby:

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

Na wejściu n, Tuples[{1,2,3},n-1]to wykaz wszystkich (n-1)-tuples elementów w {1,2,3}reprezentujące wszystkie możliwe sekwencje pojedyncze, podwójne lub potrójne wiązania do natomów węgla. +##<5&jest funkcją czystą, która zwraca, czy suma jej argumentów jest mniejsza niż 5, więc Split[#,+##<5&]&dzieli listę na podlisty składające się z kolejnych elementów, których sumy par są mniejsze niż 5. Opisanie prawidłowej alk * ne jest równoważne długości tej listy 0(w przypadku, gdy n=1) 1, a więc po prostu Countliczbie (n-1)-tuli, w których długość tej listy jest zgodna 0|1.

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

If[+##>4,4,#2]&zwraca, 4jeśli suma jego argumentów jest większa niż, 4i zwraca drugi argument w przeciwnym razie. Fold[If[+##>4,4,#2]&]wykonuje lewe Foldwejście od tej funkcji. Więc tutaj I Count-liczba, (n-1)której nie stosuje ten operator 4. Przypadek, w którym n=1jest to uwzględnione, Foldpozostaje nieoceniony, gdy jego drugim argumentem jest pusta lista {}.

ngenisis
źródło
1
Czy to zadziała? (Niby zgrane z OEIS z korektami) LinearRecurrence[{2,1,-1},{1,3,6},#][[#]]&?
Zacharý
Częścią tego, dlaczego uwielbiam tę stronę, jest poznanie wszystkich funkcji, które Mathematica ma do zaoferowania :)
ngenisis
Przez this site, to znaczy OEIS lub PPCG?
Zacharý
PPCG. Zebrałem wiele Matematyki z sugestii ludzi.
ngenisis,
3

Python, 51 bajtów

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

Jest to prosta implementacja relacji powtarzalności. Dzięki Tim Pederick za 3 bajty. Dane wyjściowe to liczba zmiennoprzecinkowa w Pythonie 3 i liczba całkowita w Pythonie 2.

Wypróbuj online!

Mego
źródło
(n*n+n)/2jest krótszy niż [1,3,6][n-1]. A jeśli używasz Pythona 3 i nie lubisz kończyć się liczbami zmiennoprzecinkowymi, (n*n+n)//2jest jeszcze krótszy.
Tim Pederick,
2

Pyth - 16 bajtów

Używa brutalnej siły.

lf.AgL4+VTtT^S3t

Pakiet testowy .

Maltysen
źródło
1
Byłoby miło przedstawić opis tych, którzy nie „grokują” Pytha.
Zacharý
2

Rubin, 62 bajty

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

Okropnie nieefektywne podejście 10 brutalnej siły. Można ulepszyć do podstawy 5 dla dodatkowych bajtów.

Liczby są generowane, gdy każda cyfra reprezentuje wiązanie (n-1 cyfr.) 0Reprezentuje rząd wiązania 1, 2reprezentuje rząd wiązania 3. Cyfry powyżej 2 są nieprawidłowe.

Mnożymy to przez 11, aby zsumować sąsiednią parę cyfr. Znów cyfry powyżej 3 są nieprawidłowe.

Łączymy dwie liczby w ciągu i wykonujemy wyrażenie regularne, aby wyszukać nieprawidłowe cyfry. Jeśli nie zostaną znalezione, zwiększamy licznik.

w programie testowym

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
źródło
2

Rubinowy, 51 bajtów

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

Na podstawie relacji powtarzalności według OEIS A006356.

Zaczyna się od tablicy dla elementów 0,1 i 2 sekwencji, które są 1 (obliczone przeze mnie, aby działało), odpowiednio 1 i 3.

Iteracyjnie dodaje nwięcej elementów do sekwencji, a następnie zwraca element n. Zawsze oblicza 2 elementy więcej, niż faktycznie potrzebuje, ale wciąż jest to czas liniowy, który jest znacznie wydajniejszy niż moja poprzednia odpowiedź.

w programie testowym

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
źródło
2

Mathematica, 42 40 bajtów

Liczba bajtów zakłada kompatybilne kodowanie jednobajtowe, takie jak CP-1252 (domyślne w instalacjach Windows).

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

To po prostu implementuje powtarzalność podaną w OEIS jako jednoargumentowy operator.

Martin Ender
źródło
2

CJam (19 bajtów)

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

Zestaw testów online . Jest to anonimowy blok (funkcja), który bierze jeden przedmiot ze stosu i pozostawia jeden na stosie. Pamiętaj, że pakiet testowy obejmuje a(0) = 1.

Zastosowany wzorzec opiera się na obserwacji powiązanej sekwencji OEIS A006356 :

Równa się transformacie INVERT (1, 2, 1, 1, 1, ...) równoważnej 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 kwietnia 2009 r

ale z odpowiednim przesunięciem, co eliminuje potrzebę finału, + 1jak teraz objęty a(0).

Sekcja

{         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
źródło
2

Brain-Flak, 56 bajtów

Wykorzystuje algorytm wyszczególniony w pierwszym komentarzu na stronie OEIS.

Wypróbuj online!

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

Wyjaśnienie

Sekwencję można zdefiniować jako taką:

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

Program rozpoczyna się od 1i wielokrotnie stosuje tę rekurencję do obliczeńu(k)

Kod z adnotacjami (faktyczna adnotacja, która ma nadejść)

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

Wizualizacja stosów

W jednej iteracji głównej pętli dzieje się tak (zwróć uwagę, że zera mogą być obecne lub nie, ale nie ma to żadnego znaczenia):

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
     ^

Stan stosów jest teraz tak samo jak to było na początku pętli, z wyjątkiem, że obecny stos ma teraz kolejne wartości u, vi wna nim.

0 '
źródło
2

Perl 6, 48

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

Pierwotnie

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

ale zapomniałem, że potrzebowałem sub ftakiego rozwiązania iteracyjnego.

bb94
źródło
2

Dyalog APL, 30 bajtów

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

Używa brutalnej siły. Objaśnienie (przynajmniej moja najlepsza próba):

⍵<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ý
źródło
1

Dyalog APL, 29 bajtów

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

Działa przy użyciu rekurencyjnej definicji sekwencji liczb całkowitych OEIS A006356.

Zacharý
źródło
1

Python z Numpy, 62 bajty

Musiałem to wypróbować, ale wydaje się, że czysty Python, a rekurencja jest krótsza niż numpy, a wyraźne, oparte na macierzy obliczenia na stronie OEIS.

from numpy import*
lambda n:(mat('1 1 1;1 0 0;1 0 1')**n)[0,0]
Tim Pederick
źródło
1

R, 61 58 55 51 50 bajtów

Pobiera dane wejściowe ze standardowego wejścia, używa potęgowania macierzowego w celu ustalenia dokładnego wyniku.

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

Jeśli wolisz rozwiązanie rekurencyjne, oto prosta implementacja relacji rekurencji wymienionej w OEIS dla 55 bajtów .

f=function(n)`if`(n<4,(n*n+n)/2,2*f(n-1)+f(n-2)-f(n-3))
rturnbull
źródło
1

Excel, 123 bajty

Implementuje formułę z 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

Jak zawsze, wprowadź A1formułę w dowolnej innej komórce.

Wykopali stare tożsamości Trig, aby sprawdzić, czy mogą być pomocne. Teraz boli mnie głowa.

Wernisch
źródło
0

Lithp , 79 bajtów

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

Implementuje rekurencyjną sekwencję liczb całkowitych wymienionych w OEIS.

Czytelny pakiet implementacyjny i testowy.

% 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
źródło