forward and backward search algorithm on an array - c#

I'm working on a simple algorithm problem for practice and i'm trying to figure out why on about 20 percent of test cases it fails. The problem is thus, given an array of ints find the average of all valid ints in the array.
An int is valid if
It is greater than or equal to -273
at least one of the previous two or next two ints are two points away from the current one
if the int is invalid it should not be included in calculating the average. Also, I don't believe the problem wants the solution to be cyclic (not sure though just thought about it while writing this so will try) i.e. if you are at the first int array[0], then there are no previous two ints as opposed to the last two being the previous two in a cyclic array.
my strategy is summed up in the code below:
public double averageTemperature(int[] measuredValues)
{
Queue<int> qLeft = new Queue<int>(2);
Queue<int> qRight = new Queue<int>(2);
double sum = 0d;
int cnt = 0;
for (int i = 0; i < measuredValues.Length; i++)
{
if (measuredValues[i] < -273)
continue;
if (qLeft.Count == 3)
qLeft.Dequeue();
for (int j = i + 1; j < measuredValues.Length; j++)
{
if (qRight.Count == 2)
{
break;
}
qRight.Enqueue(measuredValues[j]);
}
if (b(qLeft, qRight, measuredValues[i]) == true)
{
sum += measuredValues[i];
cnt++;
qLeft.Enqueue(measuredValues[i]);
}
qRight.Clear();
}
if (cnt > 0)
return sum / cnt;
return -300.0;
}
bool b(Queue<int> a, Queue<int> b, int c)
{
foreach (int q in a)
{
if (Math.Abs(q - c) <= 2)
return true;
}
foreach (int w in b)
{
if (Math.Abs(w - c) <= 2)
return true;
}
return false;
}
However, my strategy fails for this test case
{-13, 12, -14, 11, -15, 10, -16, 9, -17, 8, -18, 7, 6, -19, 5, -400, -400, 4, -390, -300, -270, 3, -12, 3, 2}
I don't understand why. I'm i missing something obvious? i know they're might be another more efficient way of solving this but i don't want to try them until i know why my "naive" way does not work.
Well I finally figured out why thanks to you guys. Here is my revised code for those who may find it helpful:
public double averageTemperature(int[] measuredValues)
{
Queue<int> qLeft = new Queue<int>(2);
Queue<int> qRight = new Queue<int>(2);
double sum = 0d;
int cnt = 0;
for (int i = 0; i < measuredValues.Length; i++)
{
if (qLeft.Count == 3)
qLeft.Dequeue();
for (int j = i + 1; j < measuredValues.Length; j++)
{
if (qRight.Count == 2)
{
break;
}
qRight.Enqueue(measuredValues[j]);
}
if (isValid(qLeft, qRight, measuredValues[i]) == true)
{
sum += measuredValues[i];
cnt++;
}
qLeft.Enqueue(measuredValues[i]);
qRight.Clear();
}
if (cnt > 0)
return sum / cnt;
return -300.0;
}
bool isValid(Queue<int> a, Queue<int> b, int c)
{
foreach (int q in a)
{
if (c >=-273 && Math.Abs(q - c) <= 2)
return true;
}
foreach (int w in b)
{
if (c >=-273 && Math.Abs(w - c) <= 2)
return true;
}
return false;
}

try starting at the same point in the nested for() loop when comparing. like this: what do you get when you run it?
public double averageTemperature(int[] measuredValues)
{
Queue<int> qLeft = new Queue<int>(2);
Queue<int> qRight = new Queue<int>(2);
double sum = 0d;
int cnt = 0;
for (int i = 0; i < measuredValues.Length; i++)
{
if (measuredValues[i] < -273)
continue;
if (qLeft.Count == 3)
qLeft.Dequeue();
for (int j = 0; j < measuredValues.Length; j++)
{
if (qRight.Count == 2)
{
break;
}
qRight.Enqueue(measuredValues[j]);
}
if (b(qLeft, qRight, measuredValues[i]) == true)
{
sum += measuredValues[i];
cnt++;
qLeft.Enqueue(measuredValues[i]);
}
qRight.Clear();
}
if (cnt > 0)
return sum / cnt;
return -300.0;
}
bool b(Queue<int> a, Queue<int> b, int c)
{
foreach (int q in a)
{
if (Math.Abs(q - c) <= 2)
return true;
}
foreach (int w in b)
{
if (Math.Abs(w - c) <= 2)
return true;
}
return false;
}
is it adding one each direction to put you two away like you were before?

