Adding a value to the Array inside a while loop - c#

I am making a program to run Fibonacci series. I have created 2 array.
1st array holds only 0, 1 (Array Name :- int[] arr)
2nd array holds other values eg: 1, 2, 3, 5..........etc ( Array Name:- int[] numbers)
I am using while loop to get the febonacci series and storing it in a 2nd array called int[] numbers.
after getting value using while loop, I am joing both the arrays using
int[] final = arr.Concat(number).ToArray();
At last, I have used foreach loop to add the febonacci series into the listbox.
The problem I have is that, I cannot able to concat both the arrays. I tried to assign number array at the top of the while loop. so that number variable will be accessible outside the while loop. But I am getting a error.
See the code below:
private void button1_Click(object sender, EventArgs e)
{
int x = 0;
int y = 1;
int z = 0;
if (!String.IsNullOrEmpty(q1input.Text))
{
int value;
if (int.TryParse(q1input.Text, out value))
{
int[] arr = {x, y };
while (z < value)
{
z = x + y;
int[] number = {z};
x = y;
y = z;
}
int[] final = arr.Concat(number).ToArray();
foreach (int num in final)
{
q2listbox.Items.Add(num);
}
}
else
{
MessageBox.Show("It is not a numeric value");
}
}
else
{
MessageBox.Show("Invalid Input");
}
}

List<int> number = new List<int>();
while (z < value)
{
z = x + y;
number.Add(z);
x = y;
y = z;
}
int[] final = arr.Concat(number).ToArray();

It might help if you separate your concerns: computing a Fibonacci sequence should be separated from your user interface code.
Part of your problem is that you're working with arrays (fixed length) in C# building something that adjustable in length. List<T> is a better data structure for your purposes. Despite its misleading name, it is an adjustable-length array rather than an actual list in the computer science sense.
Generating a Fibonacci sequence isn't as complicated as you're making it. This implementation:
public int[] FibonacciSequence( int x1 , int x2 , int upperBound )
{
if ( x1 < 0 ) throw new ArgumentException("x1 can't be negative") ;
if ( x2 < 0 ) throw new ArgumentException("x2 can't be negative") ;
if ( x1 == 0 && x2 == 0 ) throw new ArgumentException("x1 and x2 can't both be zero.") ;
List<int> values = new List<int>() ; // use List<int>, since we don't know the length in advance
values.Add(x1) ; // the first 2 elements are given
values.Add(x2) ;
// the remaining elements are computed by summing the previous two elements and shifting.
for ( int x = x1+x2 ; x > 0 && x < upperBound ; x = x1+x2 )
{
// add the new value to the list of values
values.Add(x) ;
x1 = x2 ; // x1 receives x2 (with the current x1 shifting off into oblivion
x2 = x ; // x2 receives x
}
int[] sequence = values.ToArray() ;
return sequence ;
}
There's no rule, just convention, that a Fibonacci sequence starts with [0,1] or [1,1]. You can then invoke this function with your desired seeds, thus:
int[] fibonacci = FibonacciSequence(1,1,int.MaxValue) ;
The cool thing about a Fibonacci sequence is that regardless of the seed values, the further out you go in the sequence, the ratio of any two adjacent values converges towards phi, the Golden Mean.
Even easier is to use some of LINQ's functionality-cum-magick. Using that, your Fibonnaci sequence becomes even simpler:
public IEnumerable<int> FibinacciSequence( int x1 , int x2 )
{
yield return x1 ;
yield return x2 ;
for ( int x = x1+x2 ; x > 0 && x < int.MaxValue ; x = x1+x2 )
{
yield return x ;
x1 = x2 ;
x2 = x ;
}
}
And its usage becomes something like:
int[] sequence = FibonacciSequence(1,1)
.TakeWhile( x => x < upperBound )
.ToArray()
;
You can even skip the 'ToArray() bit and simply say something like
foreach ( int value in FibonacciSequence(1,1).TakeWhile( x => x < upperBound ) )
{
q2listbox.Items.Add( value ) ;
}
which will evaluate the sequence in a lazy manner as you add each value to your list box.

Related

How to rotate an array by moving N elements from end to start?

