Numero di alcani


16

Dato un numero positivo , trova il numero di alcani con atomi di carbonio, ignorando gli stereoisomeri ; o equivalentemente, il numero di alberi senza etichetta con nodi, in modo tale che ogni nodo abbia grado .nnn4

Questa è la sequenza OEIS A000602 .

Vedi anche: Paraffine - Codice Rosetta

Esempio

Per , la risposta è , perché l' eptano ha nove isomeri :n=79

  • Eptano :H3C-CH2-CH2-CH2-CH2-CH2-CH3

eptano

  • 2-Methylhexane :H3C-CH(CH3)-CH2-CH2-CH2-CH3

2-metilesano

  • 3-Methylhexane :H3C-CH2-CH(CH3)-CH2-CH2-CH3

3-metilesano

  • 2,2- dimetilpentano : H3C-C(CH3)2-CH2-CH2-CH3

2,2-dimetilpentano

  • 2,3- dimetilpentano : H3C-CH(CH3)-CH(CH3)-CH2-CH3

2,3-dimetilpentano

  • 2,4- dimetilpentano : H3C-CH(CH3)-CH2-CH(CH3)-CH3

2,4-dimetilpentano

  • 3,3- dimetilpentano : H3C-CH2-C(CH3)2-CH2-CH3

3,3-dimetilpentano

  • 3-etilpentano : H3C-CH2-C(CH2CH3)-CH2-CH3

3-Ethylpentane

  • 2,2,3-Trimetilbutano : H3C-C(CH3)2-CH(CH3)-CH3

2,2,3-Trimethylbutane

Si noti che il 3-metilesano e il 2,3-dimetilpentano sono chirali , ma qui ignoriamo gli stereoisomeri.

Casi test

Non è necessario gestire il caso .n=0

intput	output
=============
0	1
1	1
2	1
3	1
4	2
5	3
6	5
7	9
8	18
9	35
10	75
11	159
12	355
13	802
14	1858
15	4347
16	10359
17	24894
18	60523
19	148284
20	366319

3
Sarei colpito se qualcuno riuscisse a scrivere una soluzione con Alchemist !
ბიმო

@PeterTaylor Bene Può emettere ogni volta una cifra
l4m2


@ l4m2: l'ho usato prima per una sfida di sequenza e alcune sfide numeriche , puoi anche usare un output unario che è molto probabilmente più facile. E sì, è molto probabilmente TC ( usa i bignum ), ma non l'ho provato formalmente.
ბიმო

@BMO Sembra solo in grado di simulare CM
l4m2

Risposte:


11

CJam ( 100 98 91 89 83 byte)

1a{_[XX]*\_{_0a*}:E~\{E\_{ff*W%{0@+.+}*}:C~.+2f/}:D~.+C.+3f/1\+}q~:I*DE1$D.-X\+.+I=

Prende input da stdin, output in stdout. Si noti che ciò sfrutta la licenza per non gestire l'input0 per salvare due byte incorporando le definizioni di Ce D. Demo online

NB questo è molto lento e inefficiente dalla memoria. Tagliando le matrici si ottiene una versione molto più veloce (3 byte in più). Demo online .

Dissezione

UN000.598(X)=1+XZ(S3;UN000.598(X))UN000.678(X)=XZ(S4;UN000.598(X))UN000.599(X)=Z(S2;UN000.598(X)-1)UN000.602(X)=UN000.678(X)-UN000.599(X)+UN000.598(X2)
Z(Sn;f(X))Snf(X)

Ho manipolato questo in una decomposizione leggermente più golfistica, quindi ho cercato le sequenze intermedie e ho scoperto che sono anche in OEIS:

UN000.642(X)=Z(S2,UN000.598(X))UN000631(X)=Z(S2,UN000.642(X))UN000.602(X)=UN000.642(X)+XUN000.642(X2)-XUN000631(X)

Le versioni precedenti hanno riutilizzato il blocco C(contorto di due polinomi) da questa risposta . Ne ho trovato uno molto più breve, ma non riesco ad aggiornare quella risposta perché proviene da una domanda concatenata.

