Instead of if statements use a loop? - c#

Is there any way I could use a loop instead of writing out all of these if/else statements? I'm not sure if it is possible and I have looked online and haven't seen very many guides that would help me.
int numberOne = random.Next(id2) + 1;
int numberTwo = random.Next(id2) + 1;
int numberThree = random.Next(id2) + 1;
int numberFour = random.Next(id2) + 1;
int numberFive = random.Next(id2) + 1;
if (id1 == 1)
{
int total = numberOne;
string newmessage = "message";
return Json(newmessage);
}
else if(id1 == 2)
{
int total = numberOne + numberTwo;
string newmessage = "message";
return Json(newmessage);
}
else if (id1 == 3)
{
int total = numberOne + numberTwo + numberThree;
string newmessage = "message";
return Json(newmessage);
}
else if (id1 == 4)
{
int total = numberOne + numberTwo + numberThree + numberFour;
string newmessage = "message";
return Json(newmessage);
}
else if (id1 == 5)
{
int total = numberOne + numberTwo + numberThree + numberFive;
string newmessage = "message";
return Json(newmessage);
}

What you likely want to do is:
int total = Enumerable.Range(1, id1).Sum(z => random.Next(id2) + 1);
string newmessage = "message";
return Json(newmessage);
There is no need for an explicit loop (since Enumerable.Range will do the looping for you).

Since you probably need a loop and not using lambdas, you can go with something like this:
int total = 0;
for (int i = 0; i < id1; i++)
{
total += random.Next(id2) + 1;
}
return Json("message"); // I assume you want to return total here;
The reason this works is that if id1 is 1, you'd break out of the loop after doing 1 random.Next. If id2 is 2, then you'd run thru the first number and then add the 2nd number automatically. With this approach, you could support any number, not just up to 5.

I'd go with #mjwills solution, but here's an explanation of how you might do it in a step by step fashion:
The first thing I did was declare random, id1 and id2. I varied id1 during testing. When you post code, you should include this kind of thing, that way the folks help you don't have to reverse engineer what you are thinking:
var id1 = 5;
var id2 = 10;
var random = new Random();
Then, I realize that in each case, you have a chunk of the same code (the last two lines), so I extracted that duplicated code out and put it at the bottom of the loop (and I used NewtonSoft's JsonConvert class to convert things to JSON (which I'm assuming your Json function does) - I have that NuGetted into my test project):
string newMessage = "message";
return JsonConvert.SerializeObject(newMessage);
Finally, here's the loop you were asking about. I initialize total (I could put that initialization in the for loop, but it's clearer this way). Also note that the for loop is non-standard, it loops from 1 to N inclusive (generally for loops are 0 to N-1). This loop is between the initialization code and the final code:
var total = 0;
for (var i = 1; i <= id1; ++i)
{
total += (random.Next(id2) + 1);
}
What #mjwills code does is convert that into a single expression. The Enumerable.Range(1, id1) part generates a collection of consecutive integers starting at 1 and having id1 entries. Then he calls .Sum, passing it a lambda that represents a function to run on each item in the collection before it is summed. My loop basically does the same thing.
Altogether, it looks like this:
var id1 = 5;
var id2 = 10;
var random = new Random();
var total = 0;
for (var i = 1; i <= id1; ++i)
{
total += (random.Next(id2) + 1);
}
string newMessage = "message";
return JsonConvert.SerializeObject(newMessage);

try this, it also allows you init 5 numbers using any algoritm, not just the same
//var random=new Random();
//var id2=2;
//var id1=4;
var data = new int[]{
random.Next(id2) + 1,
random.Next(id2) + 1,
random.Next(id2) + 1,
random.Next(id2) + 1,
random.Next(id2) + 1
};
var total=0;
for ( var i = 0; i < id1; i++)
{
total+=data[i];
}
var newmessage = $"message#{id1.ToString()}, total {total.ToString()} ";
return Json(newmessage);

Related

How to put multiple lines in NetTelegramBot KeybrardMarkup?

