Storing numbers between two numbers in an array - c#

as you can read from the title I'm trying to store all the numbers between two numbers in an array.
For example store the numbers between 21 and 43 (22,23,24,25,26,27,28,29...) in an array.
This is the code, I don't know why but it prints only the higher number minus one.
class Program
{
static void Main(string[] args)
{
int higher = 43;
int lower = 21;
int[] numbers = new int[22]; //the numbers between 21 and 43 are 22
for (int i = lower; i < higher;i++)
{
for (int a = 0; a < 22; a++)
{
numbers[a] = i;
}
}
for (int c = 0; c < 22; c++)
{
Console.WriteLine(numbers[c]);
}
Console.ReadLine();
}
}

This is the code, I don't know why but it prints only the higher number minus one.
This question will attract answers giving you a half dozen solutions you can cut and paste to do your assignment.
I note you did not ask a question in your question -- next time, please format your question in the form of a question. The right question to ask here is how do I learn how to spot mistakes in code I've written? because that is the vital skill you lack. Answers that give you the code will not answer that question.
I already gave you a link to a recent answer where I explain that in detail, so study that.
In particular, in your case you have to read the program you wrote as though you had not written it. As though you were coming fresh to the program that someone else wrote and trying to figure out what it does.
The first thing I would do is look at the inner loop and say to myself "what does this do, in words?"
for (int a = 0; a < 22; a++)
{
numbers[a] = i;
}
That is "put the value i in every slot of the array. Now look at the outer loop:
for (int i = lower; i < higher;i++)
{
put the value i in every slot of the array
}
Now the technique to use here is to logically "unroll" the loop. A loop just does something multiple times so write that out. It starts with lower, it goes to higher-1, so that loop does this:
put the value lower in every slot of the array
put the value lower+1 in every slot of the array
…
put the value higher-1 in every slot of the array
What does the third loop do?
print every item in the array
And now you know why it prints the highest number minus one multiple times. Because that's what the program does. We just reasoned it out.
Incidentally the answers posted so far are correct, but some are not the best.
You have a technique that you understand for "do something to every member of an array, and that is:
loop an indexer from 0 to the array size minus one
do something to the array slot at the indexer
But the solutions the other answers are proposing are the opposite:
loop an indexer from the lower to the higher value
compute an index
do something to the array slot at that index
It's important to understand that both are correct, but my feeling is that for the beginner you should stick with the pattern you know. How would we
loop an indexer from 0 to the array size minus one
do something to the array slot at the indexer
for your problem? Let's start with giving you a much better technique for looping the indexer:
for (int i = 0; i < numbers.Length; ++i)
That's a better technique because when you change the size of the array, you don't have to change the loop! And also you are guaranteed that every slot in the array is covered. Design your loops so that they are robust to changes and have good invariants.
Now you have to work out what the right loop body is:
{
int number = i + lower;
numbers[i] = number;
}
Now you know that your loop invariant is "when the loop is done, the array is full of consecutive numbers starting at lower".

For everytime you loop through i, you put that number in every slot of the array. The inner loop is what is causing your issue. A better solution would be:
int higher = 43;
int lower = 21;
int[] numbers = new int[21];
int index = 0;
for (int i = lower + 1; i < higher; i++) // if you want to store everything
// between 21 and 43, you need to
// start with 22, thus lower + 1
{
numbers[index] = i;
index++;
}
for (int c = 0; c < 21; c++)
{
Console.WriteLine(numbers[c]);
}
Console.ReadLine();

Replace a with a direct translation of i
for (int i = lower; i < higher;i++)
{
numbers[i-lower] = i;
}

Use below
int higher = 43;
int lower = 21;
int[] numbers = new int[22]; //the numbers between 21 and 43 are 22
for (int i = lower+1; i < higher; i++)
{
numbers[i-lower] = i;
}
for (int c = 1; c < 21; c++)
{
Console.WriteLine(numbers[c]);
}
Console.ReadLine();

