How to sort a jagged array [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm making a program to automate rolling initiative. I have most of it done, but I can't sort the outputs because it's a jagged array. I need the second column of each array in my jagged array to be sorted from highest to lowest.
using System;
using System.Linq;
namespace Auto_Initiative
{
class Program
{
static void Main(string[] args)
{
string[] encounter =
{
"Wizard", "18", "-2",
"Bard", "9", "3",
"Goblin 1", "16", "1",
"Goblin 2", "14", "1"
};
int[][] numbers = new int[encounter.Length / 3][];
int loop = 0;
for(int i = 0; i > encounter.Length; i += 3)
{
// Name number, real roll
numbers[loop] = new int[2] {i, Int32.Parse(encounter[i + 1]) + Int32.Parse(encounter[i + 2])};
}
Console.ReadKey();
}
}
}

One part of designing your software is choosing the right data structure for how you are planning to use it. Sometimes redundant data is required but we don't know what you are requirements are to make that decision. So as was mentioned by Sergey you should consider creating a custom class which I have shown an example of below. Also note that a string[] is not really a jagged array. By definition a jagged array has nested arrays of variable size. The data structure depicted above could be put in a regular string[][] and would not be jagged.
Object Oriented in Action
What you are looking for is stored in unitsSortedBySecondColumn.
class so65865986
{
static void Main(string[] args)
{
Encounter encounter = new Encounter
{
Units = new List<EncounterUnit> {
new EncounterUnit{
Name = "Wizard",
Column1 = 18,
Column2 = -2,
},
new EncounterUnit{
Name = "Bard",
Column1 = 9,
Column2 = 3,
},
new EncounterUnit{
Name = "Goblin 1",
Column1 = 16,
Column2 = 1,
},
new EncounterUnit{
Name = "Goblin 2",
Column1 = 14,
Column2 = 1,
},
},
};
var unitsSortedBySecondColumn = encounter.Units
.OrderBy(u => u.Column1)
.Select(u => new int[] { u.Column1, u.Column2 })
.ToArray();
}
}
class EncounterUnit
{
public string Name;
public int Column1; //Change name to whatever it means
public int Column2; //Change name to whatever it means
}
class Encounter
{
public List<EncounterUnit> Units;
}
Nested (but not Jagged) Array
class so65865986_nested_array
{
static void Main(string[] args)
{
string[][] encounter =
{
new string[] {"Wizard", "18", "-2" },
new string[] {"Bard", "9", "3" },
new string[] {"Goblin 1", "16", "1" },
new string[] {"Goblin 2", "14", "1" },
};
int[][] numbers = encounter
.Select(u => new int[] { int.Parse(u[1]), int.Parse(u[2]) })
.OrderBy(u => u[0])
.ToArray();
Console.ReadKey();
}
}
Other Notes
Also, another note. You don't need to use Int32 because it is recommended you use the aliases provided which in this case is int.

use this code:
string[] encounter =
{
"Wizard", "18", "-2",
"Bard", "9", "3",
"Goblin 1", "16", "1",
"Goblin 2", "14", "1"
};
int[,] numbers = new int[encounter.Length / 3, 3];
for (int i = 1; i < encounter.Length / 4; i++)
{
for (int j = 0; j < encounter.Length / 3; j += 1)
{
numbers[j, i] = Convert.ToInt32(encounter[i + (j * 3)]);
Console.Write(numbers[j, i] + " ");
}
Console.WriteLine(Environment.NewLine);
}
Console.ReadLine();

Related

C# append multiple string array to a new array inside for loop [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
How can I append all the string arr into one arr within a for loop?
string[] finalArray = new string[5];
for (int i = 0; i < finalArray.Length; i++)
{
string[] array1 = GenRandArray1();
string[] array2 = GenRandArray2();
string[] array3 = GenRandArray3();
string[] array4 = GenRandArray4();
// I want to combine all the string array to my finalArray.
finalArray[i] = array1 + array2 + array3 + array4
}
Since I make loop 5 times and store in finalArray[i], so the sample output will be something like this.
"12345","17896","685","984","063","991","6","9","3","6","68","20","69","52"
"43256","24356","765","345","347","983","2","1","0","5","90","34","12","76"
"76324","98754","542","625","267","865","3","2","1","8","23","43","76","86"
"00982","16864","537","847","249","136","1","0","9","3","65","80","23","17"
"12569","98754","658","345","646","999","5","9","6","3","94","63","15","47"
Do you mean concat all the arrays or a different algorithm? If you just want to concat all the arrays it just like below.
string[] finalArray = new string[5];
string[] array1 = new[] { "1", "2", "4" };
string[] array2 = new[] { "9", "3", "6" };
string[] array3 = new[] { "4", "0", "0" };
string[] array4 = new[] { "7", "8", "2" };
finalArray = finalArray.Concat(array1).Concat(array2).Concat(array3).Concat(array4).ToArray();
From your question it is not clear if you really want to concat your arrays five times, but let's assume that that is the case in your simplified code. In addition, as you remarked, you will be returning a list of arrays
Then:
List<string[]> finalArrayList = new List<string[]>();
for(int i=0; i<5; i++)
{
string[] array1 = new[] { "1", "2", "4" };
string[] array2 = new[] { "9", "3", "6" };
string[] array3 = new[] { "4", "0", "0" };
string[] array4 = new[] { "7", "8", "2" };
List<string> ConcatList = new List<string>(array1);
ConcatList.AddRange(array2);
ConcatList.AddRange(array3);
ConcatList.AddRange(array4);
finalArrayList.Add(ConcatList.ToArray());
}

Generating Random Unique items from a string list [duplicate]

This question already has answers here:
Randomize a List<T>
(28 answers)
Closed 3 years ago.
I have string list of a deck of card the strings are as such, A-DIAMONDS, 2-CLUBS, etc.
I want to be able to generate 5 unique items from this list randomly.
I know how to do this in python with Random.sample(5) but in trying to find a solution in C#. everything seems to be generating a random, put it in a list, generate another random, check it against the list and it is working fine.
Is there a more compact way of doing this in C#?
Here is my full code after using Linq for shuffling.
class Program
{
static void Main(string[] args)
{
string [] cardValues = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
string [] cardSuites = { "HEARTS", "CLUBS", "DIAMONDS", "SPADES" };
List<string> deckOfCards = new List<string>();
foreach(string cardsuit in cardSuites)
{
foreach(string cardvalues in cardValues)
{
deckOfCards.Add(cardvalues + "-" + cardsuit);
}
}
for(int i = 0; i <= 10; i++)
{
List<string> pokerHand = new List<string>();
Random rand = new Random();
deckOfCards = deckOfCards.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
for(int x = 0; x < 5; x++)
{
pokerHand.Add(deckOfCards[x]);
}
Console.WriteLine(String.Join(", ", pokerHand));
}
Console.ReadLine();
}
}
}
Here is one way to shuffle using linq. The 5 random cards are the first 5 items in the list. :
class Program
{
static void Main(string[] args)
{
List<string> deck = new List<string>() {
"S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "ST", "SJ", "SQ", "SK", "SA",
"H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "HT", "HJ", "HQ", "HK", "HA",
"C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CT", "CJ", "CQ", "CK", "CA",
"D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "DT", "DJ", "DQ", "DK", "DA"
};
Random rand = new Random();
deck = deck.Select(x => new { card = x, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.card).ToList();
}
}
You could use MoreLINQ. Simply install it from NuGet.
MoreLINQ gives you a Shuffle method. So you can do something like the following:
List<Card> deck = GetDeck();
List<Card> randomFiveCards = deck.Shuffle().Take(5).ToList();
A valid and efficient algorithm is to pick a random index between 0 and n-1 (where n is the number of cards), exchange the last card with the card at that index. Then pick a random index between 0 and n-2 and exchange second-last card with the card at that index.
Repeat other three times with n-3, n-4 and n-5 and your five randomly chosen cards will be at the end of the array.

How to Define that One String is Greater than Another? (C#) (Beginner)

I'm extremely new to coding, so the answer/s to this may be obvious. I have to make the card game War. I've created a list of strings like so for a part of the deck:
List<string> userDeck = new List<string>
{
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"Jack",
"Queen",
"King",
"Ace",
};
Is there a way I can instruct the computer that "Jack" will be greater than "10", "Queen" greater than "Jack", and so on? I'm not sure where or how I should do it.
OR, if you have any other suggestions as to how I should do this, please let me know. I have to be using a list. I initially made a list of integers instead, but I wasn't aware of an uncomplicated way to assign the names such as "Jack," "Queen," "King," etc. to them for display purposes.
Any help would be greatly appreciated.
Try to create a object called "Card". This object can contain more than a value. Eg:
public class MyCard
{
public string Name {get;set;}
public int Value {get;set;}
public MyCard(string name, int value)
{
this.Name = name;
this.Value = value;
}
}
After create this object, you will use this at your list.
List<MyCard> userDeck = new List<MyCard>();
You can fill the list this way:
usertDeck.Add(new MyCard("2", 1));
....
usertDeck.Add(new MyCard("K", 11));
So, to compare 2 cards, just check using the "Value" variable
The easiest way to refactor your code (to your requirements value per card) is to use Tuple's instead of string type in generic List as follow:
List<Tuple<int,string>> userDeck = new List<Tuple<int,string>>
{
new Tuple<int,string>(2,"2"),
new Tuple<int,string>(3,"3"),
new Tuple<int,string>(4,"4"),
new Tuple<int,string>(5,"5"),
new Tuple<int,string>(6,"6"),
new Tuple<int,string>(7,"7"),
new Tuple<int,string>(8,"8"),
new Tuple<int,string>(9,"9"),
new Tuple<int,string>(10,"10"),
new Tuple<int,string>(11,"Jack"),
new Tuple<int,string>(12,"Queen"),
new Tuple<int,string>(13,"King"),
new Tuple<int,string>(14,"Ace"),
};
Similar to Vincius's answer but with some changes for better usability:
enum Suit
{
Clubs = 1,
Diamonds = 2,
Hearts = 3,
Spades = 4
}
class Card
{
private static readonly Dictionary<string, int> rankMap = new Dictionary<string, int>()
{
{"2", 2 },
{"3", 3 },
{"4", 4 },
{"5", 5 },
{"6", 6 },
{"7", 7 },
{"8", 8 },
{"9", 9 },
{"10", 10 },
{"Jack", 11 },
{"Queen", 12 },
{"King", 13 },
{"Ace", 14 },
};
private Suit suit;
private string rank;
public Suit Suit => suit;
public string Rank => rank;
public int Value { get { return rankMap[rank]; } }
public Card(Suit s, string r)
{
suit = s;
rank = r;
}
}
The way you can use it:
Card c1 = new Card(1, "Jack"); // 1 is Clubs
Card c2 = new Card(4, "Queen"); // 4 is Spades
Console.WriteLine(c1.Value); // prints 11
Console.WriteLine(c2.Value); // prints 12

IndexOutOfBounds error [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
So I'm new to programming. I have printed two arrays next to each other. On the left column, I have Ace,2,3,4.. up until Jack, Queen king. One the right column is my suites. So Clubs, hearts etc. Now I want to randomize my whole deck, but I find only for example 3 Hearts print, nothing else. Also, I get an IndexOutOfBounds error.I can't figure out why.
Here's my code:
string[] suites = new string[] { "hearts", "clubs", "diamonds", "spades" };
string [] pack = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13" };
Random r = new Random();
string[] x = new string[] { suites[r.Next(0,3)].ToString() };
string[] y = new string[] { pack[r.Next(0,12)].ToString() };
for (int a = 0; a < 13; a++)
{
for (int p = 0; p < 4; p++)
{
Console.WriteLine(y[a] + " " + x[p]);
}
}
Replace below lines
string[] x = new string[] { suites[r.Next(0,3)].ToString() };
string[] y = new string[] { pack[r.Next(0,12)].ToString() };
With
string[] x = suites.OrderBy(a => r.Next()).ToArray();
string[] y = pack.OrderBy(a => r.Next()).ToArray();

How to measure the amount of times 0 & 1 occurs

Here is the code that outputs 1 or 0 depending on the equality of the 2 arrays
static void Main(string[] args)
{
while (true)
{
Console.WriteLine(Here());
}
Here is where the magic happens.
static int Here()
{
Random rnd = new Random();
PlayerInput();
int[] intarray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
string[] sarray = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
int i = rnd.Next(10); // creates a number between 1 and 10
int x = rnd.Next(10);
string iarray = intarray[x].ToString();
if (iarray == sarray[i])
{
return 1;
}
else
{
return 0;
}
}
it outputs 0 when the two arrays don't equal and 1 vise versa. now I want to count the amount of times it outputs 0 & 1.
Questions:
How could I do that?
Should I transfer the output to an array for easier manipulation?
Unless I'm misunderstanding your question, it seems like you could simply have two counter variables:
static void Main(string[] args)
{
int totalOnes = 0;
int totalZeroes = 0;
while (true) // need to replace this with something that will actually exit!!
{
int ret = Here();
if (ret == 1) totalOnes++; else totalZeroes++;
Console.WriteLine(ret);
}
Console.WriteLine("Total Ones: {0} Total Zeroes: {1}", totalOnes, totalZeroes);
}
EDIT: Thanks to L J for pointing out that your while loop will never exit since you have while (true). You need to address that.
like this
static void Main(string[] args)
{
var zeroCount = 0;
var oneCount = 0;
while (true)
{
var result = Here();
if (result == 1) oneCount++;
if (result == 0) zeroCount++;
Console.WriteLine($"Actual result {result}, zero count {zeroCount}, One count {oneCount}");
}
}
static int Here()
{
Random rnd = new Random();
PlayerInput();
int[] intarray = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
string[] sarray = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
**var Count1 = 0;
var Count0 = 0;**
int i = rnd.Next(10); // creates a number between 1 and 10
int x = rnd.Next(10);
string iarray = intarray[x].ToString();
if (iarray == sarray[i])
{
**Count1++;**
return 1;
}
else
{
**Count0++;**
return 0;
}
}
Count0 will contain the number of times 0 was outputted.
Count1 will contain the number of times 1 was outputted.

Categories

Resources