How to resolve the algorithm Paraffins step by step in the Kotlin programming language

Published on 22 June 2024 08:30 PM

How to resolve the algorithm Paraffins step by step in the Kotlin programming language

Table of Contents

Problem Statement

This organic chemistry task is essentially to implement a tree enumeration algorithm.

Enumerate, without repetitions and in order of increasing size, all possible paraffin molecules (also known as alkanes).

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     CnH2n+2 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.

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:

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:   The sequence is (the index starts from zero, and represents the number of carbon atoms):

Show the paraffins in some way. A flat 1D representation, with arrays or lists is enough, for instance: Showing a basic 2D ASCII-art representation of the paraffins is better; for instance (molecule names aren't necessary): http://www.cs.wright.edu/~tkprasad/courses/cs776/paraffins-turner.pdf https://github.com/ghc/nofib/blob/master/imaginary/paraffins/Main.hs http://www.ccs.neu.edu/home/will/Twobit/src/paraffins.scm http://java.net/projects/projectfortress/sources/sources/content/ProjectFortress/demos/turnersParaffins0.fss?rev=3005

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Paraffins step by step in the Kotlin programming language

The code you provided is written in Kotlin and is a program that counts the number of unrooted and rooted trees with a given number of nodes.

The program uses a recursive function called tree to calculate the number of trees with a given number of nodes and a given number of branches. The function takes the following arguments:

  • br: The number of branches in the current tree.
  • n: The number of nodes in the current tree.
  • l: The length of the current tree.
  • s: The sum of the lengths of all the branches in the current tree.
  • cnt: The number of trees with the given number of nodes and branches that have already been counted.

The function tree first calculates the sum of the lengths of all the branches in the current tree. Then, it iterates over all possible values of b, which is the number of branches in the next tree. For each value of b, the function calculates the number of trees with the given number of nodes and branches that have already been counted, and it adds this number to the sum of the lengths of all the branches in the current tree.

If the sum of the lengths of all the branches in the current tree is greater than the maximum length of a tree, or if the length of the current tree is greater than twice the sum of the lengths of all the branches in the current tree, then the function returns. Otherwise, the function calculates the number of rooted and unrooted trees with the given number of nodes and branches, and it adds these numbers to the sum of the lengths of all the branches in the current tree.

The function bicenter calculates the number of bicentered trees with a given number of nodes. A bicentered tree is a tree with two centers, which are nodes that have the same number of descendants. The function bicenter takes the following argument:

  • s: The number of nodes in the tree.

The function bicenter first checks if the number of nodes in the tree is even. If it is, then the function calculates the number of rooted trees with half the number of nodes as the given tree. Then, the function adds this number to the sum of the lengths of all the branches in the given tree.

The function main calls the functions tree and bicenter to calculate the number of rooted and unrooted trees with a given number of nodes. The function main takes the following argument:

  • args: An array of strings that contains the command-line arguments.

The function main first iterates over all possible values of n, which is the number of nodes in the tree. For each value of n, the function calls the function tree to calculate the number of rooted and unrooted trees with n nodes. Then, the function calls the function bicenter to calculate the number of bicentered trees with n nodes. The function main prints the number of rooted and unrooted trees with n nodes to the console.

Source code in the kotlin programming language

// 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]}")
    }
}


  

You may also check:How to resolve the algorithm Copy a string step by step in the REBOL programming language
You may also check:How to resolve the algorithm ISBN13 check digit step by step in the J programming language
You may also check:How to resolve the algorithm 24 game/Solve step by step in the Yabasic programming language
You may also check:How to resolve the algorithm Loops/While step by step in the C programming language
You may also check:How to resolve the algorithm Active object step by step in the Scala programming language