Numero di alci a catena dritta * nes di lunghezza determinata


28

Un alchene * a catena lineare è definito come una sequenza di atomi di carbonio collegati da legami singoli (alcano), doppi (alcheni) o tripli (alchene), (vengono usati idrogeni impliciti). Gli atomi di carbonio possono formare solo 4 legami, quindi nessun atomo di carbonio può essere costretto ad avere più di quattro legami. Un alch * ne a catena lineare può essere rappresentato come un elenco dei suoi legami carbonio-carbonio.

Questi sono alcuni esempi di alch * nes validi a catena dritta:

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

Mentre questi non lo sono, poiché almeno un atomo di carbonio avrebbe più di 4 legami:

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

Il tuo compito è quello di creare un programma / funzione che, dato un numero intero positivo n, produca / restituisca il numero di alcheni * a catena lineare validi di esattamente natomi di carbonio di lunghezza. Questo è OEIS A077998 .

Specifiche / Chiarimenti

  • È necessario gestire 1correttamente restituendo 1.
  • Alk * nes piace [1,2]e [2,1]sono considerati distinti.
  • L'output è la lunghezza di un elenco di tutti i possibili alk * nes di una data lunghezza.
  • Non è necessario gestire 0 correttamente.

Casi test:

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

Questo è il golf del codice, quindi vince il conteggio di byte più basso !


solo per chiarire, una catena è valida se vengono sommate tutte le coppie consecutive <=4, giusto?
Maltysen,

Fisso. @Maltysen: si.
Zacharý,

4
Perché esiste una sequenza OEIS per tutto? : P
HyperNeutrino del

2
@ZacharyT, esiste esattamente un idrocarburo con zero atomi di carbonio, ed è quello che ha anche zero atomi di idrogeno. È esattamente lo stesso argomento del triangolo di Pascal con un 1 in cima anziché uno 0 o letteralmente centinaia di altre sequenze combinatorie.
Peter Taylor,

1
@Emigna, perché è stata collegata la sequenza sbagliata. Lo correggerò.
Peter Taylor,

Risposte:


7

Oasi , 9 7 byte

xcd-+3V

Provalo online!

Spiegazione

Questo utilizza la relazione di ricorrenza in 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
Buon uso dei valori iniziali! Questa volta vinci;)
Emigna il

Sì, probabilmente non c'è modo di battere questo.
Zacharý,

4
@ZacharyT Solo se qualcuno riesce a trovare un modo per far entrare il programma xkcd.
hBy2Py

4
@ hBy2Py Bene, xkcd-+311funziona , perché kattualmente è un no-op ...
Luis Mendo

10

MATL , 10 byte

7K5vBiY^1)

Provalo online!

Spiegazione

Questo utilizza la caratterizzazione trovata in OEIS

a (n) è la voce in alto a sinistra dell'n-esima potenza della matrice 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

Oasi , 9 8 byte

Salvato un byte grazie ad Adnan

xc+d-63T

Provalo online!

Spiegazione

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
Bello! Inoltre, xè l'abbreviazione di 2*:).
Adnan,

1
Beat ya :-P (non avevo visto che c'era già una risposta OASIS)
Luis Mendo,

@Adnan C'è un modo per dire a Oasis che vuoi spostare l'indice della sequenza di output di 1? Voglio dire, sottrarre 1 all'argomento di input (invece di usare un'iniziale 0qui)
Luis Mendo,

1
@LuisMendo Ah, non ancora implementato. Ma è una buona idea per la prossima versione :).
Adnan,

Per riferimento futuro, questo è ora implementato
Luis Mendo il

4

Gelatina, 10 byte

745DBæ*µḢḢ

Provalo online!

Utilizza l'algoritmo di Luis Mendo .

Spiegazione

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 byte

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

Provalo online!

Usa la forza bruta.

Spiegazione

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 byte

q3:Z^TTZ+!5<As

Provalo online!

Spiegazione

Questo genera il potere cartesiano di [1 2 3]"elevato" al numero di atomi meno 1, e quindi usa la convoluzione per verificare che non vi siano più due numeri contigui in ciascuna tupla cartesiana 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 byte

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

Come ha sottolineato Luis Mendo , questo è A006356 nell'OEIS. Ecco i miei tentativi originali:

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

Per un input n, Tuples[{1,2,3},n-1]è l'elenco di tutte le (n-1)coppie di elementi nel {1,2,3}rappresentare tutte le possibili sequenze di legami singoli, doppi o tripli per gli natomi di carbonio. +##<5&è una funzione pura che restituisce se la somma dei suoi argomenti è inferiore a 5, quindi Split[#,+##<5&]&suddivide un elenco in elenchi secondari costituiti da elementi consecutivi le cui somme a coppie sono inferiori a 5. Descrivere un alk * ne valido equivale a questa lista con lunghezza 0(nel caso in cui n=1) o 1, quindi ho solo Countil numero di (n-1)-tuple in cui la lunghezza di quella lista corrisponde 0|1.

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