You are enqueuing into qLeft only when the current value in the array is valid, but this is not right. You need to enqueue into qLeft at each iteration of the outer for-loop that is being controlled by i.
See the following code:
for (int i = 0; i < measuredValues.Length; i++)
{
if (measuredValues[i] < -273)
continue;
if (qLeft.Count == 3)
qLeft.Dequeue();
for (int j = i + 1; j < measuredValues.Length; j++)
{
if (qRight.Count == 2)
{
break;
}
qRight.Enqueue(measuredValues[j]);
}
if (b(qLeft, qRight, measuredValues[i]) == true)
{
sum += measuredValues[i];
cnt++;
}
qLeft.Enqueue(measuredValues[i]); // YOU NEED TO ENQUEUE INTO qLeft EACH TIME REGARDLESS OF IT IS VALID OR INVALID
qRight.Clear();
}

Related

Cross Search generate char Matrix

I am trying to create a word search puzzle matrix, this is the code I have,
static void PlaceWords(List<string> words)
{
Random rn = new Random();
foreach (string p in words)
{
String s = p.Trim();
bool placed = false;
while (placed == false)
{
int nRow = rn.Next(0,10);
int nCol = rn.Next(0,10);
int nDirX = 0;
int nDirY = 0;
while (nDirX == 0 && nDirY == 0)
{
nDirX = rn.Next(3) - 1;
nDirY = rn.Next(3) - 1;
}
placed = PlaceWord(s.ToUpper(), nRow, nCol, nDirX, nDirY);
}
}
}
static bool PlaceWord(string s, int nRow, int nCol, int nDirX, int nDirY)
{
bool placed = false;
int LetterNb = s.Length;
int I = nRow;
int J = nCol;
if (MatriceIndice[nRow, nCol] == 0)
{
placed = true;
for (int i = 0; i < s.Length-1; i++)
{
I += nDirX;
J += nDirY;
if (I < 10 && I>0 && J < 10 && J>0)
{
if (MatriceIndice[I, J] == 0)
placed = placed && true;
else
placed = placed && false;
}
else
{
return false;
}
}
}
else
{
return false;
}
if(placed==true)
{
int placeI = nRow;
int placeJ = nCol;
for (int i = 0; i < s.Length - 1; i++)
{
placeI += nDirX;
placeJ += nDirY;
MatriceIndice[placeI,placeJ] = 1;
MatriceChars[placeJ, placeJ] = s[i];
}
}
return placed;
}
However it seems like it is an infinite loop. I am trying to add the code in a 1010 char matrix linked to a 1010 int matrix initially filled with 0 where I change the cases to 1 if the word is added to the matrix. How should I fix the code?
There are several errors. First,
MatriceChars[placeJ, placeJ] = s[i];
should be
MatriceChars[placeI, placeJ] = s[i];
Second,
for (int i = 0; i < s.Length - 1; i++)
(two occurrences) should be
for (int i = 0; i < s.Length; i++)
(You do want all the letters in the words, right?)
Third, when testing indices, you should use I >= 0, not I > 0, as the matrix indices start at 0.
However, the main logic of the code seems to work, but if you try to place too many words, you will indeed enter an infinite loop, since it just keeps trying and failing to place words that can never fit.

Getting Time limit Exceed for last 3 Test Cases in a Program:C# [duplicate]

