Anzahl der


16

Bestimmen Sie bei einer positiven Zahl n die Anzahl der Alkane mit n Kohlenstoffatomen, wobei Sie die Stereoisomere ignorieren . oder äquivalent die Anzahl der nicht beschrifteten Bäume mit n Knoten, so dass jeder Knoten einen Grad 4 .

Dies ist die OEIS-Sequenz A000602 .

Siehe auch: Paraffine - Rosetta Code

Beispiel

Für n=7 lautet die Antwort 9 , da Heptan neun Isomere hat :

  • Heptan : H3C-CH2-CH2-CH2-CH2-CH2-CH3

Heptan

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

2-Methylhexan

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

3-Methylhexan

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

2,2-Dimethylpentan

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

2,3-Dimethylpentan

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

2,4-Dimethylpentan

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

3,3-Dimethylpentan

  • H3C-CH2-C(CH2CH3)-CH2-CH3

3-Ethylpentan

  • H3C-C(CH3)2-CH(CH3)-CH3

2,2,3-Trimethylbutan

Man beachte, dass 3-Methylhexan und 2,3-Dimethylpentan chiral sind , aber wir ignorieren hier Stereoisomere.

Testfälle

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
Ich wäre beeindruckt, wenn es jemandem gelingen würde, eine Lösung mit Alchemist zu schreiben !
11.

@ PeterTaylor Nun, es kann jedes Mal eine Ziffer
ausgeben


@ l4m2: Ich habe es zuvor für eine Sequenz- Challenge und einige Zahlen- Challenges verwendet. Sie können auch eine unäre Ausgabe verwenden, was sehr wahrscheinlich einfacher ist. Und ja, es ist höchstwahrscheinlich TC ( verwendet Bignums ), ich habe es jedoch nicht offiziell bewiesen.
11.

@BMO Es sieht so aus, als könnte man CM
l4m2

Antworten:


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=

Übernimmt die Eingabe von stdin und gibt sie an stdout aus. Beachten Sie, dass dies die Lizenz ausnutzt, um keine Eingaben 0zu verarbeiten, um zwei Bytes zu sparen, indem die Definitionen von Cund eingefügt werden D. Online-Demo

Hinweis: Dies ist sehr langsam und speichereffizient. Durch Trimmen von Arrays wird eine viel schnellere Version erhalten (3 Bytes mehr). Online-Demo .

Präparation

EIN000598(x)=1+xZ(S3;EIN000598(x))EIN000678(x)=xZ(S4;EIN000598(x))EIN000599(x)=Z(S2;EIN000598(x)-1)EIN000602(x)=EIN000678(x)-EIN000599(x)+EIN000598(x2)
Z(Sn;f(x)) bezeichnet den Zyklusindex der symmetrischen Gruppe Sn auf die Funktion angewendet f(x).

Ich manipulierte dies in eine etwas golferische Dekomposition und schaute dann in den Zwischensequenzen nach und stellte fest, dass sie auch in OEIS sind:

EIN000642(x)=Z(S2,EIN000598(x))EIN000631(x)=Z(S2,EIN000642(x))EIN000602(x)=EIN000642(x)+xEIN000642(x2)-xEIN000631(x)

In früheren Versionen wurde ein Block Caus dieser Antwort wiederverwendet (zwei Polynome werden gefaltet) . Ich habe eine viel kürzere gefunden, kann diese Antwort jedoch nicht aktualisieren, da sie aus einer verketteten Frage stammt.

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

Alchemist (1547 Bytes)

_->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

Online-Demo .

Hinweis: Dies ist ziemlich langsam. Wenn Sie mit einem Interpreter testen, der es unterstützt, eine Regel mehrere Male gleichzeitig anzuwenden (z. B. meine - obwohl Sie sicherstellen, dass Sie die neueste Version haben, die einen Fehler im Parser behebt), können Sie eine erhebliche Beschleunigung erzielen, indem Sie zwei Regeln hinzufügen:

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

die eine Route durch die bestehenden Regeln inline

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

Partielle Dissektion

Auf hohem Niveau verwendet dies den gleichen Ansatz wie meine CJam-Antwort.

Das Rechenmodell von Alchemist ist im Wesentlichen die Minsky-Registermaschine . Alchemist macht jedoch die Gleichwertigkeit von Code und Daten sehr gut sichtbar, und indem viele Token auf der linken Seite einer Produktionsregel zugelassen werden, ist der Zustand nicht darauf beschränkt, durch ein Atom dargestellt zu werden: Wir können ein Tupel von Atomen verwenden, und dies erlaubt (nicht rekursive) Unterprogramme. Dies ist sehr nützlich für Golf. Das einzige, was wirklich fehlt, sind Makros und Debugging.

Für Arrays verwende ich eine Pairing-Funktion, die sich sehr gut in RMs implementieren lässt. Das leere Array wird durch dargestellt0und das Ergebnis des Voranstellens x zu ordnen EIN ist (2EIN+1)2x. Es gibt eine Unterroutine zum PKoppeln : Die Unterroutine wird aufgerufen und stellt den Wert von ebis voran b. Es gibt zwei Unterroutinen zum Aufheben der Paarung: nAufheben bder Paarung zu eund b; und tunpaarig dzu eund d. Dadurch konnte ich eine Menge Daten zwischen Variablen mischen, was wichtig ist: eine einzige "Verschiebungs" -Operation

a, b = b, 0

erweitert sich auf mindestens 17 Bytes:

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

wo Sist der aktuelle Zustand und Tist der nächste Zustand. Eine nicht-destruktiv „Kopie“ ist noch teurer, weil sie als „move“ von getan werden muss , aum bund einen Hilfs tmp, gefolgt von einer „Bewegung“ von tmpzurück zu a.

Verschleierung

Ich habe verschiedene Variablen aufeinander abgestimmt und im Verlauf des Golfspiels etwa 60 Zustände beseitigt, und viele von ihnen hatten sowieso keine besonders aussagekräftigen Namen, aber um das Golfspiel zu vervollständigen, habe ich einen Minimierer geschrieben, sodass die Namen jetzt vollständig nicht mehr zu entziffern sind. Viel Glück beim Reverse Engineering! Hier ist der Minimierer (in CJam), der einige Annahmen über den Code macht, aber angepasst werden kann, um andere Alchemist-Programme zu minimieren:

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

Warten Sie ... funktioniert dieser Interpreter? AFAICT ... Sie wählen eine zufällige Regel aus und finden dann heraus, wie oft diese angewendet werden kann. Funktioniert das überhaupt richtig?
Nur ASCII

Hmm. Wie würden Sie die Debug
-

@ ASCII-only, das würde funktionieren, ist aber nicht das, was es tut. Zuerst wird eine Regel ausgewählt, die anwendbar ist, und dann wird ermittelt, wie oft sie angewendet werden kann. Debugging ist schwierig. Eine meiner Ideen für ein Dissertationsprojekt war damals ein GUI-RM-Editor mit Rückwärts-Debugger.
Peter Taylor

aber ... Regelausführungsreihenfolge wirkt sich nicht auf die Programmreihenfolge aus
ASCII

@ Nur ASCII, ja. Deshalb gibt es so viele Variablen. Nur etwa 16 von ihnen sind Daten, der Rest ist staatlich. Ich habe den Nicht-Determinismus zum Golfen genutzt, indem ich unabhängige "Move" -Operationen effektiv parallelisiert habe.
Peter Taylor

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.