I am trying to move a number of elements in an array to the end using C#.
I have an Array (in my case a char-array), and a integer z. Now I want to move z chars to the end of another array, the other chars should move to the beginning of the array.
So if the first array is {'H','E','L','L','O'} and z = 3, the new array should be {'L','O','H','E','L'}.
I hope somebody can help me.
Best attempt:
static char[] rotate(char[] c, int z)
{
char[] nc = new char[c.Length];
for (int i = z; i < c.Length; i++)
{
nc[i - z] = c[i];
}
for (int i = 0; i < z; i++)
{
nc[i + z] = c[i];
}
return nc;
}
The problem was with the wrong indexing that was in your code.
Here's the fixed version:
static char[] rotate(char[] c, int z)
{
char[] nc = new char[c.Length];
for (int i = z; i < c.Length; i++)
{
nc[i - z] = c[i];
}
for (int i = 0; i < z; i++)
{
nc[i + z - 1] = c[i]; // <-- Change here
}
return nc;
}
However, a better solution could be the usage of doubly-linked lists that handles movement of the array items to start/end better. .NET implementation of doubly-linked list is LinkedList Class. And here you can find some examples of how to do that.
Just use Array.Copy
Copies a range of elements in one Array to another Array and performs
type casting and boxing as required.
public static void DoStuff<T>(T[]source, int z)
{
var start = source[0..z];
Array.Copy(source, z, source, 0, source.Length - z);
Array.Copy(start, 0, source, source.Length - z, z);
}
Test
var chars = "asdfghjk".ToCharArray();
DoStuff(chars, 3);
Console.WriteLine(string.Join(", ", chars));
Another way with an iterator
public static IEnumerable<T> DoStuff<T>(T[]source, int z)
=> source.Select((t, i) => source[(i + z) % source.Length]);
Or using a for loop
public static T[] DoStuff<T>(T[]source, int z)
{
var result = new T[source.Length];
for (int i = 0; i < source.Length; i++)
result[i] = source[(i + z) % source.Length];
return result;
}
Super efficient zero allocations
public static unsafe void DoStuff(char[] source, int z)
{
var start = stackalloc char[source.Length];
fixed (char* pArray = source)
{
Buffer.MemoryCopy(pArray, start, z*sizeof(char), z * sizeof(char));
Buffer.MemoryCopy(pArray+z, pArray, (source.Length-z)*sizeof(char) , (source.Length - z) * sizeof(char));
Buffer.MemoryCopy(start, pArray+ (source.Length - z), z * sizeof(char), z * sizeof(char));
}
}
Output
f, g, h, j, k, a, s, d
Note : This lacks suitable input validation and range checking, and a descriptive name. I'll leave that up to you
You can use LINQ in a single line without working on the array like that:
using System.Linq;
var letters = new[] { 'H', 'E', 'L', 'L', 'O' };
int posToRotate = 3;
var lettersRotated = letters.Skip(posToRotate).Concat(letters.Take(posToRotate)).ToArray();
Console.WriteLine(new string(lettersRotated));
That assumes letters is allocated and not null.
If the position is over than the length, nothing is done, but it can be checked before to avoid the processing (also negative indexes can be checked).
We skip the first N characters (to take the rest), then we add the first N characters we take.
We call ToArray because LINQ works on IEnumerable<> (and IQueryable<>), so execution is deferred until that here.
To replace the original array, just write:
letters = letters.Skip(posToRotate).Concat(letters.Take(posToRotate)).ToArray();
Output
LOHEL

Method to guess possible combination

