Help using TextBox and RichTextBox - c#

I'm making a menu type of all kinds of sorting algorithm. the user will input ten numbers in the TextBox, select a RadioButton, then click the generate button. the output must show each line on how the algorithm works.
(Selection Sort)
sample input from TextBox: 9 6 8 7 5 2 3 1 10 4
output:
1 6 8 7 5 2 3 9 10 4 \n
1 2 8 7 5 6 3 9 10 4 \n
1 2 3 7 5 6 8 9 10 4 \n
1 2 3 4 5 6 8 9 10 7 \n
1 2 3 4 5 6 7 9 10 8 \n
1 2 3 4 5 6 7 8 10 9 \n
1 2 3 4 5 6 7 8 9 10 \n
I made a program like these on Java, but I only used JOptionPane. I do not have any ideas on how to convert it to c# and by using TextBox and RichTextBox.
Here's my codes so far. My output always show a lot of zeros.
int[] nums = new int[10];
int i, s, min, temp;
private void EnterNum_TextChanged(object sender, EventArgs e)
{
string[] nums = EnterNum.Text.Split(' ');
//int[] nums = new int[] { int.Parse(EnterNum.Text) };
}
private void GenerateButton_Click(object sender, EventArgs e)
{
if (SelectionRadio.Checked == true)
{
for (i = 0; i < nums.Length - 1; i++)
{
min = i;
// In each iteration, find the smallest number
for (s = i + 1; s < nums.Length; s++)
{
if (nums[min] > nums[s])
{
min = s;
}
}
if (min != i)
{
temp = nums[i];
nums[i] = nums[min];
nums[min] = temp;
}
Display();
}
}
Display();
}
private void ClearButton_Click(object sender, EventArgs e)
{
richTextBox1.Clear();
}
public void Display()
{
int i;
String numbers = "";
for (i = 0; i < 10; i++)
numbers += Convert.ToInt32(nums[i]).ToString() + " ";
richTextBox1.AppendText(numbers);
}

before starting algorithm you need to fill your nums array from textbox, you see zeros because by default array is filled with zeros and you just displaying default array:
string[] numsInString = EnterNum.Text.Split(' ');
nums = new int[numsInString.Length];
for (int j = 0; j < numsInString.Length; j++)
{
nums[j] = int.Parse(numsInString[j]);
}
if (SelectionRadio.Checked == true)
//...
and to display nicely add "\n" when appending text:
richTextBox1.AppendText(numbers+"\n");
also as Matt mentioned use .ToString(), your nums are integers already so you dont need to convert int to int:
numbers += nums[i].ToString() + " ";

Related

C# Multiplication Table logic

I'm making a c# program that shows the multiplication table, by using my code I can print only complete table, how can I print random table as below.
my code bit:
using System;
public class Exer
{
public static void Main()
{
int j,n;
Console.Write("\n\n");
Console.Write("Display the multiplication table:\n");
Console.Write("-----------------------------------");
Console.Write("\n\n");
Console.Write("Input the number (Table to be calculated) : ");
n= Convert.ToInt32(Console.ReadLine());
Console.Write("\n");
for(j=1;j<=10;j++)
{
Console.Write("{0} X {1} = {2} \n",n,j,n*j);
}
}
}
Expected Output:
1 x 2 = 2
2 x 2 = 4
3 x 2 = 6
1 x 4 = 4
2 x 4 = 8
3 x 4 = 12
1 x 6 = 6
2 x 6 = 12
3 x 6 = 18
1 x 8 = 8
2 x 8 = 16
3 x 8 = 24
1 x 10 = 10
2 x 10 = 20
3 x 10 = 30
The tables in your picture are NOT random, though. There is a definite pattern. The function, DisplayMath(), is receiving an integer parameter; 3, 4, and 5 in the picture.
The output in the pictures is most likely produced by two NESTED for loops.
The integer parameter is controlling the INNER for loop, which goes from 1 to the parameter, incrementing by 1.
The OUTER loop goes from 2 to 10, incrementing by 2.
Possible code:
public static void Main() {
DisplayMath(4);
}
public static void DisplayMath(int x) {
for(int y=2; y<=10; y=y+2) {
for(int z=1; z<=x; z++) {
Console.WriteLine("{0} X {1} = {2}",z,y,z*y);
}
}
}
Output:
1 X 2 = 2
2 X 2 = 4
3 X 2 = 6
4 X 2 = 8
1 X 4 = 4
2 X 4 = 8
3 X 4 = 12
4 X 4 = 16
1 X 6 = 6
2 X 6 = 12
3 X 6 = 18
4 X 6 = 24
1 X 8 = 8
2 X 8 = 16
3 X 8 = 24
4 X 8 = 32
1 X 10 = 10
2 X 10 = 20
3 X 10 = 30
4 X 10 = 40
As per the required output, you need to change the for loop logic a little.
Because there is a logic in the expected result that you need to get before start coding, that isn't a 'random' table
for(j=2; j<=10; j=j+2 )
{
for (mathNumber = 1; mathNumber <= n; mathNumber++ )
{
Console.Write("{0} X {1} = {2} \n",mathNumber,j,mathNumber*j);
}
}
As you can see the result must be the result of the n first numbers (being n the parameter you get from Console, but perhaps is better that you get it as argument) multiplyed by the numbers 2,4,6,8,10

