I programmed a little in java a while back, and now I'm learning C#.
This is the first exercise of "medium" or "respectable" difficulty according to Codility, so I'm pretty pleased of finding out that the approach used by me was the same Sheng followed in codesays.
Writing here and in SO as a mémoire (check this if you'd like) helped me see that sometimes I get in a web of complicated thoughts and things that are very hard to program and are really bad in readability and performance. In the link I just posted I said I was going to talk me out of following futile, complicated ideas from that moment on, and so I did here and found the right solution.
I already asked in three other posts, how my code was in terms of quality this past week, and I'm happy with the results of applying the great contributions I received by members of this amazing community.
This solution, as well as the others (EarliestFrogJump, cyclicRotation & permCheck) pass with a 100% score (time complexity detected O(N+M)).
Task description
You are given N counters, initially set to 0, and you have two possible operations on them:
- increase(X) => counter X is increased by 1
- max counter => all counters are set to the maximum value of any counter.
A non-empty array A of M integers is given. This array represents consecutive operations:
if
A[K] = X
, such that 1 ≤ X ≤ N, then operation K is increase(X), ifA[K] = N + 1
then operation K is max counter. For example, given integer N = 5 and array A such that:A[0] = 3 A[1] = 4 A[2] = 4 A[3] = 6 A[4] = 1 A[5] = 4 A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0) (0, 0, 1, 1, 0) (0, 0, 1, 2, 0) (2, 2, 2, 2, 2) (3, 2, 2, 2, 2) (3, 2, 2, 3, 2) (3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
Write a function:
class Solution { public int[] solution(int N, int[] A); }
that, given an integer N and a non-empty array A consisting of M integers, returns a sequence of integers representing the values of the counters.
Result array should be returned as an array of integers.
For example, given:
A[0] = 3 A[1] = 4 A[2] = 4 A[3] = 6 A[4] = 1 A[5] = 4 A[6] = 4
the function should return [3, 2, 2, 4, 2], as explained above.
Write an efficient algorithm for the following assumptions:
N and M are integers within the range [1..100,000]; each element of array A is an integer within the range [1..N + 1].
And this is my code
/// <summary> /// Perform operations in a given array, according to another array's values /// </summary> /// <returns> /// The array created of length <paramref name="N"> after applying operations /// interpreted by integers found in <paramref name="A"/> /// </returns> public static int[] GetCountersAfterApplyingOperations(int N, int[] A) { //array of counters int[] countersArr = new int[N]; //<max> is the largest value found in <countersArr> int max = 0; int index; //when <N> is found in <A[]>, means all counters have to be set to <max> int setAllCountersOp = N ; //<floor> stores the value of <max> when a <setAllCountersOp> is found in <A[]> int floor = 0; for ( int i = 0; i < A.Length; i++ ) { //As A[i] = 1, should convert <countersArr>={0} to {1}, then index = A[i] - 1; //if <index> == <setAllCountersOp> then the new <floor> = <max> if ( index == setAllCountersOp ) { floor = max; } //If 0 <= index < N, then the counterArr[index] should be incremented else if ( index < N && index >= 0 ) { //if <setAllCountersOp> was found, no counter can be smaller than <floor> if ( countersArr[index] < floor ) { countersArr[index] = floor + 1; } else { ++countersArr[index]; } if (countersArr[index] > max ) { ++max ; } } } //if counter is smaller than <floor>, it is set to that value. for ( int i = 0; i < countersArr.Length; i ++ ) { if ( countersArr[i] < floor) { countersArr[i] = floor; } } return countersArr; }
Thanks in advance.