For practice I want to write a program that will guess random positions of x and y. For example the first point would be
int x = 0;
int y = 0;
x += rand.Next(0, 4);
y += rand.Next(0, 4);
Then from that random point I will add the another random value to x and y to have a second point. However I want to go back to find those points randomly.
To make the points:
int x = 0;
int y = 0;
List<Point> points = new List<Point>();
for (int i = 0; i < numberOfPointsWanted; i++)
{
x += rand.Next(0, 4);
y += rand.Next(0, 4);
points.Add(new Point(x, y));
}
Now I wish to guess those random points almost as if I did not have them stored in a list. Because each new point relies on its predecessor I assume some sort of recursion would be necessary. Almost like a brute force guessing application that will find those points. I am having trouble completing the method that would be able to guess every possible point given a number of desired points.
This is what I have thus far to find the rounds:
class Program
{
static int nRounds = 2;
static Point[] points = new Point[nRounds];
static Point[] test = { new Point(1, 2), new Point(4, 1) };
static bool CheckArray()
{
for (int i = 0; i < points.Length; i++)
if (points[i] != test[i]) { return false; }
return true;
}
static void PrintArray()
{
for (int i = 0; i < points.Length; i++)
Console.Write("[" + tCount + "]\t" + points[i].X + " : " + points[i].Y + "\t");
Console.Write("\n");
}
static int tCount = 0;
static int rCount = 0;
static void GetRounds(int inX, int inY)
{
for (int x = inX; x < 5; x++)
{
for (int y = inY; y < 5; y++)
{
if (rCount < nRounds)
{
tCount++;
points[rCount] = new Point(x, y);
rCount++;
GetRounds(x, y);
if (CheckArray())
{
PrintArray();
return;
}
PrintArray();
}
}
}
rCount--;
}
static void Main(string[] args)
{
GetRounds(0, 0);
Console.ReadKey();
}
}
}
I am trying to randomly generate points as shown above and then guess them based on a hashed value representing all of those points together.
This is what im expecting to see:
If only guessing two points
Point one :: Point two x and y respectively
x y :: x y
0 0 :: 0 1
0 0 :: 0 2
0 0 :: 0 3
0 0 :: 1 0
0 0 :: 1 1
0 0 :: 1 2
0 0 :: 1 3
0 0 :: 2 0
0 0 :: 2 1
0 0 :: 2 2
0 0 :: 2 3
0 0 :: 3 0
0 0 :: 3 1
0 0 :: 3 2
0 0 :: 3 3
0 1 :: 0 0
0 1 :: 0 1
0 1 :: 0 2
And so on until all possibilities of point one and point two are guessed
I'm not sure if this is exactly what you're looking for, but one way to get all those combinations is to use nested for loops:
for (int ax = 0; ax < 4; ax++)
{
for (int ay = 0; ay < 4; ay++)
{
var pointA = new Point(ax, ay);
for (int bx = 0; bx < 4; bx++)
{
for (int by = 0; by < 4; by++)
{
var pointB = new Point(bx, by);
Console.WriteLine($"{pointA.X} {pointA.Y} :: {pointB.X} {pointB.Y}");
}
}
}
}
Output
You were asking about a solution that would allow a variable number of points to be passed in. This is fairly simple to do - you just keep a List<List<Point>> of the results, and on each iteration you generate a list of possible point values (16 possible values when min is 0 and max is 3), and then generate a new list for every item in the existing results for each Point in the new set.
The problem is the size of the result set. Since a single point has 16 possible combinations of X and Y if we have a min value of 0 and a max value of 3, then for each additional point, we raise 16 to that power. So for 10 points, there are over a billion combinations.
private static List<List<Point>> GetAllCombinations(int min, int max, int count)
{
var results = new List<List<Point>>();
for (int i = 0; i < count; i++)
{
var thisSet = new List<Point>();
for (int x = min; x <= max; x++)
{
for (int y = min; y <= max; y++)
{
thisSet.Add(new Point(x, y));
}
}
// If this is our first time through, we just add each point
// as a single-item list to our results
if (results.Count == 0)
{
foreach (var item in thisSet)
{
results.Add(new List<Point> {item});
}
}
// On subsequent iterations, for each list in our results, and
// for each item in this set, we create a new list for each item,
// adding to it a copy of the existing result list. We clear
// the results in the beginning (after making a copy) and then
// add each new list to it in the inner loop.
else
{
// Make a copy of our existing results and clear the original list
var tempResults = results.ToList();
results.Clear();
foreach (var existingItem in tempResults)
{
foreach (var newPoint in thisSet)
{
// Now we populate our results again with a new set of
// lists for each existingItem and each newPoint
var newItem = existingItem.ToList();
newItem.Add(newPoint);
results.Add(newItem);
}
}
}
}
return results;
}
Example usage:
private static void Main()
{
var results = GetAllCombinations(0, 3, 5);
foreach (var result in results)
{
Console.WriteLine(string.Join(" :: ", result.Select(p => $"{p.X} {p.Y}")));
}
Console.WriteLine("With a min value of 0 and max value of 3, " +
$"5 points generated {results.Count} results.");
GetKeyFromUser("Done! Press any key to exit...");
}
Output

