So i have a project where i need to store 8 integers, between 1-10, and recall them into a histogram
The histogram is made up of the character * only. (forgive bad formatting, this is my first post)
The program works, but i think my if statements for int restriction (1-10) could be simplified.
My goal is to achieve this output with as little code as possible
The whole code, and nothing but the code (and comments)
Console.WriteLine("Hello and Welcome!\nEnter 8 values between 1 and 10\n*Press Any Key to continue*");
Console.ReadKey();
//create list to store values
List<int> values = new List<int>();
//loop to collect values
for (int i = 1; i < 9; i++)
{
//label for data validation start point
retry:
Console.WriteLine("Please Enter Value " + i, "Between 1 - 10");
//variable assigned to user input
value = Console.ReadLine();
//Convert string to integer
if (!int.TryParse(value, out validValue))
{
Console.WriteLine("~Incorrect Data Input~"); goto retry; };
if (validValue < 1) { Console.WriteLine("~Incorrect Data Input~"); goto retry; };
if (validValue > 10) { Console.WriteLine("~Incorrect Data Input~"); goto retry; };
values.Add(validValue);
}
for (int i = 0; i < 8; i++ )
{
Console.WriteLine();
for(int id = 0; id < values[i]; id++)
Console.Write("*");
}
Console.ReadKey();
This is the area im thinking could be cleaner
if (validValue < 1) { Console.WriteLine("~Incorrect Data Input~"); goto retry; };
if (validValue > 10) { Console.WriteLine("~Incorrect Data Input~"); goto retry; };
Im open to any suggestions as to how i could clean this or any part of the project up.
There is a more difficult aspect to this project, like a do this if you want to show off kind of thing, where i would need the histogram to be displayed vertically.
I figure this would be done with 2d arrays? i havent really got a clue other than needing 80 spaces and *'s in the right spaces lol.
Ive only been coding for a month or so and it being learner based, any help or suggestions would be welcomed
Thank you
Chris
Here's a sample of how you could reconstruct your logic with a couple of pointers.
Console.WriteLine("Hello and Welcome!\nEnter 8 values between 1 and 10\n*Press Any Key to continue*");
Console.ReadKey();
//create list to store values
List<int> values = new List<int>();
//loop to collect values (no need to run from 1 - 9; 0 - 8 works fine.)
for (int i = 0; i < 8; i++)
{
//label for data validation start point
int validValue = 0;
//Use a while loop instead of a goto
while (validValue == 0)
{
Console.WriteLine("Please Enter Value " + i, "Between 1 - 10");
//variable assigned to user input
var value = Console.ReadLine();
//Convert string to integer
//If the first question in the predicate fails, it won't go on to ask the other questions
if (int.TryParse(value, out validValue) && validValue > 0 && validValue < 10)
{
values.Add(validValue);
}
else
{
Console.WriteLine("~Incorrect Data Input~");
}
//If the code reaches this point and validValue hasn't been changed, it'll be 0 and the loop will run again
}
}
for (int i = 0; i < 8; i++)
{
Console.WriteLine();
for (int id = 0; id < values[i]; id++)
Console.Write("*");
}
Console.ReadKey();
Related
You're given an array of integers,in case if you see subsequence in which each following bigger than the previous on one(2 3 4 5) you have to rewrite this subsequence in the resulting array like this 2 - 5 and then the rest of the array. So in general what is expected when you have 1 2 3 5 8 10 11 12 13 14 15 the output should be something like 1-3 5 8 10-15.
I have my own idea but can't really implement it so all I managed to do is:
static void CompactArray(int[] arr)
{
int[] newArr = new int[arr.length];
int l = 0;
for (int i = 0,k=1; i <arr.length ; i+=k,k=1) {
if(arr[i+1]==arr[i]+1)
{
int j = i;
while (arr[j+1]==arr[j]+1)
{
j++;
k++;
}
if (k>1)
{
}
}
else if(k==1)
{
newArr[i] = arr[i];
}
}
In short here I walk through the array and checking if next element is sum of one and previous array element and if so I'm starting to walk as long as condition is true and after that i just rewriting elements under indices and then move to the next.
I expect that people will help me to develop my own solution by giving me suggestions instead of throwing their own based on the tools which language provides because I had that situation on the russian forum and it didn't help me, and also I hope that my explanation is clear because eng isn't my native language so sorry for possible mistakes.
If I understand the problem correctly, you just need to print the result on the screen, so I'd start with declaring the variable which will hold our result string.
var result = string.Empty
Not using other array to store the state will help us keep the code clean and much more readable.
Let's now focus on the main logic. We'd like to loop over the array.
for (int i = 0; i < array.Length; i++)
{
// Let's store the initial index of current iteration.
var beginningIndex = i;
// Jump to the next element, as long as:
// - it exists (i + 1 < array.Length)
// - and it is greater from current element by 1 (array[i] == array[i+1] - 1)
while (i + 1 < array.Length && array[i] == array[i+1] - 1)
{
i++;
}
// If the current element is the same as the one we started with, add it to the result string.
if (i == beginningIndex)
{
result += $"{array[i]} ";
}
// If it is different element, add the range from beginning element to the one we ended with.
else
{
result += $"{array[beginningIndex]}-{array[i]} ";
}
}
All that's left is printing the result:
Console.WriteLine(result)
Combining it all together would make the whole function look like:
static void CompactArray(int[] array)
{
var result = string.Empty;
for (int i = 0; i < array.Length; i++)
{
var beginningIndex = i;
while (i + 1 < array.Length && array[i] == array[i+1] - 1)
{
i++;
}
if (i == beginningIndex)
{
result += $"{array[i]} ";
}
else
{
result += $"{array[beginningIndex]}-{array[i]} ";
}
}
Console.WriteLine(result);
}
I suppose to fill the value each time the user try to make an appointment. There is Two type of Appointment: Appointment a and Appointment b. Each appointment can make it only 4 a day. So, my dimensional would have two columns for types of appointment and 4 rows for 4 appointments. I just tried if the user types only "a".
If the user types "a" for the first time, my 2D array will look like:
1111
1000
If the user types "a" for the second time, the 2D array will look like:
1111
1200
And so on... So finally the 2D array will look like:
1111
1234
int[,] slots = new int[4,2];
string appt_type;
string choice = "Y";
while (choice == "Y")
{
Console.WriteLine("Please enter a or b");
appt_type = Console.ReadLine();
if (appt_type == "a")
{
for (int i=0; i<slots.GetLength(0); i++)
{
for (int j=0; j<slots.GetLength(1); j++)
{
slots[i,0] = 1;
slots[i,j] = i+1;
}
}
int q = 0;
foreach (int i in slots)
{
if ((q%2) == 1)
Console.WriteLine(i + " ");
else
Console.Write(i + " ");
q++;
}
}
}
My final output is what I expect it. However, I want to fill each of the second column each time the user enters "a".
First enters "a"
1111 1000
Second time enters "a"
1111 1200
Third time enters "a"
1111 1230
Fourth time enters "a"
1111 1234
First of all,your for loop isn't as you want it,because before the user inputs "a" or "b" you already initialized in the for loop inside for loop,the array as it should be in the end.After the for loops the array is 1111 1234.
You can create a counter variable to count the number of times the user had entered "a" each time that you get the input.In this specific case there is a connection between the row of the array,and the amount of "a"'s the user has entered so I initialized the counter with 0 even though it value goes up only if you enter "a" again.The amount of "a"'s the user has entered-1 because it is 1 for sure after it gets into the forloop,so thats why you can also set it as the element of the array that you wanted to change.
Additionally,you can use while(true) instead of creating a variable and leave it the same.
Its pretty much like this:(Tried to use your way printing it)
int[,] slots = new int[4, 2];
string appt_type;
int counter = 0;//counts how many times the user had enter the letter "a"
while (true)
{
Console.WriteLine("Please enter a or b");
appt_type = Console.ReadLine();
if (appt_type == "a")
{
counter++;
for (int i = 0; i < slots.GetLength(0); i++)
{
for (int j = 0; j < slots.GetLength(1); j++)
{
slots[i, 0] = 1;
slots[counter - 1,1 ] = counter;//note:all of the elements that you want to change are in column 1 of the array
}
}
int q = 1;//the position of i in the array
foreach (int i in slots)
{
if(q%2!=1)
Console.WriteLine(i+" " );
else
Console.Write(i);
q++;
}
In order for your code to allow the user to input his/her choice and make the code do something based on that choice, you need to check the element's value if it is 0 or something else and then do something based on that value. Here is a quick untested fix, but you can get the gist:
for (int i=0; i<slots.GetLength(0); i++)
{
for (int j=0; j<slots.GetLength(1); j++)
{
if (slots[i,j] == 0)
{
slots[i,j] = i+1;
break;
}
}
}
I think your code can still be improved in a lot more ways. Here are my suggestions:
Break apart your code in methods to make it easier to read.
Separate the routines when A is selected, when B is selected, and
when slots is displayed.
It is clear that upon selecting choice A, the first column of the
array is set to 1111 and does not change up to the end, so set it
once and forget about going through it by checking if the first
element of the column is equal to 1.
You don't have to go through all of the elements in the second column
just to set the value. Just check for the first 0 that you encounter
and set it to the current index + 1.
Use break to get out of loops easily and eliminate the curly braces to
make the code look a bit cleaner.
Ignore the case when comparing strings, because a != A.
Here is a suggested and tested refactor. Add a break point on while(true), make it run in debug mode, and see how the code flows on every user input:
class Program
{
static void Main(string[] args)
{
var slots = new int[4, 2];
while (true)
{
Console.Write("Do you want to proceed? [Y/N]");
var choice = Console.ReadLine();
if (!choice.Equals("y", StringComparison.CurrentCultureIgnoreCase))
break;
Console.WriteLine("Please enter a or b: ");
var appt_type = Console.ReadLine();
if (appt_type.Equals("a", StringComparison.CurrentCultureIgnoreCase))
slots = AssignScheduleA(slots);
else if (appt_type.Equals("b", StringComparison.CurrentCultureIgnoreCase))
AssignScheduleB(slots);
DisplaySlotsValue(slots);
}
}
private static int[,] AssignScheduleA(int[,] slots)
{
if (slots[0,0] != 1)
{
for(int idx1 = 0; idx1 < slots.GetLength(0); idx1++)
slots[idx1, 0] = 1;
}
for(int idx2 = 0; idx2 < slots.GetLength(0); idx2++)
{
if (slots[idx2, 1] == 0)
{
slots[idx2, 1] = idx2 + 1;
break;
}
}
return slots;
}
private static void AssignScheduleB(int[,] slots)
{
throw new NotImplementedException();
}
private static void DisplaySlotsValue(int[,] slots)
{
for (int idx1 = 0; idx1 < slots.GetLength(0); idx1++)
Console.Write(slots[idx1, 0]);
Console.WriteLine();
for (int idx2 = 0; idx2 < slots.GetLength(0); idx2++)
Console.Write(slots[idx2, 1]);
Console.WriteLine();
}
}
If you go over this while on debug mode, you will understand how the code will let the user make a choice every time and fill in the array based on the choice. This code can still be improved and that can be something that you do as you learn more about C#. Happy coding!
I come from a C++ background creating basic 2D games with it, but I am trying to teach myself C# to a point to where I can get the most basic of jobs using it. I am not in school but I am following the Problems on ProjectEuler.net.
The problem question is commented into the code. I can't tell whether I solved it or not because I can't get the numbers to display from a list into the console application.
I've tried writing to console directly from the variable value with Console.WriteLine but I'm not having any luck. I've also tried converting all int list values to a string value and displaying them but that also didn't work.
I'm not looking for the answer to number 4 just looking to display the list so I can find the answer on my own.
Why can't I get the list to write to the Console?
Any help is appreciated!
static void Main(string[] args)
{
/* A palindromic number reads the same both ways.
* The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers. */
// 100 x 100 = 10000
// 999 x 999 = 998001
List<int> palindromeContainer = new List<int>();
int Increment = 2;
int Holder = 0;
for (int i = 100; i <= 999; ++i)
{
int j = i;
while (j <= 999)
{
do
{ Holder = i * j; // Gets all Possible Combinations of i * j
if ((Holder % Increment) != 0) // Checks for Prime Numbers
{
++Increment;
}
else if (Increment == Holder - 1 && Holder % Increment != 0 )
{
palindromeContainer.Add(Holder);
Increment = 2;
break;
}
else if (Increment == Holder - 1 && Holder % Increment == 0)
{
Increment = 2;
break;
}
} while (Increment < Holder);
++j;
}
}
palindromeContainer.Sort();
foreach (int line in palindromeContainer)
{
Console.WriteLine(line); // Display all items in list
}
Firstly comment out your loop logic and test without:
List<int> palindromeContainer = new List<int>();
palindromeContainer.Add(2);
palindromeContainer.Add(1);
palindromeContainer.Sort();
foreach (int line in palindromeContainer)
{
Console.WriteLine(line); // Display all items in list
}
Console.ReadLine();
This will output to the console. Then you will know this is working and console output is not the problem.
I'm very new to C# (And Stack Overflow, forgive me for any poor etiquette here), and I'm writing the game Mastermind in a console application. I'm trying to show a list of the user's guesses at the end of the game, and I know that using Console.WriteLine(); will just give me 30-odd lines off numbers which don't tell the user anything.
How can I alter my code so that the program displays 4 numbers in a group, at a time? For example:
1234
1234
1234
//Store numbers in a history list
ArrayList guesses = new ArrayList(); //This is the ArrayList
Console.WriteLine("Please enter your first guess.");
guess1 = Convert.ToInt32(Console.ReadLine());
guesses.Add(guess1);
foreach (int i in guesses)
{
Console.Write(i);
}
I assume that each element of your byte array is a single digit (0-9). If that assumption is invalid -- please let me know, I'll modify the code :)
Action<IEnumerable<int>> dump = null;
dump = items =>
{
if(items.Any())
{
var head = String.Join("", items.Take(4));
Console.WriteLine(head);
var tail = items.Skip(4);
dump(tail);
}
};
dump(guesses);
It looks like you're most of the way there, you have a console write that writes them all out without linebreaks. Next add an integer count and set it to zero. Increment it by one in the foreach loop. count % 4 == 0 will then be true for all counts that are a multiple of four. This means you can stick an if block there with a write-line to give you your groups of four.
List<int> endResult = new List<int>();
StringBuilder tempSb = new StringBuilder();
for(int i=0; i < groups.Count; i++)
{
if(i % 4 == 0) {
endResult.Add(int.Parse(sb.ToString()));
tempSb.Clear(); // remove what was already added
}
tempSb.Append(group[i]);
}
// check to make sure there aren't any stragglers left in
// the StringBuilder. Would happen if the count of groups is not a multiple of 4
if(groups.Count % 4 != 0) {
groups.Add(int.Parse(sb.ToString()));
}
This will give you a list of 4 digit ints and make sure you don't lose any if your the number of ints in your groups list is not a multiple of 4. Please note that I am continuing based on what you provided, so groups is the ArrayList of ints.
This is some thing I quickly put together:
Update:
ArrayList guesses = new ArrayList(); //This is the ArrayList
// Four or more
guesses.Add(1); guesses.Add(2);
guesses.Add(3);guesses.Add(4);
guesses.Add(5); guesses.Add(6); guesses.Add(7);guesses.Add(8); guesses.Add(9);
//Uncomment-Me for less than four inputs
//guesses.Add(1); guesses.Add(2);
int position = 0;
if (guesses.Count < 4)
{
for (int y = 0; y < guesses.Count; y++)
{
Console.Out.Write(guesses[y]);
}
}
else
{
for (int i = 1; i <= guesses.Count; i++)
{
if (i%4 == 0)
{
Console.Out.WriteLine(string.Format("{0}{1}{2}{3}", guesses[i - 4], guesses[i - 3],
guesses[i - 2], guesses[i - 1]));
position = i;
}
else
{
if (i == guesses.Count)
{
for (int j = position; j < i; j++)
{
Console.Out.Write(guesses[j]);
}
}
}
}
}
For example i have a long[] x
And im doing:
for (int i=0; i<x.length;x--)
{
}
I know that in x for example i have 30 indexs cells.
How can i loop over the cells(indexs) in the x array and find on each cell the length of it and also to get/show the numbers in each cell.
If in x[0] there is 232
And in x[1] there is 21
And so on...
I want to display 232,21,....etc
And then i want to check that if x[i].length is above 0 do...
But there is no x[i].length
So how do i do it ?
I did:
public long GetHistogramMaximum(long[] histogram)
{
long result = 0;
long count = 0;
for (int i = 0; i < histogram.Length; i++)
{
if (histogram[i] > 0)
{
MessageBox.Show(histogram[i].ToString());
break;
}
}
return result;
}
And its working but each time its showing me the number twice why the messagebox is working twice each time ?
If in the first array the number is 33454 then i see the messagebox once and then once again. Whats wrong here ? I want it to show me the number only once each time.
Its like repeating each number and show it once and then once again and only then moving to the next one.
EDIT **
Maybe the problem its showing the number twice each time have something to do with the scroll event im using ?
void trackBar1_Scroll(object sender, EventArgs e)
{
myTrackPanelss1.trackBar1.Minimum = 0;
myTrackPanelss1.trackBar1.Maximum = counter - 1;//list_of_histograms.Count-1;
long[] tt = list_of_histograms[myTrackPanelss1.trackBar1.Value];
histogramControl1.DrawHistogram(tt);
long res = GetTopLumAmount(tt, 1000);
long max = GetHistogramMaximum(tt);
if (res > -1)
label24.Text = (res / 1000.0).ToString();
setpicture(myTrackPanelss1.trackBar1.Value);
this.pictureBox1.Refresh();
}
For some reason its getting to the scroll and do everything here again. Twice in a row.
What can be the problem ?
A long[] basically holds a number of long values. Doing x[i].length is invalid, because a long does not have a property length. What is it that you are trying to achieve?
long[] x = {1,2,3} ;
x.length; //this is valid because you are querying the length / count of the array
x[0].length; //this is invalid because 1 does not have a property length
EDIT
Your loop counter will be the index. So,
for (int i =0; i < x.Length; i++)
{
//check for maximum, when you find it
Console.WriteLine("The maximum value is " + x[i]);
Console.WriteLine("The maximum value is present at index " + i);
}
As Michael says, you can find the length of the array via x.Length. In C#, x.Length (where x is an array) will return a 32-bit integer that represents the total number of elements across all dimensions. You only have a 1D array here, so that should be sufficient for what you're trying to achieve.
If you're also after the value stored in the array, the value is called as:
x[i];
So, in an example:
for ( int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
... would display the value in the array in your console.
Is that what you were asking?
Here is how to do something based on the values in the array.:
for (int i=0; i < x.Length; i++)
{
// print the number to the screen.
Console.WriteLine(x[i]);
if (x[i] > 0) {
// do something else.
}
}
I'm not sure what you meant by x--, but that's probably wrong from your description.
You could cast it to a string and get the length property.
x[i].ToString().Length
Although if you want to check if the length is above zero, then surely just the presence of a value proves this?
Your function has a terrible problem:
public long GetHistogramMaximum(long[] histogram)
{
long result = 0;
long count = 0;
for (int i = 0; i < histogram.Length; i++)
{
if (histogram[i] > 0)
{
MessageBox.Show(histogram[i].ToString());
break;
}
}
return result;
}
This way, you check the values in your array.
When i=0, it checks x[i]. So, 33454 (the value you gave in x[0]) is greater than 0, it shows the number and "break;", so it stops the "for" and do what's next: it returns the result variable that is never modified.
So variables result and count are useless in your code.
Rewrite with something that way for getting the maximum in your array:
public long GetHistogramMaximum(long[] histogram)
{
long result = 0;
for (int i = 0; i < histogram.Length; i++)
{
if (histogram[i] > result)
{
MessageBox.Show(string.Format("{0} is greater than {1}", histogram[i], result);
result = histogram[i];
}
}
return result;
}