Fibonacci and Identity functions
This commit is contained in:
parent
5556010c91
commit
7864da2701
2 changed files with 304 additions and 0 deletions
76
src/StandardLibrary/Functions/NumberTheory/Fibonacci.cs
Normal file
76
src/StandardLibrary/Functions/NumberTheory/Fibonacci.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CSMic.StandardLibrary.Functions.NumberTheory
|
||||
{
|
||||
/// <summary> </summary>
|
||||
public class Fibonacci : FunctionBase, ICodedFunction
|
||||
{
|
||||
|
||||
/// <summary> A pre-computed array of the first 140 numbers of the fibonacci sequence. </summary>
|
||||
private static decimal[] fibonacciSequence =
|
||||
[0m, 1m, 1m, 2m, 3m, 5m, 8m, 13m, 21m, 34m, 55m, 89m, 144m, 233m, 377m, 610m,
|
||||
987m, 1597m, 2584m, 4181m, 6765m, 10946m, 17711m, 28657m, 46368m, 75025m, 121393m,
|
||||
196418m, 317811m, 514229m, 832040m, 1346269m, 2178309m, 3524578m, 5702887m, 9227465m,
|
||||
14930352m, 24157817m, 39088169m, 63245986m, 102334155m, 165580141m, 267914296m,
|
||||
433494437m, 701408733m, 1134903170m, 1836311903m, 2971215073m, 4807526976m, 7778742049m,
|
||||
12586269025m, 20365011074m, 32951280099m, 53316291173m, 86267571272m, 139583862445m,
|
||||
225851433717m, 365435296162m, 591286729879m, 956722026041m, 1548008755920m, 2504730781961m,
|
||||
4052739537881m, 6557470319842m, 10610209857723m, 17167680177565m, 27777890035288m,
|
||||
44945570212853m, 72723460248141m, 117669030460994m, 190392490709135m, 308061521170129m,
|
||||
498454011879264m, 806515533049393m, 1304969544928657m, 2111485077978050m, 3416454622906707m,
|
||||
5527939700884757m, 8944394323791464m, 14472334024676221m, 23416728348467685m, 37889062373143906m,
|
||||
61305790721611591m, 99194853094755497m, 160500643816367088m, 259695496911122585m,
|
||||
420196140727489673m, 679891637638612258m, 1100087778366101931m, 1779979416004714189m,
|
||||
2880067194370816120m, 4660046610375530309m, 7540113804746346429m, 12200160415121876738m,
|
||||
19740274219868223167m, 31940434634990099905m, 51680708854858323072m, 83621143489848422977m,
|
||||
135301852344706746049m, 218922995834555169026m, 354224848179261915075m, 573147844013817084101m,
|
||||
927372692193078999176m, 1500520536206896083277m, 2427893228399975082453m, 3928413764606871165730m,
|
||||
6356306993006846248183m, 10284720757613717413913m, 16641027750620563662096m,
|
||||
26925748508234281076009m, 43566776258854844738105m, 70492524767089125814114m,
|
||||
114059301025943970552219m, 184551825793033096366333m, 298611126818977066918552m,
|
||||
483162952612010163284885m, 781774079430987230203437m, 1264937032042997393488322m,
|
||||
2046711111473984623691759m, 3311648143516982017180081m, 5358359254990966640871840m,
|
||||
8670007398507948658051921m, 14028366653498915298923761m, 22698374052006863956975682m,
|
||||
36726740705505779255899443m, 59425114757512643212875125m, 96151855463018422468774568m,
|
||||
155576970220531065681649693m, 251728825683549488150424261m, 407305795904080553832073954m,
|
||||
659034621587630041982498215m, 1066340417491710595814572169m, 1725375039079340637797070384m,
|
||||
2791715456571051233611642553m, 4517090495650391871408712937m, 7308805952221443105020355490m,
|
||||
11825896447871834976429068427m, 19134702400093278081449423917m, 30960598847965113057878492344m,
|
||||
50095301248058391139327916261m];
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "fib";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<FunctionArgument> ExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new FunctionArgument("index", FunctionValue.NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
public FunctionValue Execute(params FunctionArgument[] args)
|
||||
{
|
||||
return base.Execute(args, (_args) =>
|
||||
{
|
||||
var input = _args[0].Value;
|
||||
|
||||
int index = Convert.ToInt32(input);
|
||||
|
||||
if(index <= 0 || index > 140)
|
||||
{
|
||||
return FunctionValue.ZERO;
|
||||
}
|
||||
|
||||
return new FunctionValue(FunctionValueType.Numeric, fibonacciSequence[index]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
228
src/StandardLibrary/Functions/NumberTheory/Identity.cs
Normal file
228
src/StandardLibrary/Functions/NumberTheory/Identity.cs
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CSMic.StandardLibrary.Functions.NumberTheory
|
||||
{
|
||||
public class IsEven : FunctionBase, ICodedFunction
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "iseven";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<FunctionArgument> ExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new FunctionArgument("value", FunctionValue.NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
public FunctionValue Execute(params FunctionArgument[] args)
|
||||
{
|
||||
return base.Execute(args, (_args) =>
|
||||
{
|
||||
var input = _args[0].Value;
|
||||
|
||||
decimal value = Convert.ToDecimal(input);
|
||||
|
||||
return new FunctionValue(FunctionValueType.Numeric, IsEven.CalculateIsEven(value) ? 1m : 0m);
|
||||
});
|
||||
}
|
||||
|
||||
internal static bool CalculateIsEven(decimal value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class IsOdd : FunctionBase, ICodedFunction
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "isodd";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<FunctionArgument> ExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new FunctionArgument("value", FunctionValue.NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
public FunctionValue Execute(params FunctionArgument[] args)
|
||||
{
|
||||
return base.Execute(args, (_args) =>
|
||||
{
|
||||
var input = _args[0].Value;
|
||||
|
||||
decimal value = Convert.ToDecimal(input);
|
||||
|
||||
return new FunctionValue(FunctionValueType.Numeric, IsEven.CalculateIsEven(value) ? 0m : 1m);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class IsInt : FunctionBase, ICodedFunction
|
||||
{
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "isint";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<FunctionArgument> ExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new FunctionArgument("value", FunctionValue.NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
public FunctionValue Execute(params FunctionArgument[] args)
|
||||
{
|
||||
return base.Execute(args, (_args) =>
|
||||
{
|
||||
var input = _args[0].Value;
|
||||
|
||||
decimal value = Convert.ToDecimal(input);
|
||||
|
||||
return new FunctionValue(FunctionValueType.Numeric, CalculateIsInt(value) ? 1m : 0m);
|
||||
});
|
||||
}
|
||||
|
||||
internal static bool CalculateIsInt(decimal value)
|
||||
{
|
||||
return value == decimal.Truncate(value);
|
||||
}
|
||||
}
|
||||
|
||||
public class IsPrime : FunctionBase, ICodedFunction
|
||||
{
|
||||
private const int MaxPrimeCacheSize = 4096;
|
||||
|
||||
/// <summary>
|
||||
/// (Immutable) The prime cache lock. Concurrency needs to be enforced here because caching is
|
||||
/// transparent to library consumers and race conditions could be invisible at run-time.
|
||||
/// </summary>
|
||||
private static readonly object PrimeCacheLock = new object();
|
||||
private static readonly Dictionary<decimal, bool> PrimeCache =
|
||||
new Dictionary<decimal, bool>();
|
||||
|
||||
private static readonly Queue<decimal> PrimeCacheOrder =
|
||||
new Queue<decimal>();
|
||||
|
||||
private static readonly bool[] knownPrime = [
|
||||
false, false, true, true, false, true, false, true, false, false,
|
||||
false, true, false, true, false, false, false, true, false, true,
|
||||
false, false, false, true, false, false, false, false, false, true,
|
||||
false, true, false, false, false, false, false, true, false, false,
|
||||
false, true, false, true, false, false, false, true, false, false,
|
||||
false, false, false, true, false, false, false, false, false, true,
|
||||
false, true, false, false, false, false, false, true, false, false,
|
||||
false, true, false, true, false, false, false, false, false, true,
|
||||
false, false, false, true, false, false, false, false, false, true,
|
||||
false, false, false, false, false, false, false, true, false, false];
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return "isprime";
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<FunctionArgument> ExpectedArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new FunctionArgument("value", FunctionValue.NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
public FunctionValue Execute(params FunctionArgument[] args)
|
||||
{
|
||||
return base.Execute(args, (_args) =>
|
||||
{
|
||||
var input = _args[0].Value;
|
||||
|
||||
decimal value = Convert.ToDecimal(input);
|
||||
|
||||
return new FunctionValue(FunctionValueType.Numeric, CalculateIsPrime(value) ? 1m : 0m);
|
||||
});
|
||||
}
|
||||
|
||||
internal static bool CalculateIsPrime(decimal value)
|
||||
{
|
||||
if (!IsInt.CalculateIsInt(value) || value < 2m)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (value < knownPrime.Length)
|
||||
{
|
||||
return knownPrime[(int)value];
|
||||
}
|
||||
|
||||
if (TryGetCachedPrime(value, out bool cached))
|
||||
{
|
||||
return cached;
|
||||
}
|
||||
|
||||
if (value % 2m == 0m)
|
||||
{
|
||||
AddPrimeCache(value, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (decimal i = 3; i * i <= value; i += 2m)
|
||||
{
|
||||
if (value % i == 0m)
|
||||
{
|
||||
AddPrimeCache(value, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
AddPrimeCache(value, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TryGetCachedPrime(decimal value, out bool result)
|
||||
{
|
||||
lock (PrimeCacheLock)
|
||||
{
|
||||
return PrimeCache.TryGetValue(value, out result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddPrimeCache(decimal value, bool result)
|
||||
{
|
||||
lock (PrimeCacheLock)
|
||||
{
|
||||
if (PrimeCache.ContainsKey(value))
|
||||
return;
|
||||
|
||||
while (PrimeCache.Count >= MaxPrimeCacheSize)
|
||||
{
|
||||
decimal oldest = PrimeCacheOrder.Dequeue();
|
||||
PrimeCache.Remove(oldest);
|
||||
}
|
||||
|
||||
PrimeCache[value] = result;
|
||||
PrimeCacheOrder.Enqueue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue