Split a big loop through several smaller loops by using Task.Run() - c#

I have a big loop.
I would like split the process through several smaller loops.
So, I use the following code:
class Program
{
static void Main(string[] args)
{
List<string> input = new List<string>();
for (int i = 0; i < 100; i++)
{
input.Add(i.ToString());
}
int take = 2;
List<Task<string>> tasks = new List<Task<string>>();
for (int i = 0; i < 10; i++)
{
// Launch of the tasks
tasks.Add(Task.Run<string>(() => Process(input.Skip(i * take).Take(take).ToList())));
}
Task<string[]> resultTask = Task.WhenAll<string>(tasks.ToArray());
resultTask.Wait();
if (resultTask.Status == TaskStatus.RanToCompletion)
{
foreach (var currentText in resultTask.Result)
{
Console.WriteLine(currentText);
}
}
Console.ReadKey();
}
static int number = 0;
private static string Process(List<string> inputList)
{
foreach (var item in inputList)
{
// The process here for each small loops.
Console.WriteLine(item);
}
return "Thread " + number++;
}
}
So, I take a part of x items from the big loop et I perform the process on each obtained list.
The problem is that the parameter of the method Process is changed inside the method when the code
input.Skip(i * take).Take(take).ToList()
is executed.
I tried by cloning the list but I get the same result.
Why ?
EDIT:
The lists would appear like this:
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
...
90 91 92 93 94 95 96 97 98 99

Related

Why are 3 separate Arrays generating the same set of random numbers in c# [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 3 years ago.
I am trying to create 3 separate arrays with 7 random numbers. The problem I am running into is that when the 3 arrays are generated they all have the same set of 7 random numbers. None of them have different numbers. I am unsure on what I need to do in order for the 3 arrays to have different random numbers.
Here is the code I have so far.
static void Main(string[] args)
{
int[] array1 = GenerateRandomArrayNumbers();
int[] array2 = GenerateRandomArrayNumbers();
int[] array3 = GenerateRandomArrayNumbers();
DisplayArray(array1);
DisplayArray(array2);
DisplayArray(array3);
}
static void DisplayArray(int[] arr)
{
foreach(int i in arr)
{
Console.Write($" {i} ");
}
Console.WriteLine();
}
static int[] GenerateRandomArrayNumbers()
{
int[] RandonNumSet = new int[7];
Random rNumber = new Random();
for (int index = 0; index < RandonNumSet.Length; index++)
{
int generateNum = rNumber.Next(1, 50);
RandonNumSet[index] = generateNum;
}
Array.Sort(RandonNumSet);
return RandonNumSet;
}
Here is what it displays:
13 16 22 29 34 37 42
13 16 22 29 34 37 42
13 16 22 29 34 37 42
Thanks for any suggestions!
All of your new Random() instances share the same seed (since they're created at the same clock time).
You should either reuse a single instance or specify different seeds.

Get the pre-last element of a string split by spaces

Input examples:
7 9 12 16 18 21 25 27 30 34 36 39 43 45 48 52 54 57 61
7 9 12 16 18 21 25 27 30 34 36 39 43 45 48 52 54 57 ... 75 79
Note that it ends with a space.
I want to get 57 in the first case and 75 in the second case as integer. I tried with the following:
Convert.ToInt32(Shorten(sequence).Split(' ').ElementAt(sequence.Length - 2));
The problem is that sequence.Length is not really the right index.
You can use the overload for Split() and pass the RemoveEmptyEntires enum:
string input = "7 9 12 16 18 21 25 27 30 34 36 39 43 45 48 52 54 57 61 ";
var splitInput = input.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
var inputInt = Convert.ToInt32(splitInput[splitInput.Length - 2]);
// inputInt is 57
Doing it this way allows your last element to actually be what you want.
Fiddle here
Based on maccettura's answer, in C# 8 you can simplify index acces like so
var input = "1 2 3";
var parts = input.Split(' ', StringSplitOptions.RemoveEmptyEntries);
var value = parts.Length >= 2 ? Convert.ToInt32(parts[^2]) : null;
How about something that doesn't use strings at all.
public static int? SplitReverseInt(this string str, int ixFromBack)
{
var inWord = false;
var wEnd = 0;
var found = 0;
for (int i = str.Length - 1; i >= 0; i--)
{
var charr = str[i];
if (char.IsWhiteSpace(charr))
{
// we found the beginning of a word
if (inWord)
{
if (found == ixFromBack)
{
var myInt = 0;
for (int j = i+1; j <= wEnd; j++)
myInt = (myInt * 10 + str[j] - '0');
return myInt;
}
inWord = false;
found++;
}
}
else
{
if (!inWord)
{
wEnd = i;
inWord = true;
}
}
}
// word (number) is at the beginning of the string
if (inWord && found == ixFromBack)
{
var myInt = 0;
for (int j = 0; j <= wEnd; j++)
myInt = (myInt * 10 + str[j] - '0');
return myInt;
}
return null;
}
Performance is about 10 times faster on the example strings.
This only loops from the back, and only fetches one number, it doesnt create substrings or an array of strings we don't need.
Use like this:
var numberFromBack = SplitReverseInt(input, 1);

Calculate sum of numbers on matrix diagonal

I have a dynamic matrix and I need to to calculate sum of digits in this way:
0 1 2 3 4 5 6
10 11 12 13 14 15 16
20 21 22 23 24 25 26
30 31 32 33 34 35 36
40 41 42 43 44 45 46
50 51 52 53 54 55 56
60 61 62 63 64 65 66
I can't understand in which way I should compare i and j:
long result = 0;
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
{
// only works for diagonal
if (i == j) // should use j - 1 or i - 1?
{
result += matrix[i][j];
}
}
}
no need to scan full matrix:
long result = 0;
for (int i = 0; i < len; i++)
{
result += matrix[i][i]; // diagonal
if (i < len - 1) // stay within array bounds
result += matrix[i][i+1]; // next to diagonal
}
modification without index check on every iteration:
// assign corner value from bottom row to result
long result = matrix[len-1][len-1];
// for each row (except last!) add diagonal and next to diagonal values
for (int i = 0; i < len-1; i++)
result += matrix[i][i] + matrix[i][i+1];

Rerun a program using nested for loops

I just started learning how to program in c #, so don't shoot me if I have "dumb" questions or questions to which the answer is probably very logical.
I have the next assignment:
Use a for loop to write the next pattern:
1 2 3 4 5 6 7 8 9 10 10
11 12 13 14 15 16 17 18 19 20 20
21 22 23 24 25 26 27 28 29 30 30
31 32 33 34 35 36 37 38 39 40 40
41 42 43 44 45 46 47 48 49 50 50
51 52 53 54 55 56 57 58 59 60 60
61 62 63 64 65 66 67 68 69 70 70
71 72 73 74 75 76 77 78 79 80 80
81 82 83 84 85 86 87 88 89 90 90
91 92 93 94 95 96 97
It has to be possible for the user to set a maximum (in this example 97) and then rerun the application without restarting.
What I am trying now is this:
class Program
{
static void Main(string[] args)
{
string output = "", input = "";
int MaxWaarde, karakters = 15;
do
{
Console.WriteLine("Gelieve het maximum van de matrix in te geven");
input = Console.ReadLine();
MaxWaarde = Convert.ToInt32(input);
for (int i = 1; i <= MaxWaarde; i += 11)
{
Console.Write(i);
for (int j = i; j < MaxWaarde + 1; j += karakters)
{
Console.Write(j);
}
Console.WriteLine(karakters + "");
}
Console.Write("\nOpnieuw een matrix aanmaken? (y/n): ");
output = Console.ReadLine();
}
while (output.ToLower() == "y");
}
}
Which isn't correct at all, but I have been trying to fix this for a while now, and I think I have been staring myself blind at this one, so i really don't know which way to go with this anymore.
Somebody who can give me some advice on how to make this right?
Nested for loops doesn't seem like a good idea here.You can do it with one for loop.You are incrementing i +11 in every step,probably your mistake is here. Consider this:
for (int i = 1; i <= MaxWaarde; i++)
{
if(i % 10 != 0) Console.Write(i + " ");
else
{
Console.Write(i + " " + i + "\n");
}
}
% is modulus operator.We are looking for remainder of currentNumber / 10, if it's not zero we write the number.If it is then we write value twice and adding a newline character with \n to go the next line.Also You can use Console.WriteLine() instead of \n
Loop1: Count up from 1 to number by step 1. If number is a multiple of 10 it writes that number again with line feed.
Loop2: Do loop1 again as long user wishes.
Here you go
public static void Main(string[] args)
{
for (;;)
{
var val = int.Parse(Console.ReadLine());
for (int i = 1; i <= val; i++)
{
if (i % 10 == 0)
{
Console.WriteLine("{0} {0}", i);
}
else
{
Console.Write("{0} ", i);
}
}
Console.WriteLine();
}
}