If[+##>4,4,#2]&restituisce 4se la somma dei suoi argomenti è maggiore di 4e restituisce il secondo argomento in caso contrario. Fold[If[+##>4,4,#2]&]fa una sinistra Folddel suo input con questa funzione. Quindi, ecco Countil numero di (n-1)-tuple a cui non si applica l'applicazione di questo operatore 4. Il caso in cui n=1è coperto poiché Foldrimane non valutato quando il suo secondo argomento è l'elenco vuoto {}.


1
Funzionerebbe? (Tipo di strappato direttamente da OEIS con regolazioni) LinearRecurrence[{2,1,-1},{1,3,6},#][[#]]&?
Zacharý,

Parte del motivo per cui adoro questo sito è l'apprendimento di tutte le funzionalità che Mathematica ha da offrire :)
ngenisis,

Con this site, vuoi dire OEIS o PPCG?
Zacharý,

PPCG. Ho raccolto un sacco di Mathematica dai suggerimenti delle persone.
ngenisi,

3

Python, 51 byte

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

Questa è un'implementazione diretta della relazione di ricorrenza. Grazie a Tim Pederick per 3 byte. L'output è un float in Python 3 e un numero intero in Python 2.

Provalo online!


(n*n+n)/2è più corto di [1,3,6][n-1]. E se stai usando Python 3 e non ti piace finire con un output in virgola mobile, (n*n+n)//2è ancora più breve.
Tim Pederick,

2

Pyth - 16 byte

Usa la forza bruta.

lf.AgL4+VTtT^S3t

Test Suite .


1
Sarebbe bello fornire una descrizione per quelli di noi che non "grok" Pyth.
Zacharý,

2

Rubino, 62 byte

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

Approccio di forza bruta di base 10 orribilmente inefficiente. Potrebbe essere migliorato alla base 5 per byte aggiuntivi.

I numeri sono generati dove ogni cifra rappresenta un legame (n-1 cifre.) 0Rappresenta un ordine di legame di 1, 2rappresenta un ordine di legame di 3. Le cifre oltre 2 non sono valide.

Moltipliciamo questo per 11 per sommare la coppia di cifre adiacente. Anche in questo caso le cifre superiori a 3 non sono valide.

Combiniamo i due numeri in una stringa ed eseguiamo una regex per cercare cifre non valide. Se non ne viene trovato nessuno, incrementiamo il contatore.

nel programma di test

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

p f[gets.to_i]

2

Rubino, 51 byte

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

Basato sulla relazione di ricorrenza secondo OEIS A006356.

Inizia con una matrice per gli elementi 0,1 e 2 della sequenza che sono 1 (come calcolato da me, per farlo funzionare), 1 e 3 rispettivamente.

Iterativamente aggiunge npiù elementi alla sequenza, quindi restituisce l'elementon . Calcola sempre 2 elementi in più del necessario, ma è comunque un tempo lineare, che è molto più efficiente della mia risposta precedente.

nel programma di test

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 byte

Il conteggio dei byte presuppone una codifica a byte singolo compatibile come CP-1252 (impostazione predefinita nelle installazioni di Windows).

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

Ciò implementa semplicemente la ricorrenza data su OEIS come operatore unario.


2

CJam (19 byte)

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

Suite di test online . Questo è un blocco (funzione) anonimo che prende un oggetto in pila e ne lascia uno in pila. Si noti che la suite di test include a(0) = 1.

La ricorrenza utilizzata si basa sull'osservazione per la sequenza OEIS correlata A006356 :

È uguale alla trasformata INVERT di (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 aprile 2009

ma con l'offset appropriato, che elimina la necessità del finale + 1come ora coperto da a(0).

Dissezione

{         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 byte

Utilizza l'algoritmo dettagliato nel primo commento nella pagina OEIS.

Provalo online!

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

Spiegazione

La sequenza può essere definita come tale:

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

Il programma inizia alle 1e applica ripetutamente questa ricorrenza per il calcolou(k)

Codice annotato (annotazione effettiva a venire)

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

Visualizzazione delle pile

In un'iterazione del ciclo principale questo è ciò che accade (nota che gli zeri possono essere o meno presenti ma non importa in entrambi i casi):

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
     ^

Lo stato delle pile è ora uguale come era all'inizio del ciclo, tranne che la pila attuale ha ora i valori successivi di u, ve wsu di esso.


2

Perl 6, 48

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

Originariamente

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

ma ho dimenticato di aver bisogno del sub fmodo in cui la soluzione iterativa vince.


2

Dyalog APL, 30 byte

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

Usa la forza bruta. Spiegazione (almeno il mio miglior tentativo):

⍵<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 byte

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

Funziona utilizzando la definizione ricorsiva della sequenza intera OEIS A006356.


1

Python con Numpy, 62 byte

Ho dovuto provarlo, ma sembra puro Python e la ricorsione è più breve di numpy e il calcolo esplicito, basato su matrice sulla pagina 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 byte

Prende input dallo stdin, usa l'esponiazione della matrice per determinare il risultato esatto.

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

Se preferisci una soluzione ricorsiva, ecco un'implementazione semplice della relazione di ricorrenza elencata in OEIS, per 55 byte .

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

1

Excel, 123 byte

Implementa la formula di 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

Come sempre, inserisci A1 formula in qualsiasi altra cella.

Scavato le vecchie identità di Trig per vedere se potesse essere utile. Adesso mi fa male la testa.


0

Lithp , 79 byte

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

Implementa la sequenza di numeri interi ricorsivi elencati in OEIS.

Implementazione leggibile e suite di test.

% 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))))
)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.