Why aren't 10 and 100 considered Kaprekar numbers?

I'm trying to do the Modified Kaprekar Numbers problem (https://www.hackerrank.com/challenges/kaprekar-numbers) which describes a Kaprekar number by
Here's an explanation from Wikipedia about the ORIGINAL Kaprekar
Number (spot the difference!): In mathematics, a Kaprekar number for a
given base is a non-negative integer, the representation of whose
square in that base can be split into two parts that add up to the
original number again. For instance, 45 is a Kaprekar number, because
45² = 2025 and 20+25 = 45.
and what I don't understand is why 10 and 100 aren't Kaprekar numbers.
10^2 = 1000 and 10 + 00 = 10
Right?
So my solution
// Returns the number represented by the digits
// in the range arr[i], arr[i + 1], ..., arr[j - 1].
// If there are no elements in range, return 0.
static int NumberInRange(int[] arr, int i, int j)
{
int result = 0;
for(; i < j; ++i)
{
result *= 10;
result += arr[i];
}
return result;
}
// Returns true or false depending on whether k
// is a Kaprekar number.
// Example: IsKaprekar(45) = true because 45^2=2025 and 20+25=45
// Example: IsKaprekar(9) = false because the set of the split
// digits of 7^2=49 are {49,0},{4,9} and
// neither of 49+0 or 4+9 equal 7.
static bool IsKaprekar(int k)
{
int square = k * k;
int[] digits = square.ToString().Select(c => (int)Char.GetNumericValue(c)).ToArray();
for(int i = 0; i < digits.Length; ++i)
{
int right = NumberInRange(digits, 0, i);
int left = NumberInRange(digits, i, digits.Length);
if((right + left) == k)
return true;
}
return false;
}
is saying all the Kaprekar numbers between 1 and 100 are
1 9 10 45 55 99 100
whereas the "right" answer is
1 9 45 55 99
In 100+00 the right is 00, which is wrong because in a kaprekar number the right may start with zero (ex: 025) but cannot be entirely 0.
Therefore you can put a condition in the loop that
if(right==0)
return false;
The reason is because 10 x 10 = 100. Then you substring the right part with a length equals d = 2, that is digit count of original value (10), then the left part would be 1.
So l = 1 and r = 00, l + r = 1, that is not equals to 10.
The same for 100. 100 x 100 = 10000. l = 10, r = 000, so l + r = 10 not equal 100.
Here is my solution in JAVA.
static void kaprekarNumbers(int p, int q) {
long[] result = IntStream.rangeClosed(p, q).mapToLong(Long::valueOf)
.filter(v -> {
int d = String.valueOf(v).length();
Long sq = v * v;
String sqSt = sq.toString();
if (sqSt.length() > 1) {
long r = Long.parseLong(sqSt.substring(sqSt.length() - d));
long l = Long.parseLong(sqSt.substring(0, sqSt.length() - d));
return r + l == v;
} else return v == 1;
}).toArray();
if (result.length > 0) {
for (long l : result) {
System.out.print(l + " ");
}
} else {
System.out.println("INVALID RANGE");
}
}
How about something like this.
static bool IsKaprekar(int k)
{
int t;
for (int digits = new String(k).length(); digits > 0; digits--, t *= 10);
long sq = k * k;
long first = sq / t;
long second = sq % t;
return k == first + second;
}
find a number to divide and mod the square with in order to split it. This number should be a factor of 10 based on the number of digits in the original number.
calculate the square.
split the square.
compare the original to the sum of the splits.

C# char Conversion/Append to/with int, int64, string

