Calculate the sequence : n!/ (1+1/2+1/3+...+1/n) - c#

Calculate the following sum
1!/1 + 2!/(1+1/2) + 3!/(1+1/2+1/3) + ... + n!/ (1+1/2+1/3+...+1/n), where n > 0.
public static double GetSumSix(int n)
{
double i, result = 0.0;
static double factorial(double n)
{
double res = 1;
for (double i = 2; i <= n; i++)
res *= i;
return res;
}
for (i = 1.0; i <= n; i++)
{
result += factorial(i) / (1.0 / i);
}
return result;
}
Help me please , I don't understand why is my solution not working?

Your denominator logic is incorrect. You could create another function to work out what '1/1+1/2+...+1/n' is and use that in the denominator? right now your code will work out 1+2!*2+3!*3+...
You could actually use something similar to your factorial method
static double GetDenominator(double n)
{
double res = 1;
for (double i = 2; i <= n; i++)
//insert code here
return res;
}

The Lemon's answer is correct, you're not accumulating the denominator of the sequence so what you were calculating was:
f(n) = 1!/1 + 2!/(1/2) + 3!/(1/3) + ... n!/(1/n)
Since both the numerator and denominator of each term are algorithmically linked to the values in the prior term you can simply update them each pass through the loop. This is (slightly) faster and fairly easy to read.
public static double GetSumSix(int n)
{
double factorial = 1;
double denominator = 1;
double accum = 1;
for (int i = 2; i <= n; i++)
{
factorial *= i;
denominator += 1.0d/i;
accum += factorial / denominator;
}
return accum;
}

Your logic is not correct as per your question , also your code won't execute as you have a function inside your GetSumSix function. I have put some helping points in below code so you will understand how the logic works.
using System;
public class Program
{
public static void Main()
{
var Calculate = GetSumSix(3);
Console.WriteLine("The Answer is " + Calculate);
}
public static double GetSumSix(int n)
{
int i;
double result = 0.0;
int factorial = 1;
string calculatedFormula = String.Empty;
string FinalFormat = String.Empty;
//Find n!
for(int x=n;x>=1;x--)
{
factorial *= x;
}
// Find Denominator (1+1/2+1/3+…+1/n)
for (i = 1.0; i <= n; i++)
{
result += GetDenominator(i, ref calculatedFormula);
FinalFormat += calculatedFormula;
}
result = factorial/result;
Console.WriteLine("Calculated Formula is:"+ factorial +"/(" + FinalFormat +")When N is :" + n);
return result;
}
public static double GetDenominator(double n, ref string cal)
{
if (n == 1)
{
cal += n + "+ ";
return 1;
}
else
{
cal = "1/" + n + "+ ";
return 1 / n;
}
}
}
Thanks.

Related

Does the compiler optimize away if statements inside loop

