How would you create n nested loops for math? - c#

So, I am trying to wrap my head around understanding how you can use a variable to denote how many times a loop is nested.
Here is an example I write up to simulate the output of dimensions = 4:
static void Main(string[] args)
{
int dimensions = 4; // e.g. for (1, 2, 3, 4), dimensions = 4
Console.WriteLine($"{addNumbers(dimensions)}");
Console.ReadKey();
}
static long addNumbers(int dimensions)
{
long number = 0;
// hard coded to be dimensions = 4
for (int h = 0; h <= dimensions; h++)
for (int i = 0; i <= dimensions; i++)
for (int j = 0; j <= dimensions; j++)
for (int k = 0; k <= dimensions; k++)
number += h + i + j + k; // just some random math
return number;
}
This will present the expected output of:
5000
So to readdress the problem, how can I code to allow this for n dimensions? Thanks for your help!

For arbitrary n dimensions you can loop with a help of array int[] address which represents n dimensions:
static long addNumbers(int dimensions) {
int[] address = new int[dimensions];
// size of each dimension; not necessary equals to dimensions
// + 1 : in your code, int the loops you have i <= dimensions, j <= dimensions etc.
int size = dimensions + 1;
long number = 0;
do {
//TODO: some math here
// i == address[0]; j = address[1]; ... etc.
number += address.Sum();
// next address: adding 1 to array
for (int i = 0; i < address.Length; ++i) {
if (address[i] >= size - 1)
address[i] = 0;
else {
address[i] += 1;
break;
}
}
}
while (!address.All(index => index == 0)); // all 0 address - items're exhausted
return number;
}
Finally, let's add some Linq to look at the results:
int upTo = 5;
string report = string.Join(Environment.NewLine, Enumerable
.Range(1, upTo)
.Select(i => $"{i} -> {addNumbers(i),6}"));
Console.Write(report);
Outcome:
1 -> 1
2 -> 18
3 -> 288
4 -> 5000 // <- We've got it: 5000 for 4 dimensions
5 -> 97200

Related

Print all points in an infinite grid of n dimensions

I can not have infinite points stored in the computer, but what I mean by that is the max value of Int64 (long).
I could use a nested loop, but that would take an eternity to go to the next line, so I found another way.
All the points whose x and y values add upto n are on a diagonal.
(0,0) - 0
(1,0),(0,1) - 1
(2,0),(1,1),(0,2) - 2
(all of these are diagonals)
So we could iterate through all values of n, from 0 to max value of long, that would give us all the points on all the diagonals.
So I wrote the code to do this.
public void Main()
{
for(long i = 0; i < Int64.MaxValue; i++)
{
long[] a = new long[(i + 1)];
long[] b = new long[(i + 1)];
for(long j = 0; j <= i; j++)
{
a[j] = j;
b[j] = (i - a[j]);
}
f(a,b);
}
}
public void f(long[] a, long[] b)
{
string toPrint = "";
for(int i = 0; i < a.Length; i++)
{
toPrint += "(" + a[i] + "," + b[i] + "),";
}
Console.Write(toPrint + "\n\n");
}
It does the job for a grid of 2 dimensions, but I want it to work for n dimensions, the same idea applies

How can I stop 0 from appearing in my array

So I have a method which returns an array of the factors of a number
Tools.cs
public static long[] GetFactors(long number)
{
long range = number / 2;
long potentialFactors = 2;
long[] factors = new long[range + 1];
factors[0] = 1;
factors[range] = number;
for (long i = 1; i < range; i++)
{
if (number % potentialFactors == 0)
{
factors[i] = potentialFactors;
potentialFactors++;
} else
{
potentialFactors++;
}
}
Console.WriteLine($"here are the factors for the number {number}:\n"+string.Join("\n", factors));
return factors;
}
program.cs
static void Main(string[] args)
{
Tools.GetFactors(24);
Console.ReadLine();
}
But when I run my code, this appears:
here are the factors for the number 24:
1
2
3
4
0
6
0
8
0
0
0
12
24
How can I stop 0 from appearing, should I rewrite the "for" loop, or is there a way to remove 0 from the array?
You are allocating a fixed size array and setting the element to non-zero only when it is a factor.
You should instead use a var factors = new List<long>(); and call factors.Add(potentialFactor); to only store those numbers which are valid factors.
This code is using List instead of Array and also there are some other changes.
public static List<long> GetFactors(long number)
{
long range = number / 2;
List<long> factors = new List<long>() { 1 };
for (long i = 2; i <= range; i++)
{
if (number % i == 0)
{
factors.Add(i);
}
}
factors.Add(number);
Console.WriteLine($"here are the factors for the number {number}:\n" + string.Join("\n", factors));
return factors;
}
I agree a list is better when you dont know before hand how many factors you will gote. But if you really want to use an Array. You can loop throught this array, find the 0's one by one and them swith Left the numbers. Like so :
// Extension Method of array
public static void RemoveAllZeros(this long[] array) // O(N^2)
{
for (int i = 0; i < array.Length; i++)
{
if (array[i] == 0)
{
// Grab the index override value and continue swift left
for (int j = i; j < array.Length - 1; j++)
{
array[j] = array[j + 1];
}
}
}
}
OR using a bit of LINQ and List :p :
// Extension Method of array
public static void RemoveAllZeros(this long[] numbers)
{
int zeroPst = numbers.ToList().IndexOf(0);
if (zeroPst == -1)
return;
for (int i = zeroPst; i < numbers.Length - 1; i++)
{
numbers[i] = numbers[i + 1];
}
numbers.RemoveAllZeros(); //Recursion, carefull
}