Lately I have been working through Project Euler, specifically
https://projecteuler.net/problem=4
I create to arrays
Multiply them together
Convert the number in a CharArry
Compare the numbers
If true, my problem arises
I attempt to convert the char back to an int, or long, or string,
and
I have attempted to append the char to an int, or long, or string, or whatever
void Main()
{
int[] arrOne = new int[900]; // Initializing Array One
int[] arrTwo = new int[900]; // Initializing Array Two
Console.WriteLine(PopulateAndConvert(arrOne, arrTwo)); // Sending info into class
}
int PopulateAndConvert(int[] a, int[] b)
{
char[] c = new char[1]; // char used to store tested number
//string[] m = new string[a.Length*b.Length];
long l = 0; // Used for testing code
for(int i = 0; i < a.Length; i++) // Populating Arrays One and Two
{
a[i] = i + 100;
b[i] = i + 100;
}
for(int j = a.Length-1; j >= 0; j--) // Beginning for-loops for multiplication and testing
{
//Console.WriteLine(j);
for(int k = b.Length-1; k >= 0; k--) // Second part of for-loop previously mentioned
{
//Console.WriteLine(k);
c = (a[j] * b[k]).ToString().ToCharArray(); // Where the math and conversion happens
//Console.WriteLine(c);
if(c.Length > 5) // Checking if digit of product is greater than 5
{
if((c[0] == c[c.Length-1]) && // Comparing first and second half of product
(c[1] == c[c.Length-2]) &&
(c[2] == c[c.Length-3]))
{
/*for(int n = 0; n < c.Length; n++) // Last tidbit of code that was being attempted
sb[l].Append(Convert.ToInt32(c[0]));
l++;
Console.WriteLine(sb); */
}
}
else if (c.Length < 5) // Product with less than 6 digits go here
{
if((Convert.ToInt32(c[0]) == Convert.ToInt32(c[4])) &&
(Convert.ToInt32(c[1]) == Convert.ToInt32(c[3])))
{
//m[l] = Convert.ToChar(c); l++;
}
}
}
}
// Everything below was used to check the code that I have been trying to work through
// And to place the given products in a ascending or descending order
//foreach (char x in m)
// Console.WriteLine(m);
//IEnumerable<char> sortDescendingQuery =
// from num in c
// orderby num descending
// select num;
return 0;
}
After some time (resting the mind is always beneficial) I found a solution:
if(c.Length > 5) // Checking if digit of product is greater than 5
{
int[] n = new int[c.Length];
StringBuilder sb = new StringBuilder();
if((c[0] == c[c.Length-1]) && // Comparing first and second half of product
(c[1] == c[c.Length-2]) &&
(c[2] == c[c.Length-3]))
{
for(int l = 0; l < c.Length; l++) // Converting each value in the char array to a stringbuilder
{
sb.Append(Convert.ToInt32(new string(c[l], 1)));
}
m[q] = Int32.Parse(sb.ToString()); // Converting stringbuilder into string and then into a long
q++;
}
}
I had to convert each individual value within the char array c[] to a string, then an int, then append it to the string builder sb.
After that I then convert sb to a string (via ToString()) and Parse it to an int.
It seems like a long work around, but it works.
Now I need to Sort it numerically (another hurdle).

Is there a method to find the max of 3 numbers in C#?

