Project Euler #1, getting higher results for no apparent reason - c#

I'm having a problem with the first coding challenge on the Project Euler website. This is what you have to do:
"If we list all the natural numbers below 10 that are multiples of 3
or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000."
Here's my code (c#):
total = 0;
for (int i = 0; i <= (999 - (999 % 3)) / 3; i++)
{
total += 3 * i;
}
for (int i = 0; i <= (999 - (999 % 5)) / 5; i++)
{
total += 5 * i;
}
When I return total it gives me '266333' while it should be '233168'. I've been staring at it for about an hour and I have no clue where my code is going wrong. Sorry if this is a stupid question but google isn't helping me and I feel really dumb.

You can do in single for loop as :
int total = 0;
for (int i = 1; i < 1000; i++)
{
if (i % 3 == 0 || i % 5 == 0)
{
total += i;
}
}

Related

Using Modulo instead of two loops

I'm new at programming in general and learning C# right now.
I just wrote a little programm where I have to step through an int[] in a specific pattern. The pattern is as follows:
Start at the last entry of the array (int i)
form the sum of i and (if avaible) the three entrys above (e.g. i += i-1 ... i += i-3)
Change i to i -= 4 (if avaible)
Repeat from step 2 until i = 0;
Therefore i wrote the following loop:
for (int i = intArray.Length - 1; i >= 0; i -= 4)
{
for (int a = 1; a <= 3; a++)
{
if (i - a >= 0)
{
intArray[i] += intArray[i - a];
intArray[i - a] = 0;
}
}
}
Now my new assignment is to change my code to only use 1 loop with the help of modulo-operations. I do understand what modulo does, but i can't figure out how to use it to get rid of the second loop.
Maybe somebody explain it to me? Thank you very much in advance.
While iterating over the array, the idea would be to use the modulo 4 operation to calculate the next index to which you will add the current value.
This should work with any array lengths:
for (int i = 0; i < intArray.Length; i++){
// we check how far away we are from next index which stores the sum
var offset = (intArray.Length - 1 - i) % 4;
if (offset == 0) continue;
intArray[i+offset] += intArray[i];
intArray[i] = 0;
}
iterating the array reversely makes it a bit more complicated, but what you wanted to get rid of inner loop with modulo is probably this:
var intArray = Enumerable.Range(1, 15).ToArray();
for (int i = 1; i < intArray.Length - 1; i ++)
{
intArray[i - (i % 4)] += intArray[i];
intArray[i] = 0;
}

How would I display a For and Reverse For Loop on the same Line C#

I have been trying to get both a For and Reverse For loop to display on a line in this formation Number x Number
Due to the number being an input (people % i==0) is there to find factors of the number that has been given.
for (int i = 2; i <= people - 1; i++)
{
if (people % i==0)
{
Console.Write($"{i}m x ");
//Console.WriteLine($"{i} is factors of {input}");
}
}
for (int j = people - 1; j >= 2; j-- )
{
if (people % j == 0)
{
Console.WriteLine($"{j}m");
}
}
C# for can use compound assignments/expressions (zero or more statements separated by commas)
int people = 10;
for (int i = 2, j = people - 1; i <= people - 1; i++, j--)
Console.WriteLine($"i = {i}, j = {j}");
Output
i = 2, j = 9
i = 3, j = 8
i = 4, j = 7
i = 5, j = 6
i = 6, j = 5
i = 7, j = 4
i = 8, j = 3
i = 9, j = 2
Note : this is very common in C/++ however it's less common in C#; we tend to like things declarative, neat and readable.
Or you can calculate it on the fly
int people = 10;
for (int i = 2; i <= people - 1; i++)
Console.WriteLine($"i = {i}, j = {people-i+1}");
Full Demo Here
If you're interested in a way to achieve this using Linq, this is achievable using a Zip operation:
int start = 2;
int people = 9;
Enumerable.Range(start, people - start + 1)
.Zip(Enumerable.Range(start, people - start + 1).Reverse(), (x, y) => $"{x}m x {y}m")
.ToList()
.ForEach(Console.WriteLine);
Output
2m x 9m
3m x 8m
4m x 7m
5m x 6m
6m x 5m
7m x 4m
8m x 3m
9m x 2m
Create another index j in the first for loop
for (int i = 2; i <= people - 1; i++)
{
if (people % i==0)
{
Console.Write($"{i}m x ");
//Console.WriteLine($"{i} is factors of {input}");
}
int j = people - i + 1;
if (people % j == 0)
{
Console.WriteLine($"{j}m");
}
}

