Related
I am trying to create an array based on the ones that I have. I have two arrays which look like this
sample array A: {AB01, AB01, AB01, AB02, AB02, AB02, AB03, AB01}
sample array B: {10, 10, 20, 10, 20, 20, 40, 10}
Both arrays are dynamic so provided data is just a sample data. Same indexes in both arrays creates a pair: so for example: pair 1: AB01 10 , pair 2: AB01 10 and so on. Based on those two arrays I want to create third array which will represent indexes but including duplicates. So I want my third array to look like this:
array (3) C: {10, 10, 20, 30, 40, 40, 50, 10}
FYI I cannot use LINQ 4+
I tried nested loop over the arrays but I do not get the expected result.
for(int i = 0; i < arrayA.Length; i++){
for(int j = i + 1; j < arrayA.Length; j++){
if(arrayA[i] == arrayA[j] && arrayB[i] == arrayB[j]){
arrayC.Insert(i, 10 * (i+1));
}
else
arrayC.Insert(i, 10 * (i+2));
}
}
As I mentioned I expext my array C to be indexes of each element but I want to include duplicates:
array (3) C:
{10, 10, 20, 30, 40, 40, 50, 10}
EDIT:
As the result is not clear.
If there was no duplicates in the arrays I would want my array C to look like this:
{10, 20, 30, 40, 50, 60, 70, 80}
It means that each pair eg(AB01, 10) will be given index 10 in array C.
But when it comes to duplicates array C will look different.
Pair AB01 - 10 appears as first so I want to give it index 10. And because it appears three times at position: 0, 1 and 7 I want number 10 to be at those positions in array C. Next on I have pair AB01 - 20 it appears only one time at position 2 and values are different than in pair to so I want to give it index 20. And so on.
As written in the comments, a re-formulation of the task is:
for each pair, if it has been encountered before, use the already
allocated "index", otherwise create a new one as (previous index) +
10.
You need to remember the already assigned indexes, e.g. in a Dictionary<(string, int), int>, mapping a pair to the index. In addition. you need to keep track of the highest index assigned so far.
var arrayA = new string[] { "AB01", "AB01", "AB01", "AB02", "AB02", "AB02", "AB03", "AB01"};
var arrayB = new int[] {10, 10, 20, 10, 20, 20, 40, 10};
var assignedIndexes = new Dictionary<(string, int), int>();
var highestIndex = 0;
var result = new int[arrayA.Length];
for (var i = 0; i < arrayA.Length; i++)
{
var tuple = (arrayA[i], arrayB[i]);
if (!assignedIndexes.TryGetValue(tuple, out var index))
{
index = highestIndex + 10;
assignedIndexes.Add(tuple, index);
highestIndex = index;
}
result[i] = index;
}
Console.WriteLine(string.Join(", ", result));
Prints: 10, 10, 20, 30, 40, 40, 50, 10
If you cannot use ValueTuples, too, replace them by Tuples:
var assignedIndexes = new Dictionary<Tuple<string, int>, int>();
var tuple = Tuple.Create(arrayA[i], arrayB[i]);
I am currently following a tutorial on making a game in Unity using C#. In it, they showed us how to show the score in the center of the screen using
using UnityEngine;
using UnityEngine.UI;
public class Score : MonoBehaviour
{
public Transform player;
public Text scoreText;
// Update is called once per frame
void Update()
{
scoreText.text = player.position.z.ToString("0");
}
}
However, I want to go further and figure out how to make a high score list in the top left corner. My only experience is with python so I know I would go about making an empty array of size 10, and then each time the game restarts, if the score is greater than any of the highest 10 scores in the mentioned list, it is inserted in the corresponding position (keeping the elements ordered), and the lowest value is dropped from the list (to keep a list of just 10 elements). However, I am confused about the syntax of C#.
Currently, my thought process for the code (which would go on my restart statement), if it were python is this
##this is how I would write it in python I believe
array = np.zeros[10]
for i in range(0, len(array)):
if player.position.z.ToString("0") < array[-i]
continue
else:
array[-i-1] = player.position.z.ToString("0")
Where obviously the player.position statement is from c#. I was wondering if anyone could help me translate the thought process over. It seems I need to declare an array of strings before I can use it but I am not sure.
Thanks for any help
As I understood you want an array with 10 elements where you store the top 10 scores. So each new score which is higher than the existing top 10 is placed in the correct position of that top 10.
Something like
current Top10 => 2, 3, 5, 7, 8, 9, 12, 15, 18, 20
newScore = 16
new Top10 => 3, 5, 7, 8, 9, 12, 15, 16, 18, 20
Option 1:
string[] scoreArray = new string[10];
//Initializing the score array
for (int i = 0; i < 10; i++)
{
scoreArray[i] = 0;
}
//Somewhere in your code a new score will be assigned to this variable
int newScore;
//Checking potentially higher score
boolean replaceFlag = false;
for (int i = 0; i < 10; i++)
{
if(newScore > scoreArray[i])
{
replaceFlag = true;
}else{
//newScore lower than lowest stored score
if(i == 0)
{
//Stop the loop
i = 11;
}else if(replaceFlag){
//The rest of the elements in the array move one position back
for(int j = 0 ; j < i-1; j++ )
{
scoreArray[j] = scoreArray[j+1];
}
//Finally we insert the new score in the correct place
scoreArray[i-1] = newScore;
}
}
}
Option 2: Using List
//Create and initialize list of scores
List<int> listScores = new List<int>{ 0,0,0,0,0,0,0,0,0,0};
// If later, at some point we have the following scores 2, 3, 5, 7, 8, 9, 12, 15, 18, 20
//When you get a new score (our list will have)
listScores.Add(newScore);
//After inserting 2, 3, 5, 7, 8, 9, 12, 15, 18, 20, 16
//Ordering the list in descending order
listScores.Sort()
//Now we have 2, 3, 5, 7, 8, 9, 12, 15, 16, 18, 20,
//Drop last element of the list to keep the fixed size of 10.
listScores.RemoveAt(0)
//Now we have 3, 5, 7, 8, 9, 12, 15, 16, 18, 20
//In case you want to have the list in descending order
listScores.Sort((a, b) => -1* a.CompareTo(b));
if Score is the array, then add the scores to this Score array variable and then sort and reverse this array whenever u want to update the high score.
private void UpdateScore(int[] ScoreArray)
{
Array.Sort(ScoreArray);
Array.Reverse(ScoreArray);
}
You would create a known array size of 10 like this:
string[] aStringArray = new string[10];
Also add this at top;
using System.Collections.Generic;
Arrays - C# Programming Guide
Array must have length, if you want unknown size then use List
List<int> player = new List<int>();
player.Add(1);
I have an unsorted array of numbers. Most numbers in this array are consecutive (1, 2, 3, 4, 5,...) but sometimes there's a number in it that's higher than the rest.
int highestNumber = int.MinValue;
int secondHighestNumber = int.MinValue;
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 1207, 7, 8, 9, 1803, 10, 11, , 9000, 9001 };
int counter = 0;
foreach (int number in arr) {
if (number > highestNumber) {
secondHighestNumber = highestNumber;
highestNumber = number;
}
else if (number > secondHighestNumber) secondHighestNumber = number;
}
When I run the code, it'll tell me 9001 is the highest number and 9000 the second highest. But I want to change it so that I get an array of all the numbers from 1 to 11, with all the consecutive numbers that only have a difference of one, and a second array with all the larger numbers: 1207, 1803, 9000 and 9001.
9000 and 9001 shouldn't be in the first array, because the difference between these numbers and the rest is too high. So the end result should look like this:
int[] arr1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
int[] arr2 = new int[] { 1207, 1803, 9000, 9001 };
Some background info on what the purpose of this is:
Cient creates articles and each article has an article number that is created by looking up what the highest article number is in the "articles" table so far (e.g. 20), then the number of the new article is that number + 1 (e.g. 21); So an increment per number. However the client wishes to be able to sometimes add articles and input the article number he desires for the article, so let's say for the last article he created he inputted 7000 as article number. If he he then creates another article after that, I have to continue with that list of incrementing numbers. So unless the client changes the value of the next article again, the next new article should have 22 as article number (and not 7001).
Any help would be greatly appreciated as I've been stuck on trying to figure this out for a while now.
I'm not sure if you are just wanting to get the next number you should use or you want the 2 sets. If you want the two sets, I would do this:
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 1207, 7, 8, 9, 1803, 10, 11, , 9000, 9001 };
int counter = 0;
List<int> l1 = new List<int>();
List<int> l2 = new List<int>();
foreach (int number in arr) {
if(l1.Count==0 || l1[l1.Count-1] == (number -1))
l1.Add(number);
else
l2.Add(number);
}
int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 1207, 7, 8, 9, 1803, 10, 11, 9000, 9001 };
// Sort the array
Array.Sort(arr);
// Start at the beginning and check if the index matches the actual number.
// Computer begins at 0, so fix that
for (int index=0;index<arr.Length; index++)
{
if (arr[index] != index+1)
{
Console.WriteLine("Next ID is " +(index+1));
break;
}
}
I have data like
1 3 9 2 7 8 9
120 70 76 190 300 50 40
how can I sort the array based on the second row and return the value of the max number from the first row. I mean, the output become >
7 2 1 9 3 8 9
300 190 120 76 70 50 40
And I get the 7 as output.
First I would get your data out of the rectangular array into something a bit more usable. To do this, first convert the data into a List<Tuple<int, int>> because it is much easier to work with.
int[,] rawData = { { 1, 3, 9, 2, 7, 8, 9 }, { 120, 70, 76, 190, 300, 50, 40 } };
var data = new List<Tuple<int, int>>();
for(int i = 0; i < rawData.GetLength(1); i++)
{
data.Add(new Tuple<int, int>(rawData[0, i], rawData[1, i]));
}
Then it is just a matter of using a Linq query to get the data you want.
var result = data.OrderByDescending(x => x.Item2).First().Item1;
Fiddle
If you'd like to know the answer to 'what's the max number now' (or to put it differently, to keep the order rather then sort it post processing - beware it has a performance penalty!) then SortedList may come in handy:
int[] a = { 1, 3, 9, 2, 7, 8, 9 };
int[] b = { 120, 70, 76, 190, 300, 50, 40 };
var sortedList = new SortedList<int,int>();
for (int i = 0; i < a.Length; i++)
{
sortedList[b[i]] = a[i];
}
Console.WriteLine(sortedList.Last().Value);
(if you want to see what's current max value as you add data just move WriteLine to inside of the loop)
I'm working on a project in C# that involves keeping track of the top five high scores for a rock paper scissors game. Right now I have an array to hold the top five scores (which are integers), I sort the array in descending order, and I use a for loop to compare the score just earned by the user to the scores currently in the array. If the new score is higher than one in the array, right now the new score just takes the space in the array that the lower one occupied.
For example, if the scores were 9, 8, 5, 3, 1 and the user scored a 6, the scores would then look like this: 9, 8, 6, 3, 1. I wondered if there's a way for me to shift the lower scores over and insert the new one, so the list would look like this: 9, 8, 6, 5, 3.
This is the code I currently have, where successPercent is the score, calculated as wins divided by losses and ties:
int[] scoreArray = { 84, 25, 36, 40, 50 };
Array.Sort(scoreArray);
Array.Reverse(scoreArray);
for (int x = 0; x <= scoreArray.Length; ++x)
{
if (successPercent > scoreArray[x])
{
scoreArray[x] = Convert.ToInt32(successPercent);
break;
}
}
Something like this can do the trick:
Create temporary list
Add new score
Sort it by descending order
Take top 5...
int[] scoreArray = { 84, 25, 36, 40, 50 };
var tempList = new List<int>(scoreArray );
int newScore = ...;//Get the new score
tempList.Add(newScore);
scoreArray = tempList.OrderByDescending(x=>x)
.Take(5)
.ToArray();
You can do this without creating a new list.
[Algo]: Replace the smallest number by the new number and then sort!
int[] scoreArray = { 5, 3, 9, 8, 1 };
int new_number = 6;
//Replaces smallest number by your new number
int min_index = Array.IndexOf(scoreArray, scoreArray.Min());
scoreArray[min_index] = new_number;
Array.Sort(scoreArray);
Array.Reverse(scoreArray);
I believe your way is correct and more effient than creating redundant lists, just you are calling the Reverse method unnecessarily.Instead, leave your elements sorted in ascending order, then loop through the array, and sort it in descending order.
int[] scoreArray = { 84, 25, 36, 40, 50 };
int userScore = 100;
Array.Sort(scoreArray);
for (int x = 0; x <= scoreArray.Length; ++x)
{
if (userScore > scoreArray[x])
{
scoreArray[x] = Convert.ToInt32(userScore);
break;
}
}
Array.Sort(scoreArray,(x,y) => y.CompareTo(x));
Note: My first solution was throwing away the second highest score so I have deleted it.