1a            e# Starting from [1]...
{             e# Loop I times (see below) to build A000598 by f -> 1 + Z(S_3; f)
  _[XX]*      e#   Copy and double-inflate to f(x^3)
  \_          e#   Flip and copy: stack is f(x^3) f(x) f(x)
  {_0a*}:E~   e#   Assign copy-and-inflate to E and execute
              e#   Stack: f(x^3) f(x) f(x) f(x^2)
  \           e#   Flip
  {           e#   Define and execute block D, which applies f -> Z(S_2;f)
              e#     Stack: ... f
    E\_       e#     Stack: ... f(x^2) f(x) f(x)
    {         e#     Define and execute block C, which convolves two sequences
      ff*     e#       Multiply copies of the second sequence by each term of the first
      W%      e#       Reverse
      {       e#       Fold
        0@+.+ e#         Prepend a 0 to the first and pointwise sum
      }*
    }:C~      e#     Stack: ... f(x^2) f(x)^2
    .+2f/     e#     Pointwise average
  }:D~        e#   Stack: f(x^3) f(x) f(x^2) Z(S_2;f(x))
  .+C         e#   Stack: f(x^3) f(x)*(f(x^2) + Z(S_2;f(x)))
  .+3f/       e#   Add and divide by 3 to finish computing Z(S_3; f)
  1\+         e#   Prepend a 1
}
q~:I          e# Read input to I
*             e# Loop that many times
              e# Stack: I+1 terms of A000598 followed by junk
D             e# Stack: I+1 terms of A000642 followed by junk
E1$D          e# Stack: A000642 A000642(x^2) A000631
.-X\+.+       e# Stack: A000602
I=            e# Extract term I

5

Node.js 11.6.0 ,  229 223 221  218 byte

Derivato dall'implementazione Java suggerita su Rosetta Code .

f=(N,L=1,u=[...r=[c=[],1,...Buffer(N)]],k=u[(g=(n,B,S,i,b=B,m,d=0)=>{for(;++b<5;)for(x=c[B]=(d+r[m=n])*(d++?c[B]/d:i),u[S+=n]+=L*2<S&&x,r[S]+=b<4&&x;--m;)g(m,b,S,c[B])})(L,0,1,1),L]-=~(x=r[L++/2])*x>>1)=>L>N?k:f(N,L,u)

Provalo online!


5

Alchimista (1547 byte)

_->In_NN+2b+al+g
al+g+0NN->ak
al+g+NN->ah
ah+b->ah+m+d+z+a
ah+0b->C+Z+Q
Z+j+z->Z+j+d
Z+j+0z->M+s
M+g+b->M+g+r
M+g+h->M+g+d
M+g+0b+0h+q->J+U
J+o+h->J+o+m
J+o+a->J+o+d
J+o+0h+0a->2C+an+Q
an+j+h->an+j+d
an+j+0h->aC+s
aC+g->e+am+P
am+l+b->am+l+d
am+l+0b->al+s
ak+b->ak+m+d
ak+0b->C+aj+Q
aj+j+h->aj+j+b
aj+j+0h->I+n
I+f+e->I+f+a
I+f+b->I+f+m+d+z
I+f+0e+0b->C+ai+Q
ai+j+h->ai+j+b
ai+j+0h->aB+n
aB+f->H
H+z->H+d
H+a+e->H
H+0z+0e->G+i
G+i+0b->ag
G+i+b->az+b+n
az+f+0b->Out_a
az+f+b->G+b+n
G+f->G+t
ag+e->ag
ag+0e->af+t
af+i+e->af+i+a
af+i+0e->Out_a
Q->F+s
F+g+b->F+g+y
F+g+A->F+g
F+g+0b+0A->av+o
av+o+0m->w
av+o+m->m+ae+A
ae+m->ae+b
ae+0m->u+n
u+f+b->u+f+m
u+f+e->u+f+E
u+f+A->u+f+k+c
u+f+0b+0e+0A->ad
ad+c->ad+A
ad+0c->ac
ac+y->ac+d+c
ac+0y->ab
ab+c->ab+y
ab+0c->V+l
V+l+0k->x
V+l+k->aa+t
aa+i+0e->W
aa+i+e->Y
Y+E->Y+D+c
Y+0E->X
X+c->X+E
X+0c->aa+i
W+D->W+e
W+0D->V+P
x+E->x
x+d->x
x+b->x+k
x+0E+0d+0b->aw
aw+h->aw+d
aw+0h->aE+s
aE+g->p
p+b->p+2r
p+k->p+d
p+B->p
p+q->p
p+0b+0k+0B+0q->r+q+av+U
w+h->w+d
w+y->w+r
w+C->w+B+q
w+0h+0y+0C->aD+U
aD+o->j
U->au+s
au+g+b->au+g+d
au+g+0b->v
v+d->d+aA+t
aA+i+k->R
aA+i+0k->at
at+B->at+k+c
at+0B->L
L+c->L+B
L+r->L+b
L+0c+0r->as+n
as+f+b->as+f+r
as+f+0b->R
R+0e->K
R+e+q->ar+D+c
ar+e+q->ar+c
ar+0q->aq
aq+c->aq+q
aq+0c->R
K+D->K+e
K+h->K+b
K+0D+0h->ap+P
ap+l+b->ap+l+h
ap+l+0b->v
v+0d+k->v
v+0d+r->v
v+0d+0k+0r->o
s+0d->g
s+d->d+ao+t
ao+i->ao+P
ao+l->s
P->O+c
O+b->2c+O
O+0b->N
N+c->b+N
N+0c+e->O
N+0c+0e->l
n+b->n+c
n+0b->T
T+c->ay
T+0c->e+n
ay+c->b+T
ay+0c->f
t+d->t+c
t+0d->S
S+c->ax
S+0c->e+t
ax+c->d+S
ax+0c->i