I'm making a telegram bot with c#.
I want to read a number of names (not more than 20 tough thy could be less) and give them to the user as keyboardMarkup. With a one dimensional array they go all in one line and it's unreadable. I wanted to make 4 line with 5 names so i tried a 4x5 array. But i get this error
Error CS0029 Cannot implicitly convert type 'NetTelegramBotApi.Types.KeyboardButton[,]' to 'NetTelegramBotApi.Types.KeyboardButton[][]'
if (text == "/lista")
{
// Read a text file line by line.
listapz = System.IO.File.ReadAllLines("listapz.txt");
string selezione = "Seleziona il paziente:";
int i = 0;
int x = 0;
int y = 0;
var arrays = new KeyboardButton[4,5];
for (i = 0; i < listapz.Length; i++)
{
y = i / 5;
x = i - (y * 5);
arrays[y,x] = new KeyboardButton("$" + (i + 1) + " " + listapz[i]);
selezione += "\n$" + (i + 1) + " " + listapz[i] + "";
}
var keyb = new ReplyKeyboardMarkup()
{
Keyboard = arrays,
OneTimeKeyboard = true,
ResizeKeyboard = true
};
var reqAction = new SendMessage(update.Message.Chat.Id, selezione) { ReplyMarkup = keyb };
bot.MakeRequestAsync(reqAction).Wait();
Console.WriteLine(reqAction);
continue;
}
any solution?
You can create new one dimensional array for every line
Then
keyb.row(first_array) //you need get only values in python it will like keyb.row(*array)
keyb.row(second_array) //and so on
and add all keyboards in one reply_markup=keyb

How can I combine two strings and create sets by 4 characters, two coming from one string and other two from other string? c#

I got stuck in creating an algorithm that creates sets of 4 characters from two strings, two characters from one string and two from other string.
Example:
String one: FIRSTNAME
String two: LASTNAME
and the result that I expect is to get 10 sets of 4 characters like this: FILA, RSST, TNNA, AMME, EFLA and so on until we get 10 combinations like this.
this is the code that I made
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Name");
string name = Console.ReadLine();
Console.WriteLine("Lastname");
string lastname = Console.ReadLine();
int i;
var nchars = name.ToCharArray();
var pchars = lastname.ToCharArray();
for (i = 0; i <= 10; i++){
int ctr0;
int ctr;
int ctr2;
for (ctr = 0, ctr2 = 1, ctr0 = 1;
ctr < 10;
ctr0++, ctr = ctr + 2, ctr2 = ctr2 + 2) {
Console.WriteLine("{0}{1}{2}{3}{4}",
ctr0,
nchars[ctr],
nchars[ctr2],
pchars[ctr],
pchars[ctr2]);
}
}
}
}
and the output is good so far because I get
1FILA
2RSST
3TNNA
4AMME
but it stops when the string ends and instead of getting 10 combinations I get only 4.. what can I do?
Am I doing it wrong?
Or adding some Enumerable love.
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Name");
string name = Console.ReadLine();
Console.WriteLine("Lastname");
string lastname = Console.ReadLine();
// set the number of required sets and size
const int sets = 10;
const int size = 2;
// make both inputs long enough
var input1 = string.Concat(Enumerable.Repeat(name, (Math.Abs((sets * size) / name.Length) + 1)));
var input2 = string.Concat(Enumerable.Repeat(lastname, (Math.Abs((sets * size) / lastname.Length) + 1)));
// enumerate the index so we can substring the inputs.
var results = Enumerable.Range(0, sets)
.Select(x => $"{x + 1}{input1.Substring(x * size, size)}{input2.Substring(x * size, size)}");
// optional write to console
foreach(var result in results)
{
Console.WriteLine(result);
}
}
}
Trying to rectify your alogrithm, I think this is what you should try:
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Name");
string name = "FIRSTNAME";
Console.WriteLine("Lastname");
string lastname = "LASTNAME";
int i;
var nchars = name.ToCharArray();
var pchars = lastname.ToCharArray();
var ncharsCount = nchars.Length;
var pcharsCount = pchars.Length;
//for (i=0;i<=10;i++){
int ctr0;
int ctr;
int ctr2;
for (ctr = 0, ctr2 = 1, ctr0=1; ctr0 < 10 ;ctr0++, ctr++,ctr2++){
Console.WriteLine("{0}{1}{2}{3}{4}", ctr0,nchars[ctr%ncharsCount],nchars[ctr2%ncharsCount],pchars[ctr%pcharsCount],pchars[ctr2%pcharsCount]);
}
//}
}
}
Let's split the initial problem into several easier ones:
CircularSubstring, e.g. for value = "12345", index = 4, length = 3 we get "512"
MyGemerator which generate "FILA", "RSST" etc.
Final output in the required format
Code:
private static String CircularSubstring(string value, int index, int length) {
StringBuilder sb = new StringBuilder(length);
// + + value.Length) % value.Length -
// .Net can return negative remainder when we want it to be in [0..value.Length)
for (int i = 0; i < length; ++i)
sb.Append(value[((index + value.Length + i) % value.Length + value.Length) % value.Length]);
return sb.ToString();
}
private static IEnumerable<string> MyGenerator(string left, string right, int size) {
for (int i = 0; ; i += size)
yield return CircularSubstring(left, i, size) + CircularSubstring(right, i, size);
}
Then we are ready to generate a report in required format:
string one = "FIRSTNAME";
string two = "LASTNAME";
int size = 2; // chunks of size 2 from each (one, two) strings
int take = 10; // 10 chunks to generate
string report = string.Join(Environment.NewLine, MyGenerator(one, two, size)
.Take(take)
.Select((item, index) => $"{index + 1}{item}")
);
Console.Write(report);
Outcome:
1FILA
2RSST
3TNNA
4AMME
5EFLA
6IRST
7STNA
8NAME
9MELA
10FIST
More demo:
Console.Write(string.Join(Environment.NewLine, MyGenerator("Stack", "Overflow", 3)
.Take(12)
.Select((item, index) => $"{index + 1,2}. {item}")
));
Outcome:
1. StaOve
2. ckSrfl
3. tacowO
4. kStver
5. ackflo
6. StawOv
7. ckSerf
8. taclow
9. kStOve
10. ackrfl
11. StaowO
12. ckSver