The method should work like Math.Max(), but take 3 or more int parameters.
You could use Enumerable.Max:
new [] { 1, 2, 3 }.Max();
Well, you can just call it twice:
int max3 = Math.Max(x, Math.Max(y, z));
If you find yourself doing this a lot, you could always write your own helper method... I would be happy enough seeing this in my code base once, but not regularly.
(Note that this is likely to be more efficient than Andrew's LINQ-based answer - but obviously the more elements you have the more appealing the LINQ approach is.)
EDIT: A "best of both worlds" approach might be to have a custom set of methods either way:
public static class MoreMath
{
// This method only exists for consistency, so you can *always* call
// MoreMath.Max instead of alternating between MoreMath.Max and Math.Max
// depending on your argument count.
public static int Max(int x, int y)
{
return Math.Max(x, y);
}
public static int Max(int x, int y, int z)
{
// Or inline it as x < y ? (y < z ? z : y) : (x < z ? z : x);
// Time it before micro-optimizing though!
return Math.Max(x, Math.Max(y, z));
}
public static int Max(int w, int x, int y, int z)
{
return Math.Max(w, Math.Max(x, Math.Max(y, z)));
}
public static int Max(params int[] values)
{
return Enumerable.Max(values);
}
}
That way you can write MoreMath.Max(1, 2, 3) or MoreMath.Max(1, 2, 3, 4) without the overhead of array creation, but still write MoreMath.Max(1, 2, 3, 4, 5, 6) for nice readable and consistent code when you don't mind the overhead.
I personally find that more readable than the explicit array creation of the LINQ approach.
Linq has a Max function.
If you have an IEnumerable<int> you can call this directly, but if you require these in separate parameters you could create a function like this:
using System.Linq;
...
static int Max(params int[] numbers)
{
return numbers.Max();
}
Then you could call it like this: max(1, 6, 2), it allows for an arbitrary number of parameters.
As generic
public static T Min<T>(params T[] values) {
return values.Min();
}
public static T Max<T>(params T[] values) {
return values.Max();
}
off topic but here is the formula for middle value.. just in case someone is looking for it
Math.Min(Math.Min(Math.Max(x,y), Math.Max(y,z)), Math.Max(x,z));
Let's assume that You have a List<int> intList = new List<int>{1,2,3} if You want to get a max value You could do
int maxValue = intList.Max();
Maximum element value in priceValues[] is maxPriceValues :
double[] priceValues = new double[3];
priceValues [0] = 1;
priceValues [1] = 2;
priceValues [2] = 3;
double maxPriceValues = priceValues.Max();
If, for whatever reason (e.g. Space Engineers API), System.array has no definition for Max nor do you have access to Enumerable, a solution for Max of n values is:
public int Max(int[] values) {
if(values.Length < 1) {
return 0;
}
if(values.Length < 2) {
return values[0];
}
if(values.Length < 3) {
return Math.Max(values[0], values[1]);
}
int runningMax = values[0];
for(int i=1; i<values.Length - 1; i++) {
runningMax = Math.Max(runningMax, values[i]);
}
return runningMax;
}
You could try this code:
private float GetBrightestColor(float r, float g, float b) {
if (r > g && r > b) {
return r;
} else if (g > r && g > b) {
return g;
} else if (b > r && b > g) {
return b;
}
}
This function takes an array of integers. (I completely understand #Jon Skeet's complaint about sending arrays.)
It's probably a bit overkill.
public static int GetMax(int[] array) // must be a array of ints
{
int current_greatest_value = array[0]; // initializes it
for (int i = 1; i <= array.Length; i++)
{
// compare current number against next number
if (i+1 <= array.Length-1) // prevent "index outside bounds of array" error below with array[i+1]
{
// array[i+1] exists
if (array[i] < array[i+1] || array[i] <= current_greatest_value)
{
// current val is less than next, and less than the current greatest val, so go to next iteration
continue;
}
} else
{
// array[i+1] doesn't exist, we are at the last element
if (array[i] > current_greatest_value)
{
// current iteration val is greater than current_greatest_value
current_greatest_value = array[i];
}
break; // next for loop i index will be invalid
}
// if it gets here, current val is greater than next, so for now assign that value to greatest_value
current_greatest_value = array[i];
}
return current_greatest_value;
}
Then call the function :
int highest_val = GetMax (new[] { 1,6,2,72727275,2323});
// highest_val = 72727275
You can use if and else if method for three values but it would be much easier if you call call twice Math.Max method like this
Console.WriteLine("Largest of three: " + Math.Max(num1, Math.Max(num2, num3)));
Console.WriteLine("Lowest of three: " + Math.Min(num1, Math.Min(num2, num3)));
If you don't want to repeatedly calling the Max function, can do like this
new List<int>() { A, B, C, D, X, Y, Z }.Max()
in case you need sorting as well:
var side = new double[] {5,3,4}
Array.Sort(side);
//side[2] is a maximum
as an another variant:
T[] GetMax<T>(int number, List<T> source, T minVal)
{
T[] results = new T[number];
for (int i = 0; i < number; i++)
{
results[i] = minVal;
}
var curMin = minVal;
foreach (var e in source)
{
int resComp = Comparer.DefaultInvariant.Compare(curMin, e);
if (resComp < 0)
{
int minIndex = Array.IndexOf(results, curMin);
results[minIndex] = e;
curMin = results.Min();
}
}
return results;
}
var source = new int[] { 5, 5, 1, 2, 4, 3 }.ToList();
var result = GetMax(3, source, int.MinValue);

Categories

Resources