I'm going through another programmers code and see the following function (and several variations, are called inside a massive loop and in the critical path) and I'm wondering if the c# compiler is smart enough to optimize it:
public double SomeFunction(double p_lower, double p_upper) {
double result = 0.0;
int low = (int)Math.Ceiling(p_lower);
int high = (int)Math.Ceiling(p_upper);
for( int i = low; i <= high; ++i){
double dbl_low;
double dbl_high;
if (i == low && i == high) {
dbl_low = p_lower; // corrected from low in original post
dbl_high = p_upper; // corrected from high original post
} else if (i == low) {
dbl_low = p_lower;
dbl_high = i;
} else if (i == high) {
dbl_low = i - 1;
dbl_high = p_upper;
} else {
dbl_low = i - 1;
dbl_high = i;
}
if (dbl_low != dbl_high) {
result += f(dbl_low,dbl_high);
}
}
return result;
}
What this function does is clear, the range from p_lower to p_upper is split up three parts:
Fraction up to the first integer, steps of 1 until the last integer, fraction from last integer to p_upper and call a function on those intervals.
The first condition is the edge case where the both lower and upper are within the same unit interval (correction from original)
My instinct (from when I learned to program and compilers were horrible) would be to rewrite the code as this:
public double SomeFunction2(double p_lower, double p_upper) {
if(p_upper < p_lower){
return 0.0;
}
double result = 0.0;
double low = Math.Ceiling(p_lower);
double high = Math.Ceiling(p_upper);
/// edge case
if (Math.Abs(low - high) < 0.00001) {
return Math.Abs(p_upper-p_lower)< 0.00001? 0.0 : f(p_lower, p_upper);
}
/// first fraction
result += Math.Abs(low - p_lower)< 0.00001? 0.0 : f(p_lower, low);
/// whole intervals
for( double i = low + 1.0; i < high; ++i){ // < instead of <=
result += f(i-1.0, i);
}
/// add last fraction and return
return result + f(high - 1.0, p_upper);
}
This way, there is not a whole cascade of conditional statements that is evaluated every loop, the first of which will always be false after the first, the second will always be true except for the final one. In fact there is no conditional in the loop, since the last condition has been incorporated in the loop range.
The loop counter is a double which should not be an issue since the range for low and high is 0.0 ... 120.0 all of which are exact as a double.
Am I wasting my time and does the compiler handle all this and is all I gain some readability?
I changed your second function a bit to improve readability:
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Stopwatch sw = new Stopwatch();
const int COUNT = 10000000;
double[] lowers = new double[COUNT];
double[] uppers = new double[COUNT];
double[] result = new double[COUNT];
double[] result2 = new double[COUNT];
Random random = new Random();
for (int i = 0; i < COUNT; i++)
{
lowers[i] = Math.Round(random.NextDouble() * 60.0, 2);
uppers[i] = lowers[i] + Math.Round(random.NextDouble() * 40.0,2);
}
sw.Start();
for (int i = 0; i < COUNT; i++)
{
result[i] = SomeFunction(lowers[i], uppers[i]);
}
sw.Stop();
Console.WriteLine("Elapsed Time for SomeFunction is {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < COUNT; i++)
{
result2[i] = SomeFunction2(lowers[i], uppers[i]);
}
sw.Stop();
Console.WriteLine("Elapsed Time for SomeFunction2 is {0} ms", sw.ElapsedMilliseconds);
for (int i = 0; i < COUNT; i++)
{
if (result[i] != result2[i])
{
Console.WriteLine("i: {0}",i);
}
}
}
public static double SomeFunction(double p_lower, double p_upper) {
double result = 0.0;
int low = (int)Math.Ceiling(p_lower);
int high = (int)Math.Ceiling(p_upper);
for(int i = low; i <= high; ++i){
double dbl_low;
double dbl_high;
if (i == low && i == high) {
dbl_low = p_lower;
dbl_high = p_upper;
} else if (i == low) {
dbl_low = p_lower;
dbl_high = i;
} else if (i == high) {
dbl_low = i - 1;
dbl_high = p_upper;
} else {
dbl_low = i - 1;
dbl_high = i;
}
if (dbl_low != dbl_high) {
result += f(dbl_low,dbl_high);
}
}
return result;
}
public static double SomeFunction2(double p_lower, double p_upper) {
double result = 0.0;
if (p_upper <= p_lower) {
return result;
}
double low = Math.Ceiling(p_lower);
double high = Math.Ceiling(p_upper);
/// edge case
if (high == low) {
return f(p_lower, p_upper);
}
/// first fraction
if (low > p_lower) {
result += f(p_lower, low);
}
/// whole intervals
for (int i = (int)low + 1; i < high; ++i){
result += f(i-1.0, i);
}
/// add last fraction and return
return result + f(high - 1.0, p_upper);
}
// Simple function f(a,b) for test purpose
public static double f(double a, double b)
{
return a + b;
}
}
Running this several times gave me:
3680 ms / 1863 ms -> 49%
2362 ms / 1441 ms -> 39%
3175 ms / 2030 ms -> 36%
2956 ms / 1531 ms -> 48%
So it stays quite close in terms of performance
The answer is that the latest MS c# compiler does not optimize this code fully.
I added large arrays of random numbers to Rafalon's program as a crude benchmark.
With this simple addition function the time difference is ~1950ms for SomeFunction and ~1160ms for Somefunction2. A 40% reduction in execution time by simply moving conditionals out of the loop.
Thanks to the people pointing out the error in transcribing the original functions and pointing out there were errors/I had misunderstood part of the original function I managed to get a new function that passes all our unit tests.
using System;
using System.Diagnostics;
class Program
{
static void Main()
{
Stopwatch sw = new Stopwatch();
const int COUNT = 10000000;
double[] lowers = new double[COUNT];
double[] uppers = new double[COUNT];
double[] result = new double[COUNT];
double[] result2 = new double[COUNT];
double sumerror = 0.0;
Random random = new Random();
for (int i = 0; i < COUNT; i++)
{
lowers[i] = Math.Round(random.NextDouble() * 60.0, 2);
uppers[i] = lowers[i] + Math.Round(random.NextDouble() * 40.0,2);
}
sw.Start();
for (int i = 0; i < COUNT; i++)
{
result[i] = SomeFunction(lowers[i], uppers[i]);
}
sw.Stop();
Console.WriteLine("Elapsed Time for SomeFunction is {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < COUNT; i++)
{
result2[i] = SomeFunction2(lowers[i], uppers[i]);
}
sw.Stop();
Console.WriteLine("Elapsed Time for SomeFunction2 is {0} ms", sw.ElapsedMilliseconds);
for (int i = 0; i < COUNT; i++)
{
sumerror += (result[i] - result2[i]);
if (Math.Abs(result[i] - result2[i])> 0.0001)
{
Console.WriteLine("i: {0}",i);
}
}
Console.WriteLine(sumerror); // should be zero, and we now use the results so no optimizing everything away.
}
public static double SomeFunction(double p_lower, double p_upper) {
double result = 0.0;
int low = (int)Math.Ceiling(p_lower);
int high = (int)Math.Ceiling(p_upper);
for(int i = low; i <= high; ++i){
double dbl_low;
double dbl_high;
if (i == low && i == high) {
dbl_low = p_lower;
dbl_high = p_upper;
} else if (i == low) {
dbl_low = p_lower;
dbl_high = i;
} else if (i == high) {
dbl_low = i - 1;
dbl_high = p_upper;
} else {
dbl_low = i - 1;
dbl_high = i;
}
if (dbl_low != dbl_high) {
result += f(dbl_low,dbl_high);
}
}
return result;
}
public static double SomeFunction2(double p_lower, double p_upper) {
double result = 0.0;
double low = Math.Ceiling(p_lower);
double high = Math.Ceiling(p_upper);
/// edge case
if (Math.Abs(high - low) < 0.00001) {
return Math.Abs(p_upper-p_lower)< 0.00001? 0.0 : f(p_lower, p_upper);
}
/// first fraction
result += Math.Abs(low - p_lower)< 0.00001? 0.0 : f(p_lower, low);
/// whole intervals
for( int i = (int)low + 1; i < high; ++i){
result += f(i-1.0, i);
}
/// add last fraction and return
return result + f(high - 1.0, p_upper);
}
// Simple function f(a,b) for test purpose
public static double f(double a, double b)
{
return a + b;
}
}

Laplace Transform And Getting The Frequent Value For Gyro

I'm getting x,y,z values from gyro-sensor. Each variable is being sent 10 values per second. In 3 seconds I have;
x=[30values]
y=[30values]
z=[30values]
Some of the values are too different from the others cause of noise. With laplace transform I need to get the most frequent value from my array.
I need to filter the array with Laplace Transform equation. I need to build the equation in C#. How can I implement the array with the equation?
Since this kind of filter (Laplace) is very specialized to certain area of Engineering and needs a person who has good understanding on both the programming language (in this case is C#) and the filter itself, I would recommend you to use such source, rather than code the filter by yourself.
Here is the snippet of the source code:
class Laplace
{
const int DefaultStehfest = 14;
public delegate double FunctionDelegate(double t);
static double[] V; // Stehfest coefficients
static double ln2; // log of 2
public static void InitStehfest(int N)
{
ln2 = Math.Log(2.0);
int N2 = N / 2;
int NV = 2 * N2;
V = new double[NV];
int sign = 1;
if ((N2 % 2) != 0)
sign = -1;
for (int i = 0; i < NV; i++)
{
int kmin = (i + 2) / 2;
int kmax = i + 1;
if (kmax > N2)
kmax = N2;
V[i] = 0;
sign = -sign;
for (int k = kmin; k <= kmax; k++)
{
V[i] = V[i] + (Math.Pow(k, N2) / Factorial(k)) * (Factorial(2 * k)
/ Factorial(2 * k - i - 1)) / Factorial(N2 - k)
/ Factorial(k - 1) / Factorial(i + 1 - k);
}
V[i] = sign * V[i];
}
}
public static double InverseTransform(FunctionDelegate f, double t)
{
double ln2t = ln2 / t;
double x = 0;
double y = 0;
for (int i = 0; i < V.Length; i++)
{
x += ln2t;
y += V[i] * f(x);
}
return ln2t * y;
}
public static double Factorial(int N)
{
double x = 1;
if (N > 1)
{
for (int i = 2; i <= N; i++)
x = i * x;
}
return x;
}
}
coded by Mr. Walt Fair Jr. in CodeProject.

0-1 Knapsack algorithm

Is the following 0-1 Knapsack problem solvable:
'float' positive values and
'float' weights (can be positive or negative)
'float' capacity of the knapsack > 0
I have on average < 10 items, so I'm thinking of using a brute force implementation. However, I was wondering if there is a better way of doing it.
This is a relatively simple binary program.
I'd suggest brute force with pruning. If at any time you exceed the allowable weight, you don't need to try combinations of additional items, you can discard the whole tree.
Oh wait, you have negative weights? Include all negative weights always, then proceed as above for the positive weights. Or do the negative weight items also have negative value?
Include all negative weight items with positive value. Exclude all items with positive weight and negative value.
For negative weight items with negative value, subtract their weight (increasing the knapsack capavity) and use a pseudo-item which represents not taking that item. The pseudo-item will have positive weight and value. Proceed by brute force with pruning.
class Knapsack
{
double bestValue;
bool[] bestItems;
double[] itemValues;
double[] itemWeights;
double weightLimit;
void SolveRecursive( bool[] chosen, int depth, double currentWeight, double currentValue, double remainingValue )
{
if (currentWeight > weightLimit) return;
if (currentValue + remainingValue < bestValue) return;
if (depth == chosen.Length) {
bestValue = currentValue;
System.Array.Copy(chosen, bestItems, chosen.Length);
return;
}
remainingValue -= itemValues[depth];
chosen[depth] = false;
SolveRecursive(chosen, depth+1, currentWeight, currentValue, remainingValue);
chosen[depth] = true;
currentWeight += itemWeights[depth];
currentValue += itemValues[depth];
SolveRecursive(chosen, depth+1, currentWeight, currentValue, remainingValue);
}
public bool[] Solve()
{
var chosen = new bool[itemWeights.Length];
bestItems = new bool[itemWeights.Length];
bestValue = 0.0;
double totalValue = 0.0;
foreach (var v in itemValues) totalValue += v;
SolveRecursive(chosen, 0, 0.0, 0.0, totalValue);
return bestItems;
}
}
Yeah, brute force it. This is an NP-Complete problem, but that shouldn't matter because you will have less than 10 items. Brute forcing won't be problematic.
var size = 10;
var capacity = 0;
var permutations = 1024;
var repeat = 10000;
// Generate items
float[] items = new float[size];
float[] weights = new float[size];
Random rand = new Random();
for (int i = 0; i < size; i++)
{
items[i] = (float)rand.NextDouble();
weights[i] = (float)rand.NextDouble();
if (rand.Next(2) == 1)
{
weights[i] *= -1;
}
}
// solution
int bestPosition= -1;
Stopwatch sw = new Stopwatch();
sw.Start();
// for perf testing
//for (int r = 0; r < repeat; r++)
{
var bestValue = 0d;
// solve
for (int i = 0; i < permutations; i++)
{
var total = 0d;
var weight = 0d;
for (int j = 0; j < size; j++)
{
if (((i >> j) & 1) == 1)
{
total += items[j];
weight += weights[j];
}
}
if (weight <= capacity && total > bestValue)
{
bestPosition = i;
bestValue = total;
}
}
}
sw.Stop();
sw.Elapsed.ToString();
If you can only have positive values then every item with a negative weight must go in.
Then I guess you could calculate Value/Weight Ratio, and brute force the remaining combinations based on that order, once you get one that fits you can skip the rest.
The problem may be that the grading and sorting is actually more expensive than just doing all the calculations.
There will obviously be a different breakeven point based on the size and distribution of the set.
public class KnapSackSolver {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]); // number of items
int W = Integer.parseInt(args[1]); // maximum weight of knapsack
int[] profit = new int[N + 1];
int[] weight = new int[N + 1];
// generate random instance, items 1..N
for (int n = 1; n <= N; n++) {
profit[n] = (int) (Math.random() * 1000);
weight[n] = (int) (Math.random() * W);
}
// opt[n][w] = max profit of packing items 1..n with weight limit w
// sol[n][w] = does opt solution to pack items 1..n with weight limit w
// include item n?
int[][] opt = new int[N + 1][W + 1];
boolean[][] sol = new boolean[N + 1][W + 1];
for (int n = 1; n <= N; n++) {
for (int w = 1; w <= W; w++) {
// don't take item n
int option1 = opt[n - 1][w];
// take item n
int option2 = Integer.MIN_VALUE;
if (weight[n] <= w)
option2 = profit[n] + opt[n - 1][w - weight[n]];
// select better of two options
opt[n][w] = Math.max(option1, option2);
sol[n][w] = (option2 > option1);
}
}
// determine which items to take
boolean[] take = new boolean[N + 1];
for (int n = N, w = W; n > 0; n--) {
if (sol[n][w]) {
take[n] = true;
w = w - weight[n];
} else {
take[n] = false;
}
}
// print results
System.out.println("item" + "\t" + "profit" + "\t" + "weight" + "\t"
+ "take");
for (int n = 1; n <= N; n++) {
System.out.println(n + "\t" + profit[n] + "\t" + weight[n] + "\t"
+ take[n]);
}
}
}
import java.util.*;
class Main{
static int max(inta,int b)
{
if(a>b)
return a;
else
return b;
}
public static void main(String args[])
{
int n,i,cap,j,t=2,w;
Scanner sc=new Scanner(System.in);
System.out.println("Enter the number of values ");
n=sc.nextInt();
int solution[]=new int[n];
System.out.println("Enter the capacity of the knapsack :- ");
cap=sc.nextInt();
int v[]=new int[n+1];
int wt[]=new int[n+1];
System.out.println("Enter the values ");
for(i=1;i<=n;i++)
{
v[i]=sc.nextInt();
}
System.out.println("Enter the weights ");
for(i=1;i<=n;i++)
{
wt[i]=sc.nextInt();
}
int knapsack[][]=new int[n+2][cap+1];
for(i=1;i<n+2;i++)
{
for(j=1;j<n+1;j++)
{
knapsack[i][j]=0;
}
}
/*for(i=1;i<n+2;i++)
{
for(j=wt[1]+1;j<cap+2;j++)
{
knapsack[i][j]=v[1];
}
}*/
int k;
for(i=1;i<n+1;i++)
{
for(j=1;j<cap+1;j++)
{
/*if(i==1||j==1)
{
knapsack[i][j]=0;
}*/
if(wt[i]>j)
{
knapsack[i][j]=knapsack[i-1][j];
}
else
{
knapsack[i][j]=max(knapsack[i-1][j],v[i]+knapsack[i-1][j-wt[i]]);
}
}
}
//for displaying the knapsack
for(i=0;i<n+1;i++)
{
for(j=0;j<cap+1;j++)
{
System.out.print(knapsack[i][j]+" ");
}
System.out.print("\n");
}
w=cap;k=n-1;
j=cap;
for(i=n;i>0;i--)
{
if(knapsack[i][j]!=knapsack[i-1][j])
{
j=w-wt[i];
w=j;
solution[k]=1;
System.out.println("k="+k);
k--;
}
else
{
solution[k]=0;
k--;
}
}
System.out.println("Solution for given knapsack is :- ");
for(i=0;i<n;i++)
{
System.out.print(solution[i]+", ");
}
System.out.print(" => "+knapsack[n][cap]);
}
}
This can be solved using Dynamic Programming. Below code can help you solve the 0/1 Knapsack problem using Dynamic Programming.
internal class knapsackProblem
{
private int[] weight;
private int[] profit;
private int capacity;
private int itemCount;
private int[,] data;
internal void GetMaxProfit()
{
ItemDetails();
data = new int[itemCount, capacity + 1];
for (int i = 1; i < itemCount; i++)
{
for (int j = 1; j < capacity + 1; j++)
{
int q = j - weight[i] >= 0 ? data[i - 1, j - weight[i]] + profit[i] : 0;
if (data[i - 1, j] > q)
{
data[i, j] = data[i - 1, j];
}
else
{
data[i, j] = q;
}
}
}
Console.WriteLine($"\nMax profit can be made : {data[itemCount-1, capacity]}");
IncludedItems();
}
private void ItemDetails()
{
Console.Write("\nEnter the count of items to be inserted : ");
itemCount = Convert.ToInt32(Console.ReadLine()) + 1;
Console.WriteLine();
weight = new int[itemCount];
profit = new int[itemCount];
for (int i = 1; i < itemCount; i++)
{
Console.Write($"Enter weight of item {i} : ");
weight[i] = Convert.ToInt32(Console.ReadLine());
Console.Write($"Enter the profit on the item {i} : ");
profit[i] = Convert.ToInt32(Console.ReadLine());
Console.WriteLine();
}
Console.Write("\nEnter the capacity of the knapsack : ");
capacity = Convert.ToInt32(Console.ReadLine());
}
private void IncludedItems()
{
int i = itemCount - 1;
int j = capacity;
while(i > 0)
{
if(data[i, j] == data[i - 1, j])
{
Console.WriteLine($"Item {i} : Not included");
i--;
}
else
{
Console.WriteLine($"Item {i} : Included");
j = j - weight[i];
i--;
}
}
}
}