Generate multiplication table from a single for loop

Is it possible to generate a multiplication table (for example, from 1 to 9) with a single for loop?
Yes, using something like this... But why not using two nested loops?
for (int i = 0; i < 9 * 9; ++i)
{
int a = i / 9 + 1;
int b = i % 9 + 1;
Console.WriteLine("{0} * {1} = {2}", a, b, a * b);
}
To generate the multiplication table of 1-9 with a single for loop you could loop 81 time and use the division and modulo operator to get the two operands.
for (int i = 0; i < 9*9; ++i)
{
int a = i / 9 + 1;
int b = i % 9 + 1;
Console.WriteLine($"{a} * {b} = {a * b}");
//Console.WriteLine("{0} * {1} = {2}", a, b, a * b);
}
Note, there must be a better way to construct the output, but I'm not familiar with C#.
Here's a hint for one way to do it.
How can you extract all of the needed multipliers and multiplicands from a single integer from 0 to 81?
try:
Console.WriteLine(" 1 2 3 4 5 6 7 8 9");
for (int i = 1; i<10; i++)
Console.WriteLine(
string.Format("{0}: {1:#0} {2:#0} {3:#0} {4:#0} " +
"{5:#0} {6:#0} {7:#0} {8:#0} {9:#0}",
i, i, 2*i, 3*i, 4*i, 5*i, 6*i, 7*i, 8*i, 9*i));
here, the code for multiplication tables based on our criteria
suppose
Enter a value:2
Enter b value:10
then the output is like 2*1=2 to 2*10=20...
static void Main(string[] args)
{
int a, b, c, d;
Console.WriteLine("enter a value:");
a = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("enter b value:");
b = Convert.ToInt32(Console.ReadLine());
for (d = 1; d <=b; d++)
{
c = a * d;
Console.WriteLine("{0}*{1}={2}",a,d,c);
}
Console.ReadLine();
}
class Program
{
static void Main(string[] args)
{
Console.Write("Enter the value:");
int m = int.Parse(Console.ReadLine());
if (m == 0)
return;
for(int i=1;i<=10;i++)
Console.WriteLine("{0} * {1} ={2}",m,i,m*i);
Console.ReadLine();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication11
{
class Program
{
int a;
int b;
int c;
public void Accept()
{
Console.WriteLine("enter the no.:");
a = Convert.ToInt32(Console.ReadLine());
}
public void Process()
{
for (int c = 1; c <= 10; c++)
{
b = a * c;
Console.WriteLine("table: {0}", b);
}
Console.ReadLine();
}
public void Display()
{
//Console.WriteLine(a "X" + c +"="b);
}
static void Main(string[] args)
{
Program pr = new Program();
pr.Accept();
pr.Process();
Console.ReadKey();
}
}
}
It is C solution, but you may easily re-write it into whatever language you like.
#include <stdio.h>
void Mult_table(int n)
{
int i;
int a = 0;
int b = 0;
int count = 0;
for (i= 0; i< n*n; ++i)
{
a = i/n + 1;
b = i%n + 1;
printf("%4d ", a*b);
count++;
if(count %n == 0) /*new line*/
{
printf("\n");
}
}
}
Output (if n = 10, but will work with any n):
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100

Categories

Resources