Demo online .

Nota: questo è abbastanza lento. Se si esegue il test con un interprete che supporta l'applicazione di una regola più volte contemporaneamente (ad es. La mia - anche se assicurarsi di disporre dell'ultima versione che corregge un bug nel parser), è possibile ottenere una notevole accelerazione aggiungendo due regole:

T+2c->b+T
S+2c->d+S

che incorporano un percorso attraverso le regole esistenti

T+c->ay
ay+c->b+T
S+c->ax
ax+c->d+S

Dissezione parziale

Ad alto livello, questo utilizza lo stesso approccio della mia risposta CJam.

Il modello di calcolo di Alchemist è essenzialmente la macchina del registro Minsky . Tuttavia, Alchemist espone molto bene l'equivalenza di codice e dati e, consentendo in modo efficace molti token sul lato sinistro di una regola di produzione, lo stato non è costretto a essere rappresentato da un atomo: possiamo usare una tupla di atomi, e questo consente subroutine (non ricorsive). Questo è molto utile per il golf. Le uniche cose che davvero mancano sono le macro e il debuggability.

0XUN(2UN+1)2XPebnbebtded

a, b = b, 0

si espande ad almeno 17 byte:

S+a->S+b
S+0a->T

dove Sè lo stato corrente ed Tè lo stato successivo. Una "copia" non distruttivo è ancora più costoso, in quanto deve essere fatto come una "mossa" da aa be un ausiliario tmp, seguito da un "spostare" da tmpritorna a.

Offuscazione

Ho modificato le varie variabili tra loro ed eliminato circa 60 stati nel processo di golf del programma, e molti di loro non avevano comunque nomi particolarmente significativi, ma per golf completamente ho scritto un minimizer, quindi i nomi ora sono completamente indecifrabili. Buona fortuna reverse engineering esso! Ecco il minimizer (in CJam), che fa alcune ipotesi sul codice ma potrebbe essere adattato per minimizzare altri programmi Alchemist:

e# Obfuscate / minimise Alchemist program

e# Tokenise
qN%[SNS]e_*S%

e# Get token frequencies for substitution purposes, special-casing the I/O ones
_["+" "0" "2" "->" "_" N "In_n" "n" "Out_tmp2" "tmp2"]-
$e`$W%1f=

e# Empirically we want a two-char input for n and a one-char one for tmp2
["In_n" "Out_tmp2" "n" "tmp2"]\+
["In_NN" "Out_a" "NN"] "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"1/:A+ A2m*:e_"NN"a-+
1$,<

er
_s,p

Aspetta ... funziona quell'interprete? AFAICT ... scegli una regola casuale, poi scopri quante volte può essere applicata. Funziona anche correttamente?
ASCII

Hmm. Come migliorare la debuggabilità
solo ASCII il

@ Solo ASCII, funzionerebbe ma in realtà non è quello che fa. Seleziona innanzitutto una regola applicabile e quindi determina quante volte può essere applicata. La debuggabilità è complicata. Una delle mie idee per un progetto di tesi nel corso della giornata era un editor RM GUI con debugger all'indietro.
Peter Taylor,

ma ... l'ordine di esecuzione della regola influisce sull'ordine del programma, no
ASCII solo l'

@ Solo ASCII, sì. Ecco perché ci sono così tante variabili. Solo circa 16 di questi sono dati: il resto è stato. Ho usato il non determinismo per giocare a golf parallelizzando in modo efficace operazioni indipendenti di "mossa".
Peter Taylor

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.