C# fibonacci function returning errors

I am practising a C# console application, and I am trying to get the function to verify if the number appears in a fibonacci series or not but I'm getting errors.
What I did was:
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(isFibonacci(20));
}
static int isFibonacci(int n)
{
int[] fib = new int[100];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i <= 100; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (n == fib[i])
{
return 1;
}
}
return 0;
}
}
Can anybody tell me what am I doing wrong here?
Here's a fun solution using an infinite iterator block:
IEnumerable<int> Fibonacci()
{
int n1 = 0;
int n2 = 1;
yield return 1;
while (true)
{
int n = n1 + n2;
n1 = n2;
n2 = n;
yield return n;
}
}
bool isFibonacci(int n)
{
foreach (int f in Fibonacci())
{
if (f > n) return false;
if (f == n) return true;
}
}
I actually really like this kind of Fibonacci implementation vs the tradition recursive solution, because it keeps the work used to complete a term available to complete the next. The traditional recursive solution duplicates some work, because it needs two recursive calls each term.
The problem lies in <= the following statement:
for (int i = 2; i <= 100; i++)
more to the point the =. There is no fib[100] (C# zero counts) so when you check on i=100 you get an exception.
the proper statement should be
for (int i = 2; i < 100; i++)
or even better
for (int i = 2; i < fib.Length; i++)
And here is a solution that beats all of yours!
Because, why iteration when you have smart mathematicians doing closed-form solutions for you? :)
static bool IsFibonacci(int number)
{
//Uses a closed form solution for the fibonacci number calculation.
//http://en.wikipedia.org/wiki/Fibonacci_number#Closed-form_expression
double fi = (1 + Math.Sqrt(5)) / 2.0; //Golden ratio
int n = (int) Math.Floor(Math.Log(number * Math.Sqrt(5) + 0.5, fi)); //Find's the index (n) of the given number in the fibonacci sequence
int actualFibonacciNumber = (int)Math.Floor(Math.Pow(fi, n) / Math.Sqrt(5) + 0.5); //Finds the actual number corresponding to given index (n)
return actualFibonacciNumber == number;
}
Well, for starters your array is only 10 long and you're filling it with ~100 items (out-of-range-exception) - but there are better ways to do this...
for example, using this post:
long val = ...
bool isFib = Fibonacci().TakeWhile(x => x <= val).Last() == val;
int[] fib = new int[10];
for (int i = 2; i <= *100*; i++)
You're going out of the bounds of your array because your loop conditional is too large. A more traditional approach would be to bound the loop by the size of the array:
for (int i = 2; i < fib.Length; i++)
And make your array bigger, but as Marc said, there are better ways to do this, and I would advise you spend some time reading the wikipedia article on Fibonacci numbers.
One thing you can do is check for an early exit. Since you're trying to determine if a given number is in the Fibonacci sequence, you can do bounds checking to exit early.
Example:
static bool isFibonacci(int n)
{
int[] fib = new int[100];
fib[0] = 1;
fib[1] = 1;
for (int i = 2; i <= fib.Length; i++)
{
fib[i] = fib[i - 1] + fib[i - 2];
if (n == fib[i])
{
return true;
}
else if (n < fib[i])
{
return false; //your number has been surpassed in the fib seq
}
}
return false;
}
public static int FibNo(int n) {
int result = 0; int No = 0; int N1 = 1;
if (n< 0)
{ throw new ArguementException("number must be a positive value"); }
if (n <= 1)
{ result = n; return result; }
for(int x=1; x < n; x++)
{ result = No + N1; No = N1; N1=result; }
return result;
}