How do I print just a final sum in this problem?

I am a beginner, trying to solve Project Euler problem 1:
"If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.", but, you probably know this problem.
So I get a correct answer but my program lists all sums up to a final sum. But how do I manage to just print final sum?
int x = 0;
for (int i = 1; i < 1000; i ++)
{
if (i % 3 == 0 || i % 5 == 0)
{
Console.WriteLine(x += i);
You have a Console.WriteLine inside a loop, so every time the if is true, a print out to the console will occur. Move the Console.WriteLine so it is outside of the loop
I think you would have quite quickly discovered this problem if you had used the debugger to step through the code line by line. Do you know how to use the debugger? If not, drop a comment and I'll write some introductory lines
You should keep console.WriteLine() outside of 'for' loop,
Your code should go look like this-
int x=0;
for (int i = 1; i < 1000; i ++){
if (i%3==0 || i%5==0){
x+=i;
}}
console.WriteLine(x);
good start bro, you can just make the Console.WriteLine(x) after the for loop
You don't need to write every time you add i to x. You can just add it and then print after you ran the for loop.
int x = 0;
for (int i = 0; i < 1000; i++)
{
if (i % 3 == 0 || i % 5 == 0)
{
x += i;
}
}
Console.WriteLine(x);
If you want to print only the final result, move the Console.WriteLine command out of the iteration and place it after it. This way it will execute only once.
int x = 0;
for (int i = 1; i < 1000; i ++)
{
if (i % 3 == 0 || i % 5 == 0)
{
x += i;
}
}
Console.WriteLine(x);

How to get number of digits divisible by 5

I want to find the total number of digits divisible by 5 between 1 - 100, in C# windows form, how to proceed from here?
int sum;
private void button2_Click(object sender, EventArgs e)
{
int[] intarray = new int[100];
for (int i = 0; i < 99; i++)
{
intarray[i] = i + 1;
}
foreach (int a in intarray)
{
if (a / 5 == 0)
{
}
}
}
Note than a / 5 == 0 is wrong. For example 10 is divisible by 2, the result is 10/5 = 2, not equal to 0.
if (a % 5 == 0)
{
//then a is divisible by 5. print or store it
}
The modulus operator, also known as Remainder, returns the remainder of the integer division.
Therefore, the full answer:
int nInRange = 0;
foreach (int a in intarray)
if (a % 5 == 0)
nInRange++;
Maybe this is what you want.
public static IEnumerable<int> GetIntsDivisible(int start, int finish, int divisor)
{
for (var i = start; i <= finish; i++)
if (i % divisor == 0)
yield return i;
}
public static void Main()
{
Console.WriteLine(string.Join(", ", GetIntsDivisible(1, 100, 5)));
}
or if you don't want to yield
public static List<int> GetIntsDivisible(int start, int finish, int divisor)
{
var result = new List<int>();
for (var i = start; i <= finish; i++)
if (i % divisor == 0)
result.Add(i);
return result;
}
Output
5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100
Full demo here
Initialize a variable as 0
for e.g. Count = 0;
then add statement Count++ in your if block as follows:
if (a % 5 == 0)
{
Count++;
}
Since question is a bit vague in exact requirement, I will write the basic logic that can find the numbers exactly divisible by other number.
There is something called modulus (%) operator. It gives you the remainder of division.e.g. 11%5 will be 1, 13%5 will be 3, whereas 15%5 will be 0
so logic goes like,
for(int i=0;i<=100;i++)
{
if((i%5)==0)
{
\\this is ur number
}
}
Every one has address your question but no one talk about this weird attempt.
I really think you should take 5 minute and read your code because you are just running everywhere.
You should take the pen and paper before going head first into coding.
Here is a simple reading of your code so you understand what you were doing.
Line 1:
int[] intarray = new int[100];
So you start win an array, I guess it's for the result, right ? You will not be storing the number from 1 to 100 for no reason?
Line 2:
for (int i = 0; i < 99; i++)
Now we count from 0 to 98, I though it was form 1 to 100 .. Yes 98 as you are using < instead of <=
Line 3:
intarray[i] = i + 1;
Why ? 3rd line and you are already lost! You are filling the array with number you just iterate. It's like filling a bottle with water, then use it to fill an other bottle because you needed water.
If you iterate from 1 to 100 you could have check if it was divisible.
for (int i = 1; i <= 100; i++)
Line 4:
foreach (int a in intarray)
Again ? We are back counting from 1 to 100..
Line 5:
if (a / 5 == 0)
If this is suppose to tell you if it divisible thats wrong. The correct math operator is the Modulo. The division symbole won't give you the result you expect.
{1,2,3,4} will give you True. Anything else will be false.
int count = 0;
for (int i = 1; i <= 100; i++)
{
if ((i % 5) == 0)
{
count++;
textBox1.Text = count.ToString();
}
}
Alternatively,
int num = (100 + 5) / 5 - (1 + 5 - 1) / 5;
//Show result here

Calculate Nth Pi Digit

I am trying to calculate the nth digit of Pi without using Math.Pi which can be specified as a parameter.
I modified an existing algorithm, since I like to find the Nth digit without using string conversions or default classes.
This is how my algorithm currently looks like:
static int CalculatePi(int pos)
{
List<int> result = new List<int>();
int digits = 102;
int[] x = new int[digits * 3 + 2];
int[] r = new int[digits * 3 + 2];
for (int j = 0; j < x.Length; j++)
x[j] = 20;
for (int i = 0; i < digits; i++)
{
int carry = 0;
for (int j = 0; j < x.Length; j++)
{
int num = (int)(x.Length - j - 1);
int dem = num * 2 + 1;
x[j] += carry;
int q = x[j] / dem;
r[j] = x[j] % dem;
carry = q * num;
}
if (i < digits - 1)
result.Add((int)(x[x.Length - 1] / 10));
r[x.Length - 1] = x[x.Length - 1] % 10; ;
for (int j = 0; j < x.Length; j++)
x[j] = r[j] * 10;
}
return result[pos];
}
So far its working till digit 32, and then, an error occurs.
When I try to print the digits like so:
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
Console.WriteLine("{0} digit of Pi is : {1}", i, CalculatePi(i));
}
Console.ReadKey();
}
This I get 10 for the 32rd digit and the 85rd digit and some others as well, which is obviously incorrect.
The original digits from 27 look like so:
...3279502884.....
but I get
...32794102884....
Whats wrong with the algorithm, how can I fix this problem?
And can the algorithm still be tweaked to improve the speed?
So far it works right up until the cursor reaches digit 32. Upon which, an exception is thrown.
Rules are as follows:
Digit 31 is incorrect, because it should be 5 not a 4.
Digit 32 should be a 0.
When you get a 10 digit result you need to carry 1 over to the previous digit to change the 10 to a 0.
The code changes below will work up to ~ digit 361 when 362 = 10.
Once the program enters the 900's then there are a lot of wrong numbers.
Inside your loop you can do this by keeping track of the previous digit, only adding it to the list after the succeeding digit has been computed.
Overflows need to be handled as they occur, as follows:
int prev = 0;
for (int i = 0; i < digits; i++)
{
int carry = 0;
for (int j = 0; j < x.Length; j++)
{
int num = (int)(x.Length - j - 1);
int dem = num * 2 + 1;
x[j] += carry;
int q = x[j] / dem;
r[j] = x[j] % dem;
carry = q * num;
}
// calculate the digit, but don't add to the list right away:
int digit = (int)(x[x.Length - 1] / 10);
// handle overflow:
if(digit >= 10)
{
digit -= 10;
prev++;
}
if (i > 0)
result.Add(prev);
// Store the digit for next time, when it will be the prev value:
prev = digit;
r[x.Length - 1] = x[x.Length - 1] % 10;
for (int j = 0; j < x.Length; j++)
x[j] = r[j] * 10;
}
Since the digits are being updated sequentially one-by-one, one whole iteration later than previously, the if (i < digits - 1) check can be removed.
However, you need to add a new one to replace it: if (i > 0), because you don't have a valid prev value on the first pass through the loop.
The happy coincidence of computing only the first 100 digits means the above will work.
However, what do you suppose will happen when a 10 digit result follows a 9 digit one? Not good news I'm afraid, because the 1 with need carrying over to the 9 (the previous value), which will make it 10.
A more robust solution is to finish your calculation, then do a loop over your list going backwards, carrying any 10s you encounter over to the previous digits, and propagating any carries.
Consider the following:
for (int pos = digits - 2; pos >= 1; pos--)
{
if(result[pos] >= 10)
{
result[pos] -= 10;
result[pos - 1] += 1;
}
}

Categories