Code doesn't show correct product c#

I'm studying coding and I'm on project 8 of project euler.
I was able to show the product "5832" for four adjacent digits when I'm using my code however when I use it on 13 digits, it doesn't work. My code is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace practice
{
class Program
{
static void Main(string[] args)
{
const string number = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
string input1, input2, input3, input4, input5;
string input6, input7, input8, input9, input10;
string input11, input12, input13;
int convert1, convert2, convert3, convert4, convert5;
int convert6, convert7, convert8, convert9, convert10;
int convert11, convert12, convert13;
convert1 = convert2 = convert3 = convert4 = convert5 = convert6 = convert7 = convert8 = 0;
convert9 = convert10 = convert11 = convert12 = convert13 = 0;
int counter;
int product = 0;
int largest = 0;
int length = number.Length - 13;
for (counter = 1; counter <= length; counter++)
{
input1 = number.Substring(counter, 1);
input2 = number.Substring(counter+1, 1);
input3 = number.Substring(counter+2, 1);
input4 = number.Substring(counter+3, 1);
input5 = number.Substring(counter+4, 1);
input6 = number.Substring(counter+5, 1);
input7 = number.Substring(counter+6, 1);
input8 = number.Substring(counter+7, 1);
input9 = number.Substring(counter+8, 1);
input10 = number.Substring(counter+9, 1);
input11 = number.Substring(counter+10, 1);
input12 = number.Substring(counter+11, 1);
input13 = number.Substring(counter+12, 1);
convert1 = Convert.ToInt32(input1);
convert2 = Convert.ToInt32(input2);
convert3 = Convert.ToInt32(input3);
convert4 = Convert.ToInt32(input4);
convert5 = Convert.ToInt32(input5);
convert6 = Convert.ToInt32(input6);
convert7 = Convert.ToInt32(input7);
convert8 = Convert.ToInt32(input8);
convert9 = Convert.ToInt32(input9);
convert10 = Convert.ToInt32(input10);
convert11 = Convert.ToInt32(input11);
convert12 = Convert.ToInt32(input12);
convert13 = Convert.ToInt32(input13);
product = convert1 * convert2 * convert3 * convert4 * convert5 * convert6
* convert7 * convert8 * convert9 * convert10 * convert11
* convert12 * convert13;
if (largest < product) { largest = product; }
}
Console.WriteLine("The largest number is {0}", largest);
Console.ReadKey();
}
}
}
It doesn't show the correct answer which I find daunting. The next steps
I did is:
1. Check the last 13 digits of my variables to check if it loops and multiplies correctly "0420420752963450".
2. Check if it works with the first four numbers and first five numbers which are surprisingly correct.
3. Studied how others have done it.
4. Links used:
Homework in Java. Find the largest product of five consecutive digits
http://www.mathblog.dk/solution-to-problem-8-of-project-euler/
I seem to not get it. Please guide me on seeing my mistake. Thank you.
Your product variable is int and you parse your consecutive numbers to int. Max value for integer is 2,147,483,647. So when you multiply 13 numbers it's quite possible you will exceed the limit and the value will overflow giving incorrect result. Perhaps, consider using BigInteger instead.
What about something like this:
[Test]
public void Test()
{
const string number = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int index = 0;
int largest = 0;
var largestString = "";
const int length = 13;
while (index + length <= number.Length)
{
var substring = number.Substring(index, length);
var product = ProductOfEachNumber(substring);
if (product > largest)
{
largestString = substring;
largest = product;
}
index++;
}
Console.WriteLine("The largest number is {0}", largest);
Console.WriteLine("The largest number string is {0}", largestString);
}
[Test]
public void TestSubstring()
{
var res = ProductOfEachNumber("9989");
res.Should().Be(5832);
}
private static int ProductOfEachNumber(string substring)
{
return substring.Aggregate(1, (current, c) => current*Int32.Parse(c.ToString()));
}
Gives output:
The largest number is 2091059712
The largest number string is 9781797784617
Try this one, let me know. You have to modify it.
static void Main(string[] args)
{
Stopwatch sw = Stopwatch.StartNew();
int x = Largest();
Console.WriteLine(x);
Console.WriteLine("Time used (float): {0} ms", sw.Elapsed.TotalMilliseconds);
Console.WriteLine("Time used (rounded): {0} ms", sw.ElapsedMilliseconds);
Console.ReadKey();
}
public static int Largest()
{
string p = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int largest = 0;
int numm = 0;
for (int i = 0; i < p.Length - 4; i++)
{
numm = int.Parse(p.Substring(i, 1)) *
int.Parse(p.Substring(i + 1, 1)) *
int.Parse(p.Substring(i + 2, 1)) *
int.Parse(p.Substring(i + 3, 1)) *
int.Parse(p.Substring(i + 4, 1));
if (numm > largest)
{
largest = numm;
}
}
return largest;
}