I think higher & lower are variables so following will give you output
for any higher and lower numbers
class Program
{
static void Main(string[] args)
{
int higher = 43;
int lower = 21;
int numDiff = higher - lower - 1;
int[] numbers = new int[numDiff]; //the numbers between 21 and 43 are 22
for(int i = 0; i<numbers.Length; i++)
{
numbers[i] = numDiff + i + 1;
}
for(int b = 0; b<numbers.Length; b++)
{
Console.WriteLine(numbers[b]);
}
Console.ReadLine();
}
}

Related

Which is the more efficient way to swap these list elements in C#? Why do they behave differently?

I'm doing brainteasers and exercises on hackerrank to prepare for an interview test and came across some weird behaviour.
The taks in question is Minimum Swaps 2 from the Interview Preparation Kit's Arrays section.
Depending on which of the two elements I put into my temporary variable, it either passes or fails on timeout on most test cases.
Version A:
static int minimumSwaps(int[] arr) {
int swaps=0;
int tmp=0;
int n = arr.Length;
for(int i = 0; i < n; i++){
if(arr[i]==i+1) continue;
tmp = arr[arr[i]-1];
arr[arr[i]-1] = arr[i];
arr[i] = tmp;
i--;
swaps++;
}
return swaps;
}
Version B
static int minimumSwaps(int[] arr) {
int swaps=0;
int tmp=0;
int n = arr.Length;
for(int i = 0; i < n; i++){
if(arr[i]==i+1) continue;
tmp = arr[i];
arr[i] = arr[arr[i]-1];
arr[arr[i]-1]=tmp;
i--;
swaps++;
}
return swaps;
}
A passes, B times out on all but one test.
What it actually does is find the minimum amount of swaps to sort an array of consecutive integers. That's why i can be used to compare values and indices.
If arr[i] is on the corresponding index, we continue, if it's wrong, we swap it with the index it's supposed to be at, decrement i and repeat.
I'm honestly at a loss as to why storing arr[arr[i]-1] in tmp is less complicated than storing arr[i] first. It must have something to do with the intermediate machine code it get's compiled to, right?
I'd be grateful for any explanation so I don't run into similar issues in the future.

Printing square with non repetitive character

I want to print a rectangle like this :
&#*#
#*#&
*#&#
#&#*
But problem is that i can't find the algorithm to print this.
I only know how to print a simple rectangle/square
public static void Main(string[] args)
{
Console.Out.Write("Saisir la taille : ");
int taille = int.Parse(Console.In.ReadLine());
int i;
int j;
for(i = 0; i < taille; i++){
for(j = 0; j < taille; j++){
Console.Write("*");
}
Console.WriteLine("");
}
}
Thank you !
First things first unless you need your iterators outside of your loop, just declare them in the for declaration
public static void Main(string[] args)
{
Console.Out.Write("Saisir la taille : ");
int taille = int.Parse(Console.In.ReadLine());
for(int i = 0; i < taille; i++){
for(int j = 0; j < taille; j++){
Console.Write("*");
}
Console.WriteLine("");
}
}
Second you'll need a list of the characters you want to use, given your example
char[] chars = { '&', `#`, `*`, '#' };
and we'll need a way to know which character we want to use at any given time, say an iterator we can call characterIndex for simplicity. We will increment it each iteration. If incrementing it puts it out of the range of our character array, if characterIndex == 4, we set it back to zero.
int characterIndex;
To get the scrolling effect you have, before each line we must select a characterIndex that is offset by the row
characterIndex = i % chars.Length;
Tying it all together
public static void Main(string[] args)
{
char[] chars = { '&', `#`, `*`, '#' };
int characterIndex;
Console.Out.Write("Saisir la taille : ");
int taille = int.Parse(Console.In.ReadLine());
for(int i = 0; i < taille; i++){
characterIndex = i % chars.Length;
for(int j = 0; j < taille; j++){
Console.Write(chars[characterIndex]);
characterIndex++;
if(characterIndex == chars.Length)
characterIndex = 0;
}
Console.WriteLine("");
}
}
Getting the permutations by nesting for loops will only work if you know exactly how many elements there will be. Basically you need to write a for-loop for every element after the 1st.
The proper way to deal with this is Recursion. While there are cases where Recursion and nested for-loops are interchangeable. And in cases where they are, for loops have a potential speed advantage. While normally the speed rant applies to such differences, with the sheer amount of data both Recursion and Loops might have to deal with, it often maters - so best to prefer loops where possible.
Permutations is AFAIK not a case where loops and recursion are interchangeable. Recurions seems to be mandatory. Some problem as simply inherently recursive. As the recursion version is fairly well known, I will not post any example code.
You should defiitely use Recursion. With your example code I basically asume you are:
In a learning environment
You just learned recursion
A input variant recurions can effortless solve (like a 6 or 20 size input), is the next assignment

