Modulus (%) in for-loop - c#

I have a code here and I would like that it will display the first 10 and if I click on that, it will display again the second batch. I tried this first with my first for-code and it work now I'm working with arrays it seems it didn't accept it
The one I commented dont work? is this wrong?
Thanks
long [] potenzen = new long[32];
potenzen[0] = 1;
for (int i = 1; i < potenzen.Length; ++i)
{
potenzen[i] = potenzen[i-1] * 2;
//if (potenzen % 10 == 0)
// Console.ReadLine();
}
foreach (long elem in potenzen)
{
Console.WriteLine(" " + elem);
}

long [] potenzen = new long[32];
potenzen[0] = 1;
for (int i = 1; i < potenzen.Length; ++i)
{
potenzen[i]=potenzen[i-1]*2;
Console.WriteLine(potenzen[i-1]);
if (i % 10 == 0)
Console.ReadLine();
}
is more in line with what you want. An improvement would be to separate your data-manipulation logic from your data display logic.
long [] potenzen = new long[32];
potenzen[0] = 1;
for (int i = 1; i < potenzen.Length; ++i)
potenzen[i]=potenzen[i-1]*2;
for (int i = 0; i < potenzen.Length; ++i)
{
Console.WriteLine(potenzen[i]);
if (i % 10 == 0)
Console.ReadLine();
}
Of course, you could do this without an array
long potenzen = 1;
for (int i = 1; i < 32; ++i)
{
Console.WriteLine(potenzen);
potenzen = potenzen * 2;
if (i % 10 == 0)
Console.ReadLine();
}

You need:
if (i % 10 == 0)
and not:
if (potenzen % 10 == 0)

Applying the modulus operator to an array of longs is dubious.

potenzen is an array so you maybe try
if (i % 10 == 0)
or maybe
if (potenzen[i] % 10 == 0)

You're taking an array mod 10 -- at best, in an unsafe language, you'd be doing the modulo operation on a memory address.
This should work fine if you just change the line to:
// if you don't want to pause the first time you run it, replace with:
// if (i > 0 && i % 10 == 0) {
if (i % 10 == 0) {
Console.ReadLine();
}

Try changing it to:
long [] potenzen = new long[32];
potenzen[0] = 1;
Console.WriteLine(potenzen[0]);
for (int i = 1; i < potenzen.Length; ++i)
{
potenzen[i]=potenzen[i-1]*2;
Console.WriteLine(potenzen[i]);
if (i % 10 == 0)
{
var s = Console.ReadLine();
// break if s == some escape condition???
}
}
Right now, you're never printing, unless you completely finish your first for loop. My guess is that you're not allowing the full 32 elements to complete, so you're never seeing your results -
This will print them as they go.

Related

How to solve time constraint with coding challenge