Converting a row of string numbers to int

I have a txt with multiple rows, in the first row the first number N is how many rows there'll be after the third and the second number M is the amount of colums there will be. The second row contains M amount of numbers. The third one is the same as the second one just with a lower number.
The example looks like this:
6 8
9 9 9 9 9 9 9 9
5 5 5 5 5 5 5 5
8 4 6 6 6 6 6 6
7 5 7 6 6 6 6 5
6 6 6 5 5 5 5 6
8 6 8 7 7 7 7 6
8 6 6 6 6 6 6 6
8 6 6 6 6 6 6 1
So the N is 6 meaning there's six more rows after the 3rd one, M is 8 so there are 8 colums.
I've already split the first row and declared them to variables, and got the 9 and 5 declared. Now I have to split the remaining rows in the same array, so they are like this: "8" "4" "6" "6" "6" "6" "6" "6" "7" "5" "7" "6" ect...
I've tried putting the rows in an array and then split them into another with a for cicle but it doesn't seem to work.
I've got this so far:
static void Main(string[] args)
{
string[] frow = Console.ReadLine().Split(' ');
int dn = int.Parse(frow[0]);
int an = int.Parse(frow[1]);
string[] rows = new string[an];
int[] points = new int[an * dn];
string[] mxp = Console.ReadLine().Split(' ');
string[] mnp = Console.ReadLine().Split(' ');
int maxp = int.Parse(mxp[0]);
int minp = int.Parse(mnp[0]);
for (int i = 0; i < dn; i++)
{
rows[i] = Console.ReadLine();
points[i] = rows[i].Split(' ');
}
}
Every help is appreciated.
Why do something in one line of code when you can do it in a whole page?
This is what I was talking about in the comments. First I create a function that, when given a line of text, returns an array of integers:
public static bool TryGetLineOfNumbers (string line, out int[] numbers){
numbers = null; //out parameters must always be set, cover the failure case
var individualStrings = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
numbers = new int[individualStrings.Length];
// convert the strings into numbers, failing on a conversion error
for(var i = 0; i< individualStrings.Length; ++i){
if (!int.TryParse(individualStrings[i], out numbers[i])){
return false;
}
}
return true;
}
I'm way too lazy to type nine lines of numbers into a console, so I just created a hard-coded array of strings in my main function:
var testNumbers = new string[]{
"6 8",
"9 9 9 9 9 9 9 9",
"5 5 5 5 5 5 5 5",
"8 4 6 6 6 6 6 6",
"7 5 7 6 6 6 6 5",
"6 6 6 5 5 5 5 6",
"8 6 8 7 7 7 7 6",
"8 6 6 6 6 6 6 6",
"8 6 6 6 6 6 6 1",
};
My intention was to have a function that read the console and returned an IEnumerable<string> (so that I could use the hard-coded array or the function in my testing), but I couldn't get DotNet Fiddle to handle yield return properly (it also didn't like interpolated strings). That function (which didn't work) looked like:
public static IEnumerable<string> GetStringsFromConsole(){
var str = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(str)){
yield return str;
}
}
So, now my Main routine looks like:
public static void Main()
{
var testNumbers = new string[]{
"6 8",
"9 9 9 9 9 9 9 9",
"5 5 5 5 5 5 5 5",
"8 4 6 6 6 6 6 6",
"7 5 7 6 6 6 6 5",
"6 6 6 5 5 5 5 6",
"8 6 8 7 7 7 7 6",
"8 6 6 6 6 6 6 6",
"8 6 6 6 6 6 6 1",
};
//need to initialize these to keep the compiler happy
var lineNumber = 0;
int [,] numbers = null;
int[] dimensions = null;
foreach (var line in testNumbers)
{
++lineNumber; //i.e., it starts with one
if (lineNumber == 1) {
var firstLineValid = TryGetLineOfNumbers(line, out dimensions);
if (!firstLineValid || dimensions.Length != 2) {
throw new Exception ("The first line of text must have exactly two numbers");
}
numbers = new int[dimensions[0], dimensions[1]];
} else if (lineNumber < 4){
int[] ignoredNumbers;
var line23Valid = TryGetLineOfNumbers(line, out ignoredNumbers);
if (!line23Valid || ignoredNumbers.Length != dimensions[1]){
throw new Exception ("The second or third line is in the incorrect format");
}
} else {
int[] oneLine;
var normalLineValid = TryGetLineOfNumbers(line, out oneLine);
if (!normalLineValid || oneLine.Length != dimensions[1]){
throw new Exception ("Line " + lineNumber.ToString() + " is incorrectly formatted");
}
for(var i = 0; i < dimensions[1]; ++i){
numbers[lineNumber-4, i] = oneLine[i];
}
}
}
if (lineNumber != dimensions[0] + 3){
throw new Exception("Not enough inputted data");
}
//ok, got all the numbers, let's see them on the console:
for(var i = 0; i < dimensions[0]; ++i){
for(var j = 0; j < dimensions[1]; ++j){
Console.Write(numbers[i,j].ToString() + " ");
}
Console.WriteLine();
}
}
Yeah, it's a lot of code, but it's pretty self-explanatory. It also pays attention and validates the inputs. It's lightly tested
Reading the code over, it's probably worth refactoring the format and length test code (repeated three times) into a separate function, but that would be for another day.
Here's just a general example of how you can split strings. Copy and paste your data to a file, and change the filePath string to match the path of the file. Run below. I suggest setting a breakpoint at the Console.ReadKey() and looking at each of the variables after they've been assigned to, to see what each function does:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace HelpingStackOverflow
{
class Program
{
static void Main(string[] args)
{
string filePath = #"C:\Users\me\Desktop\data.txt";
string fileContents = File.ReadAllText(filePath);
string[] allLines = fileContents.Split('\n');
int n = Convert.ToInt32(allLines[0].Split(" ")[0]);
int m = Convert.ToInt32(allLines[0].Split(" ")[1]);
string secondRow = allLines[1].Trim('\r');
string thirdRow = allLines[2].Trim('\r');
string[] remainingLines = allLines.Skip(3).ToArray();
//so now you have different arrays
//if you want to break a line into an additional array you can do so
//and do whatever you want with the parts like this:
List<string[]> allParts = new List<string[]>();
foreach (string line in remainingLines)
{
var parts = line.Trim('\r').Split(" ");
allParts.Add(parts);
}
Console.ReadKey();
}
}
}

