Related
I want to write a card exchange game. I have an Arraylist of Colors in which values start from -1 to 6. Each element of this array implies id colors. There is also an ArrayList Player Properties in which cards with colors are stored. I need to create an ArrayList with eight zeros that will imply id Colors. Next, skip the ArrayList Player Properties through this array and if there is some element in the array, then increase the ArrayList Colors index by +1.
Eg:
ArrayList Colors =new ArrayList(){-1,0,1,2,3,4,5,6};
ArrayList Player Properties = new ArrayList(){0,4,6};
This array should imply that its element is an element of the Colors array
ArrayList buffer = new ArrayList(){0,0,0,0,0,0,0,0};
If an array comes to the input in this form: {0,4,6};
Then the index of this array is added by +1, like this: {0,1,0,0,0,1,0,1};
How do I implement this in code?
I don't have any code examples because I don't know how to implement it, sorry in advance that I didn't provide more code, I really need help, thank you all in advance for your help
You can use the Linq function Contains to check if a value is present in an array. Something like this:
var colors = new int[] { -1, 0, 1, 2, 3, 4, 5, 6 };
var playerProperties = new int[] { 0, 4, 4, 6 };
var result = colors.Select(c => playerProperties.Where(x => x == c).Count());
Console.WriteLine(string.Join(", ", result));
prints 0, 1, 0, 0, 0, 2, 0, 1
What you want is a histogram of the card values that you accumulate.
Since this is C# you better start thinking of a data model for each player. There are two arrays to consider, one with the card values: -1,0,..6 and one with the card counts, how many of each card a player has.
Here is how this would play out:
static class Program
{
static void Main(string[] args)
{
var player1 = new Player("Player1");
Console.WriteLine(player1);
// Player1 : 0,0,0,0,0,0,0,0
player1.Hand(0,4,6);
Console.WriteLine(player1);
// Player1: 0,1,0,0,0,1,0,1
}
}
You can to this point with the following Player class that handles the logic inside the .Hand() method.
public class Player
{
public static readonly int[] CardValues = { -1, 0, 1, 2, 3, 4, 5, 6 };
public Player(string name)
{
CardCounts = new int[CardValues.Length];
Name = name;
}
public int[] CardCounts { get; }
public string Name { get; }
public void Hand(params int[] cards)
{
foreach (var card in cards)
{
int index = Array.IndexOf(CardValues, card);
if (index >= 0)
{
CardCounts[index] += 1;
}
}
}
public override string ToString()
{
return $"{Name} : {string.Join(",", CardCounts)}";
}
}
Note that ArrayList is really old technology, and not type safe. In it place there is List<>, but in this case the length of the array is fixed since there is a finite set of card values, and that does not change, so no need for a collection, as a plain old Array would suffice.
Because your array is a fixed representation:
var Colors = new []{-1,0,1,2,3,4,5,6};
var PlayerProperties = new []{0,4,6};
var buffer = new []{0,0,0,0,0,0,0,0};
You can calculate which indexes in the buffer should be set to 1
foreach(var pp in PlayerProperties)
buffer[pp+1] += 1;
Value 0 always occurs at index 1. Value 4 always occurs at index 5. Value 6 always occurs at index 7. Thus the formula is value+1..
I'm trying to get a reference on a sub array from a existing array.
I want to be able to update the original array when i'm doing a modification on the sub array.
Example :
byte[] array = {0 , 1, 2, 3, 4};
byte[] subarray = array.Skip(2).Take(3).ToArray();
subarray[0] = 8;
Console.WriteLine("array[2] = " + array[2]);
I want to see :
array[2] = 8
but instead, i get :
array[2] = 2
I read this solution but its not good enough because I dont want to give the option to modify array values that are not in the range, like this :
ArraySegment<byte> segment = new ArraySegment<byte>(array, 2, 3);
byte[] segmentByte = segment.ToArray();
I can modifiy all the original array through segmentByte. This is what i want to prevent.
You can write simple Array and ArraySegment<of T> wrapper that provides set of required operations only:
struct StrictRangeArraySegment<T>
{
ArraySegment<T> _segment;
public StrictRangeArraySegment(T[] array)
: this(array, 0, array.Length)
{
}
public StrictRangeArraySegment(T[] array, int offset, int count)
: this(new ArraySegment<T>(array, offset, count))
{
}
public StrictRangeArraySegment(ArraySegment<T> segment)
{
_segment = segment;
}
public int Count
{
get
{
return _segment.Count;
}
}
public T this[int index]
{
get
{
if (index < 0 || index >= _segment.Count)
throw new ArgumentOutOfRangeException(nameof(index));
return _segment.Array[_segment.Offset + index];
}
set
{
if (index < 0 || index >= _segment.Count)
throw new ArgumentOutOfRangeException(nameof(index));
_segment.Array[_segment.Offset + index] = value;
}
}
}
For reference see ArraySegment<Of T> source code.
If you take a closer look at ToList method, you will see that it completely generate a new list which is not referred to the old one at all. So what you change only reflect to subarray only.
The only solution is to use that ArraySegment that you don't want to.
public List<TResult> ToList()
{
var list = new List<TResult>();
foreach (TSource item in _source)
{
list.Add(_selector(item));
}
return list;
}
One option is creating a type to box your integers as a property of an object. Then updating the property will have the desired result:
public class Box<T>
{
public T Value {get;set;}
public Box<T>(T item) {Value = item;}
}
Box<byte>[] array = {new Box<byte>(0), new Box<byte>(1), new Box<byte>(2), new Box<byte>(3), new Box<byte>(4)};
Box<byte>[] subarray = array.Skip(2).Take(3).ToArray();
subarray[0].Value = 8;
Console.WriteLine("array[2] = " + array[2].Value);
//you'll see "8" instead of "2" now
You might also want to look at Span<T>. It's not fully released yet, but it might make it possible to accomplish your goal here.
How can I add a single Integer to an Integer Array?
if (valuesHigherThanAverage.Length == 0) valuesHigherThanAverage[valuesHigherThanAverage.Length] = arrayGetal;
else valuesHigherThanAverage[valuesHigherThanAverage.Length + 1] = arrayGetal;
I have this code and I have also tried with for or foreach loop but it doesn't worked. And I need to use an INT[] and may not use an List.
You can't add a new item in an array, you have to create a new array with size+1, copy all existing values, and then set the last item value.
An easier way is to use a List<int>, which will automatically resize if you run out of space. Calling the Add method suffices then.
Here a sample of an array resizing algorithm (Array.Resize could automate this, but this is just to show you how it should work):
int[] oldItems = new int[] { 1, 2, 3 };
int[] newItems = new int[oldItems.Length * 2];
for (int i = 0; i < oldItems.Length; i++)
{
newItems[i] = oldItems[i];
}
newItems[oldItems.Length + 1] = 4;
The array is not designed to be extended as new elements are added. You will need to call Array.Resize(Of T) to increase the size but this is will be quite inefficient.
Data types more in line for what you want to do is List<T>.
You cannot change the size of array like valuesHigherThanAverage.Length + 1. It has fixed size. You are crossing the upper bound of the array.
You can create a new Array with the length of the old array + 1.
public static int[] AddIntToArray(int[] sourceArray, int addValue)
{
int[] newArray = new int[sourceArray.Length + 1];
Array.Copy(sourceArray, newArray, sourceArray.Length);
newArray[newArray.Length] = addValue;
return newArray;
}
The task is to write a simple method that can sort int array (in ascending or descending order - should be set as enum type parameter of this method). I have written the method itself and enum, but I have no idea how to set enum as method parameter:(
Would be great to get any help from you, guys, cause I am completely new to coding.
class Program
{
public enum options
{
UpSortOption,
DownSortOption
}
public static void Main(string[] args)
{
int[] arr = new int[] { 3, 8, 0, 2, 16 };
}
static void orderArray(int [] array, options op)
{
switch(op)
{
case options.UpSortOption:
Array.Sort(array);
foreach (int number in array)
{
Console.Write(number + " ");
}
break;
case options.DownSortOption:
Array.Sort(array);
Array.Reverse(array);
foreach (int number in array)
{
Console.Write(number + " ");
}
break;
}
}
}
The signature of the method looks fine, Now you wanted to call this method by passing the first parameter of type integer array and the second parameter of type options for that you can use the following code:
orderArray(arr,options.UpSortOption);
Or else you can declare a variable of type options and pass that variable, the change you have to make for that case will be:
options optionsVariable = options.DownSortOption;
orderArray(arr,optionsVariable);
Let's take a step back to see if it helps your understanding.
If you have a method that takes a string and an int like this
string MyMethod(string str, int num)
{
// Do something
}
You'd use it like this
string rslt = MyMethod("Hello", 123);
What you've got here is something that takes in some stuff, does something to it, and gives you something in return. In this case MyMethod takes a string and an int, does something with them and returns a string which you then call rslt.
Your example follows the same basic pattern so you need to take your method - orderArray and give it the two things it wants - an int array and an option like this
int[] arr = new int[] { 3, 8, 0, 2, 16 };
orderArray(arr, options.UpSortOption);
Alternatively, you could create an options much like you'd create a string and then call your method like this
int[] arr = new int[] { 3, 8, 0, 2, 16 };
options myOption = options.UpSortOption;
orderArray(arr, myOption);
To fully illustrate the point that an enum as a parameter isn't any different from say a string you could modify your method like this
static void orderArray(int[] array, string op)
{
if (op == "UpSortOption")
{
Array.Sort(array);
foreach (int number in array)
{
Console.Write(number + " ");
}
}
else
{
Array.Sort(array);
Array.Reverse(array);
foreach (int number in array)
{
Console.Write(number + " ");
}
}
}
Then call it like this
int[] arr = new int[] { 3, 8, 0, 2, 16 };
string myOption = "UpSortOption";
orderArray(arr, myOption);
This is how you pass it as a parameter
orderArray(int [] array, typeof(options)){
//Beep bap boop
}
Hope this aids you.
Exactly that's how you set up Enum as a method parameter.
To call this method use:
orderArray(arr, options.UpSortOption);
You can also assign enum value to a variable and use this to call a method:
options sortOpt = options.UpSortOption;
orderArray(arr, sortOpt);
You can also cast integer to an enum:
orderArray(arr, (options)0);
OR
int opt = 0;
orderArray(arr, (options)opt);
Remembering, that if not specified otherwise, first element is 0, second is 1 and so on.
By the way, you should rather use PascalCase to name an enum type, like:
public enum Options
{ ... }
So there's this blog that gives Five programming problems every Software Engineer should be able to solve in less than 1 hour and I'm just revisiting some of the concepts.
The first question reads
Write three functions that compute the sum of the numbers in a given list using a for-loop, a while-loop, and recursion.
Obviously the for- and while-loops are easy, but i started out with
int[] l = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
Is it at all possible to pop an item off the list and then pass the shortened list every time?
An attempt I saw in python:
numbers = [1,2,3,4,5,6,7,8,9]
def recurse_count(lst):
if len(lst) == 1:
return lst[0]
else:
i = len(lst) - 1
subtotal = lst[i] + lst[i - 1]
lst.pop() #into the void with you
lst[-1] = subtotal
return recurse_count(lst)
Would it be possible with a int[] in c# ?
A very elegant solution would be:
static public int sumThisUp(IEnumerable<int> list)
{
return list.FirstOrDefault() + (list.Any() ? sumThisUp(list.Skip(1)) : 0);
}
Yes. I do belive the List-class has a simple removeAt(int)-method. A recursive method would look like this:
public int sumThisUp(List<int> list) {
int result = list[0];
list.removeAt(0);
return (list.length > 0) ? result + sumThisUp(list) : result;
}
Alternatively if you dont wanna edit the orginal list this would do:
public int sumThisUp2(List<int> list, int index = 0) {
int result = list[index++];
return (list.Count > index) ? result + sumThisUp2(list, index) : result;
}
Yes, it is possible in C#.
But I want to introduce some trick first: instead of modifying the source list we can just pass the start index. It will be much faster:
private static int Sum(int[] array, int startIndex)
{
if (startIndex >= array.Length)
{
return 0;
}
return array[startIndex] + Sum(array, startIndex + 1);
}
static void Main(string[] args)
{
int[] array = new int[] { 1, 2, 3, 4 };
int result = Sum(array, 0);
Console.WriteLine(result);
}
This should do it:
public int Sum(int[] numbers, int startAt = 0)
{
if (startAt == numbers.Length)
return 0;
return numbers[startAt] + Sum(numbers, startAt + 1);
}