Strand sort in c# using arrays only

i have a homework using strand sort and i must take the growing sequence of numbers from the initial array and merge them together in the array that represents our result (C#)
Like this one http://imgur.com/nQFzJw7
So far i did something like that
public static int[] Str(int[] a)
{
int i, j, x ,temp,k=0,count=1;
int size = a.Length;
int len = a.Length;
Strand = new int[size];
Merged = new int[size];
for (i = k; i < size; i++)
{
x = a[i];
Strand[0] = x;
for (i = k; i < size; i++) //checking if there's a bigger int than the first one
{
if (a[i] > x)
{
x = a[i];
}
}
for (i = k; i < len; i++)
{
if (a[i] == x) // checking if the max appears more than 1 time
{
temp = a[i];
a[i] = a[len];
a[len] = temp;
len--; //swaps the max numbers to the last position
Strand[count] = x;
count++;
}
}
for (i = 0; i < count; i++) // cant find a way to put in the final merged and sorted array
{
}
count = 1;
k++;
}
Any suggestions?
You always need to extract the first element into strand
strand[0] = a[0]
count = 1
Then you need to extract suitable elements into strand, shifting the rest of array
for i = 1 to size - 1
if a[i] >= strand[count - 1]
strand[count++] = a[i]
else
a[i - count] = a[i]
size = size - count
Then you need merge current strand and merged - look for Merge procedure from MergeSort
Repeat these steps until size becomes 0

Most efficient way to find the smallest index where its value minus the value of a previous index is smaller than a given x?

I have five long integers p, q, s, m and x. An array numbers[] is created by the following formula.
numbers[0] = s;
for(int i=1; i<numbers.Length;i++){
numbers[i] = (p * numbers[i-1] + q) % m;
}
The first value of numbers (numbers[0]) is s.
What is the most efficient way to find index j where i < j and |numbers[j] - numbers[i]| <= x or |numbers[j] - numbers[i]| >= m-x.
For instance, in a case where p = 3, q= 7, s= 1, m= 29 en x= 1 the array will be:
numbers[0] = 1, numbers[1] = 10, numbers[2] = 8 and numbers[3] = 2.
In this case index j would be 3, because numbers[3] - numbers[0]<=x, because x is 1.
I thought about using something such as a variant of counting sort or radix sort but I can't get anything to work.
As i < j, then you need to grant that numbers has a length of at least 2.
You could do two nested loops, the outer one ranging from j = 1 to numbers.Length - 1 (granting the possible solution to be the smallest j) to i = 0 to i < j.
Then you compare both positions according your specs. If true, return j. If it finishes both loops, then there is no solution.
Edit: Code Sample
public int GetSmallestIndex(long[] numbers, long x, long m)
{
if (numbers.Length >= 2)
{
for (int j = 1; j < numbers.Length; j++)
{
for (int i = 0; i < j; i++)
{
long diff = Math.Abs(numbers[j] - numbers[i]);
if (diff <= x || diff >= m - x)
return j;
}
}
}
return -1; //If no solution is found, return -1 as convention
}
The only way to find out if something is more efficient is to benchmark it by using the StopWatch in System.Diagnostics.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
public static void Main()
{
var stopWatch = new Stopwatch();
stopWatch.Start();
const long x = 1;
var numbers = new long[] {3, 7, 1, 29};
var theSmallestIndex = SmallestIndex(x, numbers);
stopWatch.Stop();
Console.WriteLine("Elapsed Time: {0}", stopWatch.Elapsed);
Console.WriteLine("Smallest Index: {0}", theSmallestIndex);
Console.ReadKey();
}
public static long SmallestIndex(long x, long[] numbers)
{
var values = ValuesMinusTheValueOfPreviousIndex(x, numbers.ToList());
var smallest = values.Values.OrderBy(n => n).FirstOrDefault();
var result = values.Where(n => n.Value.Equals(smallest));
return result.FirstOrDefault().Key;
}
public static Dictionary<int, long> ValuesMinusTheValueOfPreviousIndex(long x, List<long> numbers)
{
var results = new Dictionary<int, long>();
foreach (var number in numbers)
{
var index = numbers.IndexOf(number);
var previousNumber = index > 0 ? numbers.ElementAt(index - 1) : 0;
var result = number - previousNumber;
results.Add(index, result);
}
return results;
}
}
}
EDIT: Added Math.Abs as you requested in the comments
long p = 3, q = 7, s = 1, m = 29, x = 1;
long[] numbers = new long[10];
numbers[0] = s;
for (int i = 1; i < numbers.Length; i++)
{
numbers[i] = (p * numbers[i - 1] + q) % m;
}
// Find the smallest index j in numbers, where i < j &&
// (numbers[j] - numbers[i] <= x || numbers[j] - numbers[i] >= m-x)
int smallestIndex = 0;
long comparison;
for (int j = 1; j < numbers.Length; j++)
{
for (int i = 0; i < j; i++)
{
comparison = Math.Abs(numbers[j] - numbers[i]);
if (comparison <= x || comparison >= m - x)
{
smallestIndex = j;
break;
}
}
if (smallestIndex != 0) break;
}
if (smallestIndex == 0)
{
// No result matches the conditions
}
else
{
// j is the smallest index matching the conditions
// Before using Abs, in the example j is 2, because 8 - 10 = -2, lesser than x
// Now using absolute values, In the example j is 3
}