Show a pyramid based on number input

I'm currently stuck on this problem the goal is to be able to print out a pyramid depending on the input number.
Ex: input = 3
It should look like this:
1
23
I'm able to make it work with some numbers but it doesn't work with other inputs.
The current logic that I follow is by dividing the input by 2 then add the remainder to the next one to be divided.
Example input: 10
10 / 2 = 5 remainder: 0
5 / 2 = 2 remainder: 1
2 + 1 (previous remainder)/ 2 = 1 remainder: 1
1
Whereas it would look like this:
5
2
2
1
The rules of the pyramid that I'm trying to make only needs to have one or two differences per row.
That's why I'll be needing to deduct 1 from 5 and add it to the next one:
4
3
2
1
Thus having pyramid like this: 10
****
***
**
*
The problem is this approach isn't applicable on other inputs and I'm having a hard time on finding a different approach for this.
This code works for your example, although it might be improved to detect whenever a number is not suitable to print a piramid.
static void Main(string[] args)
{
while (true)
{
Console.Write("Enter a number:");
int input = int.Parse(Console.ReadLine());
List<List<string>> piramid = new List<List<string>>();
int rowNumber = 1, dotsCount = 0;
while (dotsCount < input)
{
List<string> row = new List<string>();
for (int i = 1; i <= rowNumber && dotsCount < input; i++)
{
row.Add("*");
dotsCount++;
}
piramid.Add(row);
rowNumber++;
}
Console.WriteLine("Piramid");
Print(piramid);
Console.WriteLine("Piramid (inverted)");
PrintInverted(piramid);
}
}
static void Print(List<List<string>> piramid)
{
foreach (var item in piramid)
{
item.ForEach(Console.Write);
Console.Write("\n");
}
}
static void PrintInverted(List<List<string>> piramid)
{
for (int i = piramid.Count - 1; i >= 0; i--)
{
List<string> item = piramid[i];
item.ForEach(Console.Write);
Console.Write("\n");
}
}

c# Hackerrank code terminated due to time out but there is no way to optimize this code further?

