Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Paraffins

View file

@ -0,0 +1,94 @@
This organic chemistry task is essentially to implement a tree enumeration algorithm.
;Task:
Enumerate, without repetitions and in order of increasing size, all possible paraffin molecules (also known as [[wp:alkane|alkane]]s).
Paraffins are built up using only carbon atoms, which has four bonds, and hydrogen, which has one bond.   All bonds for each atom must be used, so it is easiest to think of an alkane as linked carbon atoms forming the "backbone" structure, with adding hydrogen atoms linking the remaining unused bonds.
In a paraffin, one is allowed neither double bonds (two bonds between the same pair of atoms), nor cycles of linked carbons. &nbsp; So all paraffins with &nbsp; '''n''' &nbsp; carbon atoms share the empirical formula &nbsp; &nbsp; <big>C<sub>n</sub>H<sub>2n+2</sub></big>
But for all &nbsp; '''n''' ≥ 4 &nbsp; there are several distinct molecules ("isomers") with the same formula but different structures.
The number of isomers rises rather rapidly when &nbsp; '''n''' &nbsp; increases.
In counting isomers it should be borne in mind that the four bond positions on a given carbon atom can be freely interchanged and bonds rotated (including 3-D "out of the paper" rotations when it's being observed on a flat diagram), &nbsp; so rotations or re-orientations of parts of the molecule (without breaking bonds) do not give different isomers. &nbsp; So what seem at first to be different molecules may in fact turn out to be different orientations of the same molecule.
;Example:
With &nbsp; '''n''' = 3 &nbsp; there is only one way of linking the carbons despite the different orientations the molecule can be drawn; &nbsp; and with &nbsp; '''n''' = 4 &nbsp; there are two configurations:
:::* &nbsp; a &nbsp; straight &nbsp; chain: &nbsp; &nbsp; <big>(CH<sub>3</sub>)(CH<sub>2</sub>)(CH<sub>2</sub>)(CH<sub>3</sub>)</big>
:::* &nbsp; a branched chain: &nbsp; &nbsp; &nbsp; <big>(CH<sub>3</sub>)(CH(CH<sub>3</sub>))(CH<sub>3</sub>)</big>
<br>
Due to bond rotations, it doesn't matter which direction the branch points in.
The phenomenon of "stereo-isomerism" (a molecule being different from its mirror image due to the actual 3-D arrangement of bonds) is ignored for the purpose of this task.
The input is the number &nbsp; '''n''' &nbsp; of carbon atoms of a molecule (for instance '''17''').
The output is how many different different paraffins there are with &nbsp; '''n''' &nbsp; carbon atoms (for instance &nbsp; 24,894 &nbsp; if &nbsp; '''n''' = 17).
The sequence of those results is visible in the OEIS entry: &nbsp;
::: &nbsp; [[oeis:A00602|A00602: number of n-node unrooted quartic trees; number of n-carbon alkanes C(n)H(2n+2) ignoring stereoisomers]].
The sequence is (the index starts from zero, and represents the number of carbon atoms):
1, 1, 1, 1, 2, 3, 5, 9, 18, 35, 75, 159, 355, 802, 1858, 4347, 10359,
24894, 60523, 148284, 366319, 910726, 2278658, 5731580, 14490245,
36797588, 93839412, 240215803, 617105614, 1590507121, 4111846763,
10660307791, 27711253769, ...
;Extra credit:
Show the paraffins in some way.
A flat 1D representation, with arrays or lists is enough, for instance:
<syntaxhighlight lang="text">*Main> all_paraffins 1
[CCP H H H H]
*Main> all_paraffins 2
[BCP (C H H H) (C H H H)]
*Main> all_paraffins 3
[CCP H H (C H H H) (C H H H)]
*Main> all_paraffins 4
[BCP (C H H (C H H H)) (C H H (C H H H)),
CCP H (C H H H) (C H H H) (C H H H)]
*Main> all_paraffins 5
[CCP H H (C H H (C H H H)) (C H H (C H H H)),
CCP H (C H H H) (C H H H) (C H H (C H H H)),
CCP (C H H H) (C H H H) (C H H H) (C H H H)]
*Main> all_paraffins 6
[BCP (C H H (C H H (C H H H))) (C H H (C H H (C H H H))),
BCP (C H H (C H H (C H H H))) (C H (C H H H) (C H H H)),
BCP (C H (C H H H) (C H H H)) (C H (C H H H) (C H H H)),
CCP H (C H H H) (C H H (C H H H)) (C H H (C H H H)),
CCP (C H H H) (C H H H) (C H H H) (C H H (C H H H))]</syntaxhighlight>
Showing a basic 2D ASCII-art representation of the paraffins is better; for instance (molecule names aren't necessary):
<syntaxhighlight lang="text"> methane ethane propane isobutane
H H H H H H H H H
│ │ │ │ │ │ │ │ │
H ─ C ─ H H ─ C ─ C ─ H H ─ C ─ C ─ C ─ H H ─ C ─ C ─ C ─ H
│ │ │ │ │ │ │ │ │
H H H H H H H │ H
H ─ C ─ H
H</syntaxhighlight>
;Links:
* &nbsp; A paper that explains the problem and its solution in a functional language:
http://www.cs.wright.edu/~tkprasad/courses/cs776/paraffins-turner.pdf
* &nbsp; A Haskell implementation:
https://github.com/ghc/nofib/blob/master/imaginary/paraffins/Main.hs
* &nbsp; A Scheme implementation:
http://www.ccs.neu.edu/home/will/Twobit/src/paraffins.scm
* &nbsp; A Fortress implementation: &nbsp; &nbsp; &nbsp; &nbsp; (this site has been closed)
http://java.net/projects/projectfortress/sources/sources/content/ProjectFortress/demos/turnersParaffins0.fss?rev=3005
<br><br>

View file

@ -0,0 +1,39 @@
V nMax = 250
V nBranches = 4
V rooted = [BigInt(0)] * (nMax + 1)
V unrooted = [BigInt(0)] * (nMax + 1)
rooted[0] = BigInt(1)
rooted[1] = BigInt(1)
unrooted[0] = BigInt(1)
unrooted[1] = BigInt(1)
F choose(m, k)
I k == 1
R m
V result = m
L(i) 1 .< k
result = result * (m + i) I/ (i + 1)
R result
F tree(br, n, l, sum, cnt)
V s = 0
L(b) br + 1 .. :nBranches
s = sum + (b - br) * n
I s > :nMax {R}
V c = choose(:rooted[n], b - br) * cnt
I l * 2 < s {:unrooted[s] += c}
I b == :nBranches {R}
:rooted[s] += c
L(m) (n - 1 .< 0).step(-1)
tree(b, m, l, s, c)
F bicenter(s)
I (s [&] 1) == 0
:unrooted[s] += :rooted[s I/ 2] * (:rooted[s I/ 2] + 1) I/ 2
L(n) 1 .. nMax
tree(0, n, n, 1, BigInt(1))
bicenter(n)
print(n: unrooted[n])

View file

@ -0,0 +1,115 @@
#include <stdio.h>
#define MAX_N 33 /* max number of tree nodes */
#define BRANCH 4 /* max number of edges a single node can have */
/* The basic idea: a paraffin molecule can be thought as a simple tree
with each node being a carbon atom. Counting molecules is thus the
problem of counting free (unrooted) trees of given number of nodes.
An unrooted tree needs to be uniquely represented, so we need a way
to cannonicalize equivalent free trees. For that, we need to first
define the cannonical form of rooted trees. Since rooted trees can
be constructed by a root node and up to BRANCH rooted subtrees that
are arranged in some definite order, we can define it thusly:
* Given the root of a tree, the weight of each of its branches is
the number of nodes contained in that branch;
* A cannonical rooted tree would have its direct subtrees ordered
in descending order by weight;
* In case multiple subtrees are the same weight, they are ordered
by some unstated, but definite, order (this code doesn't really
care what the ordering is; it only counts the number of choices
in such a case, not enumerating individual trees.)
A rooted tree of N nodes can then be constructed by adding smaller,
cannonical rooted trees to a root node, such that:
* Each subtree has fewer than BRANCH branches (since it must have
an empty slot for an edge to connect to the new root);
* Weight of those subtrees added later are no higher than earlier
ones;
* Their weight total N-1.
A rooted tree so constructed would be itself cannonical.
For an unrooted tree, we can define the radius of any of its nodes:
it's the maximum weight of any of the subtrees if this node is used
as the root. A node is the center of a tree if it has the smallest
radius among all the nodes. A tree can have either one or two such
centers; if two, they must be adjacent (cf. Knuth, tAoCP 2.3.4.4).
An important fact is that, a node in a tree is its sole center, IFF
its radius times 2 is no greater than the sum of the weights of all
branches (ibid). While we are making rooted trees, we can add such
trees encountered to the count of cannonical unrooted trees.
A bi-centered unrooted tree with N nodes can be made by joining two
trees, each with N/2 nodes and fewer than BRANCH subtrees, at root.
The pair must be ordered in aforementioned implicit way so that the
product is cannonical. */
typedef unsigned long long xint;
#define FMT "llu"
xint rooted[MAX_N] = {1, 1, 0};
xint unrooted[MAX_N] = {1, 1, 0};
/* choose k out of m possible values; chosen values may repeat, but the
ordering of them does not matter. It's binomial(m + k - 1, k) */
xint choose(xint m, xint k)
{
xint i, r;
if (k == 1) return m;
for (r = m, i = 1; i < k; i++)
r = r * (m + i) / (i + 1);
return r;
}
/* constructing rooted trees of BR branches at root, with at most
N radius, and SUM nodes in the partial tree already built. It's
recursive, and CNT and L carry down the number of combinations
and the tree radius already encountered. */
void tree(xint br, xint n, xint cnt, xint sum, xint l)
{
xint b, c, m, s;
for (b = br + 1; b <= BRANCH; b++) {
s = sum + (b - br) * n;
if (s >= MAX_N) return;
/* First B of BR branches are all of weight n; the
rest are at most of weight N-1 */
c = choose(rooted[n], b - br) * cnt;
/* This partial tree is singly centered as is */
if (l * 2 < s) unrooted[s] += c;
/* Trees saturate at root can't be used as building
blocks for larger trees, so forget them */
if (b == BRANCH) return;
rooted[s] += c;
/* Build the rest of the branches */
for (m = n; --m; ) tree(b, m, c, s, l);
}
}
void bicenter(int s)
{
if (s & 1) return;
/* Pick two of the half-size building blocks, allowing
repetition. */
unrooted[s] += rooted[s/2] * (rooted[s/2] + 1) / 2;
}
int main()
{
xint n;
for (n = 1; n < MAX_N; n++) {
tree(0, n, 1, 1, n);
bicenter(n);
printf("%"FMT": %"FMT"\n", n, unrooted[n]);
}
return 0;
}

View file

@ -0,0 +1,106 @@
#include <gmp.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_BRANCH 4
#define MAX_N 500
mpz_t bcache[MAX_N + 1];
mpz_t ucache[MAX_N + 1];
mpz_t *rcache[MAX_N + 1][MAX_BRANCH + 1];
mpz_t tmp1, tmp2;
void choose(mpz_t r, mpz_t m, int k)
{
int i;
mpz_set(r, m);
mpz_add_ui(tmp1, m, 1);
for (i = 1; i < k; ) {
mpz_mul(r, r, tmp1);
mpz_divexact_ui(r, r, ++i);
if (i >= k) break;
mpz_add_ui(tmp1, tmp1, 1);
}
}
mpz_t rtmp1, rtmp2;
void calc_rooted(mpz_t res, int n, int b, int r)
{
mpz_set_ui(res, 0);
if (n == 1 && b == 0 && r == 0) {
mpz_set_ui(res, 1);
return;
} else if (n <= b || n <= r || n == 1 || b == 0 || r == 0)
return;
int b1, r1;
for (b1 = 1; b1 <= b && r * b1 < n; b1++) {
choose(rtmp1, bcache[r], b1);
mpz_set_ui(rtmp2, 0);
for (r1 = 0; r1 < r && r1 + r * b1 < n; r1++)
mpz_add(rtmp2, rtmp2, rcache[n - r * b1][b - b1][r1]);
mpz_addmul(res, rtmp1, rtmp2);
}
}
void calc_first_branch(int n)
{
int b, r;
mpz_init_set_ui(bcache[n], 0);
for (b = 0; b < MAX_BRANCH; b++)
for (r = 0; r < n; r++)
mpz_add(bcache[n], bcache[n], rcache[n][b][r]);
}
void calc_unrooted(int n)
{
int b, r;
for (b = 0; b <= MAX_BRANCH; b++) {
mpz_t *p = malloc(sizeof(mpz_t) * n);
rcache[n][b] = p;
for (r = 0; r < n; r++) {
mpz_init(p[r]);
calc_rooted(p[r], n, b, r);
}
}
calc_first_branch(n);
mpz_init_set_ui(ucache[n], 0);
for (r = 0; r * 2 < n; r++)
for (b = 0; b <= MAX_BRANCH; b++)
mpz_add(ucache[n], ucache[n], rcache[n][b][r]);
if (!(n & 1)) {
mpz_add_ui(rtmp1, bcache[n/2], 1);
mpz_mul(rtmp1, rtmp1, bcache[n/2]);
mpz_divexact_ui(rtmp1, rtmp1, 2);
mpz_add(ucache[n], ucache[n], rtmp1);
}
}
void init(void)
{
mpz_init(tmp1), mpz_init(tmp2);
mpz_init(rtmp1), mpz_init(rtmp2);
}
int main(void)
{
int i;
init();
for (i = 0; i <= MAX_N; i++) {
calc_unrooted(i);
gmp_printf("%d: %Zd\n", i, ucache[i]);
}
return 0;
}

View file

@ -0,0 +1,44 @@
import std.stdio, std.bigint;
enum uint nMax = 250;
enum uint nBranches = 4;
__gshared BigInt[nMax + 1] rooted = [1.BigInt, 1.BigInt /*...*/],
unrooted = [1.BigInt, 1.BigInt /*...*/];
void tree(in uint br, in uint n, in uint l, in uint inSum,
in BigInt cnt) nothrow {
__gshared static BigInt[nBranches] c;
uint sum = inSum;
foreach (immutable b; br + 1 .. nBranches + 1) {
sum += n;
if (sum > nMax || (l * 2 >= sum && b >= nBranches))
return;
if (b == br + 1) {
c[br] = rooted[n] * cnt;
} else {
c[br] *= rooted[n] + b - br - 1;
c[br] /= b - br;
}
if (l * 2 < sum)
unrooted[sum] += c[br];
if (b < nBranches)
rooted[sum] += c[br];
foreach_reverse (immutable m; 1 .. n)
tree(b, m, l, sum, c[br]);
}
}
void bicenter(in uint s) nothrow {
if ((s & 1) == 0)
unrooted[s] += rooted[s / 2] * (rooted[s / 2] + 1) / 2;
}
void main() {
foreach (immutable n; 1 .. nMax + 1) {
tree(0, n, n, 1, 1.BigInt);
n.bicenter;
writeln(n, ": ", unrooted[n]);
}
}

View file

@ -0,0 +1,100 @@
' version 31-12-2016
' compile with: fbc -s console
' uses gmp, translation from pascal
#Include Once "gmp.bi"
Const As Integer max_n = 500, branch = 4
Dim Shared As mpz_ptr rooted(), unrooted(), c()
Dim Shared As mpz_ptr cnt, tmp
Sub tree(br As UInteger, n As UInteger, l As UInteger, sum As UInteger, cnt As mpz_ptr)
Dim As UInteger b, m
For b = br +1 To branch
sum = sum + n
If sum > max_n Then Return
' prevent unneeded long math
If (l * 2 >= sum) And (b >= branch) Then Return
If b = (br +1) Then
mpz_mul(c(br), rooted(n), cnt)
Else
mpz_add_ui(tmp, rooted(n), b - br -1)
mpz_mul(c(br), c(br), tmp)
mpz_divexact_ui(c(br), c(br), b - br)
End If
If l * 2 < sum Then
mpz_add(unrooted(sum), unrooted(sum), c(br))
End If
If b < branch Then
mpz_add(rooted(sum), rooted(sum), c(br))
For m = n -1 To 1 Step -1
tree(b, m, l, sum, c(br))
Next
End If
Next
End Sub
Sub bicenter(s As UInteger)
If (s And 1) = 1 Then Return
mpz_add_ui(tmp, rooted(s \ 2), 1)
mpz_mul(tmp, rooted(s \ 2), tmp)
mpz_tdiv_q_2exp(tmp, tmp, 1)
mpz_add(unrooted(s), unrooted(s), tmp)
End Sub
' ------=< MAIN >=------
Dim As UInteger n, sum
Dim As ZString Ptr ans
ReDim rooted(max_n), unrooted(max_n)
For n = 0 To max_n
rooted(n) = Allocate(Len(__mpz_struct)) : Mpz_init( rooted(n))
unrooted(n) = Allocate(Len(__mpz_struct)) : Mpz_init(unrooted(n))
Next
For n = 0 To 1
mpz_set_ui( rooted(n), 1)
mpz_set_ui(unrooted(n), 1)
Next
ReDim c(branch -1)
For n = 0 To branch -1
c(n) = Allocate(Len(__mpz_struct)) : Mpz_init(c(n))
Next
cnt = Allocate(Len(__mpz_struct)) : Mpz_init_set_ui(cnt, 1)
tmp = Allocate(Len(__mpz_struct)) : Mpz_init(tmp)
sum = 1
For n = 1 To max_n
tree(0, n, n, sum, cnt)
bicenter(n)
'gmp_printf("%d: %Zd"+Chr(13)+Chr(10), n, unrooted(n))
ans = Mpz_get_str (0, 10, unrooted(n))
Print Using "###: "; n; : Print *ans
Next
For n = 0 To max_n
mpz_Clear( rooted(n))
mpz_Clear(unrooted(n))
Next
For n = 0 To branch -1
mpz_clear(c(n))
Next
mpz_clear(cnt)
mpz_clear(tmp)
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,61 @@
package main
import (
"fmt"
"math/big"
)
const branches = 4
const nMax = 500
var rooted, unrooted [nMax + 1]big.Int
var c [branches]big.Int
var tmp = new(big.Int)
var one = big.NewInt(1)
func tree(br, n, l, sum int, cnt *big.Int) {
for b := br + 1; b <= branches; b++ {
sum += n
if sum > nMax {
return
}
if l*2 >= sum && b >= branches {
return
}
if b == br+1 {
c[br].Mul(&rooted[n], cnt)
} else {
tmp.Add(&rooted[n], tmp.SetInt64(int64(b-br-1)))
c[br].Mul(&c[br], tmp)
c[br].Div(&c[br], tmp.SetInt64(int64(b-br)))
}
if l*2 < sum {
unrooted[sum].Add(&unrooted[sum], &c[br])
}
if b < branches {
rooted[sum].Add(&rooted[sum], &c[br])
}
for m := n - 1; m > 0; m-- {
tree(b, m, l, sum, &c[br])
}
}
}
func bicenter(s int) {
if s&1 == 0 {
tmp.Rsh(tmp.Mul(&rooted[s/2], tmp.Add(&rooted[s/2], one)), 1)
unrooted[s].Add(&unrooted[s], tmp)
}
}
func main() {
rooted[0].SetInt64(1)
rooted[1].SetInt64(1)
unrooted[0].SetInt64(1)
unrooted[1].SetInt64(1)
for n := 1; n <= nMax; n++ {
tree(0, n, n, 1, big.NewInt(1))
bicenter(n)
fmt.Printf("%d: %d\n", n, &unrooted[n])
}
}

View file

@ -0,0 +1,44 @@
-- polynomial utils
a `nmul` n = map (*n) a
a `ndiv` n = map (`div` n) a
instance (Integral a) => Num [a] where
(+) = zipWith (+)
negate = map negate
a * b = foldr f undefined b where
f x z = (a `nmul` x) + (0 : z)
abs _ = undefined
signum _ = undefined
fromInteger n = fromInteger n : repeat 0
-- replace x in polynomial with x^n
repl a n = concatMap (: replicate (n-1) 0) a
-- S2: (a^2 + b)/2
cycleIndexS2 a b = (a*a + b)`ndiv` 2
-- S4: (a^4 + 6 a^2 b + 8 a c + 3 b^2 + 6 d) / 24
cycleIndexS4 a b c d = ((a ^ 4) +
(a ^ 2 * b) `nmul` 6 +
(a * c) `nmul` 8 +
(b ^ 2) `nmul` 3 +
d `nmul` 6) `ndiv` 24
a598 = x1
-- A000598: A(x) = 1 + (1/6)*x*(A(x)^3 + 3*A(x)*A(x^2) + 2*A(x^3))
x1 = 1 : ((x1^3) + ((x2*x1)`nmul` 3) + (x3`nmul`2)) `ndiv` 6
x2 = x1`repl`2
x3 = x1`repl`3
x4 = x1`repl`4
-- A000678 = x CycleIndex(S4, A000598(x))
a678 = 0 : cycleIndexS4 x1 x2 x3 x4
-- A000599 = CycleIndex(S2, A000598(x) - 1)
a599 = cycleIndexS2 (0 : tail x1) (0 : tail x2)
-- A000602 = A000678(x) - A000599(x) + A000599(x^2)
a602 = a678 - a599 + x2
main = mapM_ print $ take 200 $ zip [0 ..] a602

View file

@ -0,0 +1,32 @@
import Data.Array
choose :: Integer -> Int -> Integer
choose m k = let kk = toInteger k in (product [m..m+kk-1]) `div` (product [1..kk])
max_branches = 4
max_nodes = 200
bcache = listArray (0, max_nodes)
[sum[rcache!n!b!r | r <- [0..n], b <- [0..max_branches-1]] | n <- [0..max_nodes]]
build_block = (bcache !)
rcache = listArray (0,max_nodes) [arr_b i | i <- [0..max_nodes]] where
arr_b n = listArray(0,max_branches) [arr_r b n | b <- [0..max_branches]]
arr_r b n = listArray(0,n) [rooted n b r | r <- [0..n]]
rooted 1 0 0 = 1
rooted 1 _ _ = 0
rooted _ 0 _ = 0
rooted _ _ 0 = 0
rooted n b r
| (n <= b) || (n <= r) = 0
| otherwise = sum [(firsts b1) * (rests b1) | b1 <- [1..b], r * b1 < n] where
firsts = choose (build_block r)
rests bb = sum [rcache!(n-r*bb)!(b - bb)!r1 | r1 <- [0..r-1], r1 < (n-r*bb)]
unrooted n = unicenter + bycenter where
unicenter = sum [ rcache!n!b!r | b <- [0..max_branches], r <-[0..n], r * 2 < n]
bycenter| odd n = 0
| otherwise = x * (x + 1) `div` 2 where x = build_block (n `div` 2)
main = mapM_ print $ map (\x->(x, unrooted x)) [1..max_nodes]

View file

@ -0,0 +1,32 @@
part3=: ;@((<@([(],.(-+/"1))],.]+i.@(]-~1+<.@-:@-))"0 i.@>:@<.@%&3))
part4=: 3 :0
ij=.; (,.]+i.@:(]-~1+[:<.3%~y-]))&.> i.1+<.y%4
(,.y - +/"1) ; (<@(],"1 0 <.@-:@(y-[) (] + i.@>:@-) {:@] >. (>.-:y)-[)~+/)"1 ij
)
c0=: */@:{
c1=: 13 :'(*-:@(*>:))/y{~}:x'
c2=: 13 :'(*-:@(*>:))~/y{~}.x'
c3=: 13 :'3!2+y{~{.x'
radGenN=: [:;[:(],[:+/c0`c1`c2`c3@.(#.@(}.=}:)@[)"1)&.>/(<1x),~part3&.>@ i.@-
bcpGenN=: [: , 0 ,.~ -:@(*>:)@({~i.)
c11=: 13 :'*/(y{~0 1{x), -:(*>:)y{~{:x'
c12=: 13 :'*/(y{~0 3{x), -:(*>:)y{~2{x'
c13=: 13 :'*/(y{~{.x) , 3!2+ y{~{: x'
c14=: 13 :'*/(y{~_2{.x), -:(*>:)y{~{.x'
c15=: 13 :'*/ -:(*>:) y{~0 3{x'
c16=: 13 :'*/(y{~{:x) , 3!2+ y{~{. x'
c17=: 13 :'4!3+y{~{.x'
cassl=: c0`c11`c12`c13`c14`c15`c16`c17
ccpGenN=: 4 :0
if. 0=y do. i.0 return. end.
y{.2({.,0,}.) 0,+/@:(x cassl@.(#.@(}.=}:)@[)"1~[)@:part4"0 [1-.~i.y-1
)
NofParaff=: {. radGenN ((ccpGenN +:) + bcpGenN ) 2&|+<.@-:

View file

@ -0,0 +1,7 @@
6 6 $ NofParaff 36
1 1 1 1 2 3
5 9 18 35 75 159
355 802 1858 4347 10359 24894
60523 148284 366319 910726 2278658 5731580
14490245 36797588 93839412 240215803 617105614 1590507121
4111846763 10660307791 27711253769 72214088660 188626236139 493782952902

View file

@ -0,0 +1,59 @@
import java.math.BigInteger;
import java.util.Arrays;
class Test {
final static int nMax = 250;
final static int nBranches = 4;
static BigInteger[] rooted = new BigInteger[nMax + 1];
static BigInteger[] unrooted = new BigInteger[nMax + 1];
static BigInteger[] c = new BigInteger[nBranches];
static void tree(int br, int n, int l, int inSum, BigInteger cnt) {
int sum = inSum;
for (int b = br + 1; b <= nBranches; b++) {
sum += n;
if (sum > nMax || (l * 2 >= sum && b >= nBranches))
return;
BigInteger tmp = rooted[n];
if (b == br + 1) {
c[br] = tmp.multiply(cnt);
} else {
c[br] = c[br].multiply(tmp.add(BigInteger.valueOf(b - br - 1)));
c[br] = c[br].divide(BigInteger.valueOf(b - br));
}
if (l * 2 < sum)
unrooted[sum] = unrooted[sum].add(c[br]);
if (b < nBranches)
rooted[sum] = rooted[sum].add(c[br]);
for (int m = n - 1; m > 0; m--)
tree(b, m, l, sum, c[br]);
}
}
static void bicenter(int s) {
if ((s & 1) == 0) {
BigInteger tmp = rooted[s / 2];
tmp = tmp.add(BigInteger.ONE).multiply(rooted[s / 2]);
unrooted[s] = unrooted[s].add(tmp.shiftRight(1));
}
}
public static void main(String[] args) {
Arrays.fill(rooted, BigInteger.ZERO);
Arrays.fill(unrooted, BigInteger.ZERO);
rooted[0] = rooted[1] = BigInteger.ONE;
unrooted[0] = unrooted[1] = BigInteger.ONE;
for (int n = 1; n <= nMax; n++) {
tree(0, n, n, 1, BigInteger.ONE);
bicenter(n);
System.out.printf("%d: %s%n", n, unrooted[n]);
}
}
}

View file

@ -0,0 +1,65 @@
def MAX_N: 500; # imprecision begins at 46
def BRANCH: 4;
# state: [unrooted, ra]
# tree(br; n; l; sum; cnt) where initially: l=n, sum=1 and cnt=1
def tree(br; n; l; sum; cnt):
# The inner function is used to implement the range(b+1; BRANCH) loop
# as there are early exits.
# On completion, _tree returns [unrooted, ra]
def _tree: # state [ (b, c, sum), (unrooted, ra)]
if length != 5 then error("_tree input has length \(length)") else . end
| .[0] as $b | .[1] as $c | .[2] as $sum | .[3] as $unrooted | .[4] as $ra
| if $b > BRANCH then [$unrooted, $ra]
else
($sum + n) as $sum
| if $sum >= MAX_N or
# prevent unneeded long math
( l * 2 >= $sum and $b >= BRANCH) then [$unrooted, $ra] # return
else (if $b == br + 1 then $ra[n] * cnt
else ($c * ($ra[n] + (($b - br - 1)))) / ($b - br) | floor
end) as $c
| (if l * 2 < $sum then ($unrooted | .[$sum] += $c)
else $unrooted end) as $unrooted
| if $b >= BRANCH then [$b+1, $c, $sum, $unrooted, $ra] | _tree # next
else [$unrooted, ($ra | .[$sum] += $c) ]
| reduce range(1; n) as $m (.; tree($b; $m; l; $sum; $c))
| ([$b + 1, $c, $sum] + .) | _tree
end
end
end
;
# start by incrementing b, and prepending values for (b,c,sum)
([br+1, cnt, sum] + .) | _tree
;
# input and output: [unrooted, ra]
def bicenter(s):
if s % 2 == 1 then .
else
.[1][s / 2] as $aux
| .[0][s] += ($aux * ($aux + 1)) / 2 # 2 divides odd*even
end
;
def array(n;init): [][n-1] = init | map(init);
def ra: array( MAX_N; 0) | .[0] = 1 | .[1] = 1;
def unrooted: ra;
# See below for a simpler implementation using "foreach"
def paraffins:
# range(1; MAX_N)
def _paraffins(n):
if n >= MAX_N then empty
else tree(0; n; n; 1; 1) | bicenter(n)
| [n, .[0][n]], # output
_paraffins(n+1)
end;
[unrooted, ra] | _paraffins(1)
;
paraffins

View file

@ -0,0 +1,7 @@
def paraffins:
foreach range(1; MAX_N) as $n
( [unrooted, ra];
tree(0; $n; $n; 1; 1) | bicenter($n);
[$n, .[0][$n]]
)
;

View file

@ -0,0 +1,42 @@
const branches = 4
const nmax = 500
const rooted = zeros(BigInt, nmax + 1)
const unrooted = zeros(BigInt, nmax + 1)
rooted[1] = rooted[2] = unrooted[1] = unrooted[2] = 1
const c = zeros(BigInt, branches)
function tree(br, n, l, sum, cnt)
for b in br+1:branches
sum += n
if (sum > nmax) || (l * 2 >= sum && b >= branches)
return
elseif b == br + 1
c[br + 1] = rooted[n + 1] * cnt
else
c[br + 1] *= rooted[n + 1] + b - br - 1
c[br + 1] = div(c[br + 1], b - br)
end
if l*2 < sum
unrooted[sum + 1] += c[br + 1]
end
if b < branches
rooted[sum + 1] += c[br + 1]
end
for m in n-1:-1:1
tree(b, m, l, sum, c[br + 1])
end
end
end
bicenter(n) = if iseven(n) unrooted[n + 1] += div(rooted[div(n, 2) + 1] * (rooted[div(n, 2) + 1] + 1), 2) end
function paraffins()
for n in 1:nmax
tree(0, n, n, 1, one(BigInt))
bicenter(n)
println("$n: $(unrooted[n + 1])")
end
end
paraffins()

View file

@ -0,0 +1,48 @@
// version 1.1.4-3
import java.math.BigInteger
const val MAX_N = 250
const val BRANCHES = 4
val rooted = Array(MAX_N + 1) { if (it < 2) BigInteger.ONE else BigInteger.ZERO }
val unrooted = Array(MAX_N + 1) { if (it < 2) BigInteger.ONE else BigInteger.ZERO }
val c = Array(BRANCHES) { BigInteger.ZERO }
fun tree(br: Int, n: Int, l: Int, s: Int, cnt: BigInteger) {
var sum = s
for (b in (br + 1)..BRANCHES) {
sum += n
if (sum > MAX_N || (l * 2 >= sum && b >= BRANCHES)) return
var tmp = rooted[n]
if (b == br + 1) {
c[br] = tmp * cnt
}
else {
val diff = (b - br).toLong()
c[br] *= tmp + BigInteger.valueOf(diff - 1L)
c[br] /= BigInteger.valueOf(diff)
}
if (l * 2 < sum) unrooted[sum] += c[br]
if (b < BRANCHES) rooted[sum] += c[br]
for (m in n - 1 downTo 1) tree(b, m, l, sum, c[br])
}
}
fun bicenter(s: Int) {
if ((s and 1) == 0) {
var tmp = rooted[s / 2]
tmp *= tmp + BigInteger.ONE
unrooted[s] += tmp.shiftRight(1)
}
}
fun main(args: Array<String>) {
for (n in 1..MAX_N) {
tree(0, n, n, 1, BigInteger.ONE)
bicenter(n)
println("$n: ${unrooted[n]}")
}
}

View file

@ -0,0 +1,10 @@
s[m_, p_, n_] :=
CycleIndexPolynomial[SymmetricGroup[m],
Table[ComposeSeries[p, x^i + O[x]^(n + 1)], {i, m}]];
G000598[n_] := Nest[1 + x s[3, #, n] &, 1 + O[x], n];
G000602[n_] :=
x s[4, #, n] - s[2, # - 1, n] +
ComposeSeries[#, x^2 + O[x]^(n + 1)] &[G000598[n]];
A000602[n_] := SeriesCoefficient[G000602[n], n];
A000602List[n_] := CoefficientList[G000602[n], x];
Grid@Transpose@{Range[0, 200], A000602List@200}

View file

@ -0,0 +1,41 @@
import bigints
const
nMax: int32 = 250
nBranches = 4
var rooted, unrooted: array[nMax + 1, BigInt]
rooted[0..1] = [1.initBigInt, 1.initBigInt]
unrooted[0..1] = [1.initBigInt, 1.initBigInt]
for i in 2 .. nMax:
rooted[i] = 0.initBigInt
unrooted[i] = 0.initBigInt
proc choose(m: BigInt; k: int32): BigInt =
result = m
if k == 1: return
for i in 1 ..< k:
result = result * (m + i) div (i + 1)
proc tree(br, n, l, sum: int32; cnt: BigInt) =
var s: int32 = 0
for b in br + 1 .. nBranches:
s = sum + (b - br) * n
if s > nMax: return
let c = choose(rooted[n], b - br) * cnt
if l * 2 < s: unrooted[s] += c
if b == nBranches: return
rooted[s] += c
for m in countdown(n-1, 1):
tree b, m, l, s, c
proc bicenter(s: int32) =
if (s and 1) == 0:
unrooted[s] += rooted[s div 2] * (rooted[s div 2] + 1) div 2
for n in 1 .. nMax:
tree 0, n, n, 1, 1.initBigInt
n.bicenter
echo n, ": ", unrooted[n]

View file

@ -0,0 +1,15 @@
paraffin(p) =
{
local (P = p+1, R, U = R = Vec([1,1], P));
for (n = 1, p,
((B,n,C,S,l=n) -> my(b,c,i,s);
for (b = 1, 4-B,
if ((s = S + b * n) < P,
c = R[n+1] * C * prod(i = 1, b-1, (R[n+1]+i)/(i+1));
if (l+l < s, U[s+1] += c);
if (B+b < 4, R[s+1] += c; i = n; while (i--, self()(B+b, i, c, s, l)))))
)(0,n,1,1);
if (n % 2,, U[n+1] += R[n/2+1] * (R[n/2+1]+1)/2);
print([n, U[n+1]]))
}

View file

@ -0,0 +1,19 @@
iso(B,n,C,S,l=n) =
{
my (b,c,i,s);
for (b = 1, 4-B,
if ((s = S + b * n) < P,
c = R[n+1] * C * prod(i = 1, b-1, (R[n+1]+i)/(i+1));
if (l+l < s, U[s+1] += c);
if (B+b < 4, R[s+1] += c; i = n; while (i--, iso(B+b, i, c, s, l)))))
}
paraffin(p) =
{
local (P = p+1, R, U = R = Vec([1,1], P));
for (n = 1, p, iso(0, n, 1, 1);
if (n % 2,, U[n+1] += R[n/2+1] * (R[n/2+1]+1)/2);
print([n, U[n+1]]))
}

View file

@ -0,0 +1,88 @@
Program Paraffins;
uses
gmp;
const
max_n = 500;
branch = 4;
var
rooted, unrooted: array [0 .. max_n-1] of mpz_t;
c: array [0 .. branch-1] of mpz_t;
cnt, tmp: mpz_t;
n: integer;
fmt: pchar;
sum: integer;
procedure tree(br, n, l: integer; sum: integer; cnt: mpz_t);
var
b, m: integer;
begin
for b := br + 1 to branch do
begin
sum := sum + n;
if sum >= max_n then
exit;
(* prevent unneeded long math *)
if (l * 2 >= sum) and (b >= branch) then
exit;
if b = (br + 1) then
mpz_mul(c[br], rooted[n], cnt)
else
begin
mpz_add_ui(tmp, rooted[n], b - br - 1);
mpz_mul(c[br], c[br], tmp);
mpz_divexact_ui(c[br], c[br], b - br);
end;
if l * 2 < sum then
mpz_add(unrooted[sum], unrooted[sum], c[br]);
if b < branch then
begin
mpz_add(rooted[sum], rooted[sum], c[br]);
for m := n-1 downto 1 do
tree(b, m, l, sum, c[br]);
end;
end;
end;
procedure bicenter(s: integer);
begin
if odd(s) then
exit;
mpz_add_ui(tmp, rooted[s div 2], 1);
mpz_mul(tmp, rooted[s div 2], tmp);
mpz_tdiv_q_2exp(tmp, tmp, 1);
mpz_add(unrooted[s], unrooted[s], tmp);
end;
begin
for n := 0 to 1 do
begin
mpz_init_set_ui(rooted[n], 1);
mpz_init_set_ui(unrooted[n], 1);
end;
for n := 2 to max_n-1 do
begin
mpz_init_set_ui(rooted[n], 0);
mpz_init_set_ui(unrooted[n], 0);
end;
for n := 0 to BRANCH-1 do
mpz_init(c[n]);
mpz_init(tmp);
mpz_init_set_ui(cnt, 1);
sum := 1;
for n := 1 to MAX_N do
begin
tree(0, n, n, sum, cnt);
bicenter(n);
mp_printf('%d: %Zd'+chr(13)+chr(10), n, @unrooted[n]);
end;
end.

View file

@ -0,0 +1,110 @@
program CountAlkanes;
{$mode objfpc}{$H+}
uses SysUtils; // only for output
type TArrayUint64 = array of uint64;
{
Function to count alkanes, based on: Shinsaku Fujita,
"Numbers of Alkanes and Monosubstituted Alkanes.
A Long-Standing Interdisciplinary Problem over 130 Years",
Bull. Chem. Soc. Jpn. Vol. 83, No. 1, 118 (2010)
}
function CountAlkanes() : TArrayUint64;
const
MAX_RESULT_INDEX = 49; // as far as this code can get without multi-precision
MAX_R_INDEX = MAX_RESULT_INDEX div 2;
var
R : array [0..MAX_R_INDEX] of uint64;
nrCentUnb : uint64; // number of centroidal unbalanced alkanes
temp : uint64;
m, n, h, i, j, k : integer;
begin
SetLength( result, MAX_RESULT_INDEX + 1); // zero-based
{
Calculate enough of the coefficients R[], where the generating function
r(x) = R[0] + R[1]x + R[2]x^2 + R[3]x^3 + ... satifies
r(x) = 1 + (x/6)[r(x)^3 + 2r(x^3) + 3r(x)r(x^2)] (Fujita, equation 4)
}
R[0] := 1;
n := 0;
repeat
if (n mod 3 = 0) then temp := 2*R[n div 3]
else temp := 0;
for j := 0 to (n div 2) do begin
inc( temp, 3 * R[j] * R[n - 2*j]);
end;
for j := 0 to n do begin
for k := 0 to (n - j) do begin
inc(temp, R[j] * R[k] * R[n - j - k]);
end;
end;
Assert( temp mod 6 = 0); // keep an eye on it
inc(n);
R[n] := temp div 6;
until (n = MAX_R_INDEX);
{
Now use the generating function
(x/24)[r(x)^4 + 3r(x^2)^2 + *r(x)r(x^3) + 6r(x)^2r(x^2) + 6r(x^4)]
where inserting r(x) up to the term in x^m will give the number of alkanes
of orders 2m+1 and 2m+2, as the coefficients of x^(2m+1) and x^(2m+2).
Note: In Fujita's paper, equation 23, the factor is 1/24 not x/24,
but x/24 seems to be needed to give correct results.
}
result[0] := 1; // conventional
for n := 1 to MAX_RESULT_INDEX do begin
m := (n - 1) div 2; // so n = 2*m + 1 or 2*m + 2
temp := 0;
// These loops are written for clarity not efficiency
for k := 0 to m do begin
for j := 0 to m do begin
for i := 0 to m do begin
h := n - 1 - i - j - k;
if (h >= 0) and (h <= m) then inc( temp, R[h]*R[i]*R[j]*R[k]);
end;
end;
end;
if Odd(n) then begin
for k := 0 to m do begin
inc( temp, 3*R[k]*R[m - k]);
end;
end;
for k := 0 to (n - 1) div 3 do begin
j := n - 1 - 3*k;
if (j <= m) then inc( temp, 8*R[j]*R[k]);
end;
for k := 0 to m do begin
for j := 0 to m do begin
i := n - 1 - 2*k - j;
if (i >= 0) and (i <= m) then inc( temp, 6*R[i]*R[j]*R[k]);
end;
end;
if (n mod 4 = 1) then inc( temp, 6*R[(n - 1) div 4]);
Assert( temp mod 24 = 0); // keep an eye on it
nrCentUnb := temp div 24;
if Odd(n) then
result[n] := nrCentUnb
else begin
temp := R[n div 2];
result[n] := nrCentUnb + (temp*(temp + 1) div 2);
end;
end;
end;
// Call function and display the results
var
nrAlkanes : TArrayUint64;
k : integer;
begin
nrAlkanes := CountAlkanes();
for k := 0 to Length( nrAlkanes) - 1 do
WriteLn( SysUtils.Format( '%2d %d', [k, nrAlkanes[k]]));
end.

View file

@ -0,0 +1,40 @@
use Math::GMPz;
my $nmax = 250;
my $nbranches = 4;
my @rooted = map { Math::GMPz->new($_) } 1,1,(0) x $nmax;
my @unrooted = map { Math::GMPz->new($_) } 1,1,(0) x $nmax;
my @c = map { Math::GMPz->new(0) } 0 .. $nbranches-1;
sub tree {
my($br, $n, $l, $sum, $cnt) = @_;
for my $b ($br+1 .. $nbranches) {
$sum += $n;
return if $sum > $nmax || ($l*2 >= $sum && $b >= $nbranches);
if ($b == $br+1) {
$c[$br] = $rooted[$n] * $cnt;
} else {
$c[$br] *= $rooted[$n] + $b - $br - 1;
$c[$br] /= $b - $br;
}
$unrooted[$sum] += $c[$br] if $l*2 < $sum;
return if $b >= $nbranches;
$rooted[$sum] += $c[$br];
for my $m (reverse 1 .. $n-1) {
next if $sum+$m > $nmax;
tree($b, $m, $l, $sum, $c[$br]);
}
}
}
sub bicenter {
my $s = shift;
$unrooted[$s] += $rooted[$s/2] * ($rooted[$s/2]+1) / 2 unless $s & 1;
}
for my $n (1 .. $nmax) {
tree(0, $n, $n, 1, Math::GMPz->new(1));
bicenter($n);
print "$n: $unrooted[$n]\n";
}

View file

@ -0,0 +1,53 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAX_N</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">BRANCH</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">4</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">rooted</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MAX_N</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">unrooted</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MAX_N</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">tree</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">br</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tot</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">cnt</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">br</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">BRANCH</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tot</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">tot</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">MAX_N</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">tot</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">BRANCH</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tot</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">==</span><span style="color: #000000;">br</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n1</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">cnt</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">*=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n1</span><span style="color: #0000FF;">]+(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">-</span><span style="color: #000000;">br</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))/(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">-</span><span style="color: #000000;">br</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;"><</span><span style="color: #000000;">tot</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;"><</span><span style="color: #000000;">BRANCH</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">c</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tot</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">bicenter</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">even</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">aux</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">aux</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">aux</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">MAX_N</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">bicenter</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><</span><span style="color: #000000;">10</span> <span style="color: #008080;">or</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">MAX_N</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d: %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--

View file

@ -0,0 +1,64 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">max_n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">200</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">branch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">4</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ivals</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)&</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">max_n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">rooted</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">max_n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ivals</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">unrooted</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">max_n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ivals</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">branch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">tmp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">tree</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">br</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">mpz</span> <span style="color: #000000;">cnt</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">cbr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">br</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">br</span> <span style="color: #008080;">to</span> <span style="color: #000000;">branch</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">></span><span style="color: #000000;">max_n</span>
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">s</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">branch</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">br</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cbr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">cnt</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #7060A8;">mpz_add_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tmp</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">-</span><span style="color: #000000;">br</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cbr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cbr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tmp</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_divexact_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cbr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cbr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">-</span><span style="color: #000000;">br</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;"><</span><span style="color: #000000;">s</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">u</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cbr</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;"><</span><span style="color: #000000;">branch</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cbr</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cbr</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">bicenter</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">even</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">aux</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">rooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">u</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">mpz_add_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tmp</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">aux</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tmp</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">aux</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tmp</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_tdiv_q_2exp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tmp</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tmp</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">u</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">u</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tmp</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">mpz</span> <span style="color: #000000;">cnt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">max_n</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tree</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cnt</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">bicenter</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">25</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">mpz_get_short_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">unrooted</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--

View file

@ -0,0 +1,63 @@
int MAX_N = 300;
int BRANCH = 4;
array ra = allocate(MAX_N);
array unrooted = allocate(MAX_N);
void tree(int br, int n, int l, int sum, int cnt)
{
int c;
for (int b = br + 1; b < BRANCH + 1; b++)
{
sum += n;
if (sum >= MAX_N)
return;
// prevent unneeded long math
if (l * 2 >= sum && b >= BRANCH)
return;
if (b == br + 1)
{
c = ra[n] * cnt;
}
else
{
c = c * (ra[n] + (b - br - 1)) / (b - br);
}
if (l * 2 < sum)
unrooted[sum] += c;
if (b < BRANCH)
{
ra[sum] += c;
for (int m=1; m < n; m++)
{
tree(b, m, l, sum, c);
}
}
}
}
void bicenter(int s)
{
if (!(s & 1))
{
int aux = ra[s / 2];
unrooted[s] += aux * (aux + 1) / 2;
}
}
void main()
{
ra[0] = ra[1] = unrooted[0] = unrooted[1] = 1;
for (int n = 1; n < MAX_N; n++)
{
tree(0, n, n, 1, 1);
bicenter(n);
write("%d: %d\n", n, unrooted[n]);
}
}

View file

@ -0,0 +1,53 @@
try:
import psyco
psyco.full()
except ImportError:
pass
MAX_N = 300
BRANCH = 4
ra = [0] * MAX_N
unrooted = [0] * MAX_N
def tree(br, n, l, sum = 1, cnt = 1):
global ra, unrooted, MAX_N, BRANCH
for b in xrange(br + 1, BRANCH + 1):
sum += n
if sum >= MAX_N:
return
# prevent unneeded long math
if l * 2 >= sum and b >= BRANCH:
return
if b == br + 1:
c = ra[n] * cnt
else:
c = c * (ra[n] + (b - br - 1)) / (b - br)
if l * 2 < sum:
unrooted[sum] += c
if b < BRANCH:
ra[sum] += c;
for m in range(1, n):
tree(b, m, l, sum, c)
def bicenter(s):
global ra, unrooted
if not (s & 1):
aux = ra[s / 2]
unrooted[s] += aux * (aux + 1) / 2
def main():
global ra, unrooted, MAX_N
ra[0] = ra[1] = unrooted[0] = unrooted[1] = 1
for n in xrange(1, MAX_N):
tree(0, n, n)
bicenter(n)
print "%d: %d" % (n, unrooted[n])
main()

View file

@ -0,0 +1,113 @@
from itertools import count, chain, tee, islice, cycle
from fractions import Fraction
from sys import setrecursionlimit
setrecursionlimit(5000)
def frac(a,b): return a//b if a%b == 0 else Fraction(a,b)
# infinite polynomial class
class Poly:
def __init__(self, gen = None):
self.gen, self.source = (None, gen) if type(gen) is Poly \
else (gen, None)
def __iter__(self):
# We're essentially tee'ing it everytime the iterator
# is, well, iterated. This may be excessive.
return Poly(self)
def getsource(self):
if self.gen == None:
s = self.source
s.getsource()
s.gen, self.gen = tee(s.gen, 2)
def next(self):
self.getsource()
return next(self.gen)
__next__ = next
# Overload "<<" as stream input operator. Hey, C++ does it.
def __lshift__(self, a): self.gen = a
# The other operators are pretty much what one would expect
def __neg__(self): return Poly(-x for x in self)
def __sub__(a, b): return a + (-b)
def __rsub__(a, n):
a = Poly(a)
def gen():
yield(n - next(a))
for x in a: yield(-x)
return Poly(gen())
def __add__(a, b):
if type(b) is Poly:
return Poly(x + y for (x,y) in zip(a,b))
a = Poly(a)
def gen():
yield(next(a) + b)
for x in a: yield(x)
return Poly(gen())
def __radd__(a,b):
return a + b
def __mul__(a,b):
if not type(b) is Poly:
return Poly(x*b for x in a)
def gen():
s = Poly(cycle([0]))
for y in b:
s += y*a
yield(next(s))
return Poly(gen())
def __rmul__(a,b): return a*b
def __truediv__(a,b):
if not type(b) is Poly:
return Poly(frac(x, b) for x in a)
a, b = Poly(a), Poly(b)
def gen():
r, bb = a,next(b)
while True:
aa = next(r)
q = frac(aa, bb)
yield(q)
r -= q*b
return Poly(gen())
def repl(self, n):
def gen():
for x in self:
yield(x)
for i in range(n-1): yield(0)
return Poly(gen())
def __pow__(self, n):
return Poly(self) if n == 1 else self * self**(n-1)
def S2(a,b): return (a*a + b)/2
def S4(a,b,c,d): return a**4/24 + a**2*b/4 + a*c/3 + b**2/8 + d/4
x1 = Poly()
x2 = x1.repl(2)
x3 = x1.repl(3)
x4 = x1.repl(4)
x1 << chain([1], (x1**3 + 3*x1*x2 + 2*x3)/6)
a598 = x1
a678 = Poly(chain([0], S4(x1, x2, x3, x4)))
a599 = S2(x1 - 1, x2 - 1)
a602 = a678 - a599 + x2
for n,x in zip(count(0), islice(a602, 500)): print(n,x)

View file

@ -0,0 +1,32 @@
#!/usr/bin/python3
from functools import lru_cache
def Z_S(n, f, k):
"""
The cycle index of the symmetric group has recurrence
Z(S_n, f(x)) = 1/n \sum_{i=1}^n f(x^i) Z(S_{n-i}, f(x)).
This function finds the coefficient of x^k in Z(S_n, f(x))
"""
# Special case to avoid division by zero
if n == 0:
return 1 if k == 0 else 0
# Special case as a speed optimisation
if n == 1:
return f(k)
return sum(
sum(f(ij // i) * Z_S(n-i, f, k - ij) for ij in range(0, k+1, i))
for i in range(1, n+1)
) // n
@lru_cache(maxsize=None)
def A000598(k): return 1 if k == 0 else Z_S(3, A000598, k-1)
@lru_cache(maxsize=None)
def A000642(k): return Z_S(2, A000598, k)
def A000631(k): return Z_S(2, A000642, k)
def A000602(k): return A000642(k) + (A000642((k-1) // 2) if k % 2 == 1 else 0) - A000631(k-1)
for k in range(500): print(k, A000602(k))

View file

@ -0,0 +1,31 @@
/*REXX pgm enumerates (without repetition) the number of paraffins with N carbon atoms. */
parse arg nodes . /*obtain optional argument from the CL.*/
if nodes=='' | nodes=="," then nodes= 100 /*Not specified? Then use the default.*/
rooted. = 0; rooted.0= 1; rooted.1= 1 /*define the base rooted numbers.*/
unrooted. = 0; unrooted.0= 1; unrooted.1= 1 /* " " " unrooted " */
numeric digits max(9, nodes % 2) /*this program may use gihugeic numbers*/
w= length(nodes) /*W: used for aligning formatted nodes*/
say right(0, w) unrooted.0 /*show enumerations of 0 carbon atoms*/
/* [↓] process all nodes (up to NODES)*/
do C=1 for nodes; h= C % 2 /*C: is the number of carbon atoms. */
call tree 0, C, C, 1, 1 /* [↓] if # of carbon atoms is even···*/
if \(C//2) then unrooted.C= unrooted.C + rooted.h * (rooted.h + 1) % 2
say right(C, w) unrooted.C /*display an aligned formatted number. */
end /*C*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
tree: procedure expose rooted. unrooted. nodes #. /*this function is recursive.*/
parse arg br,n,L,sum,cnt; nm= n - 1; LL= L + L
brp= br + 1
do b=brp to 4; sum= sum + n
if sum>nodes then leave
if b==4 then if LL>=sum then leave
if b==brp then #.br= rooted.n * cnt
else #.br= #.br * (rooted.n + b - brp) % (b - br)
if LL<sum then unrooted.sum= unrooted.sum + #.br
if b==4 then leave
rooted.sum= rooted.sum + #.br
do m=nm by -1 for nm; call tree b, m, L, sum, #.br
end /*m*/
end /*b*/ /* ↑↑↑↑↑↑↑↑↑ recursive. */
return

View file

@ -0,0 +1,36 @@
#lang racket
(define MAX_N 33)
(define BRANCH 4)
(define rooted (make-vector MAX_N 0))
(define unrooted (make-vector MAX_N 0))
(for ([i 2]) (vector-set! rooted i 1) (vector-set! unrooted i 1))
(define (vector-inc! v i d) (vector-set! v i (+ d (vector-ref v i))))
(define (choose m k)
(if (= k 1) m
(for/fold ([r m]) ([i (in-range 1 k)]) (/ (* r (+ m i)) (add1 i)))))
(define (tree br n cnt sum l)
(let/ec return
(for ([b (in-range (add1 br) (add1 BRANCH))])
(define s (+ sum (* (- b br) n)))
(when (>= s MAX_N) (return))
(define c (* (choose (vector-ref rooted n) (- b br)) cnt))
(when (< (* l 2) s) (vector-inc! unrooted s c))
(when (= b BRANCH) (return))
(vector-inc! rooted s c)
(for ([m (in-range (sub1 n) 0 -1)]) (tree b m c s l)))))
(define (bicenter s)
(when (even? s)
(vector-inc! unrooted s (* (vector-ref rooted (/ s 2))
(add1 (vector-ref rooted (/ s 2)))
1/2))))
(for ([n (in-range 1 MAX_N)])
(tree 0 n 1 1 n)
(bicenter n)
(printf "~a: ~a\n" n (vector-ref unrooted n)))

View file

@ -0,0 +1,45 @@
sub count-unrooted-trees(Int $max-branches, Int $max-weight) {
my @rooted = flat 1,1,0 xx $max-weight - 1;
my @unrooted = flat 1,1,0 xx $max-weight - 1;
sub count-trees-with-centroid(Int $radius) {
sub add-branches(
Int $branches, # number of branches to add
Int $w, # weight of heaviest branch to add
Int $weight is copy, # accumulated weight of tree
Int $choices is copy, # number of choices so far
) {
$choices *= @rooted[$w];
for 1 .. $branches -> $b {
($weight += $w) <= $max-weight or last;
@unrooted[$weight] += $choices if $weight > 2*$radius;
if $b < $branches {
@rooted[$weight] += $choices;
add-branches($branches - $b, $_, $weight, $choices) for 1 ..^ $w;
$choices = $choices * (@rooted[$w] + $b) div ($b + 1);
}
}
}
add-branches($max-branches, $radius, 1, 1);
}
sub count-trees-with-bicentroid(Int $weight) {
if $weight %% 2 {
my \halfs = @rooted[$weight div 2];
@unrooted[$weight] += (halfs * (halfs + 1)) div 2;
}
}
gather {
take 1;
for 1 .. $max-weight {
count-trees-with-centroid($_);
count-trees-with-bicentroid($_);
take @unrooted[$_];
}
}
}
my constant N = 100;
my @paraffins = count-unrooted-trees(4, N);
say .fmt('%3d'), ': ', @paraffins[$_] for flat 1 .. 30, N;

View file

@ -0,0 +1,36 @@
MAX_N = 500
BRANCH = 4
def tree(br, n, l=n, sum=1, cnt=1)
for b in br+1 .. BRANCH
sum += n
return if sum >= MAX_N
# prevent unneeded long math
return if l * 2 >= sum and b >= BRANCH
if b == br + 1
c = $ra[n] * cnt
else
c = c * ($ra[n] + (b - br - 1)) / (b - br)
end
$unrooted[sum] += c if l * 2 < sum
next if b >= BRANCH
$ra[sum] += c
(1...n).each {|m| tree(b, m, l, sum, c)}
end
end
def bicenter(s)
return if s.odd?
aux = $ra[s / 2]
$unrooted[s] += aux * (aux + 1) / 2
end
$ra = [0] * MAX_N
$unrooted = [0] * MAX_N
$ra[0] = $ra[1] = $unrooted[0] = $unrooted[1] = 1
for n in 1...MAX_N
tree(0, n)
bicenter(n)
puts "%d: %d" % [n, $unrooted[n]]
end

View file

@ -0,0 +1,34 @@
object Paraffins extends App {
val (nMax, nBranches) = (250, 4)
val rooted, unrooted = Array.tabulate(nMax + 1)(i => if (i < 2) BigInt(1) else BigInt(0))
val (unrooted, c) = (rooted.clone(), new Array[BigInt](nBranches))
for (n <- 1 to nMax) {
def tree(br: Int, n: Int, l: Int, inSum: Int, cnt: BigInt): Unit = {
var sum = inSum
for (b <- br + 1 to nBranches) {
sum += n
if (sum > nMax || (l * 2 >= sum && b >= nBranches)) return
if (b == br + 1) c(br) = rooted(n) * cnt
else {
c(br) = c(br) * (rooted(n) + BigInt(b - br - 1))
c(br) = c(br) / BigInt(b - br)
}
if (l * 2 < sum) unrooted(sum) = unrooted(sum) + c(br)
if (b < nBranches) rooted(sum) = rooted(sum) + c(br)
for (m <- n - 1 to 1 by -1) tree(b, m, l, sum, c(br))
}
}
def bicenter(s: Int): Unit = if ((s & 1) == 0) {
val halves = rooted(s / 2)
unrooted(s) = unrooted(s) + ((halves + BigInt(1)) * halves >> 1)
}
tree(0, n, n, 1, BigInt(1))
bicenter(n)
println(f"$n%3d: ${unrooted(n)}%s")
}
}

View file

@ -0,0 +1,62 @@
$ include "seed7_05.s7i";
include "bigint.s7i";
const integer: max_n is 500;
const integer: branch is 4;
var array bigInteger: rooted is max_n times 0_;
var array bigInteger: unrooted is max_n times 0_;
const proc: tree (in integer: br, in integer: n, in integer: l, in var integer: sum, in bigInteger: cnt) is func
local
var integer: b is 0;
var integer: m is 0;
var bigInteger: c is 0_;
var bigInteger: diff is 0_;
begin
for b range br + 1 to branch do
sum +:= n;
if sum > max_n or l * 2 >= sum and b >= branch then
# Prevent unneeded long math.
b := branch;
else
if b = (br + 1) then
c := rooted[n] * cnt;
else
diff := bigInteger conv (b - br);
c := c * (rooted[n] + pred(diff)) div diff;
end if;
if l * 2 < sum then
unrooted[sum] +:= c;
end if;
if b < branch then
rooted[sum] +:= c;
for m range n-1 downto 1 do
tree(b, m, l, sum, c);
end for;
end if;
end if;
end for;
end func;
const proc: bicenter (in integer: s) is func
begin
if not odd(s) then
unrooted[s] +:= (rooted[s div 2] * succ(rooted[s div 2])) >> 1;
end if;
end func;
const proc: main is func
local
var bigInteger: cnt is 1_;
var integer: n is 0;
var integer: sum is 1;
begin
rooted[1] := 1_;
unrooted[1] := 1_;
for n range 1 to max_n do
tree(0, n, n, sum, cnt);
bicenter(n);
writeln(n <& ": " <& unrooted[n]);
end for;
end func;

View file

@ -0,0 +1,46 @@
package require Tcl 8.5
set maxN 200
set rooted [lrepeat $maxN 0]
lset rooted 0 1; lset rooted 1 1
set unrooted $rooted
proc choose {m k} {
if {$k == 1} {
return $m
}
for {set r $m; set i 1} {$i < $k} {incr i} {
set r [expr {$r * ($m+$i) / ($i+1)}]
}
return $r
}
proc tree {br n cnt sum l} {
global maxN rooted unrooted
for {set b [expr {$br+1}]} {$b <= 4} {incr b} {
set s [expr {$sum + ($b-$br) * $n}]
if {$s >= $maxN} return
set c [expr {[choose [lindex $rooted $n] [expr {$b-$br}]] * $cnt}]
if {$l*2 < $s} {
lset unrooted $s [expr {[lindex $unrooted $s] + $c}]
}
if {$b == 4} return
lset rooted $s [expr {[lindex $rooted $s] + $c}]
for {set m $n} {[incr m -1]} {} {
tree $b $m $c $s $l
}
}
}
proc bicenter {s} {
if {$s & 1} return
global unrooted rooted
set r [lindex $rooted [expr {$s/2}]]
lset unrooted $s [expr {[lindex $unrooted $s] + $r*($r+1)/2}]
}
for {set n 1} {$n < $maxN} {incr n} {
tree 0 $n 1 1 $n
bicenter $n
puts "${n}: [lindex $unrooted $n]"
}

View file

@ -0,0 +1,51 @@
import "/big" for BigInt
import "/fmt" for Fmt
var branches = 4
var nMax = 250
var rooted = List.filled(nMax + 1, BigInt.zero)
var unrooted = List.filled(nMax + 1, BigInt.zero)
var c = List.filled(branches, BigInt.zero)
var tree
tree = Fn.new { |br, n, l, sum, cnt|
var b = br + 1
while (b <= branches) {
sum = sum + n
if (sum > nMax) return
if (l*2 >= sum && b >= branches) return
if (b == br + 1) {
c[br] = rooted[n] * cnt
} else {
var tmp = rooted[n] + BigInt.new(b - br - 1)
c[br] = c[br] * tmp
c[br] = c[br] / BigInt.new(b - br)
}
if (l*2 < sum) unrooted[sum] = unrooted[sum] + c[br]
if (b < branches) rooted[sum] = rooted[sum] + c[br]
var m = n - 1
while (m > 0) {
tree.call(b, m, l, sum, c[br])
m = m - 1
}
b = b + 1
}
}
var bicenter = Fn.new { |s|
if (s%2 == 0) {
var tmp = (rooted[(s/2).floor] + BigInt.one) * rooted[(s/2).floor]
tmp = tmp >> 1
unrooted[s] = unrooted[s] + tmp
}
}
rooted[0] = BigInt.one
rooted[1] = BigInt.one
unrooted[0] = BigInt.one
unrooted[1] = BigInt.one
for (n in 1..nMax) {
tree.call(0, n, n, 1, BigInt.one)
bicenter.call(n)
Fmt.print("$3d: $i", n, unrooted[n])
}

View file

@ -0,0 +1,35 @@
var BN=Import("zklBigNum");
const nMax=100, nBranches=4;
var rooted =(nMax+1).pump(List.createLong(nMax+1).write,BN.fp(0)),
unrooted=(nMax+1).pump(List.createLong(nMax+1).write,BN.fp(0));
rooted[0]=BN(1); rooted[1]=BN(1); unrooted[0]=BN(1); unrooted[1]=BN(1);
fcn tree(br,n,l,inSum,cnt){
var c=(nBranches).pump(List().write,0); // happens only once
sum := inSum;
foreach b in ([br + 1 .. nBranches]){
sum += n;
if (sum > nMax or (l * 2 >= sum and b >= nBranches)) return();
if (b == br + 1) c[br] = rooted[n] * cnt; // -->BigInt
else{
c[br].mul(rooted[n] + b - br - 1);
c[br].div(b - br);
}
if (l * 2 < sum) unrooted[sum].add(c[br]);
if (b < nBranches) rooted[sum].add(c[br]);
foreach m in ([n-1 .. 1,-1]) { tree(b, m, l, sum, c[br]); }
}
}
fcn bicenter(s){
if (s.isEven) unrooted[s].add(rooted[s / 2] * (rooted[s / 2] + 1) / 2);
}
foreach n in ([1 .. nMax]){
tree(0, n, n, 1, BN(1));
bicenter(n);
println(n, ": ", unrooted[n]);
}