remaining values from HashSet into secondary out

We've been asked to create a program which takes 2 input (which I have parsed) for seats and passengers in a plane and randomly place passengers on seats in a plane in one output as well as placing the remaining seats in a secondary output.
I was wondering if there is a simple way to replace the remaining values in HashSet, into the listBoxLedige.
As it works now, the seats are being distributing but the values in the secondary output arent related the the first output.
if(passengers > seats)
{
MessageBox.Show("For mange passagerer");
}
else
{
HashSet<int> check = new HashSet<int>();
for(int i = 0; i <= passengers - 1; i++)
{
int resultat = rnd.Next(1, seats + 1);
while(check.Contains(resultat))
{
resultat = rnd.Next(1, seats + 1);
}
check.Add(resultat);
int[] passagerer01 = new int[passengers];
passagerer01[i] = i+1;
listBoxFulde.Items.Add("Passager #" + passagerer01[i] + "på sæde #" + resultat);
}
HashSet<int> ledige01 = new HashSet<int>();
for(int i = 0; i <= (seats - passengers - 1); i++)
{
int tilbage = rnd.Next(1, seats + 1);
while(ledige01.Contains(tilbage))
{
ledige01.Add(tilbage);
}
listBoxLedige.Items.Add("Sæde #" + tilbage);
I'm not exactly sure I understand your problem, but have you taken a look at the Except LINQ extension method? Judging by your wording ("remaining values"), it might be the right method for you.
Edit Here's how it's done:
IEnumerable<int> empty = allSeats.Except(check);
Note how empty is now a deferred enumerator (unless you do a .ToArray(), .ToList() or similar on it).
Here's what I'd do (see Range and ExceptWith):
HashSet<int> ledige01 = new HashSet<int>(
Enumerable.Range(1, seats));
ledige01.ExceptWith(taken);
Note in generating the seeds you can remove the trial and error by simply shuffling the seats and taking the first N:
var taken = HashSet<int>(Enumerable.Range(1,seats).Shuffle().Take(passengers));
For hints on how to do shuffle, see e.g. Optimal LINQ query to get a random sub collection - Shuffle
As an aside:
int[] passagerer01 = new int[passengers];
passagerer01[i] = i+1;
listBoxFulde.Items.Add("Passager #" + passagerer01[i] + "på sæde #" + resultat);
looks to be something other than you need :) But I'm assuming it's unfinished and you're likely aware of that
A 'fully' edited take:
if(passengers > seats)
{
MessageBox.Show("For mange passagerer");
}
else
{
HashSet<int> taken = new HashSet<int>();
for(int i = 0; i <= passengers - 1; i++)
{
int resultat;
do {
resultat = rnd.Next(1, seats + 1);
} while(taken.Contains(resultat));
taken.Add(resultat);
listBoxFulde.Items.Add("Passager #" + (i+1) + "på sæde #" + resultat);
}
HashSet<int> ledige01 = new HashSet<int>(
Enumerable.Range(1, seats));
ledige01.ExceptWith(taken);
if(passengers > seats)
{
MessageBox.Show("For mange passagerer");
}
else
{
HashSet<int> taken = new HashSet<int>();
for(int i = 0; i <= passengers - 1; i++)
{
int resultat;
do {
resultat = rnd.Next(1, seats + 1);
} while(taken.Contains(resultat));
taken.Add(resultat);
listBoxFulde.Items.Add("Passager #" + (i+1) + "på sæde #" + resultat);
}
HashSet<int> ledige01 = new HashSet<int>(Enumerable.Range(1, seats));
ledige01.ExceptWith(taken);
foreach(var tilbage in ledige01)
listBoxLedige.Items.Add("Sæde #" + tilbage);
Not a hundred percent sure I understand your problem or solution, but are you aware that you declare and initialize passagerer01 once for each passenger, then deterministically (not randomly) assign seat i+1 to passenger i and afterwards throw away that array? If you wanted to keep the information, you'd have to declare the array outside the for loop.
Also, it doesn't really seem like you're doing anything meaningful in that second part of your code. To determine the empty seats, it would make sense to go through numbers 1 to passengers, check if they are in the set check and, if not, add them to set ledige01. Or, of course, to do something equivalent using a library method as suggested by sehe.
As a last note, in computer science you usually start counting from zero. Thus, you would usually have seat numbers 0 to seats-1 and choose seats randomly like so: rnd.Next(0, seats). And you would usually loop like this: for(int i = 0; i < passengers; i++) instead of for(int i = 0; i <= passengers - 1; i++).

Adding numbers to a string?

I have strings that look like "01", "02". Is there an easy way that I can change the string into a number, add 1 and then change it back to a string so that these strings now look like "02", "03" etc. I'm not really good at C# as I just started and I have not had to get values before.
To get from a string to an integer, you can youse int.Parse():
int i = int.Parse("07");
To get back into a string with a specific format you can use string.Format():
strings = string.Format("{0:00}",7);
The latter should give "07" if I understand http://www.csharp-examples.net/string-format-int/ correctly.
You can convert the string into a number using Convert.ToInt32(), add 1, and use ToString() to convert it back.
int number = Convert.ToInt32(originalString);
number += 1;
string newString = number.ToString();
Parse the integer
int i = int.Parse("07");
add to your integer
i = i + 1;
make a new string variable and assign it to the string value of that integer
string newstring = i.ToString();
AddStringAndInt(string strNumber, int intNumber)
{
//TODO: Add error handling here
return string.Format("{0:00}", (int.TryParse(strNumber) + intNumber));
}
static string StringsADD(string s1, string s2)
{
int l1 = s1.Count();
int l2 = s2.Count();
int[] l3 = { l1, l2 };
int minlength = l3.Min();
int maxlength = l3.Max();
int komsu = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < maxlength; i++)
{
Int32 e1 = Convert.ToInt32(s1.PadLeft(maxlength, '0').ElementAt(maxlength - 1 - i).ToString());
Int32 e2 = Convert.ToInt32(s2.PadLeft(maxlength, '0').ElementAt(maxlength - 1 - i).ToString());
Int32 sum = e1 + e2 + komsu;
if (sum >= 10)
{
sb.Append(sum - 10);
komsu = 1;
}
else
{
sb.Append(sum);
komsu = 0;
}
if (i == maxlength - 1 && komsu == 1)
{
sb.Append("1");
}
}
return new string(sb.ToString().Reverse().ToArray());
}
I needed to add huge numbers that are 1000 digit. The biggest number type in C# is double and it can only contain up to 39 digits. Here a code sample for adding very huge numbers treating them as strings.

Categories