CSharp (.Net) 📦

CSharp (.Net) 📦#

namespace DllFibonacci;

using System;

public class MyFiboClass
{
    public class FibonacciResult
    {
        public FbReturn Result { get; set; }
        public double GoldenNumber { get; set; }
    }
    public enum FbReturn
    {
        OK,
        TMT,
        TB,
        PRM_ERR
    }

    /// <summary>Checks if a number is prime.</summary>
    /// <param name="number">The number to check for primality.</param>
    /// <param name="maxFactor">The maximum factor to consider.</param>
    /// <returns>True if the number is prime, otherwise false.</returns>
    static bool IsPrime(ulong numberPrime, ulong maxFactor)
    {
        ulong maxSearch = (numberPrime < maxFactor) ? numberPrime : maxFactor;
        for (ulong i = 2; i < maxSearch; ++i)
        {
            if (numberPrime % i == 0)
                return false;
        }
        return true;
    }

    /// <summary>
    /// Performs factorization of a given number and populates arrays with the factors and their primality.
    /// </summary>
    /// <param name="arTerms">An array to store the factors.</param>
    /// <param name="arPrimes">An array to store the primality of factors.</param>
    /// <param name="baseIndex">The base index in the arrays to start storing factors.</param>
    /// <param name="maxFactor">The maximum factor to consider during factorization.</param>

    static void Factorization(ulong[] arTerms, bool[] arPrimes, int baseIndex, ulong maxFactor)
    {
        int position = 0;
        ulong result = arTerms[baseIndex];
        ulong testNbr = 2;

        while (result != 1)
        {
            if (result % (ulong)testNbr == 0)
            {
                position += 1;
                arTerms[baseIndex + position] = (ulong)testNbr;
                arPrimes[baseIndex + position] = IsPrime(testNbr, maxFactor);
                result /= (ulong)testNbr;
                if (position == 49)
                    break;
            }
            else
            {
                testNbr += 1;
                if (testNbr > maxFactor)
                    break;
            }
        }
    }

    /// <summary>
    /// Calculates Fibonacci sequences with additional information.
    /// </summary>
    /// <param name="fbStart">The starting value for the Fibonacci sequence.</param>
    /// <param name="maxTerms">The maximum number of terms in the Fibonacci sequence.</param>
    /// <param name="maxFibo">The maximum Fibonacci value allowed.</param>
    /// <param name="maxFactor">The maximum factor to consider during factorization.</param>
    /// <param name="nbrOfLoops">The number of loops to run the calculation.</param>
    /// <param name="arTerms">An array to store the terms of the Fibonacci sequence.</param>
    /// <param name="arPrimes">An array to store the primality of terms.</param>
    /// <param name="arError">An array to store error values.</param>
    /// <returns>A <see cref="FibonacciResult"/> object containing the result and the golden number.</returns>

    public static FibonacciResult fibonacci_interop_cs(ulong fbStart, byte maxTerms, ulong maxFibo, ulong maxFactor, byte nbrOfLoops,
        ulong[] arTerms, bool[] arPrimes, double[] arError)
    {
        double goldenNbr = 0;

        if (fbStart < 1 || maxFibo < 1 || maxTerms < 3 || maxFactor < 2 || nbrOfLoops < 1)
            return new FibonacciResult { Result = FbReturn.PRM_ERR, GoldenNumber = goldenNbr };

        if (maxTerms > 93)
            return new FibonacciResult { Result = FbReturn.TMT, GoldenNumber = goldenNbr };

        if (maxFibo > 18446744073709551615 || maxFactor > 18446744073709551615)
            return new FibonacciResult { Result = FbReturn.TB, GoldenNumber = goldenNbr };

        double goldenConst = (1 + Math.Sqrt(5)) / 2;

        for (int loop = 0; loop < nbrOfLoops; ++loop)
        {
            Array.Fill(arTerms, 0UL);
            arTerms[0] = arTerms[50] = (ulong)fbStart;
            Array.Fill(arPrimes, false);
            Array.Fill(arError, 0.0f);

            Factorization(arTerms, arPrimes, 0, maxFactor);
            Factorization(arTerms, arPrimes, 50, maxFactor);

            for (int currentTerm = 2; currentTerm < maxTerms; ++currentTerm)
            {
                int baseIndex = currentTerm * 50;
                ulong nextValue = arTerms[baseIndex - 50] + arTerms[baseIndex - 100];

                if (nextValue > (ulong)maxFibo)
                    return new FibonacciResult { Result = FbReturn.TB, GoldenNumber = goldenNbr };

                arTerms[baseIndex] = nextValue;
                arPrimes[baseIndex] = IsPrime(arTerms[baseIndex], maxFactor);
                arError[currentTerm] =
                    Math.Abs((float)(goldenConst - ((double)arTerms[baseIndex] / arTerms[baseIndex - 50])));
                Factorization(arTerms, arPrimes, baseIndex, maxFactor);
            }

            goldenNbr = (double)arTerms[(maxTerms - 1) * 50] / arTerms[(maxTerms - 2) * 50];
        }

        return new FibonacciResult { Result = FbReturn.OK, GoldenNumber = goldenNbr };
    }
}