I was doing some exercises about recursion but I stumbled upon one which I just cannot seem to think of a solution for.
List<int> list = new List<int>(new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
so the first one was using the above list create a method:
public string ForwardString(List<int> theList, int from)
in which the recursive function returns a set of numbers based onto the index that was given so
8 returns "8 9 10 11"
5 returns "5 6 7 8 9 10 11"
etc. okay piece of cake.
public static string ForwardString(List<int> list, int from)
{
if (from >= list.Count || list.Count == 0)
return "";
if (list.Count - 1 == from)
return " " + list[from];
return (" " + list[from]) + ForwardString(list, (from + 1));
}
but then there is also one for backwards:
public string BackwardString(List<int> theList, int i)
so you enter 5 and the output should be "11 10 9 8 7 6 5" but I can't seem to find a solution for this I tried adding to the front of a string but that yielded in the same result as above method. And for the life of me I simply can't come up with a good method.
Something like this
public static string ForwardString(List<int> list, int from) {
// Validation (since we implement public method we should be ready for any input)
if (null == list)
return ""; // or throw new ArgumentNullException(nameof(list));
else if (list.Count == 0)
return "";
else if (from >= list.Count)
return "";
else if (from < 0)
from = 0; // or throw new ArgumentOutOfRangeException(nameof(from));
// Recursion stop: on the last item
if (from == list.Count - 1)
return list[from].ToString();
// Recursion call: current item, space, then all the other items
// i.e. "5" + " " + "6 ... 11"
return list[from].ToString() + " " + ForwardString(list, from + 1);
}
In case of BackwardString you have to change Recursion call:
public static string BackwardString(List<int> list, int from) {
// Validation (since we implement public method we should be ready for any input)
if (null == list)
return ""; // or throw new ArgumentNullException(nameof(list));
else if (list.Count == 0)
return "";
else if (from >= list.Count)
return "";
else if (from < 0)
from = 0; // or throw new ArgumentOutOfRangeException(nameof(from));
// Recursion stop: on the last item
if (from == list.Count - 1)
return list[from].ToString();
// Recursion call: all the other items, space, then current item
// i.e. "11 ... 6" + " " + "5"
return BackwardString(list, from + 1) + " " + list[from].ToString();
}
Let's run some tests (with a pinch of Linq):
using System.Linq;
...
List<int> data = Enumerable.Range(0, 12).ToList();
var result = Enumerable
.Range(0, 12)
.Select(i => $"{i,2} fwd: {ForwardString(data, i),-25} bwd: {BackwardString(data, i)}");
string report = string.Join(Environment.NewLine, result);
Console.Write(report);
Outcome:
0 fwd: 0 1 2 3 4 5 6 7 8 9 10 11 bwd: 11 10 9 8 7 6 5 4 3 2 1 0
1 fwd: 1 2 3 4 5 6 7 8 9 10 11 bwd: 11 10 9 8 7 6 5 4 3 2 1
2 fwd: 2 3 4 5 6 7 8 9 10 11 bwd: 11 10 9 8 7 6 5 4 3 2
3 fwd: 3 4 5 6 7 8 9 10 11 bwd: 11 10 9 8 7 6 5 4 3
4 fwd: 4 5 6 7 8 9 10 11 bwd: 11 10 9 8 7 6 5 4
5 fwd: 5 6 7 8 9 10 11 bwd: 11 10 9 8 7 6 5
6 fwd: 6 7 8 9 10 11 bwd: 11 10 9 8 7 6
7 fwd: 7 8 9 10 11 bwd: 11 10 9 8 7
8 fwd: 8 9 10 11 bwd: 11 10 9 8
9 fwd: 9 10 11 bwd: 11 10 9
10 fwd: 10 11 bwd: 11 10
11 fwd: 11 bwd: 11
Related
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
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();
}
}
}
I am working on this program. My purpose is to Store the result of calculated input data in one int[] variable and display it in one line using messagebox.show.
int[] data = new int[] { 65, 66, 67, 32, 100, 90 }; // I declare int[] data it contain my data that I want to work with the length change.
int[] array = new int[6]; // i declare a table length of 6
foreach (var b in data) // for every element in my data I want to do this operations and build my array.
{
array[0] = b / 200;
array[1] = b / 79;
array[2] = b / 27;
array[3] = b / 19;
array[4] = b / 21;
array[5] = b / 3;
Console.WriteLine("{0}", string.Join(" ", array)); // this line is for console application
// output of this line is :
/*
0 0 2 3 3 21
0 0 2 3 3 22
0 0 2 3 3 22
0 0 1 1 1 10
0 1 3 5 4 33
0 1 3 4 4 30 */
MessageBox.Show(" "+ string.Join(" ", array)); // this line is for windowsform application
My purpose is in windowsform application to display my variable using messagebox.show. I aim the calculated to store them in one variable and to display them like this one :
0 0 2 3 3 21 0 0 2 3 3 22 0 0 2 3 3 22 0 0 1 1 1 10 0 1 3 5 4 33 0 1 3 4 4 30
I really appreciate any help.
kind regards
You can simply join the string in loop and then display them outside of the loop in your message box. Use StringBuilder class for appending results.
StringBuilder sb = new StringBuilder();
for(...)
{
...
...
sb.AppendFormat("{0} ", string.Join(" ", array).Trim())
}
MessageBox.Show(sb.ToString());
I have a sequence of numbers to generate, and I want to generate it using some sort of algorithm (iterative or recursive, doesn't matter).
Contextualizing: This numbers are indexes to iterative over a list of lists. I need to do a permutation (combination, i don't know exactly), but I need to generate all combinations of all positions of that list of lists.
The sequence and the output I am trying to get is:
1 1
2 1
3 1
4 1
5 1
1 2
2 1
3 1
4 1
5 1
1 3
2 1
3 1
4 1
5 1
1 4
2 1
3 1
4 1
5 1
1 5
2 1
3 1
4 1
5 1
1 1
2 2
3 1
4 1
5 1
1 2
2 2
3 1
4 1
5 1
1 3
2 2
3 1
4 1
5 1
1 4
2 2
3 1
4 1
5 1
1 5
2 2
3 1
4 1
5 1
1 1
2 3
3 1
4 1
5 1
1 2
2 3
3 1
4 1
5 1
1 3
2 3
3 1
4 1
5 1
1 4
2 3
3 1
4 1
5 1
1 5
2 3
3 1
4 1
5 1
1 1
2 4
3 1
4 1
5 1
and so on... the last state is:
1 5
2 5
3 5
4 5
5 5
Note that at each line break is a step of iteration or recursion. The algorithm must be generic. This code that i wrote can help, but it isn't what I want. :(
List<List<int>> lstDays = new List<List<int>>
{
new List<int>{1,2,3,4,5}, //day 18
new List<int>{1,2,3,4,5}, //day 19
new List<int>{1,2,3,4,5}, //day 22
new List<int>{1,2,3,4,5}, //day 23
new List<int>{1,2,3,4,5}, //day 24
};
for(int i=0;i<lstDays.Count;i++)
{
for(int j=0;j<lstDays[i].Count;j++)
{
for(int k=0;k<lstDays.Count;k++)
{
Console.Write(k+1);
//Console.Write(j+1);
Console.Write('\n');
}
Console.Write('\n');
}
}
I hope that you can help me ! (:
You can do it like this:
int[] second = new[] {0,0,0,0,0};
bool finish = false;
while (true) {
for (int i = 0 ; i != 5 ; i++) {
Console.WriteLine("{0} {1}", i+1, second[i]+1);
}
Console.WriteLine();
int p = 0;
do {
second[p]++;
if (second[p] == 5) {
second[p] = 0;
p++;
} else {
break;
}
} while (p != 5);
if (p == 5) break;
}
The sequence of the second digits is stored in the array "creatively" named second. The do/while loop "increments" this array as if it were a base-5 number stored as five separate digits.
Here is a demo on ideone.
Based on comments below by the venerable Eric Lippert, edits for the OPs original intent:
public void OutputSequence(int length){
Recurse(length-1, Enumerable.Range(1, length).ToArray(), new int[length]);
}
public void Recurse(int position, int[] arr, int[] state){
if (position == -1){
PrintState(state);
return;
}
for (int i = 0; i < arr.Length; i++)
{
state[position] = arr[i];
Recurse(position-1, arr, state);
}
}
public void PrintState(int[] state){
for (int i = 0; i < state.Length; i++)
Console.WriteLine ("{0} {1}",i+1, state[i]);
Console.WriteLine ();
}
OutputSequence(5); will give the output the OP originally asked for.
Old Answer
What you're looking for is called a Cartesian Product. LINQ is your friend:
var pairs = from i in Enumerable.Range(1, 5)
from j in Enumerable.Range(1, 5)
select new {i, j};
foreach(var p in pairs)
Console.WriteLine ("{0} {1}", p.i, p.j);
EDIT: Just for fun, here's a way to do N-Ary cartesian products.
public IEnumerable<IEnumerable<int>> NAryCartesianProduct(int upper, int times){
if (times == 0)
return Enumerable.Empty<IEnumerable<int>>();
var nums = Enumerable.Range(1, upper);
IEnumerable<IEnumerable<int>> products = nums.Select(i => new[]{i});
for (int i = 1; i < times; i++)
{
products = from p in products
from n in nums
select p.Concat(new [] {n});
}
return products;
}
And now you can get what you had before with:
var p = NAryCartesianProduct(5, 2);
foreach(var i in p)
Console.WriteLine (i);
I'm sure there's a more efficient way than creating new arrays all of the time but I just hacked this up quick :)
Here's a much more informative answer on this: Generating all Possible Combinations
EDIT2: Apparently the original link is the origination of the answer from that SO post. I didn't read through to the end until now.
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() + " ";