C#: How should I go about shuffling contents of an array?

I have an array of integers called cards[52]. Each element contains an integer that represents a card (cards[0] = 5 would represent the 6 of clubs for example).
This is how I shuffled the array. It works, but I am getting repeats.
private void shuffleCards()
{
for (int i = 0; i < cards.Length; i++)
{
int randIndex = r.Next(0, 52);
int origCard = cards[i];
cards[i] = cards[randIndex];
cards[randIndex] = origCard;
}
}
r is the Random variable I initialized in the beginning of the program.
When testing the program, I noticed I would get the same card 2 or 3 times. Obviously I cannot get repeats, they all must be different. I can't see in any way how this method gives me repeats.
How can I shuffle this array without any repeats? Thanks.
EDIT
Okay, turns out the shuffle function wasn't the problem. It is the deal() function that is causing the problem.
private void deal()
{
for (int i = 0; i < 26; i++)
{
userCards[i] = cards[i];
setUserValue(); //ignore this
}
for (int i = 26; i < 52; i++)
{
opponentCards[i - 26] = cards[i];
setOpponentValue(); //ignore this
}
}
I know for sure it isn't the shuffle function. I printed the results of all the cards to a text file and saw no iterations. However, when the cards are dealt to the user and the opponent, that's when all the iterations occur. Any advice?
There is very simple algorithm known as Fisher Yates shuffling algorithm which does the shuffling in O(n) time and O(1) space complexity.
Use a random function that generates a random index from the given set and replace the random element generated with the last index. Decrement last index and continue like this for the rest of elements.
Let the array of size n be : arr[n]
void randomize ( int arr[], int n )
{
// Use a different seed value so that we don't get same
// result each time we run this program
srand ( time(NULL) );
// Start from the last element and swap one by one. We don't
// need to run for the first element that's why i > 0
for (int i = n-1; i > 0; i--)
{
// Pick a random index from 0 to i
int j = rand() % (i+1);
// Swap arr[i] with the element at random index
swap(&arr[i], &arr[j]);
}
}
Source : Algorithm

What is wrong with my code (it deals with array size)?