Sum of digits in C#

What's the fastest and easiest to read implementation of calculating the sum of digits?
I.e. Given the number: 17463 = 1 + 7 + 4 + 6 + 3 = 21
You could do it arithmetically, without using a string:
sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}
I use
int result = 17463.ToString().Sum(c => c - '0');
It uses only 1 line of code.
For integer numbers, Greg Hewgill has most of the answer, but forgets to account for the n < 0. The sum of the digits of -1234 should still be 10, not -10.
n = Math.Abs(n);
sum = 0;
while (n != 0) {
sum += n % 10;
n /= 10;
}
It the number is a floating point number, a different approach should be taken, and chaowman's solution will completely fail when it hits the decimal point.
public static int SumDigits(int value)
{
int sum = 0;
while (value != 0)
{
int rem;
value = Math.DivRem(value, 10, out rem);
sum += rem;
}
return sum;
}
int num = 12346;
int sum = 0;
for (int n = num; n > 0; sum += n % 10, n /= 10) ;
I like the chaowman's response, but would do one change
int result = 17463.ToString().Sum(c => Convert.ToInt32(c));
I'm not even sure the c - '0', syntax would work? (substracting two characters should give a character as a result I think?)
I think it's the most readable version (using of the word sum in combination with the lambda expression showing that you'll do it for every char). But indeed, I don't think it will be the fastest.
I thought I'd just post this for completion's sake:
If you need a recursive sum of digits, e.g: 17463 -> 1 + 7 + 4 + 6 + 3 = 21 -> 2 + 1 = 3
then the best solution would be
int result = input % 9;
return (result == 0 && input > 0) ? 9 : result;
int n = 17463; int sum = 0;
for (int i = n; i > 0; i = i / 10)
{
sum = sum + i % 10;
}
Console.WriteLine(sum);
Console.ReadLine();
I would suggest that the easiest to read implementation would be something like:
public int sum(int number)
{
int ret = 0;
foreach (char c in Math.Abs(number).ToString())
ret += c - '0';
return ret;
}
This works, and is quite easy to read. BTW: Convert.ToInt32('3') gives 51, not 3. Convert.ToInt32('3' - '0') gives 3.
I would assume that the fastest implementation is Greg Hewgill's arithmetric solution.
private static int getDigitSum(int ds)
{
int dssum = 0;
while (ds > 0)
{
dssum += ds % 10;
ds /= 10;
if (dssum > 9)
{
dssum -= 9;
}
}
return dssum;
}
This is to provide the sum of digits between 0-9
public static int SumDigits1(int n)
{
int sum = 0;
int rem;
while (n != 0)
{
n = Math.DivRem(n, 10, out rem);
sum += rem;
}
return sum;
}
public static int SumDigits2(int n)
{
int sum = 0;
int rem;
for (sum = 0; n != 0; sum += rem)
n = Math.DivRem(n, 10, out rem);
return sum;
}
public static int SumDigits3(int n)
{
int sum = 0;
while (n != 0)
{
sum += n % 10;
n /= 10;
}
return sum;
}
Complete code in: https://dotnetfiddle.net/lwKHyA
int j, k = 1234;
for(j=0;j+=k%10,k/=10;);
A while back, I had to find the digit sum of something. I used Muhammad Hasan Khan's code, however it kept returning the right number as a recurring decimal, i.e. when the digit sum was 4, i'd get 4.44444444444444 etc.
Hence I edited it, getting the digit sum correct each time with this code:
double a, n, sumD;
for (n = a; n > 0; sumD += n % 10, n /= 10);
int sumI = (int)Math.Floor(sumD);
where a is the number whose digit sum you want, n is a double used for this process, sumD is the digit sum in double and sumI is the digit sum in integer, so the correct digit sum.
static int SumOfDigits(int num)
{
string stringNum = num.ToString();
int sum = 0;
for (int i = 0; i < stringNum.Length; i++)
{
sum+= int.Parse(Convert.ToString(stringNum[i]));
}
return sum;
}
If one wants to perform specific operations like add odd numbers/even numbers only, add numbers with odd index/even index only, then following code suits best. In this example, I have added odd numbers from the input number.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Please Input number");
Console.WriteLine(GetSum(Console.ReadLine()));
}
public static int GetSum(string num){
int summ = 0;
for(int i=0; i < num.Length; i++){
int currentNum;
if(int.TryParse(num[i].ToString(),out currentNum)){
if(currentNum % 2 == 1){
summ += currentNum;
}
}
}
return summ;
}
}
The simplest and easiest way would be using loops to find sum of digits.
int sum = 0;
int n = 1234;
while(n > 0)
{
sum += n%10;
n /= 10;
}
#include <stdio.h>
int main (void) {
int sum = 0;
int n;
printf("Enter ir num ");
scanf("%i", &n);
while (n > 0) {
sum += n % 10;
n /= 10;
}
printf("Sum of digits is %i\n", sum);
return 0;
}
Surprised nobody considered the Substring method. Don't know whether its more efficient or not. For anyone who knows how to use this method, its quite intuitive for cases like this.
string number = "17463";
int sum = 0;
String singleDigit = "";
for (int i = 0; i < number.Length; i++)
{
singleDigit = number.Substring(i, 1);
sum = sum + int.Parse(singleDigit);
}
Console.WriteLine(sum);
Console.ReadLine();

Categories