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.
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 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 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] + " " );
}
}
}
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)]);
}
}
}
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() + " ";