How do I get my code to work?

I have a one assignment
I have to make one dimension array with 20 numbers - first 10 numbers are from 1 do 10. others 10 numbers I have to get in method called Dopolni - where I have to sum together array with one another like - p11 = p0+p1, p12 = p1+p2, p14 = p2+p3 and so on - I dont know how to arrange it to get those other 10 numbers - help please
my code till now is
static void Dopolni(int[] p)
{
for (int i = 11; i < 20; i++)
{
p[i] = p[i] + 1;
}
}
static void Main(string[] args)
{
int[] p = new int[20];
for (int i = 1; i < 20; i++)
{
if (i <= 10)
{
p[i] += i;
}
Console.WriteLine("{0}", p[i]);
}
Dopolni(p);
Console.WriteLine(p);
Console.ReadKey(true);
}
All numbers I have to write out in main window. Hope someone can help out
The indices of the first 10 numbers range from 0 to 9, the others from 10 to 19. But since you always sum two consecutive numbers, you will only get 9 sums! In order to get 10 sums, you could start by summing 0 with p[0]:
int previous = 0;
for (int i = 0; i < 10; i++) {
p[i + 10] = previous + p[i];
previous = p[i];
}
public static void Main()
{
int[] p = new int[20];
for (int i = 0; i < 10; i++)
{
p[i] = i + 1;
ยจ
Console.WriteLine(p[i]);
}
Dopolni(p);
}
static void Dopolni(int[] p)
{
for (int i = 10; i < 20; i++)
{
p[i] = p[i - 10] + p[i - 9];
Console.WriteLine(p[i]);
}
}
This looks like trouble:
int[] p = new int[20];
Console.WriteLine(p);
What you want is to loop through p and print each element, not rely on the array implementation of ToString().
Try:
foreach (var n in p)
Console.WriteLine(n);
Do you need to have it in a function? Its really quite simple...
Notice I use 'out int[]', thats what your missing in your code. Out specifies you want in/out param, not just in ;)
static void Main()
{
int[] p = new int[20];
// First 10 numbers
for (int i = 0; i < 10; i++)
p[i] = i + 1;
Dolpini(out p);
foreach (int m in p)
Console.WriteLine(m);
}
static void Dolpini(out int[] numbers)
{
// Next 10 numbers
for (int k = 10; k < 20; k++)
p[k] = p[k-10] + p[k-9];
}

Categories

Resources