I am initializing array size to 1 but I am updating it in the subsequent lines. It is not even storing the first element in the array as the array size is 1 initially but I expected it would. Could someone provide me with an explanation? Here is the code:
class Program
{
static void Main(string[] args)
{
int num = int.Parse(Console.ReadLine());
Console.Write("The binary number for " + num + " is ");
int size = 1;
int[] binary = new int[size];
size = 0;
while(num>=1)
{
if (num % 2 == 0)
binary[size++] = 0;
else
binary[size++] = 1;
//size += 1;
num = num / 2;
}
for (int i = size - 1; i >= 0; i--)
{
Console.Write(binary[i]);
}
Console.WriteLine();
Console.Write("The Compliment of this number is ");
for (int i = size - 1; i >= 0; i--)
{
if (binary[i] == 0)
binary[i] = 1;
else
binary[i] = 0;
}
for (int i = size - 1; i >= 0; i--)
{
Console.Write(binary[i]);
}
Console.WriteLine();
Console.ReadKey();
}
}
You cannot resize an array, it always has the length you gave it to during initialization (1 in your case).
I think the problem is specifically in your expectation that you can update an array size "in the subsequent lines."
When you make the array here:
int[] binary = new int[size];
Then the size is set in stone
When you call something like:
binary[size++] = 0;
This will not actually increase the number of slots in your array. In fact, that code is only changing the index where you are looking to read or write values. I can see that your code is going to quickly go out of bounds of the array (if you ask for anything but binary[0]
It turns out this array is a tricky data type to use; arrays have a fixed size on creation. You want something that can grow!
So you can either:
-Use an array, but declare that it's size is Math.Ciel(logbase2(yourNumber)) to make sure you will have enough space
-Use a data structure that can grow, like a string or list
-You can create a new array every time you need it bigger and assign it like:
binary = new int[++size];
binary[size-1]=whatever
Good luck, hope this helps!

Im trying scramble randomaly strings but some of the strings dosen't get scrambled at all what could it be?

This is the code:
private static StringBuilder MakeRandomwords(string theWord)
{
var jumbleSb = new StringBuilder();
jumbleSb.Append(theWord);
int lengthSb = jumbleSb.Length;
for (int i = 0; i < lengthSb; ++i)
{
int index1 = (RandomGen.Next() % lengthSb);
int index2 = (RandomGen.Next() % lengthSb);
Char temp = jumbleSb[index1];
jumbleSb[index1] = jumbleSb[index2];
jumbleSb[index2] = temp;
}
return jumbleSb;
}
And this is the List that im using to build the scrambled words:
private void GetText()
{
_lengthaboveone = new List<string>();
for (int i = 0; i < _words.Count; i++)
{
string word = _words[i];
if (word.Length < 4) continue;
string first = word.Substring(0, 1);
string last = word.Substring(word.Length - 1, 1);
string middle = word.Substring(1, word.Length - 2);
_lengthaboveone.Add(middle);
_words[i] = first + MakeRandomwords(middle) + last;
}
_scrambledWords = _words;
}
In the end the List _scrambledWords contain over 1000 strings in each index a string of a word most of them scrambled but some of them are left the same as they were in the original.
The question is if there is something wrong with my MakeRandomwords ?
Could be it did scrambled the word and it was scrambled to how it was before ? So maybe i need to add something to the code that will keep scramble the word untill the word is scrambled by compraing it ot the original untill the word is scrambled ?
Take a look at the Fisher–Yates shuffle algorithm and implement the following pseudo code to achieve a good distribution of elements:
To shuffle an array a of n elements (indices 0..n-1):
for i from n − 1 downto 1 do
j ← random integer with 0 ≤ j ≤ i
exchange a[j] and a[i]
To elaborate on Tim Schmelter's comment asking about RandomGen.Next(), in case you've been wondering: If you instantiate a new Random instance every time you're entering the for loop, the generated pseudo-random numbers will by nature be quite repetitive. This is due to the way that the Random class is implemented in the .NET framework. By reusing a shared instance like you do, one can avoid that issue.
This is not the problem here, though. In your algorithm, you're picking two random array elements and swapping them. It's highly likely that there are some array elements that never get selected this way. Thus, there's a good chance that some elements won't have changed their position in the array when you're done, which is why it doesn't look shuffled well.
Instead of randomly swapping two locations, swap every location to a random location... it will look more random because each element will have moved. With your current design there is a good chance some items won't ever move.
for (int i = 0; i < lengthSb; ++i)
{
int index1 = i;
int index2 = (RandomGen.Next() % lengthSb);
Char temp = jumbleSb[index1];
jumbleSb[index1] = jumbleSb[index2];
jumbleSb[index2] = temp;
}

Categories

Resources