Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Paraffins/00-META.yaml
Normal file
2
Task/Paraffins/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Paraffins
|
||||
94
Task/Paraffins/00-TASK.txt
Normal file
94
Task/Paraffins/00-TASK.txt
Normal 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. So all paraffins with '''n''' carbon atoms share the empirical formula <big>C<sub>n</sub>H<sub>2n+2</sub></big>
|
||||
|
||||
But for all '''n''' ≥ 4 there are several distinct molecules ("isomers") with the same formula but different structures.
|
||||
|
||||
The number of isomers rises rather rapidly when '''n''' 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), so rotations or re-orientations of parts of the molecule (without breaking bonds) do not give different isomers. So what seem at first to be different molecules may in fact turn out to be different orientations of the same molecule.
|
||||
|
||||
|
||||
;Example:
|
||||
With '''n''' = 3 there is only one way of linking the carbons despite the different orientations the molecule can be drawn; and with '''n''' = 4 there are two configurations:
|
||||
:::* a straight chain: <big>(CH<sub>3</sub>)(CH<sub>2</sub>)(CH<sub>2</sub>)(CH<sub>3</sub>)</big>
|
||||
:::* a branched chain: <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 '''n''' of carbon atoms of a molecule (for instance '''17''').
|
||||
|
||||
The output is how many different different paraffins there are with '''n''' carbon atoms (for instance 24,894 if '''n''' = 17).
|
||||
|
||||
The sequence of those results is visible in the OEIS entry:
|
||||
::: [[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:
|
||||
* A paper that explains the problem and its solution in a functional language:
|
||||
http://www.cs.wright.edu/~tkprasad/courses/cs776/paraffins-turner.pdf
|
||||
|
||||
* A Haskell implementation:
|
||||
https://github.com/ghc/nofib/blob/master/imaginary/paraffins/Main.hs
|
||||
|
||||
* A Scheme implementation:
|
||||
http://www.ccs.neu.edu/home/will/Twobit/src/paraffins.scm
|
||||
|
||||
* A Fortress implementation: (this site has been closed)
|
||||
http://java.net/projects/projectfortress/sources/sources/content/ProjectFortress/demos/turnersParaffins0.fss?rev=3005
|
||||
<br><br>
|
||||
|
||||
39
Task/Paraffins/11l/paraffins.11l
Normal file
39
Task/Paraffins/11l/paraffins.11l
Normal 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])
|
||||
115
Task/Paraffins/C/paraffins-1.c
Normal file
115
Task/Paraffins/C/paraffins-1.c
Normal 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;
|
||||
}
|
||||
106
Task/Paraffins/C/paraffins-2.c
Normal file
106
Task/Paraffins/C/paraffins-2.c
Normal 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;
|
||||
}
|
||||
44
Task/Paraffins/D/paraffins.d
Normal file
44
Task/Paraffins/D/paraffins.d
Normal 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]);
|
||||
}
|
||||
}
|
||||
100
Task/Paraffins/FreeBASIC/paraffins.basic
Normal file
100
Task/Paraffins/FreeBASIC/paraffins.basic
Normal 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
|
||||
61
Task/Paraffins/Go/paraffins.go
Normal file
61
Task/Paraffins/Go/paraffins.go
Normal 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])
|
||||
}
|
||||
}
|
||||
44
Task/Paraffins/Haskell/paraffins-1.hs
Normal file
44
Task/Paraffins/Haskell/paraffins-1.hs
Normal 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
|
||||
32
Task/Paraffins/Haskell/paraffins-2.hs
Normal file
32
Task/Paraffins/Haskell/paraffins-2.hs
Normal 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]
|
||||
32
Task/Paraffins/J/paraffins-1.j
Normal file
32
Task/Paraffins/J/paraffins-1.j
Normal 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&|+<.@-:
|
||||
7
Task/Paraffins/J/paraffins-2.j
Normal file
7
Task/Paraffins/J/paraffins-2.j
Normal 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
|
||||
59
Task/Paraffins/Java/paraffins.java
Normal file
59
Task/Paraffins/Java/paraffins.java
Normal 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Task/Paraffins/Jq/paraffins-1.jq
Normal file
65
Task/Paraffins/Jq/paraffins-1.jq
Normal 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
|
||||
7
Task/Paraffins/Jq/paraffins-2.jq
Normal file
7
Task/Paraffins/Jq/paraffins-2.jq
Normal 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]]
|
||||
)
|
||||
;
|
||||
42
Task/Paraffins/Julia/paraffins.julia
Normal file
42
Task/Paraffins/Julia/paraffins.julia
Normal 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()
|
||||
48
Task/Paraffins/Kotlin/paraffins.kotlin
Normal file
48
Task/Paraffins/Kotlin/paraffins.kotlin
Normal 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]}")
|
||||
}
|
||||
}
|
||||
10
Task/Paraffins/Mathematica/paraffins.math
Normal file
10
Task/Paraffins/Mathematica/paraffins.math
Normal 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}
|
||||
41
Task/Paraffins/Nim/paraffins.nim
Normal file
41
Task/Paraffins/Nim/paraffins.nim
Normal 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]
|
||||
15
Task/Paraffins/PARI-GP/paraffins-1.parigp
Normal file
15
Task/Paraffins/PARI-GP/paraffins-1.parigp
Normal 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]]))
|
||||
}
|
||||
19
Task/Paraffins/PARI-GP/paraffins-2.parigp
Normal file
19
Task/Paraffins/PARI-GP/paraffins-2.parigp
Normal 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]]))
|
||||
}
|
||||
88
Task/Paraffins/Pascal/paraffins-1.pas
Normal file
88
Task/Paraffins/Pascal/paraffins-1.pas
Normal 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.
|
||||
110
Task/Paraffins/Pascal/paraffins-2.pas
Normal file
110
Task/Paraffins/Pascal/paraffins-2.pas
Normal 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, 1–18 (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.
|
||||
40
Task/Paraffins/Perl/paraffins.pl
Normal file
40
Task/Paraffins/Perl/paraffins.pl
Normal 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";
|
||||
}
|
||||
53
Task/Paraffins/Phix/paraffins-1.phix
Normal file
53
Task/Paraffins/Phix/paraffins-1.phix
Normal 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>
|
||||
<!--
|
||||
64
Task/Paraffins/Phix/paraffins-2.phix
Normal file
64
Task/Paraffins/Phix/paraffins-2.phix
Normal 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>
|
||||
<!--
|
||||
63
Task/Paraffins/Pike/paraffins.pike
Normal file
63
Task/Paraffins/Pike/paraffins.pike
Normal 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]);
|
||||
}
|
||||
}
|
||||
53
Task/Paraffins/Python/paraffins-1.py
Normal file
53
Task/Paraffins/Python/paraffins-1.py
Normal 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()
|
||||
113
Task/Paraffins/Python/paraffins-2.py
Normal file
113
Task/Paraffins/Python/paraffins-2.py
Normal 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)
|
||||
32
Task/Paraffins/Python/paraffins-3.py
Normal file
32
Task/Paraffins/Python/paraffins-3.py
Normal 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))
|
||||
31
Task/Paraffins/REXX/paraffins.rexx
Normal file
31
Task/Paraffins/REXX/paraffins.rexx
Normal 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
|
||||
36
Task/Paraffins/Racket/paraffins.rkt
Normal file
36
Task/Paraffins/Racket/paraffins.rkt
Normal 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)))
|
||||
45
Task/Paraffins/Raku/paraffins.raku
Normal file
45
Task/Paraffins/Raku/paraffins.raku
Normal 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;
|
||||
36
Task/Paraffins/Ruby/paraffins.rb
Normal file
36
Task/Paraffins/Ruby/paraffins.rb
Normal 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
|
||||
34
Task/Paraffins/Scala/paraffins.scala
Normal file
34
Task/Paraffins/Scala/paraffins.scala
Normal 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")
|
||||
}
|
||||
}
|
||||
62
Task/Paraffins/Seed7/paraffins.seed7
Normal file
62
Task/Paraffins/Seed7/paraffins.seed7
Normal 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;
|
||||
46
Task/Paraffins/Tcl/paraffins.tcl
Normal file
46
Task/Paraffins/Tcl/paraffins.tcl
Normal 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]"
|
||||
}
|
||||
51
Task/Paraffins/Wren/paraffins.wren
Normal file
51
Task/Paraffins/Wren/paraffins.wren
Normal 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])
|
||||
}
|
||||
35
Task/Paraffins/Zkl/paraffins.zkl
Normal file
35
Task/Paraffins/Zkl/paraffins.zkl
Normal 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]);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue