Printing square with non repetitive character - c#

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

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.

Storing numbers between two numbers in an array

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();
}
}

Square of Stars [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
namespace SquareStars
{
class Program
{
static void Main(string[] args)
{
var n = int.Parse(Console.ReadLine());
for (int i = 0; i <n-1; i++)
{
Console.Write("*");
}
for (int i = 0; i < n-1; i++)
{
Console.WriteLine("*");
}
for (int i = 0; i < n; i++)
{
Console.Write("*");
}
}
}
}
My exercises is to do Square of Stars like this:
depends of "n".I try to use for loops,but I can do right side of square.
I do this:
***
*
***
but I want this:
*** ****
* * * *
*** or * *
****
Can sameone help me to this code????
The following should do:
public static string CreateASCIISquare(int squareSideLength, char c = '*')
{
if (squareSideLength < 1)
return "";
if (squareSideLength == 1)
return c.ToString();
var horizontalOuterRow = new String(c, squareSideLength);
var horizontalInnerRow = $"{c}{new string(' ', squareSideLength - 2)}{c}";
var squareBuilder = new StringBuilder();
squareBuilder.AppendLine(horizontalOuterRow);
for (int i = 0; i < squareSideLength - 2; i++)
{
squareBuilder.AppendLine(horizontalInnerRow);
}
squareBuilder.Append(horizontalOuterRow);
return squareBuilder.ToString();
}
Ok, so lets explain the code a little bit:
Always validate the data going into your method. In your case the user can specify the length of the square's side. Are there any invalid values? Well clearly yes, -2 doesn't seem to be a valid choice.
You have many options here. You can tell the user the value is not valid, you can simply ignore it, do nothing and let your application crash and die miserably, or you can return an empty square. All are valid choices, but consciously choose one and design according to your decision. In my case I chose to return an empty square:
if (squareSideLength < 0)
return "";
Are there any trivial cases I can manage easily without for loops and Console.Writes etc.? Yes, lengths 0 and 1 seem pretty straightforward. It stands to reason that if I've returned the empty square for negative values, I do the same for 0 sized squares. So I change the previous code to:
if (squareSideLength < 1)
return "";
Good, now what about 1? Well that's pretty easy too isn't it?
if (squareSideLength == 1)
return c.ToString();
Moral of the story: take care of invalid data or trivial cases first. Many times trivial cases can also be corner cases that can complicate your general solution, get them out of the way fast!
Ok, now lets think about what a square looks like:
**
**
***
* *
***
****
* *
* *
****
Well the pattern seems pretty obvious. A square is made up of two rows containing the specified number of stars, and 0 or more rows containing only 2 stars and squareSideLength - 2 spaces in between. Well, its only two types of rows, lets build them up front:
var horizontalOuterRow = new String(c, squareSideLength);
var horizontalInnerRow = $"{c}{new string(' ', squareSideLength - 2)}{c}";
Great! We got our building blocks, now lets build our square:
So how does that go? Well we simply start by adding a horizontalOuterRow then we add the squareSideLength - 2 horizontalInnerRows and we finish up adding one more horizontalOuterRow.
And voilá, we got ourselves our nice little ASCII square:
squareBuilder.AppendLine(horizontalOuterRow);
for (int i = 0; i < squareSideLength - 2; i++)
{
squareBuilder.AppendLine(horizontalInnerRow);
}
squareBuilder.Append(horizontalOuterRow);
The fact that I've used a StringBuilder is not really germane to the question, but get into the habit of using this tool when constructing dynamically built strings you don't know the length of beforehand. Concatenating strings can give you pretty bad performance so it's best to avoid it if possible.
Now we proudly return our beautiful ASCII square back to our extatic user and bask under the general round of applause:
return squareBuilder.ToString();
Hope this little answer helps you.
Remember, to code well, break everything up into very small tasks, and take care of them one at a time. Think how you'd do it by hand and write it that way. Once you have it working there'll be time to see if you need to optimize, refactor, etc. your code. But the key is getting it to work with code as clear as possible.
You can use the string(char, int) constructor to create strings of repeating characters. This lets you simplify the code to use a single for loop:
var n = int.Parse(Console.ReadLine());
Console.WriteLine(new string('*', n));
for (int i = 0; i < n - 2; i++)
{
Console.WriteLine("*" + new string(' ', n - 2) + "*");
}
Console.WriteLine(new string('*', n));
class Program
{
static void Main(string[] args)
{
var n = int.Parse(Console.ReadLine());
for (int row = 1; row <= n; row++)
{
for (int col = 1; col <= n; col++)
{
if (row == 1 || row == n)
{
Console.Write("*");
}
else
{
if (col == 1 || col == n)
{
Console.Write("*");
}
else
{
Console.Write(" ");
}
}
}
Console.WriteLine();
}
Console.ReadKey();
}
}
You can change Console.WriteLine in 2nd loop like this :
class Program
{
static void Main(string[] args)
{
var n = int.Parse(Console.ReadLine());
for (int i = 0; i < n - 1; i++)
{
Console.Write("*");
}
for (int i = 0; i < n - 1; i++)
{
Console.WriteLine(i == 0 ? "*" : "*" + string.Empty.PadLeft(n - 2) + "*");
}
for (int i = 0; i < n; i++)
{
Console.Write("*");
}
}
}

Sort two dimensional string array by id using insertion sort - C#

I'm new here and sorry If my question is stupid, but I really need you help.
I need to sort that two dimensional string array by id (the first column):
string [,] a = new string [,]
{
{"2","Pena","pena"},
{"1","Kon","kon"},
{"5","Sopol","sopol"},
{"4","Pastet","pastet"},
{"7","Kuche","kuche"}
};
The problem is that I'm sorting only the number and I want after them to sort the words. That's what I did so far
static void Main(string[] args)
{
string [,] a = new string [,]
{
{"2","Pena","pena"},
{"1","Kon","kon"},
{"5","Sopol","sopol"},
{"4","Pastet","pastet"},
{"7","Kuche","kuche"}
};
int b = a.GetLength(0);
Console.WriteLine(b);
Console.WriteLine(a[0,0]);
Console.WriteLine(a[0,1]);
Console.WriteLine(a[1,0]);
InsertionSort(a, b);
Console.WriteLine();
Console.Write("Sorted Array: ");
printArray(a);
Console.WriteLine();
Console.Write("Press any key to close");
Console.ReadKey();
}
public static void InsertionSort(string[,] iNumbers, int iArraySize)
{
int i, j, index;
for (i = 1; i < iArraySize; i++)
{
for (int k = 0; k < iNumbers.GetLength(1); k++)
{
index = Convert.ToInt32(iNumbers[i, 0]);
j = i;
while ((j > 0) && (Convert.ToInt32(iNumbers[j - 1, 0]) > index))
{
iNumbers[j, k] = iNumbers[j - 1, k];
j = j - 1;
}
iNumbers[j, 0] = Convert.ToString(index);
}
}
}
static void printArray(string[,] iNumbers)
{
for (int i = 0; i < iNumbers.GetLength(0); i++)
{
for (int k = 0; k < iNumbers.GetLength(1); k++)
{
Console.Write(iNumbers[i, k] + " ");
}
}
Console.WriteLine();
}
Unfortunatelly as output I get
1 Pena pena 2 Kon kon 4 Sopol sopol 5 Pastet pastet 7 Kuche kuche
I would be really grateful if you could help me.
Based on the nature of the example and the question, I am guessing that this is a homework assignment and so must be implemented in a fashion that is a) not far from your current example, and b) actually demonstrates an insertion sort.
With that in mind, the following is a corrected version of your example that works:
public static void InsertionSort(string[,] iNumbers, int iArraySize)
{
int i, j, index;
for (i = 1; i < iArraySize; i++)
{
index = Convert.ToInt32(iNumbers[i, 0]);
j = i;
while ((j > 0) && (Convert.ToInt32(iNumbers[j - 1, 0]) > index))
{
for (int k = 0; k < iNumbers.GetLength(1); k++)
{
string temp = iNumbers[j, k];
iNumbers[j, k] = iNumbers[j - 1, k];
iNumbers[j - 1, k] = temp;
}
j = j - 1;
}
}
}
I made two key changes to your original code:
I rearranged the k and j loops so that the k loop is the inner-most loop, rather than the j loop. Your j loop is the one performing the actual sort, while the k loop is what should be actually moving a row for an insertion operation.
In your original example, you had this reversed, with the result that by the time you went to sort anything except the index element of a row, everything looked sorted to the code (because it's only comparing the index element) and so nothing else got moved.
With the above example, the insertion point is determined first, and then the k loop is used simply to do the actual insertion.
I added logic to actually swap the elements. In your original code, there wasn't really a swap there. You had hard-coded the second part of a swap, simply copying the index element to the target, so the swap did work for the index element. But it wouldn't have achieved the swap for any other element; instead, you'd just have overwritten data.
With the above, a proper, traditional swap is used: one of the values to be swapped is copied to a temp local variable, the other value to be swapped is copied to the location of the first value, and then finally the saved value is copied to the location of the second.
The above should be good enough to get you back on track with your assignment. However, I will mention that you can get rid of the k loop altogether if your teacher will allow you to implement this using jagged arrays (i.e. a single-dimensional array containing several other single-dimensional arrays), or by using a second "index array" (i.e. where you swap the indexes relative to the original array, but leave the original array untouched).

Using a nested for loop and getting unexpected repetitions in c#

I've the following code in c# visual basic 2010:
for (int i = 7; i > 0; i--)
{
Char star = '*';
string numbers = "765432" ;
//Console.WriteLine(star);
for (int a = 0; a < i; a++)
{
Console.Write(star);
}
for (int b = 0; b < i; b++)
{
numbers.TrimEnd(numbers[numbers.Length - 1]);
Console.Write(numbers);
}
Console.WriteLine();
}
Console.ReadLine();
I was expecting the outcome:
*765432
repeated on the screen 7 times, instead I get:
*****765432765432765432765432765432
****765432765432765432765432
***765432765432765432
**765432765432
*765432
(I can't display the full outcome because it doesn't come back properly on screen but it's basically the variables star and numbers displayed 7 times on line 1, 6 times on line 2 etc. until once in line 7)
My understanding is that the a and b variables declared in the for loops should dictate how many times the for loop is entered into, why are the star and numbers variables also being written 7 times then 6 times to match the number of times the loop is entered into? Especially when they are initialised as * and 765432?
This is the problem (I suspect, anyway - it's certainly a problem):
numbers.TrimEnd(numbers[numbers.Length - 1]);
Strings are immutable in .NET. TrimEnd doesn't change the existing string - it returns a reference to a new one. As highlighted in the documentation:
This method does not modify the value of the current instance. Instead, it returns a new string in which all trailing characters found in trimChars are removed from the current string.
You'd also be better off using Substring for simplicity to "remove" the last character:
numbers = numbers.Substring(0, numbers.Length - 1);
Or indeed Remove:
numbers = numbers.Remove(numbers.Length - 1);
... although this will actually fail on the 7th iteration as the string will be empty at this point. It's not really what you were trying to achieve, but I think you need to take a step back from it and think carefully about each step in the process.
TrimEnd returns a new string, it doesn't modify the original string. You have to assign it back to number. Strings are immutable.
number = numbers.TrimEnd(numbers[numbers.Length - 1]);
Check for string length before indexing its element. In your for loop you can add the condition like:
for (int b = 0; b < i && numbers.Length > 0; b++)
No. The 'a' for loop runs, outputting that many stars, and the 'b' for loop runs next, outputting that many strings. If you just want '*765432' to repeat 7 times, you need to change
for (int a = 0; a < i; a++)
{
Console.Write(star);
}
for (int b = 0; b < i; b++)
{
numbers.TrimEnd(numbers[numbers.Length - 1]);
Console.Write(numbers);
}
To
for (int a = 0; a < 7; a++)
{
Console.Write(star);
Console.Write(numbers);
}
And take out the parent loop; that's what is giving you the incrementingly shorter lines.
This produce the output you are expecting:
for (int i = 0; i < 7; i++)
{
Char star = '*';
string numbers = "765432" ;
Console.WriteLine(star);
Console.Write(numbers);
Console.WriteLine();
}
I was expecting the outcome: *765432 repeated on the screen 7 times
You never need to use TrimEnd() and multiple for loop in this situation.
public static void Main()
{
for (int i = 7; i > 0;i--)
{
char star = '*';
string numbers = "765432";
Console.WriteLine(star + numbers);
}
Console.ReadLine();
}
output:
*765432
*765432
*765432
*765432
*765432
*765432
*765432

Categories

Resources