I was doing a coding test (for practice) that went something like this:
Input is a string with |'s and *'s.
E.g. **|*|*|**|***
Implement the function:
List<int> countItems(string line, List<int> startLocations, List<int> endLocations)
Count the number of * characters that are between an opening and closing pair of | characters.
Where the 2 locations are arrays with the start and end locations (indices) to consider withing the string line.
For example if line = *|*|* and startLocations = [1] and endLocations = [3] it means
I need to check the substring *|*.
And since there is only 1 pipe, the result is zero.
The location values seemed to be 1-based and not 0-based for some reason.
If the range was 1 and 5, for example, the result would be 1 because there is only 1 * between pipes.
The code I came up with that did manage to solve about half the test cases is as follows:
List<int> countItems(string line, List<int> startLocations, List<int> endLocations)
{
var results = new List<int>();
if (String.IsNullOrWhiteSpace(line) || startLocations.Count == 0)
{
return results;
}
for (var i = 0; i < startLocations.Count; i++)
{
var startIndex = startLocations[i] - 1;
var endIndex = endLocations[i] - 1;
var start = false;
var total = 0;
var tempTotal = 0;
for (var j = startIndex; j < endIndex; j++)
{
if (!start && line[j] == '|')
{
start = true;
tempTotal = 0;
}
else if (start && line[j] == '*')
{
tempTotal++;
}
else if (line[j] == '|')
{
total += tempTotal;
tempTotal = 0;
}
}
if (line[endIndex] == '|')
{
total += tempTotal;
}
results.Add(total);
}
return results;
}
All the test cases either passed or failed because it ran out of time.
The error said it exceeded a time of 3 seconds.
Now I couldn't see the actual data being passed into the tests, so I'm not able to test it more.
But I suspect the solution was some kind of temporary list or dictionary so as to only iterate over the string 1 time instead of many times as in my code.
I want to learn what kind of solution to use in cases like this, but not really sure if this is a common type of question where the solution has some kind of name or common concept.
I would appreciate any obvious pointers to solving this type of question or even links to similar programming challenges where I can practice more.
In this case I think the best option would be to use stack theory.
It is a variation of the parenthesis balancing problem. You can find more about it here
Article parenthesis balancing problem
I managed to redo the test and I found the answer and problem type.
This is a "plates between candles" type of problem.
I was trying to solve it myself but almost ran out of time and eventually just copy/pasted an answer I found.
This was a practice run, not an actual test or application.
This was the solution that worked... I'll be studying it to better understand it...
List<int> numberOfItems(string s, List<int> startIndices, List<int> endIndices)
{
int q = startIndices.Count;
int l = s.Length;
for (var i = 0; i < startIndices.Count; i++)
{
startIndices[i]--;
endIndices[i]--;
}
var ans = new List<int>();
var prev = new int[l];
var next = new int[l];
var preSum = new int[l];
int p = -1, nxt = -1;
// calculating prev candle up to this index.
for (int i = 0; i < l; i++)
{
if (s[i] == '|')
{
p = i;
}
prev[i] = p;
}
//Calculating next candle from this index.
for (int i = l - 1; i >= 0; i--)
{
if (s[i] == '|')
{
nxt = i;
}
next[i] = nxt;
}
int c = 0;
// calculating the number of stars between these indices.
for (int i = 0; i < l; i++)
{
if (s[i] == '*')
{
c++;
}
preSum[i] = c;
}
// calculating ans.
for (int k = 0; k < q; k++)
{
int i = startIndices[k];
int j = endIndices[k];
int right = prev[j];// position of left candle.
int left = next[i];// position of right candle.
//cout<<right<<left;
if (left == -1 || right == -1 || left > right)
{
ans.Add(0);
}
else
{
ans.Add(preSum[right] - preSum[left]);
}
}
return ans;
}

How to convert For Loop results into an Array then count the integers of the resulting Array in C#?

In C#, how would I go about converting the result of a For Loop into an Array and count (Display on the Console) the number of integers stored in that converted array?
Please see below for what I have thus far:
for (int i = 1; i < 100; i++)
{
if (i % 3 == 0)
{
Console.WriteLine(i);
}
}
And feel free to let me know if there is a different way to count the results of the code I have above.
Please let me know what you think.
There are a few different ways to accomplish what you're after. You can use a for-loop as you've done and accomplish it like so:
var list = new List<int>();
var sum = 0;
for (var i = 1; i < 100; i++)
{
if (i % 3 != 0)
continue;
list.Add(i);
Console.WriteLine(i);
sum += i;
}
Console.WriteLine($"Count: {list.Count}");
Console.WriteLine($"Sum: {sum}");
You could also accomplish this with Linq:
var numbers = Enumerable.Range(1, 99)
.Where(i => i % 3 == 0)
.ToList();
var sum = numbers.Sum();
numbers.ForEach(Console.WriteLine);
Console.WriteLine($"Count: {numbers.Count}");
Console.WriteLine($"Sum: {sum}");
You can use List for that purpose:
var list = new List<int>();
for (int i = 1; i < 100; i++)
{
if (i % 3 == 0)
{
list.Add(i);
Console.WriteLine(i);
}
}
Console.WriteLine(list.Count);
There is no need to insert the numbers into a collection to count them. Just use a variable as counter
int count = 0;
for (int i = 1; i < 100; i++)
{
if (i % 3 == 0)
{
count++; // Increments count by 1.
Console.WriteLine(i);
}
}
Console.WriteLine("The count is " + count);
List<int> myList = new List<int>();
for (int i = 1; i < 100; i++) {
if (i % 3 == 0) {
Console.WriteLine(i);
myList.Add(i);
}
}
Console.WriteLine(myList.Count);
//if you want an array....
int[] myArray;
myArray = myList.ToArray();

Run time of shellsort and insertionsort change depending on execution order

1/ DateTime before = DateTime.Now;
2/ shellSort(List1);
3/ DateTime after = DateTime.Now;
4/ Console.WriteLine(after - before);
5/
6/ before = DateTime.Now;
7/ insertionSort(List2);
8/ after = DateTime.Now;
9/ Console.WriteLine(after - before);
I am trying to compare the run time of two different sorting algorithms. List1 here is equal to List2. I was expecting shell sort to be faster than insertion sort but although first WriteLine differs, it usually prints something like this = 00:00:00.0035037. The second one however, either prints 00:00:00 or something smaller than the first print. I thought maybe the insertion sort was better suited for List's current state however even when i swap the line 7 and line 2 i still get the same result. What is causing this? Why is the second executed function runs faster? Or am i using the Dates completely wrong?
Edit : I used Stopwatch instead of DateTime Class as advised in another post. The result is pretty much the same. The second one usually runs faster but every now and then it's slower than the first one. I also used a pre-written shellsort code to see if my implementation was bad but that was also a dead end.
As requested, shellsort and insertionsort implementations
static void shellSort(List<int> numbers) // Implementation i found online
{
int i, j, increment, temp;
increment = 3;
while (increment > 0)
{
for (i = 0; i < numbers.Count ; i++)
{
j = i;
temp = numbers[i];
while ((j >= increment) && (numbers[j - increment] > temp))
{
numbers[j] = numbers[j - increment];
j = j - increment;
}
numbers[j] = temp;
}
if (increment / 2 != 0)
increment = increment / 2;
else if (increment == 1)
increment = 0;
else
increment = 1;
}
}
public static void insertionSort(List<int> numbers)
{
int i = 0;
while (i != numbers.Count)
{
int k = i;
while (k != 0 && numbers[k] < numbers[k - 1])
{
int temp = numbers[k - 1];
numbers[k - 1] = numbers[k];
numbers[k] = temp;
k--;
}
i++;
}
}
Also this was my implementation of shellsort
public static void shellSort(List<int> Liste)
{
int n = Liste.Count;
int gap = (Liste.Count - 1) / 2;
while (gap > 0)
{
int i = 0;
for(int k = gap; k < n; k++) {
int p = i;
int m = k;
while (p >= 0)
{
if (Liste[p] > Liste[m])
{
int temp = Liste[p];
Liste[p] = Liste[m];
Liste[m] = temp;
m = p;
}
else
break;
p = p - gap;
}
i++;
}
gap = gap / 2;
}
}

Need Help using the Mod Function for looping in C#

