So I want to output Pi with arbitrary precision digit by digit. I found some code here https://rosettacode.org/wiki/Pi#C.23
public IEnumerable<long> PiDigits(long b = 10)
{
BigInteger
k = 1,
l = 3,
n = 3,
q = 1,
r = 0,
t = 1
;
// skip integer part
var nr = b * (r - t * n);
n = b * (3 * q + r) / t - b * n;
q *= b;
r = nr;
for (; ; )
{
var tn = t * n;
if (4 * q + r - t < tn)
{
yield return (long)n;
nr = b * (r - tn);
n = b * (3 * q + r) / t - b * n;
q *= b;
}
else
{
t *= l;
nr = (2 * q + r) * l;
var nn = (q * (7 * k) + 2 + r * l) / t;
q *= k;
l += 2;
++k;
n = nn;
}
r = nr;
}
}
And it's working correctly but there's no explanation to it. I want to understand this algorithm but it looks too complicated. And variables' name don't give me anything. So could you please tell me what algorithm is that co I could continue my research. Thank you!
This is an implementation of the spigot algorithm translated from an implementation by Jeremy Gibbons.
His paper explains the inner workings of the algorithm. You should find the information you need at pages 5 and 6.
Related
Example a: √12 =2√3
Example b: √16 = 4
I am trying to get both.
Whilst I can of course use Math.Sqrt(4) to achieve outcome b, I've no idea how to achieve a, or further how to get both to work simultaneously which is the goal. How do I achieve this type of simplification in C#?
I have tried several libraries including MathNet, Symbolics and NCalc with no success.
This post may have solved it in c++, although I do not know for sure. My attempts at converting that solution to even see if it worked were very much a failure:
var outside_root = 1;
var inside_root = 800;
var d = 2;
while (d * d <= inside_root)
if (inside_root % (d * d) == 0) //# inside_root evenly divisible by d * d
{
inside_root = inside_root / (d * d);
outside_root = (outside_root * d);
}
while (d * d > inside_root) {
d = (d + 1);}
Thank you for any help
The given C++ can be translated into C# without a lot of changes. Also a couple of modifications can be made to the original algorithm to reduce number of multiplications and increase overall performance:
static (int, int) Sqrt2(int n)
{
int m = 1, d = 2;
int dSquared;
while ((dSquared = d * d) <= n)
{
while ((n % dSquared) == 0)
{
n /= dSquared;
m *= d;
}
d++;
}
return (m, n);
}
static void Main(string[] args)
{
Console.WriteLine(Sqrt2(12)); // prints (2, 3)
Console.WriteLine(Sqrt2(16)); // prints (4, 1)
Console.WriteLine(Sqrt2(13)); // prints (1, 13)
}
This could be one of the solution
I think this is efficient. I used it in my calculator app
I did that using java. Hope this will help
static void surd_form(long a) {
long i = 2;
long sq = 1;
long k = 4;
long p = 1;
while (k <= a) {
if (a % i == 0) {
if (a % k == 0) {
a /= k;
sq *= i;
} else {
a /= i;
p *= i;
}
} else {
i += 1;
}
k = i * i;
}
System.out.println(sq + "" + "√" + (a * p));
}
Two (2 digit) numbers are written together, so they form one 4 digit number. This 4 digit number can be divided by the multiplication of this two numbers. The problem is that I have to find this numbers.
I wrote an algorithm and get 2 pair of these numbers.
1) 13 and 52, so 1352 can be divided by 13 * 52.
2) 17 and 34, so 1734 can be divided by 17 * 34.
My algorithm looks like this:
for (int i = 1010; i <= 9999; i++)
{
int mult = (i / 100) * (i % 100);
if ((i % 100) > 9 && i % mult == 0)
{
Console.WriteLine(i / 100 + " <--> " + i % 100);
}
}
Edit: with this algorithm (based on mentallurg answer) I find this numbers a bit faster
for (int i = 10; i < 99; i++)
{
for (int j = 10; j < 99; j++)
{
int mult = i * j;
int num = i * 100 + j;
if (num % mult == 0)
{
Console.WriteLine(i + " <--> " + j);
}
}
}
I am interested in how I can make this algorithm more efficient.
This is very efficient:
var query =
from x in Enumerable.Range(10, 90)
from n in Enumerable.Range(1, 10).TakeWhile(w => w * x < 100)
let v = x * (100 + n)
where v % (n * x * x) == 0
select new { x, y = n * x };
It computes all possible first digits. It then computes all of the possible second digits that are multiples of the first digit that are greater than zero and less than 100. It then produces the a candidate value at checks if it is divisible by the product of both digits.
It gives both of the possible answers.
Here's the equivalent using for loops:
for (int x = 10; x <= 99; x++)
{
for (int n = 1; x * n < 100; n++)
{
var j = x * n;
int v = x * 100 + j;
int d = x * j;
if (v % d == 0)
{
Console.WriteLine(x + " <--> " + j);
}
}
}
Supposed one of the pairs are a and b, and so the four digits number can be expressed as 100a + b. Do a little math
100a + b = m * a * b
Divided by a on both sides, we have
100 + b / a = m * b
We can conclude that
b can be divided by a, let's say (b == n * a);
b must be greater than a, since 101 is a prime. And it cannot be 3/7/9 times of a, since 103/107/109 are also primes, but let’s neglect this to make the for loop simpler. This can be easily handled in the inner loop of the following code.
So the for loop can be written like this
for (int a = 10; a < 50; a++)
{
for (int n = 2; n * a < 100; n++)
{
if ((100 + n) % (n * a) == 0)
Console.WriteLine(a + " " + n * a);
}
}
The number of iteration of the loop is reduced to a few dozens, from almost 10 thousand.
Use 2 nested cycles from 1 to 99 and you will avoid two division operations on each step.
I am working on my app using Unity3D, and I am trying to get the user input string from the input filed then use that string to calculate the total sum by applying values from variables, but just cannot get to work. I have this
int B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U;
int characterLength = 0;
int numberLength = 0;
List<int> fomulaList = new List<int>();
List<int> numberList = new List<int>();
foreach (char c in charactersField.text)
{
characterLength++;
fomulaList.Add(c);
Debug.Log(c);
}
formulaArray = fomulaList.ToArray();
Debug.Log("Formula Length: " + formulaArray.Length + " " + formulaArray[0].ToString("D1") + " " + formulaArray[1].ToString("D1"));
Let's say: I typed in BC, and when I print out the DebugLog I got
Formula Length: 2 66 67
which is fine
foreach (char c in numbersField.text)
{
numberLength++;
Debug.Log(c);
}
for (int i = 0; i < winningNumberArray.Length; i++)
{
B = winningNumberArray[i] / 100000; //100000
C = (winningNumberArray[i] % 100000) / 10000; //10000
D = (winningNumberArray[i] % 10000) / 1000; //1000
E = (winningNumberArray[i] % 1000) / 100; //100
F = (winningNumberArray[i] % 100) / 10; //10
G = winningNumberArray[i] % 10; //1
H = twoNumberArray[i] / 10; //10
I = twoNumberArray[i] % 10; //1
J = firstThreeNumberArray[i] / 100; //100
K = (firstThreeNumberArray[i] % 100) / 10; //10
L = firstThreeNumberArray[i] % 10; //1
M = secondThreeNumberArray[i] / 100; //100
N = (secondThreeNumberArray[i] % 100) / 10; //10
O = secondThreeNumberArray[i] % 10; //1
P = thirdThreeNumberArray[i] / 100; //100
Q = (thirdThreeNumberArray[i] % 100) / 10; //10
R = thirdThreeNumberArray[i] % 10; //1
S = fourthThreeNumberArray[i] / 100; //100
T = (fourthThreeNumberArray[i] % 100) / 10; //10
U = fourthThreeNumberArray[i] % 10; //1
int sum = formulaArray.Sum();
Debug.Log("Sum: " + sum.ToString());
But when I print out the to I got
Sum: 133
It seems to me that the values for B and C are not from
B = winningNumberArray[i] / 100000;
C = (winningNumberArray[i] % 100000) / 10000;
How can I solve this?
The issue is likely that you are confusing the char 'B' with the variable B. Despite the similarities, they are completely unrelated.
It sounds like what you are trying to do is take user input, and get a particular value based on that user input. The right data structure for that, generally, in C# is a Dictionary.
In your case you would want:
Dictionary<char,int>
where char is the key (e.g. 'A' or 'B') and int is the value you are currently adding to your A or B variables).
I would like to find all positive integer solutions to the equation
a^3 + b^3 = c^3 + d^3 where a,b,c,d are integers between 1 to 1000;
for (int a = 1; a <= 1000; ++a)
{
for (int b = 1; b <= 1000; ++b)
{
for (int c = 1; c <= 1000; ++c)
{
for (int d = 1; d <= 1000; ++d)
{
if (Math.Pow(a, 3) + Math.Pow(b, 3) == Math.Pow(c, 3) + Math.Pow(d, 3))
{
Console.WriteLine("{0} {1} {2} {3}", a,b,c,d);
}
}
}
}
I know that d = Math.Pow(a^3 + b^3 - c^3, 1/3), so
for (int a = 1; a <= 1000; ++a)
{
for (int b = 1; b <= 1000; ++b)
{
for (int c = 1; c <= 1000; ++c)
{
int d = (int)Math.Pow(Math.Pow(a, 3) + Math.Pow(b, 3) - Math.Pow(c, 3), 1/3);
if (Math.Pow(a, 3) + Math.Pow(b, 3) == Math.Pow(c, 3) + Math.Pow(d, 3))
{
Console.WriteLine("{0} {1} {2} {3}", a,b,c,d);
}
}
}
}
But the second algorithm produce much smaller number of results. Where is the bug in my code?
I try (double)1/3 but the second algorithm still gives me smaller number of results then first one
Pretty much none of these answers are right.
Your question is:
Where is the bug in my code?
If you are using double-precision arithmetic to solve a problem in the integers, you are doing something wrong. Do not use Math.Pow at all, and particularly do not use it to extract cube roots and expect that you will get an exact integer answer.
So how should you actually solve this problem?
Let's be smarter about not doing unnecessary work. Your program discovers that 13 + 123 = 93 + 103, but also that 123 + 13 = 103 + 93, and so on. If you know the first one then you can know the second one pretty easily.
So what should we do to make this more efficient?
First, b must be larger than a. That way we never waste any time figuring out that 13 + 123 = 123 + 13.
Similarly, d must be larger than c.
Now, we can also say that c and d must be between a and b. Do you see why?
Once we put these restrictions in place:
for (int a = 1; a <= 1000; ++a)
for (int b = a + 1; b <= 1000; ++b)
for (int c = a + 1; c < b; ++c)
for (int d = c + 1; d < b; ++d)
if (a * a * a + b * b * b == c * c * c + d * d * d)
Console.WriteLine($"{a} {b} {c} {d}");
Your program becomes a lot faster.
Now, there are ways to make it faster still, if you're willing to trade more memory for less time. Can you think of some ways that this program is wasting time? How many times are the same computations done over and over again? How can we improve this situation?
We might notice for example that a * a * a is computed every time through the three inner loops!
for (int a = 1; a <= 1000; ++a)
{
int a3 = a * a * a;
for (int b = a + 1; b <= 1000; ++b)
{
int b3 = b * b * b;
int sum = a3 + b3;
for (int c = a + 1; c < b; ++c)
{
int c3 = c * c * c;
int d3 = sum - c3;
for (int d = c + 1; d < b; ++d)
if (d3 == d * d * d)
Console.WriteLine($"{a} {b} {c} {d}");
}
}
}
But we could be even smarter than that. For example: what if we created a Dictionary<int, int> that maps cubes to their cube roots? There are only 1000 of them! Then we could say:
for (int a = 1; a <= 1000; ++a)
{
int a3 = a * a * a;
for (int b = a + 1; b <= 1000; ++b)
{
int b3 = b * b * b;
int sum = a3 + b3;
for (int c = a + 1; c < b; ++c)
{
int c3 = c * c * c;
int d3 = sum - c3;
if (dict.HasKey(d3))
{
d = dict[d3];
Console.WriteLine($"{a} {b} {c} {d}");
}
}
}
}
Now you don't have to compute cubes or cube roots of d; you just look up whether it is a cube, and if it is, what its cube root is.
Even as a double, 1/3 cannot be represented exactly with any IEEE floating point types.
So, you aren't actually computing the cube root of a value, but rather raising the value to the power of 0.333333333333333333333333333334 or some slightly off version. This introduces rounding errors that result in increasing error factors.
Consider the case with a = 995, b = 990, c = 990: your first loop would generate a match with d = 995, but your computation produces d = 994 due to rounding errors, which fails to match your condition. This will rarely match, which explains the results you are seeing.
To fix the problem, you could work entirely with floating point, but that would get messy since you have to check ranges due to representational problems even then, and only after you find a possibly suitable range, you would then have to check the integer versions. Another solution is to approach this from the mathematics standpoint rather than brute-force, although that will likely require kernel methods and get very messy.
Replace
int d = (int)Math.Pow(Math.Pow(a, 3) + Math.Pow(b, 3) - Math.Pow(c, 3), 1/3);
with
int d = (int)Math.Round(Math.Pow(Math.Pow(a, 3) + Math.Pow(b, 3) - Math.Pow(c, 3), 1.0/3), 0);
if(d > 1000) continue; // Restrict solutions as in brute force algorithm
The two errors fixed are,
1/3 is computed as an integer division resulting in 0. Using 1.0/3 forces a floating point division.
Because of floating point errors the calculation may return say 3.999999994 instead of 4. When cast to an integer this is truncated to 3, effectively removing a solution. Using Math.Round(3.999999994, 0) rounds this up to 4.0 which is cast to 4 as an integer.
Your problem is, that the result from this line: int d = (int)Math.Pow(Math.Pow(a, 3) + Math.Pow(b, 3) - Math.Pow(c, 3), 1/3); can be a non Integer value, which would not fullfill your requirement. But by casting it to int you get a larger amount of solutions.
You should change d to a double and then just check if d is an integer value between 1 and 1000:
double d = Math.Pow(Math.Pow(a, 3) + Math.Pow(b, 3) - Math.Pow(c, 3), 1.0/3.0);
double epsilon = 0.000000001;
double dint = Math.Round(d, 0);
if (dint<=d+epsilon && dint>=d-epsilon && dint>=1-epsilon && dint<=1000+epsilon)
{
Console.WriteLine("{0} {1} {2} {3}", a,b,c,d);
}
Edit: I added an epsilon to make sure your double comparison will work
I am baffled here. I have a function to return a double, sometimes it returns the correct value, but most of the times it return NaN. From my understanding NaN is returned when we have something like 0/0. Below is the function returning NaN, all it's variables are declared as doubles.
public double SuperiorValue(List<double> l)
{
valueKn[0] = 0;
valueKn[1] = 0;
valueKn[2] = 1.69;
valueKn[3] = 1.18;
valueKn[4] = 0.95;
valueKn[5] = 0.82;
valueKn[6] = 0.75;
valerKn[7] = 0.67;
valueKn[8] = 0.63;
valueKn[9] = 0.58;
valueKn[10] = 0.561;
valueKn[11] = 0.542;
valueKn[12] = 0.523;
valueKn[13] = 0.504;
valueKn[14] = 0.485;
valueKn[15] = 0.466;
valueKn[16] = 0.447;
valueKn[17] = 0.428;
valueKn[18] = 0.409;
valueKn[19] = 0.39;
valueKn[20] = 0.382;
Xm = (l.Sum()) / (l.Count);
for (int i = 0; i < l.Count; i++)
{
sumTemporary = l[i] - Xm;
sum = sum + sumTemporary;
}
kn = valueKn[l.Count];
sx = Math.Sqrt((1 / l.Count - 1) * (sum * sum));
Vx = sx / Xm;
Xksup = Xm * (1 + kn * Vx);
Xkinf = Xm * (1 - kn * Vx);
return Xksup;
}
What baffles me even more is that never is the list made of less than 3 elements and greater than 15, and it still often returns NaN but like I said sometimes it returns the correct value. Any thoughts on this ?
Look at
Math.Sqrt((1 / l.Count - 1) * (sum * sum))
The 1 / l.Count is an integer division, it will be 0 for all l.Count > 1 and then you are computing Sqrt(-1 * (sum * sum)) .
But (1.0 / l.Count - 1) would still be negative, you probably want (1.0 / (l.Count - 1))
The fix is then:
Math.Sqrt((1.0 / (l.Count - 1)) * (sum * sum))