Given an array of n integers and a number, d, perform left rotations on the array. Then print the updated array as a single line of space-separated integers.
Sample Input:
5 4
1 2 3 4 5
The first line contains two space-separated integers denoting the respective values of n (the number of integers) and d (the number of left rotations you must perform).
The second line contains n space-separated integers describing the respective elements of the array's initial state.
Sample Output:
5 1 2 3 4
static void Main(String[] args)
{
string[] arr_temp = Console.ReadLine().Split(' ');
int n = Int32.Parse(arr_temp[0]);
int d = Int32.Parse(arr_temp[1]);
string[] arr = Console.ReadLine().Split(' ');
string[] ans = new string[n];
for (int i = 0; i < n; ++i)
{
ans[(i + n - d) % n] = arr[i];
}
for (int j = 0; j < n; ++j)
{
Console.Write(ans[j] + " ");
}
}
How to use less memory to solve this problem?
This will use less memory in most cases as the second array is only as big as the shift.
public static void Main(string[] args)
{
int[] n = { 1, 2, 3, 4, 5 };
LeftShiftArray(n, 4);
Console.WriteLine(String.Join(",", n));
}
public static void LeftShiftArray<T>(T[] arr, int shift)
{
shift = shift % arr.Length;
T[] buffer = new T[shift];
Array.Copy(arr, buffer, shift);
Array.Copy(arr, shift, arr, 0, arr.Length - shift);
Array.Copy(buffer, 0, arr, arr.Length - shift, shift);
}
This problem can get a bit tricky but also has a simple solution if one is familiar with Queues and Stacks.
All I have to do is define a Queue (which will contain the given array) and a Stack.
Next, I just have to Push the Dequeued index to the stack and Enqueue the Popped index in the Queue and finally return the Queue.
Sounds confusing? Check the code below:
static int[] rotLeft(int[] a, int d) {
Queue<int> queue = new Queue<int>(a);
Stack<int> stack = new Stack<int>();
while(d > 0)
{
stack.Push(queue.Dequeue());
queue.Enqueue(stack.Pop());
d--;
}
return queue.ToArray();
}
Do you really need to physically move anything? If not, you could just shift the index instead.
Actually you asked 2 questions:
How to efficiently rotate an array?
and
How to use less memory to solve this problem?
Usually efficiency and low memory usage are mutually exclusive. So I'm going to answer your second question, still providing the most efficient implementation under that memory constraint.
The following method can be used for both left (passing negative count) or right (passing positive count) rotation. It uses O(1) space (single element) and O(n * min(d, n - d)) array element copy operations (O(min(d, n - d)) array block copy operations). In the worst case scenario it performs O(n / 2) block copy operations.
The algorithm is utilizing the fact that
rotate_left(n, d) == rotate_right(n, n - d)
Here it is:
public static class Algorithms
{
public static void Rotate<T>(this T[] array, int count)
{
if (array == null || array.Length < 2) return;
count %= array.Length;
if (count == 0) return;
int left = count < 0 ? -count : array.Length + count;
int right = count > 0 ? count : array.Length - count;
if (left <= right)
{
for (int i = 0; i < left; i++)
{
var temp = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = temp;
}
}
else
{
for (int i = 0; i < right; i++)
{
var temp = array[array.Length - 1];
Array.Copy(array, 0, array, 1, array.Length - 1);
array[0] = temp;
}
}
}
}
Sample usage like in your example:
var array = Enumerable.Range(1, 5).ToArray(); // { 1, 2, 3, 4, 5 }
array.Rotate(-4); // { 5, 1, 2, 3, 4 }
Isn't using IEnumerables better? Since It won't perform all of those maths, won't allocate that many arrays, etc
public static int[] Rotate(int[] elements, int numberOfRotations)
{
IEnumerable<int> newEnd = elements.Take(numberOfRotations);
IEnumerable<int> newBegin = elements.Skip(numberOfRotations);
return newBegin.Union(newEnd).ToArray();
}
IF you don't actually need to return an array, you can even remove the .ToArray() and return an IEnumerable
Usage:
void Main()
{
int[] n = { 1, 2, 3, 4, 5 };
int d = 4;
int[] rotated = Rotate(n,d);
Console.WriteLine(String.Join(" ", rotated));
}
I have also tried this and below is my approach...
Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
I have tried to used stack and queue in C# to achieve the output as follows:
public int[] rotateArray(int[] A, int rotate)
{
Queue<int> q = new Queue<int>(A);
Stack<int> s;
while (rotate > 0)
{
s = new Stack<int>(q);
int x = s.Pop();
s = new Stack<int>(s);
s.Push(x);
q = new Queue<int>(s);
rotate--;
}
return q.ToArray();
}
I've solve the challange from Hackerrank by following code. Hope it helps.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApp1
{
class ArrayLeftRotationSolver
{
TextWriter mTextWriter;
public ArrayLeftRotationSolver()
{
mTextWriter = new StreamWriter(#System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);
}
public void Solve()
{
string[] nd = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(nd[0]);
int d = Convert.ToInt32(nd[1]);
int[] a = Array.ConvertAll(Console.ReadLine().Split(' '), aTemp => Convert.ToInt32(aTemp))
;
int[] result = rotLeft(a, d);
mTextWriter.WriteLine(string.Join(" ", result));
mTextWriter.Flush();
mTextWriter.Close();
}
private int[] rotLeft(int[] arr, int shift)
{
int n = arr.Length;
shift %= n;
int[] vec = new int[n];
for (int i = 0; i < n; i++)
{
vec[(n + i - shift) % n] = arr[i];
}
return vec;
}
static void Main(string[] args)
{
ArrayLeftRotationSolver solver = new ArrayLeftRotationSolver();
solver.Solve();
}
}
}
Hope this helps.
public static int[] leftrotation(int[] arr, int d)
{
int[] newarr = new int[arr.Length];
var n = arr.Length;
bool isswapped = false;
for (int i = 0; i < n; i++)
{
int index = Math.Abs((i) -d);
if(index == 0)
{
isswapped = true;
}
if (!isswapped)
{
int finalindex = (n) - index;
newarr[finalindex] = arr[i];
}
else
{
newarr[index] = arr[i];
}
}
return newarr;
}
Take the Item at position 0 and add it at the end. remove the item at position 0. repeat n times.
List<int> iList = new List<int>();
private void shift(int n)
{
for (int i = 0; i < n; i++)
{
iList.Add(iList[0]);
iList.RemoveAt(0);
}
}
An old question, but I thought I'd add another possible solution using just one intermediate array (really, 2 if you include the LINQ Take expression). This code rotates to right rather than left, but may be useful nonetheless.
public static Int32[] ArrayRightRotation(Int32[] A, Int32 k)
{
if (A == null)
{
return A;
}
if (!A.Any())
{
return A;
}
if (k % A.Length == 0)
{
return A;
}
if (A.Length == 1)
{
return A;
}
if (A.Distinct().Count() == 1)
{
return A;
}
for (var i = 0; i < k; i++)
{
var intermediateArray = new List<Int32> {A.Last()};
intermediateArray.AddRange(A.Take(A.Length - 1).ToList());
A = intermediateArray.ToArray();
}
return A;
}
O(1) space, O(n) time solution
I think in theory this is as optimal as it gets, since it makes a.Length in-place swaps and 1 temp variable swap per inner loop.
However I suspect O(d) space solutions would be faster in real life due to less code branching (fewer CPU command pipeline resets) and cache locality (mostly sequential access vs in d element steps).
static int[] RotateInplaceLeft(int[] a, int d)
{
var swapCount = 0;
//get canonical/actual d
d = d % a.Length;
if(d < 0) d += a.Length;
if(d == 0) return a;
for (var i = 0; swapCount < a.Length; i++) //we're done after a.Length swaps
{
var dstIdx = i; //we need this becasue of ~this: https://youtu.be/lJ3CD9M3nEQ?t=251
var first = a[i]; //save first element in this group
for (var j = 0; j < a.Length; j++)
{
var srcIdx = (dstIdx + d) % a.Length;
if(srcIdx == i)// circled around
{
a[dstIdx] = first;
swapCount++;
break; //hence we're done with this group
}
a[dstIdx] = a[srcIdx];
dstIdx = srcIdx;
swapCount++;
}
}
return a;
}
If you take a look at constrains you will see that d <= n (number of rotations <= number of elements in array). Because of that this can be solved in 1 line.
static int[] rotLeft(int[] a, int d)
{
return a.Skip(d).Concat(a.Take(d)).ToArray();
}
// using the same same array, and only one temp variable
// shifting everything several times by one
// works, simple, but slow
public static int[] ArrayRotateLeftCyclical(int[] a, int shift)
{
var length = a.Length;
for (int j = 0; j < shift; j++)
{
int t = a[0];
for (int i = 0; i < length; i++)
{
if (i == length - 1)
a[i] = t;
else
a[i] = a[i + 1];
}
}
return a;
}
Let's say if I have a array of integer 'Arr'. To rotate the array 'n' you can do as follows:
static int[] leftRotation(int[] Arr, int n)
{
int tempVariable = 0;
Queue<int> TempQueue = new Queue<int>(a);
for(int i=1;i<=d;i++)
{
tempVariable = TempQueue.Dequeue();
TempQueue.Enqueue(t);
}
return TempQueue.ToArray();`
}
Let me know if any comments. Thanks!
This is my attempt. It is easy, but for some reason it timed out on big chunks of data:
int arrayLength = arr.Length;
int tmpCell = 0;
for (int rotation = 1; rotation <= d; rotation++)
{
for (int i = 0; i < arrayLength; i++)
{
if (arr[i] < arrayElementMinValue || arr[i] > arrayElementMaxValue)
{
throw new ArgumentException($"Array element needs to be between {arrayElementMinValue} and {arrayElementMaxValue}");
}
if (i == 0)
{
tmpCell = arr[0];
arr[0] = arr[1];
}
else if (i == arrayLength - 1)
{
arr[arrayLength - 1] = tmpCell;
}
else
{
arr[i] = arr[i + 1];
}
}
}
what about this?
public static void RotateArrayAndPrint(int[] n, int rotate)
{
for (int i = 1; i <= n.Length; i++)
{
var arrIndex = (i + rotate) > n.Length ? n.Length - (i + rotate) : (i + rotate);
arrIndex = arrIndex < 0 ? arrIndex * -1 : arrIndex;
var output = n[arrIndex-1];
Console.Write(output + " ");
}
}
It's very straight forward answer.
Main thing is how you choose the start index.
public static List<int> rotateLeft(int d, List<int> arr) {
int n = arr.Count;
List<int> t = new List<int>();
int h = d;
for (int j = 0; j < n; j++)
{
if ((j + d) % n == 0)
{
h = 0;
}
t.Add(arr[h]);
h++;
}
return t;
}
using this code, I have successfully submitted to hacker rank problem,
// fast and beautiful method
// reusing the same array
// using small temp array to store replaced values when unavoidable
// a - array, s - shift
public static int[] ArrayRotateLeftWithSmallTempArray(int[] a, int s)
{
var l = a.Length;
var t = new int[s]; // temp array with size s = shift
for (int i = 0; i < l; i++)
{
// save cells which will be replaced by shift
if (i < s)
t[i] = a[i];
if (i + s < l)
a[i] = a[i + s];
else
a[i] = t[i + s - l];
}
return a;
}
https://github.com/sam-klok/ArraysRotation
public static void Rotate(int[] arr, int steps)
{
for (int i = 0; i < steps; i++)
{
int previousValue = arr[arr.Length - 1];
for (int j = 0; j < arr.Length; j++)
{
int currentValue = arr[j];
arr[j] = previousValue;
previousValue = currentValue;
}
}
}
Here is an in-place Rotate implementation of a trick posted by גלעד ברקן in another question. The trick is:
Example, k = 3:
1234567
First reverse in place each of the two sections delineated by n-k:
4321 765
Now reverse the whole array:
5671234
My implementation, based on the Array.Reverse method:
/// <summary>
/// Rotate left for negative k. Rotate right for positive k.
/// </summary>
public static void Rotate<T>(T[] array, int k)
{
ArgumentNullException.ThrowIfNull(array);
k = k % array.Length;
if (k < 0) k += array.Length;
if (k == 0) return;
Debug.Assert(k > 0);
Debug.Assert(k < array.Length);
Array.Reverse(array, 0, array.Length - k);
Array.Reverse(array, array.Length - k, k);
Array.Reverse(array);
}
Live demo.
Output:
Array: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Rotate(5)
Array: 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7
Rotate(-2)
Array: 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9

Can somebody tell me why this code is not working? I am trying to find the 10001st prime number

The code gives me the answer 43739 which is wrong. I don't know which part of the code I messed up, help would be much appreciated.
{
int primenumbers = 4;
int thenumber = 2;
int finalnumber = 0;
while (primenumbers <= 10001)
{
for (int x = 2; x < 10; x++)
{
if (thenumber % x == 0)
{
x = 10;
}
if (x == 9)
{
finalnumber = thenumber;
primenumbers += 1;
break;
}
}
thenumber += 1;
}
Console.WriteLine(finalnumber);
}
Let's split the initial problem into smaller ones: first, check for being prime:
private static bool IsPrime(int value) {
if (value <= 1)
return false;
else if (value % 2 == 0)
return value == 2;
int n = (int) (Math.Sqrt(value) + 0.5);
for (int d = 3; d <= n; d += 2)
if (value % d == 0)
return false;
return true;
}
Then enumerate prime numbers (2, 3, 5, 7, 11...):
// Naive; sieve algorithm will be better off
private static IEnumerable<int> Primes() {
for (int i = 1; ; ++i)
if (IsPrime(i))
yield return i;
}
Finally, query with a help of Linq:
using System.Linq;
...
int result = Primes().Skip(10000).First();
Console.Write(result);
And you'll get
104743

Find the missing integer in Codility

I need to "Find the minimal positive integer not occurring in a given sequence. "
A[0] = 1
A[1] = 3
A[2] = 6
A[3] = 4
A[4] = 1
A[5] = 2, the function should return 5.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
I wrote the code in codility, but for many cases it did not worked and the performance test gives 0 %. Please help me out, where I am wrong.
class Solution {
public int solution(int[] A) {
if(A.Length ==0) return -1;
int value = A[0];
int min = A.Min();
int max = A.Max();
for (int j = min+1; j < max; j++)
{
if (!A.Contains(j))
{
value = j;
if(value > 0)
{
break;
}
}
}
if(value > 0)
{
return value;
}
else return 1;
}
}
The codility gives error with all except the example, positive and negative only values.
Edit: Added detail to answer your actual question more directly.
"Please help me out, where I am wrong."
In terms of correctness: Consider A = {7,2,5,6,3}. The correct output, given the contents of A, is 1, but our algorithm would fail to detect this since A.Min() would return 2 and we would start looping from 3 onward. In this case, we would return 4 instead; since it's the next missing value.
Same goes for something like A = {14,15,13}. The minimal missing positive integer here is again 1 and, since all the values from 13-15 are present, the value variable will retain its initial value of value=A[0] which would be 14.
In terms of performance: Consider what A.Min(), A.Max() and A.Contains() are doing behind the scenes; each one of these is looping through A in its entirety and in the case of Contains, we are calling it repeatedly for every value between the Min() and the lowest positive integer we can find. This will take us far beyond the specified O(N) performance that Codility is looking for.
By contrast, here's the simplest version I can think of that should score 100% on Codility. Notice that we only loop through A once and that we take advantage of a Dictionary which lets us use ContainsKey; a much faster method that does not require looping through the whole collection to find a value.
using System;
using System.Collections.Generic;
class Solution {
public int solution(int[] A) {
// the minimum possible answer is 1
int result = 1;
// let's keep track of what we find
Dictionary<int,bool> found = new Dictionary<int,bool>();
// loop through the given array
for(int i=0;i<A.Length;i++) {
// if we have a positive integer that we haven't found before
if(A[i] > 0 && !found.ContainsKey(A[i])) {
// record the fact that we found it
found.Add(A[i], true);
}
}
// crawl through what we found starting at 1
while(found.ContainsKey(result)) {
// look for the next number
result++;
}
// return the smallest positive number that we couldn't find.
return result;
}
}
The simplest solution that scored perfect score was:
public int solution(int[] A)
{
int flag = 1;
A = A.OrderBy(x => x).ToArray();
for (int i = 0; i < A.Length; i++)
{
if (A[i] <= 0)
continue;
else if (A[i] == flag)
{
flag++;
}
}
return flag;
}
Fastest C# solution so far for [-1,000,000...1,000,000].
public int solution(int[] array)
{
HashSet<int> found = new HashSet<int>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] > 0)
{
found.Add(array[i]);
}
}
int result = 1;
while (found.Contains(result))
{
result++;
}
return result;
}
A tiny version of another 100% with C#
using System.Linq;
class Solution
{
public int solution(int[] A)
{
// write your code in C# 6.0 with .NET 4.5 (Mono)
var i = 0;
return A.Where(a => a > 0).Distinct().OrderBy(a => a).Any(a => a != (i = i + 1)) ? i : i + 1;
}
}
A simple solution that scored 100% with C#
int Solution(int[] A)
{
var A2 = Enumerable.Range(1, A.Length + 1);
return A2.Except(A).First();
}
public class Solution {
public int solution( int[] A ) {
return Arrays.stream( A )
.filter( n -> n > 0 )
.sorted()
.reduce( 0, ( a, b ) -> ( ( b - a ) > 1 ) ? a : b ) + 1;
}
}
It seemed easiest to just filter out the negative numbers. Then sort the stream. And then reduce it to come to an answer. It's a bit of a functional approach, but it got a 100/100 test score.
Got an 100% score with this solution:
https://app.codility.com/demo/results/trainingUFKJSB-T8P/
public int MissingInteger(int[] A)
{
A = A.Where(a => a > 0).Distinct().OrderBy(c => c).ToArray();
if (A.Length== 0)
{
return 1;
}
for (int i = 0; i < A.Length; i++)
{
//Console.WriteLine(i + "=>" + A[i]);
if (i + 1 != A[i])
{
return i + 1;
}
}
return A.Max() + 1;
}
JavaScript solution using Hash Table with O(n) time complexity.
function solution(A) {
let hashTable = {}
for (let item of A) {
hashTable[item] = true
}
let answer = 1
while(true) {
if(!hashTable[answer]) {
return answer
}
answer++
}
}
The Simplest solution for C# would be:
int value = 1;
int min = A.Min();
int max = A.Max();
if (A.Length == 0) return value = 1;
if (min < 0 && max < 0) return value = 1;
List<int> range = Enumerable.Range(1, max).ToList();
List<int> current = A.ToList();
List<int> valid = range.Except(current).ToList();
if (valid.Count() == 0)
{
max++;
return value = max;
}
else
{
return value = valid.Min();
}
Considering that the array should start from 1 or if it needs to start from the minimum value than the Enumerable.range should start from Min
MissingInteger solution in C
int solution(int A[], int N) {
int i=0,r[N];
memset(r,0,(sizeof(r)));
for(i=0;i<N;i++)
{
if(( A[i] > 0) && (A[i] <= N)) r[A[i]-1]=A[i];
}
for(i=0;i<N;i++)
{
if( r[i] != (i+1)) return (i+1);
}
return (N+1);
}
My solution for it:
public static int solution()
{
var A = new[] { -1000000, 1000000 }; // You can try with different integers
A = A.OrderBy(i => i).ToArray(); // We sort the array first
if (A.Length == 1) // if there is only one item in the array
{
if (A[0]<0 || A[0] > 1)
return 1;
if (A[0] == 1)
return 2;
}
else // if there are more than one item in the array
{
for (var i = 0; i < A.Length - 1; i++)
{
if (A[i] >= 1000000) continue; // if it's bigger than 1M
if (A[i] < 0 || (A[i] + 1) >= (A[i + 1])) continue; //if it's smaller than 0, if the next integer is bigger or equal to next integer in the sequence continue searching.
if (1 < A[0]) return 1;
return A[i] + 1;
}
}
if (1 < A[0] || A[A.Length - 1] + 1 == 0 || A[A.Length - 1] + 1 > 1000000)
return 1;
return A[A.Length-1] +1;
}
class Solution {
public int solution(int[] A) {
int size=A.length;
int small,big,temp;
for (int i=0;i<size;i++){
for(int j=0;j<size;j++){
if(A[i]<A[j]){
temp=A[j];
A[j]=A[i];
A[i]=temp;
}
}
}
int z=1;
for(int i=0;i<size;i++){
if(z==A[i]){
z++;
}
//System.out.println(a[i]);
}
return z;
}
enter code here
}
In C# you can solve the problem by making use of built in library functions. How ever the performance is low for very large integers
public int solution(int[] A)
{
var numbers = Enumerable.Range(1, Math.Abs(A.Max())+1).ToArray();
return numbers.Except(A).ToArray()[0];
}
Let me know if you find a better solution performance wise
C# - MissingInteger
Find the smallest missing integer between 1 - 1000.000.
Assumptions of the OP take place
TaskScore/Correctness/Performance: 100%
using System;
using System.Linq;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
var A = new int[] { -122, -5, 1, 2, 3, 4, 5, 6, 7 }; // 8
var B = new int[] { 1, 3, 6, 4, 1, 2 }; // 5
var C = new int[] { -1, -3 }; // 1
var D = new int[] { -3 }; // 1
var E = new int[] { 1 }; // 2
var F = new int[] { 1000000 }; // 1
var x = new int[][] { A, B, C, D, E, F };
x.ToList().ForEach((arr) =>
{
var s = new Solution();
Console.WriteLine(s.solution(arr));
});
Console.ReadLine();
}
}
// ANSWER/SOLUTION
class Solution
{
public int solution(int[] A)
{
// clean up array for negatives and duplicates, do sort
A = A.Where(entry => entry > 0).Distinct().OrderBy(it => it).ToArray();
int lowest = 1, aLength = A.Length, highestIndex = aLength - 1;
for (int i = 0; i < aLength; i++)
{
var currInt = A[i];
if (currInt > lowest) return lowest;
if (i == highestIndex) return ++lowest;
lowest++;
}
return 1;
}
}
}
Got 100% - C# Efficient Solution
public int solution (int [] A){
int len = A.Length;
HashSet<int> realSet = new HashSet<int>();
HashSet<int> perfectSet = new HashSet<int>();
int i = 0;
while ( i < len)
{
realSet.Add(A[i]); //convert array to set to get rid of duplicates, order int's
perfectSet.Add(i + 1); //create perfect set so can find missing int
i++;
}
perfectSet.Add(i + 1);
if (realSet.All(item => item < 0))
return 1;
int notContains =
perfectSet.Except(realSet).Where(item=>item!=0).FirstOrDefault();
return notContains;
}
class Solution {
public int solution(int[] a) {
int smallestPositive = 1;
while(a.Contains(smallestPositive)) {
smallestPositive++;
}
return smallestPositive;
}
}
Well, this is a new winner now. At least on C# and my laptop. It's 1.5-2 times faster than the previous champion and 3-10 times faster, than most of the other solutions. The feature (or a bug?) of this solution is that it uses only basic data types. Also 100/100 on Codility.
public int Solution(int[] A)
{
bool[] B = new bool[(A.Length + 1)];
for (int i = 0; i < A.Length; i++)
{
if ((A[i] > 0) && (A[i] <= A.Length))
B[A[i]] = true;
}
for (int i = 1; i < B.Length; i++)
{
if (!B[i])
return i;
}
return A.Length + 1;
}
Simple C++ solution. No additional memory need, time execution order O(N*log(N)):
int solution(vector<int> &A) {
sort (A.begin(), A.end());
int prev = 0; // the biggest integer greater than 0 found until now
for( auto it = std::begin(A); it != std::end(A); it++ ) {
if( *it > prev+1 ) break;// gap found
if( *it > 0 ) prev = *it; // ignore integers smaller than 1
}
return prev+1;
}
int[] A = {1, 3, 6, 4, 1, 2};
Set<Integer> integers = new TreeSet<>();
for (int i = 0; i < A.length; i++) {
if (A[i] > 0) {
integers.add(A[i]);
}
}
Integer[] arr = integers.toArray(new Integer[0]);
final int[] result = {Integer.MAX_VALUE};
final int[] prev = {0};
final int[] curr2 = {1};
integers.stream().forEach(integer -> {
if (prev[0] + curr2[0] == integer) {
prev[0] = integer;
} else {
result[0] = prev[0] + curr2[0];
}
});
if (Integer.MAX_VALUE == result[0]) result[0] = arr[arr.length-1] + 1;
System.out.println(result[0]);
I was surprised but this was a good lesson. LINQ IS SLOW. my answer below got me 11%
public int solution (int [] A){
if (Array.FindAll(A, x => x >= 0).Length == 0) {
return 1;
} else {
var lowestValue = A.Where(x => Array.IndexOf(A, (x+1)) == -1).Min();
return lowestValue + 1;
}
}
I think I kinda look at this a bit differently but gets a 100% evaluation. Also, I used no library:
public static int Solution(int[] A)
{
var arrPos = new int[1_000_001];
for (int i = 0; i < A.Length; i++)
{
if (A[i] >= 0)
arrPos[A[i]] = 1;
}
for (int i = 1; i < arrPos.Length; i++)
{
if (arrPos[i] == 0)
return i;
}
return 1;
}
public int solution(int[] A) {
// write your code in Java SE 8
Set<Integer> elements = new TreeSet<Integer>();
long lookFor = 1;
for (int i = 0; i < A.length; i++) {
elements.add(A[i]);
}
for (Integer integer : elements) {
if (integer == lookFor)
lookFor += 1;
}
return (int) lookFor;
}
I tried to use recursion in C# instead of sorting, because I thought it would show more coding skill to do it that way, but on the scaling tests it didn't preform well on large performance tests. Suppose it's best to just do the easy way.
class Solution {
public int lowest=1;
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
if (A.Length < 1)
return 1;
for (int i=0; i < A.Length; i++){
if (A[i]==lowest){
lowest++;
solution(A);
}
}
return lowest;
}
}
Here is my solution in javascript
function solution(A) {
// write your code in JavaScript (Node.js 8.9.4)
let result = 1;
let haveFound = {}
let len = A.length
for (let i=0;i<len;i++) {
haveFound[`${A[i]}`] = true
}
while(haveFound[`${result}`]) {
result++
}
return result
}
class Solution {
public int solution(int[] A) {
var sortedList = A.Where(x => x > 0).Distinct().OrderBy(x => x).ToArray();
var output = 1;
for (int i = 0; i < sortedList.Length; i++)
{
if (sortedList[i] != output)
{
return output;
}
output++;
}
return output;
}
}
You should just use a HashSet as its look up time is also constant instead of a dictionary. The code is less and cleaner.
public int solution (int [] A){
int answer = 1;
var set = new HashSet<int>(A);
while (set.Contains(answer)){
answer++;
}
return answer;
}
This snippet should work correctly.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int result = 1;
List<int> lst = new List<int>();
lst.Add(1);
lst.Add(2);
lst.Add(3);
lst.Add(18);
lst.Add(4);
lst.Add(1000);
lst.Add(-1);
lst.Add(-1000);
lst.Sort();
foreach(int curVal in lst)
{
if(curVal <=0)
result=1;
else if(!lst.Contains(curVal+1))
{
result = curVal + 1 ;
}
Console.WriteLine(result);
}
}
}

Matrix Row - QuickSort recursion problem

I've adapted QuickSort Method to sort Array's Row.
Here's the code:
That one works fine
static void QuickSort(int lowBound, int highBound, int[] a)
{
int temp = 0;
int x = random.Next(lowBound, highBound);
int pivot = a[x];
int i = lowBound;
int j = highBound;
do
{
while (a[i] < pivot) i++;
while (pivot < a[j]) j--;
if (i <= j)
{
temp = a[i]; //changes an element smaller than the pivot...
a[i] = a[j];//... with the greater one
a[j] = temp;
i++; j--;
}
}
while (i <= j);
if (lowBound < j) { QuickSort(lowBound, j, a); }//recursion
if (i < highBound){ QuickSort(i,highBound, a); }
}
Here's the problematic method
static void QuickSortMatrix(int[,] a)
{
int n = a.GetLength(0);
int m = a.GetLength(1);
for (int i = 0; i < n; i++)
{
QuickSortRow(0, m - 1, i, a);
}
for (int j = 0; j < m; j++)
{
QuickSortRow(0, n - 1, j, a);
}
}
static void QuickSortRow(int lowBound, int highBound, int row, int[,] a)
{
int temp = 0;
int x = random.Next(lowBound, highBound);
int pivot = a[row,x];
int p = lowBound;
int q = highBound;
do
{
while (a[row,p] < pivot) p++;
while (pivot < a[row,q]) q--;
if (p <= q)
{
temp = a[row,p];
a[row,p] = a[row,q];
a[row,q] = temp;
p++; q--;
}
}
while (p <= q);
if (lowBound < q) { QuickSortRow(lowBound, q, row, a); }
if (p < highBound) { QuickSortRow(p, highBound,row, a); }
}
At first when the "for" loop is executed everything's ok bur for some reason when executed recursively the row that should be constant when calling the method goes outside the matrix boundaries.
Here's my array and rows reaches value of 4
int[,] matrix =
{
{7,8,9,10,11,5},
{3,6,4,16,22,4},
{7,9,17,8,3,21},
{24,7,11,19,3,4}
};
I hope my explanation was clear enough.
Could anybody advise me? What I'm missing here?
Thank you for your kind help!
BR
Stephan
n is the number of rows in the matrix (4)
m is the number of columns in the matrix (6)
In your second loop you are going 0..m and passing that value to the row parameter. It blows up because there are more columns in the matrix than rows. i.e. It tries to read matrix[4, 0].
Note: as far as I can tell you don't need the second loop because your rows are already sorted after the first loop. Remove that and it won't throw an exception.

Categories