for (int i = 0; i < 100; i = (i%10))
{
age = (age +10);
int_year = (int_year + 10);
So I am trying to use the Mod function for looping in C#, the requirement is that it the int_year and age loop 100 times but only every 10th increment is kept. Thanks in advance :)
Why not just mod 10 within the loop to determine if this is the 10th iteration:
for (int i = 0; i < 100; i++)
{
if (i % 10 == 0)
{
// Every 10th iteration
}
}
You can use step equal to 10:
for (int i = 0; i < 100; i += 10)
{
// Every 10th iteration
}
I think it's more efficient than using mod.

A recursion related issue in c#

This is the background to this question:
Background
Take any integer n greater than 1 and apply the following algorithm
If n is odd then n = n × 3 + 1 else n = n / 2
If n is equal to 1 then stop, otherwise go to step 1
The following demonstrates what happens when using a starting n of 6
6 - 3 - 10 - 5 - 16 - 8 - 4 - 2 - 1
After 8 generations of the algorithm we get to 1.
It is conjectured that for every number greater than 1 the repeated application of this algorithm will
eventually get to 1.
The question is how can I find a number that takes exactly 500 generations to reduce to 1?
The code below is my version but appearntly got some wrong logic. Could you help me correct this? Thanks in advance.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sequence1
{
class Program
{
static void Main(string[] args)
{
int start = 1;
int flag = 0;
int value;
while(true){
int temp = (start - 1) / 3;
string sta = temp.ToString();
if (Int32.TryParse(sta, out value) )
{
if (((start - 1) / 3) % 2 == 1)
{
start = (start - 1) / 3;
flag++;
if (flag == 500)
{
break;
}
}
else
{
start = start * 2;
flag++;
if (flag == 500)
{
break;
}
}
}
else
{
start = start * 2;
flag++;
if (flag == 500)
{
break;
}
}
}
Console.WriteLine("result is {0}", start);
Console.ReadLine();
}
}
}
Since your question's title is "A recursion related issue", I will give you a recursive solution.
int Process(int input, int maxRecursionDepth)
{
// condition to break recursion
if (maxRecursionDepth == 0 || input == 1)
return input;
if (input % 2 == 1) // odd case
return Process(input * 3 + 1, maxRecursionDepth - 1);
else // even case
return Process(input / 2, maxRecursionDepth - 1);
}
Now to find all number in a specified range, that return 1 after exactly 500 recursions:
int startRange = 1, endRange = 1000;
int maxDepth = 500;
List<int> resultList = new List<int>();
for (int i = startRange; i <= endRange; i++)
{
if (Process(i, maxDepth) == 1)
resultList.Add(i);
}
Your problem is a part of Collatz conjecture (about recursively defined function) which has not been solved yet:
http://en.wikipedia.org/wiki/Collatz_conjecture
so I think brute force is a good way out:
public static int GetMinNumber(int generations) {
if (generations < 0)
throw new ArgumentOutOfRangeException("generations");
// Memoization will be quite good here
// but since it takes about 1 second (on my computer) to solve the problem
// and it's a throwaway code (all you need is a number "1979515")
// I haven't done the memoization
for (int result = 1; ; ++result) {
int n = result;
int itterations = 0;
while (n != 1) {
n = (n % 2) == 0 ? n / 2 : 3 * n + 1;
itterations += 1;
if (itterations > generations)
break;
}
if (itterations == generations)
return result;
}
}
...
int test1 = GetMinNumber(8); // <- 6
int test2 = GetMinNumber(500); // <- 1979515
Observing the problem,
13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
In the third iteration we hit the number 10, which is smaller than 13
So instead of calculating the sequence count every time we can use a cache.
static int GetMinCollatz(int maxChain)
{
const long number = 1000000;
int minNumber = 0;
// Temporary values
int tempCount = 0;
long temp = 0;
// Cache
int[] sequenceCache = new int[number + 1];
// Fill the array with -1
for (int index = 0; index < sequenceCache.Length; index++)
{
sequenceCache[index] = -1;
}
sequenceCache[1] = 1;
for (int index = 2; index <= number; index++)
{
tempCount = 0;
temp = index;
// If the number is repeated then we can find
// sequence count from cache
while (temp != 1 && temp >= index)
{
if (temp % 2 == 0)
temp = temp / 2;
else
temp = temp * 3 + 1;
tempCount++;
}
sequenceCache[index] = tempCount + sequenceCache[temp];
if (sequenceCache[index] == maxChain)
{
minNumber = index;
}
}
return minNumber;
}
For more details refer project euler and this.
A recursive solution
private void ReduceTo1(int input, ref int totalCount)
{
totalCount++;
if (input % 2 == 0)
{
input = input / 2;
}
else
{
input = input * 3 + 1;
}
if (input != 1)
ReduceTo1(input, ref totalCount);
}
to test
int desireValue = 0;
for (int i = 1; i < 100000; i++)
{
int totalCount = 0;
ReduceTo1(i, ref totalCount);
if (totalCount >= 500)
{
desireValue = i;
break;
}
}

Categories