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 1 year ago.
Improve this question
There is a number N (i.e., N = 3).
I create an array from -N to N (i.e. {-3, -2, -1, 0, 1, 2, 3})
I randomly remove a number from the array (i.e. {-3, -2, 0, 1, 2, 3}, removed -1)
I shuffle the Array (i.e. {-2, 0, 2, 3, -3, 1})
Write a function
public int FindMissing(int[] arr)
That takes the shuffled Array from the initial steps and identifies and returns the array's missing number.
I've done it like this, but I think I did it wrong:
public partial class findMissingNumber
{
public static int FindMissing(int[] arr, int N)
{
int summ = (N - 1) * N / 2;
int sumarr = 1;
for (int i = 1; i < arr.Length; i++)
{
sumarr += arr[i];
}
return summ - sumarr;
}
public static void Main()
{
Console.WriteLine(FindMissing(new int[] { -2, 0, 2, 3, -3, 1 }, 3));
Console.ReadLine();
}
}
The sum of all the numbers in an array [-N, N] is 0.
If an element is missing it'll be 0 minus the missing number.
If 1 is missing, sum = 0 - 1, therefore the missing number is -sum. Except when 0 is missing.
With LINQ is very easy:
using System.Linq;
class findMissingNumber
{
public static int FindMissing(int[] arr)
{
return (arr.Contains(0)) ? -arr.Sum() : 0;
}
public static void Main()
{
Console.WriteLine(FindMissing(new int[] { -2, 2, 1, 3, -3, -1 }));
}
}
Of course if you know that the array will always miss a number you don't even need to check if 0 is missing and it all boils down to -arr.Sum()
Without LINQ is a little longer, but works in the same way:
public static int FindMissing(int[] arr)
{
int sum = 0;
if (Array.FindIndex(arr, x => x == 0) < 0)
return 0;
Array.ForEach(arr, x => sum += x);
return -sum;
}
Again, if you know that an element will alwas be missing, you can avoid looking for zero
I used lambdas, but you can write your predicate as you like https://zetcode.com/csharp/predicate/
Related
public static int FindMaxNumForMaxSum(int[] nums, int k)
{
int retVal = 0;
int N = nums.Length;
var counter = 1;
var map = new Dictionary<int, int>();
for (var i = 0; i < N; i++)
{
if (nums[i] == retVal)
{
counter++;
continue;
}
var complement = k - nums[i];
retVal = complement;
if (nums[i] == complement)
{
if (!map.ContainsKey(complement))
{
map.Add(complement, counter);
}
else
{
map[complement] = counter++;
}
}
else
{
map.Add(complement, counter);
}
}
return counter;
}
Above is my code.
Problem description below:
Given a list of n integers arr[0..(n-1)], determine the number of different pairs of elements within it which sum to k.
If an integer appears in the list multiple times, each copy is considered to be different; that is, two pairs are considered different if one pair includes at least one array index which the other doesn't, even if they include the same values.
The above solution doesn't see to produce expected output and also there is a problem of adding duplicate keys in a dictionary.
Example 1
n = 5
k = 6
arr = [1, 2, 3, 4, 3]
output = 2
The valid pairs are 2+4 and 3+3.
Example 2
n = 5
k = 6
arr = [1, 5, 3, 3, 3]
output = 4
Example 3
arr = [2, 3, 6, 7, 4, 5, 1]
output = 3
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 2 years ago.
Improve this question
Imagine we got a couple of 3x3 2D arrays that are identified by a X Y coordinate.
Pseudo code:
Array 0-0 Array 1-0
[[1,2,1] [[1,2,1]
[2,3,2] [2,3,2]
[3,1,2]] [3,1,2]]
Array 0-1 Array 1-1
[[1,2,1] [[1,2,1]
[2,3,2] [2,3,2]
[3,1,2]] [3,1,2]]
And we also have an index array, to index all this sub-arrays.
chunk_array = [
[Array 0-0, Array 0-1],
[Array 1-0, Array 1,1]
]
The problem is how to quickly create a final array, 6x6 containing all sub-arrays without having to iterate all elements of the array as this is a very critical place that has to operate in the minimal time possible.
So question: What would be the quickest way to perform this operation ? I've looked at Buffer copy, but not sure still what would be the best approach here.
Here's a solution based on the suggestion of Alexei Levenkov in the comments. From his comment: Fastest way to do something is not to do it at all... Does that work in your case (i.e. by wrapping all 4 into a class that exposes indexing the way you like)?
You create your four individual arrays and then add them to a wrapper capable of holding those arrays in a rectangular array. I use a function to access the individual elements, but you could use an indexer instead (if you are inclined that way - I'm not, that accessor seems a bit too complex for a simple indexer).
Here's the main class:
public class CompositeArray<T> where T:new()
{
private readonly T[,][,] _componentArray = null;
public int IndividualArrayWidth { get; }
public int IndividualArrayHeight { get; }
public int ComponentArrayWidth { get; }
public int ComponentArrayHeight { get; }
public int OverallArrayWidth => IndividualArrayWidth * ComponentArrayWidth;
public int OverallArrayHeight => IndividualArrayHeight * ComponentArrayHeight;
public CompositeArray(int individualArrayWidth, int individualArrayHeight, int componentArrayWidth,
int componentArrayHeight)
{
IndividualArrayWidth = individualArrayWidth;
IndividualArrayHeight = individualArrayHeight;
ComponentArrayWidth = componentArrayWidth;
ComponentArrayHeight = componentArrayHeight;
_componentArray = new T[ComponentArrayWidth, ComponentArrayHeight][,];
}
public void SetIndividualArray(int x, int y, T[,] array)
{
if (x < 0 || x >= IndividualArrayWidth)
{
throw new ArgumentOutOfRangeException(nameof(x), x, $#"Must be between 0 and {IndividualArrayWidth - 1}");
}
if (y < 0 || y >= IndividualArrayHeight)
{
throw new ArgumentOutOfRangeException(nameof(y), y, $#"Must be between 0 and {IndividualArrayHeight - 1}");
}
if (array.GetLength(0) != IndividualArrayWidth || array.GetLength(1) != IndividualArrayHeight)
{
throw new ArgumentOutOfRangeException(nameof(array), $#"Must be between an array that is {IndividualArrayWidth} by {IndividualArrayHeight}");
}
_componentArray[x, y] = array;
}
public T GetOverallElement(int x, int y)
{
if (x < 0 || x >= OverallArrayWidth)
{
throw new ArgumentOutOfRangeException(nameof(x), x, $#"Must be between 0 and {OverallArrayWidth - 1}");
}
if (y < 0 || y >= OverallArrayHeight)
{
throw new ArgumentOutOfRangeException(nameof(y), y, $#"Must be between 0 and {OverallArrayHeight - 1}");
}
int whichArrayX = x / IndividualArrayWidth;
int innerX = x % IndividualArrayWidth;
int whichArrayY = y / IndividualArrayHeight;
int innerY = y % IndividualArrayHeight;
return (_componentArray[whichArrayX, whichArrayY][innerX, innerY]);
}
}
Note that I create a rectangularly jagged rectangular array. It took a bit to figure out the syntax.
Note that there is no copying at all. You only pay for two integer divisions and two integer modulus operations per element access. If you only use 2x2 arrays, you could reduce that to two bit-shifts and two bit-tests (since division by two is a simple bit-shift, and checking for even/odd is simply a test of the least significant bit).
Here's some code that exercises that class:
int[,] array00 = new int[,]
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[,] array01 = new int[,]
{
{11, 12, 13},
{14, 15, 16},
{17, 18, 19}
};
int[,] array10 = new int[,]
{
{21, 22, 23},
{24, 25, 26},
{27, 28, 29}
};
int[,] array11 = new int[,]
{
{31, 32, 33},
{34, 35, 36},
{37, 38, 39}
};
CompositeArray<int> bigArray = new CompositeArray<int>(array00.GetLength(0), array00.GetLength(1), 2,2);
bigArray.SetIndividualArray(0, 0, array00);
bigArray.SetIndividualArray(0, 1, array01);
bigArray.SetIndividualArray(1, 0, array10);
bigArray.SetIndividualArray(1, 1, array11);
var shouldBe2 = bigArray.GetOverallElement(0, 1);
var shouldBe6 = bigArray.GetOverallElement(1, 2);
var shouldBe28 = bigArray.GetOverallElement(5, 1);
var shouldBe16 = bigArray.GetOverallElement(1, 5);
var shouldBe32 = bigArray.GetOverallElement(3, 4);
I think the best you can do is copy chunks of 3 values as they are all the source values that are contiguous in the destination array:
var ans = new int[6,6];
for (int row = 0; row < 2; ++row) {
for (int col = 0; col < 2; ++col) {
var srcArray = chunk_array[row, col];
for (int subRow = 0; subRow < 3; ++subRow) {
Array.Copy(srcArray, subRow*3, ans, subRow*6+row*18+col*3, 3);
}
}
}
Some performance testing doesn't show much optimization of this code possible.
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 5 years ago.
Improve this question
Let's say I have a list / array of integers, i.e:
{1, 2, 3, 4}
Is there a way to get every single possible combination of additions and add them to another list / array?
Like this:
1+2, 1+3, 1+4,
2+3, 2+4,
3+4,
1+2+3, 1+2+4, 1+3+4,
2+3+4,
1+2+3+4
So the end-result would be (without duplicates):
{3, 4, 5, 6, 7, 8, 9, 10}
With more specific to int list you can do that
static List<int> GetCombination(List<int> list, List<int> combinations, int sumNum, bool addNumberToResult = false)
{
if (list.Count == 0) {
return combinations;
}
int tmp;
for (int i = 0; i <= list.Count - 1; i++) {
tmp = sumNum + list[i];
if(addNumberToResult){
combinations.Add(tmp);
}
List<int> tmp_list = new List<int>(list);
tmp_list.RemoveAt(i);
GetCombination(tmp_list,combinations,tmp, true);
}
return combinations;
}
and to call it simply do
List<int> numbers = new List<int>(){1,2,3,4,5};
List<int> possibleCombination = GetCombination(numbers, new List<int>(), 0);
and to remove duplicate
possibleCombination.Distinct()
If you want it orderer you can call
possibleCombination.Distinct().OrderBy(itm => itm)
or
possibleCombination.Distinct().OrderByDescending(itm => itm)
C# fiddle
Edit : As Pierre rightly pointed out, the code did not stick to the question, I corrected accordingly, adding an parameters for adding or not the numbers to the result list.
Based on this great answer here is a version that will allow you to eliminate the "small subset"(*)
public static List<List<T>> GetCombination<T>(List<T> inputList, int minimumItems = 1)
{
int count = (int)Math.Pow(2, inputList.Count) - 1;
List<List<T>> result = new List<List<T>>(count + 1);
if (minimumItems == 0)
result.Add(new List<T>());
for (int i = 1; i <= count; i++)
{
List<T> combinason = new List<T>(inputList.Count);
for (int j = 0; j < inputList.Count; j++)
{
if ((i >> j & 1) == 1)
combinason.Add(inputList[j]);
}
if (combinason.Count >= minimumItems)
result.Add(combinason);
}
return result;
}
Result:
>> { {1,2}, {1,3}, {2,3}, {1,2,3}, {1,4}, {2,4},
>> {1,2,4}, {3,4}, {1,3,4}, {2,3,4}, {1,2,3,4} }
From here a simple .Sum() on the subset:
Subsets.ForEach( s => result.Add(s.Sum()) );
As you wanted to clear every duplicate in the list:
DoublonList.Distinct();
C# fiddle
ps: (*) Can't find the word in english for groupe of only one element
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 8 years ago.
Improve this question
I have a dice game, where I need to find the highest pair of 5 dices and get the total of it.
I have made this code so far which counts the numbers into pairs. Now I want to find the highest pair.
Code:
int Pair[];
Pair = new int[7] {0, 0, 0, 0, 0, 0, 0} //Seven pairs because i dont want to use Pair[0]
int TT[];
TT = new int[5] { 1, 6, 3, 1, 3 }; //five dice
int t = 1;
for(int i = 0; i < 5; i++)
{
if ( TT[i] == t)
{
Pair[t] = Pair[t] + 1;
t = t + 1;
}
}
If I understand your problem correctly, I think you are overcomplicating it. If you think about it, what you want are the two highest numbers from an arry. Simply sort it, and reverse it, and take the two first numbers.
class Program
{
static void Main(string[] args)
{
int[] Dice = new int[5] { 1, 6, 3, 1, 3 };
Array.Sort(Dice);
Array.Reverse(Dice);
Console.WriteLine("The largest pair is ({0}, {1})", Dice[0], Dice[1]);
}
}
The other possibility for the largets pair (as mentioned in a comment) is that you want to find the highest number in the list that occurs twice. You can do this by sorting the Array, reversing it, so you read from the highest number. Then incrementally check if the current number matches the next number, and if this is the case, you found the highest pair.
class Program
{
static void Main(string[] args)
{
int[] Dice = new int[5] { 1, 6, 3, 1, 3 };
Array.Sort(Dice);
Array.Reverse(Dice);
for (int i = 1; i < Dice.Length; i++)
{
if (Dice[i] == Dice[i - 1])
{
Console.WriteLine("The largest pair is ({0}, {1})", Dice[i], Dice[i-1]);
break;
}
}
}
}
I have an integer array int[] number = { 3,4,2,5,1};
The minimum number of steps to sort it should be 2. But I am getting 4.
static void Main(string[] args)
{
int[] number = { 3,4,2,5,1};
int result = get_order(number);
Console.ReadKey();
}
public static int get_order(int[] input1)
{
input1 = input1.OrderByDescending(o => o).ToArray();
bool flag = true;
int temp;
int numLength = input1.Length;
int passes = 0;
for (int i = 1; (i <= (numLength - 1)) && flag; i++)
{
flag = false;
for (int j = 0; j < (numLength - 1); j++)
{
if (input1[j + 1] > input1[j])
{
temp = input1[j];
input1[j] = input1[j + 1];
input1[j + 1] = temp;
flag = true;
}
}
passes++;
}
return passes+1;
}
What is the problem and what changes i need to do in my code?
Edit
implement #Patashu, algorithm,
public static int get_order(int[] input1)
{
var sorterArray = input1.OrderByDescending(o => o).ToArray();
var unsortedArray = input1;
int temp1;
int swap = 0;
int arrayLength = sorterArray.Length;
for (int i = 0; i < arrayLength; i++)
{
if (sorterArray[i] != unsortedArray[i])
{
temp1 = unsortedArray[i];
unsortedArray[i] = sorterArray[i];
for (int j = i + 1; j < arrayLength; j++)
{
if (unsortedArray[j] == sorterArray[i])
{
unsortedArray[j] = temp1;
swap++;
break;
}
}
}
}
return swap;
}
The problem with your algorithm is that it only attempts swapping adjacent elements.
3,4,2,5,1 is best sorted by swapping 3 with 5, which is an unadjacent swap, and then 2 with 3.
So, I suggest that you will find a better algorithm by doing the following:
1) First, sort the array into descending order using the built in sorting function of C#.
2) Now, you can use this sorted array as a comparison - iterate through the array from left to right. Every time you see an element in the unsorted array that is != to the element in the same space in the sorted array, look deeper into the unsorted array for the value the sorted array has there, and do one swap.
e.g.
3,4,2,5,1
Sort using Sort -> 5,4,3,2,1 is our sorted array
3 is != 5 - look in unsorted array for 5 - found it, swap them.
Unsorted is now 5,4,2,3,1
4 == 4
2 is != 3 - look in unsorted array for 3 - found it, swap them.
Unsorted is now 5,4,3,2,1
2 == 2
1 == 1
We're at the end of the unsorted array and we did two swaps.
EDIT: In your algorithm implementation, it looks almost right except
instead of
unsortedArray[j] = sorterArray[i];
unsortedArray[i] = temp1;
you had it backwards, you want
unsortedArray[j] = temp1;
unsortedArray[i] = sorterArray[i];
Since you're asking why you're getting 4 steps, and not how to calculate the passes, the correct way to do this is to simply step through your code. In your case the code is simple enough to step through on a piece of paper, in the debugger, or with added debug statements.
Original: 3, 4, 2, 5, 1
Pass: 1: 4, 3, 5, 2, 1
Pass: 2: 4, 5, 3, 2, 1
Pass: 3: 5, 4, 3, 2, 1
Pass: 4: 5, 4, 3, 2, 1
Basically what you see is that each iteration you sort one number into the correct position. At the end of pass one 2 is in the correct position. Then 3, 4, 5.
Ah! But this is only 3 passes you say. But you're actually incrementing passes regardless of flag, which shows you that you actually did one extra step where the array is sorted (in reverse order) but you didn't know this so you had to go through and double check (this was pass 4).
To improve performance, you do not need to start checking the array from the beginning.
Better than the last equal element.
static int MinimumSwaps(int[] arr)
{
int result = 0;
int temp;
int counter = 0;
for (int i = 0; i < arr.Length; ++i)
{
if (arr[i] - 1 == i)
{
//once all sorted then
if(counter==arr.Length)break;
counter++;
continue;
}
temp = arr[arr[i]-1];
arr[arr[i] - 1] = arr[i];
arr[i] = temp;
result++;//swapped
i = counter ;//needs to start from the last equal element
}
return result;
}
At the start:
{ 3,4,2,5,1}; // passes = 0
Round 1 reuslt:
{ 4,3,2,5,1};
{ 4,3,5,2,1}; // passes = 1
Round 2 reuslt:
{ 4,5,3,2,1}; // passes = 2
Round 3 reuslt:
{ 5,4,3,2,1}; // passes = 3 and flag is set to true
Round 4 reuslt:
{ 5,4,3,2,1}; // same result and passes is incremented to be 4
You fail to mention that the array is supposed to be sorted in descending order, which is usually not the default expected behavior (at least in "C" / C++). To turn:
3, 4, 2, 5, 1
into:
1, 2, 3, 4, 5
one indeed needs 4 (non-adjacent) swaps. However, to turn it into:
5, 4, 3, 2, 1
only two swaps suffice. The following algorithm finds the number of swaps in O(m) of swap operations where m is number of swaps, which is always strictly less than the number of items in the array, n (alternately the complexity is O(m + n) of loop iterations):
int n = 5;
size_t P[] = {3, 4, 2, 5, 1};
for(int i = 0; i < n; ++ i)
-- P[i];
// need zero-based indices (yours are 1-based)
for(int i = 0; i < n; ++ i)
P[i] = 4 - P[i];
// reverse order?
size_t count = 0;
for(int i = 0; i < n; ++ i) {
for(; P[i] != i; ++ count) // could be permuted multiple times
std::swap(P[P[i]], P[i]); // look where the number at hand should be
}
// count number of permutations
This indeed finds two swaps. Note that the permutation is destroyed in the process.
The test case for this algorithm can be found here (tested with Visual Studio 2008).
Here is the solution for your question :)
static int MinimumSwaps(int[] arr)
{
int result = 0;
int temp;
int counter = 0;
for (int i = 0; i < arr.Length; ++i)
{
if (arr[i] - 1 == i)
{
//once all sorted then
if(counter==arr.Length)break;
counter++;
continue;
}
temp = arr[arr[i]-1];
arr[arr[i] - 1] = arr[i];
arr[i] = temp;
result++;//swapped
i = 0;//needs to start from the beginning after every swap
counter = 0;//clearing the sorted array counter
}
return result;
}