I was doing a hacker rank challenge in c# to try and bring some of my c skills over to c#. Now I know hacker rank is notoriously stupid with killing programs due to time out (in this case if it lasts more than 3 seconds). But I honestly cannot think of a way to optimize this code further.
Here are the instructions:
https://www.hackerrank.com/challenges/ctci-array-left-rotation
Basically the challenge is to shift an array of numbers some x amount of times over in the left direction inside the array.
To my knowledge this code is as minimal as it can get and still do the thing they requested. The only way I can think to optimize this code further is to merge the constraint "if(a[i] > 1000000 || a[i] < 1 )" with the writeline forloop at the end of the code, but I tried that and it didn't work.
To me this is literally the minimum number of operations to move the array over by an amount x. But the code fails in test case 7 and 8 (out of 8) due to time out. Am I missing something?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int i, j;
int temp = 0;
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
//constraints
if(n >= 100000 || n < 1 )
{
System.Environment.Exit(1);
}
if(k > n || n < 1 )
{
System.Environment.Exit(1);
}
for(i = 0; i< n; i++)
{
if(a[i] > 1000000 || a[i] < 1 )
{
System.Environment.Exit(1);
}
}
//double for loop. one adjust position by one. then repeat k number of times.
for(j = 0; j<k; j++)
{
for(i = 0; i< n-1; i++)
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
//view array
for(i = 0; i< n; i++)
{
Console.Write(a[i] + " " );
}
}
}
I used a queue mechanism to get this working. That way you don't have to do any array copy and just rotating the string to the end.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {
static int[] leftRotation(int[] arr, int rotation) {
Queue<int> queue = new Queue<int>(arr);
for (int i = 0; i < rotation; i++)
{
queue.Enqueue(queue.Dequeue());
}
return queue.ToArray();
}
static void Main(String[] args) {
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int d = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
int[] result = leftRotation(a, d);
Console.WriteLine(String.Join(" ", result));
}
}
Shuffling the values one at a time is very slow. There is no need to do this. One can think of the rotation as moving 2 blocks - the values to the left of the rotation point and the values including and to the right of the rotation point
1 2 3 4 5 6 7 8 9
Rotate this 3 times is
move 1-3 to a temp variable
move 4-9 to the start of the array
move 1-3 to the end of 4-9
Edit: Add a bit more detail
We want to rotate the array 3 places.
move 1 2 3 to a temporary array
1 2 3
1 2 3 4 5 6 7 8 9
move 4-9 to the start of the array
1 2 3
4 5 6 7 8 9 7 8 9
move 1-3 to the end of the array
1 2 3
4 5 6 7 8 9 1 2 3
We can get away without the temp array for the left hand block if we create a new target array and copy everything to it. The following passes all the tests for the problem
var result = new int[a.Length];
var block2Length = a.Length - k;
Array.Copy(a, k, result, 0, block2Length);
Array.Copy(a, 0, result, block2Length, k);
Console.WriteLine(string.Join(" ", result.Select(v => v.ToString())));
Other Points
The constraints in HackerRank are part of the problem definition - they are telling us what the values can/will do so that we don't have to worry about solving a more general problem
e.g.
1 <= a[i] < 10^6
tells us the numbers will all be within the range for standard integers, no need to use long or BigInteger. As part of the solution we don't need to confirm these. In a real world situation different rules apply but here we have as much code checking values that cannot be wrong as we have solving the problem.
This has already been answered but there is a different solution that is very fast:
The idea is that you use the periodicity of the shifting. Shifting an element n+1 times is the same as shifting it 1 time which boils down to k % n.
Thus, you can simply create a new array and move the "old" elements directly to the correct spot. See the sample code below:
static void Main(String[] args) {
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
// use the periodicity of the shifting creating a shift between 0 and n - 1.
int shifts = k % n;
// Create a new array to hold the elements at their new positions.
int[] newPositions = new int[a.Length];
// You only need to iterate of the array once assigning each element its new position.
for(int i= 0; i < a.Length; ++i)
{
// Here is the magic: (for clarification see table below)
int position = (i - shifts + n)%n;
newPositions[position] = a[i];
}
foreach(var element in newPositions)
Console.Write($"{element} ");
}
This is more intuitive once you write it down on paper. The table might prints more values than the array contains to show the actual positions in the array.
-4 -3 -2 -1 | 0 1 2 3 4 (array indices)
=============================
2 3 4 5 | 1 2 3 4 5 (array contents without shift)
3 4 5 1 | 2 3 4 5 1 (shifted 1 time)
4 5 1 2 | 3 4 5 1 2 (shifted 2 times)
5 1 2 3 | 4 5 1 2 3 (shifted 3 times)
1 2 3 4 | 5 1 2 3 4 (shifted 4 times)
formula: i - k + n
results:
i=0: 0 - 4 + 5 = 1
i=1: 1 - 4 + 5 = 2
i=2: 2 - 4 + 5 = 3
i=3: 3 - 4 + 5 = 4
i=4: 4 - 4 + 5 = 5
i=5: 5 - 4 + 5 = 6 => 0
EDIT: I skipped the parts to check the boundaries for the sake of simplicity.
Updated answer.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
int i, j, z;
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
string[] a_temp = Console.ReadLine().Split(' ');
int[] a = Array.ConvertAll(a_temp,Int32.Parse);
int[] temparray = new int[2*n];
//constraints
if(n >= 100000 || n < 1 )
{
System.Environment.Exit(1);
}
if(k > n || n < 1 )
{
System.Environment.Exit(1);
}
for(i = 0; i< n; i++)
{
if(a[i] > 1000000 || a[i] < 1 )
{
System.Environment.Exit(1);
}
}
for(j = 0; j<n; j++)
{
z = (j-k) %n;
if(z != 0)
{
z= (n+ z) %n;
}
temparray[z] = a[j];
}
//view array
for(i = 0; i< n; i++)
{
Console.Write(temparray[i] + " " );
}
}
}

How to check how many times a value appears in an array?

So this is what I want my output to look like:
How many numbers? 10
Give number 1: 1
Give number 2: 3
Give number 3: 1
Give number 4: 3
Give number 5: 4
Give number 6: 6
Give number 7: 4
Give number 8: 8
Give number 9: 2
Give number 10: 1
Number 1 appeared 3 times
Number 2 appeared 1 times
Number 3 appeared 2 times
Number 4 appeared 2 times
Number 6 appeared 1 times
Number 8 appeared 1 times
The thing is, I've got the part which reads the user input done. However, I have no idea how to continue with the part which tells how many times each number appeared.
Also, I'm doing this as a schoolwork so most of the code is in Finnish. I hope you can still understand it, though.
using System;
namespace Ohjelma
{
class Ohjelma
{
static void Main()
{
Console.Write("Kuinka monta lukua? ");
int pituus = Convert.ToInt32(Console.ReadLine());
int[] luvut = new int[pituus];
for (int i = 0; i < pituus; i++)
{
Console.Write("Anna {0}. luku:", i + 1);
luvut[i] = Convert.ToInt32(Console.ReadLine());
}
for (int i = 0; i < luvut.Length; i++)
{
Console.Write(luvut[i]);
}
Console.ReadLine();
}
}
}
Edit: Sorry about the code block on the example of what it should output, not exactly sure how to use blockquotes even though I tried. Thanks!
You can use LINQ like:
var query = luvut.GroupBy(r => r)
.Select(grp => new
{
Value = grp.Key,
Count = grp.Count()
});
For output you can use:
foreach (var item in query)
{
Console.WriteLine("Value: {0}, Count: {1}", item.Value, item.Count);
}
int[] num = { 1, 1, 1, 3, 3, 4, 5, 6, 7, 0 };
int[] count = new int[10];
//Loop through 0-9 and count the occurances
for (int x = 0; x < 10; x++){
for (int y = 0; y < num.Length; y++){
if (num[y] == x)
count[x]++;
}
}
//For displaying output only
for (int x = 0; x < 10; x++)
Console.WriteLine("Number " + x + " appears " + count[x] + " times");
Program Output:
Number 0 appears 1 times
Number 1 appears 3 times
Number 2 appears 0 times
Number 3 appears 2 times
Number 4 appears 1 times
Number 5 appears 1 times
Number 6 appears 1 times
Number 7 appears 1 times
Number 8 appears 0 times
I understand how bad it feels when all your classmates had finish theirs, and you are still struggling. My codes should be simple enough for your learning.
If you don't want to use LINQ, you can code as follows:-
public class Program
{
public static void Main()
{
int[] arr1 = new int[] {1,3,3,5,5,4,1,2,3,4,5,5,5};
List<int> listArr1 = arr1.ToList();
Dictionary<int,int> dict1 = new Dictionary<int,int>();
foreach(int i in listArr1)
{
if(dict1.ContainsKey(i))
{
int value = dict1[i];
value++;
dict1[i]= value;
}
else
{
dict1.Add(i,1);
}
}
for(int x = 0 ; x < dict1.Count(); x++)
{
Console.WriteLine("Value {0} is repeated {1} times", dict1.Keys.ElementAt(x),dict1[dict1.Keys.ElementAt(x)]);
}
}
}

Categories