Finding Consecutive repetition of Elements in C# Array and Altering the element - c#

I was given this problem
Given an int array length 3, if there is a 2 in the array immediately followed by a 3,
set the 3 element to 0.
For Example ({1, 2, 3}) → {1, 2, 0}
({2, 3, 5}) → {2, 0, 5}
({1, 2, 1}) → {1, 2, 1}
And this is my implementation.
int[] x = { 1, 2, 1 };
for (int i = 0; i < x.Length; i++)
{
if (x[i] == 2 && x[i + 1] == 3)
{
for (int j = 0; j < x.Length; j++)
{
if (x[j]==3)
{
x[j] = 0;
}
}
}
}
foreach (int i in x)
{
Console.Write(i);
}
I got zero as result. Can you help me to find where I am at mistake. I can't figure it out because the lecturer didn't gave any explanation in details.

You do not need all these loops: with the length of 3, you need to perform only two checks, like this:
if (x[0]==2 && x[1]==3) x[1] = 0;
if (x[1]==2 && x[2]==3) x[2] = 0;
For arrays of arbitrary size, you could use a single loop:
for (var i = 0 ; i < x.Length-1 ; i++) {
if (x[i]==2 && x[i+1]==3) x[i+1] = 0;
}

In your code, you have a proper check: if (x[i] == 2 && x[i + 1] == 3) However, there are 2 things you could improve on.
1) If you're going to do x[i + 1] you need to make sure that i can never be the last element of the array, because the + 1 will overflow the array. So instead of i < x.Length in the for loop, try i < x.Length - 1. It seems like duct taping, but there isn't really a better way (none I know of).
2) If the condition is true, you then have a for that will find and replace EVERY 3 in the array with a 0, regardless of if the 3 is preceded by a 2. You already know that x[i] is 2 and x[i + 1] is 3 (as determined by the if that we know at this point must be true), so the index of the 3 to be replaced is i + 1, thus: x[i + 1] = 0; No loop needed.

You can do it with one loop.
// In the test part of the for loop, use ' i < x.Length - 1'
// so you don't evaluate the last element + 1 and get an IndexOutOfRangeException
for (int i = 0; i < x.Length - 1; i++)
{
if (x[i] == 2 && x[i + 1] == 3)
x[i + 1] = 0;
}

Related

Find the threshold value

(FF14:RR) This item can have 5 materias, 1 highlevel, 4 lowlevel.
I simplified the loops by having 3 types of materias (but i have 6, anw).
I put the materia in an item and then call Group.GetStats() to evaluate the statistics of the item then i store it in a List first checking its unicity.
Calling Group.GetStats() gives me a Dictionary with 3 caracteristics. And i want to filter the number of possibilities based on those statistics.
Example :
Stat1 - Stat2 - Stat3
(9, 7, 5)
(3, 10, 5)
(9, 7, 6)
(8, 6, 4)
(7, 6, 8)
(7, 7, 7) <-
(7, 7, 6)
(6, 6, 5)
(7, 6, 7)
All the tuples under (7, 7, 7) are useless because adding nothing more.
I already ended the algorithm to get all the possible materia combinations but i want to filter the combinations that are not useful.
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = j; k < 3; k++)
{
for (int l = k; l < 3; l++)
{
for (int m = l; m < 3; m++)
{
ItemContainer Group = new ItemContainer(735, 400, 0, 1, 4, 864, 471, 6, new string[] { "Facet Alembic", "Facet Mortar" });
Group.AddMateria(new Materia(i >= 3 ? i-3 : i));
Group.AddMateria(new Materia(j));
Group.AddMateria(new Materia(k));
Group.AddMateria(new Materia(l));
Group.AddMateria(new Materia(m));
if (DEBUG) Console.WriteLine("{" + string.Join(",", Group.GetStats()) + "}");
string tempkey = string.Join(",", Group.GetStats());
if (i >= 3)
{
if (!unicityChecker.ContainsKey(tempkey))
{
if (isAnyBetter(Group.GetStats(),betterChecker.GetStats())) // Condition to keep it
{
ContainerList_1.Add(Group);
unicityChecker.Add(tempkey, Group.GetStats());
}
}
}
else
{
/*
find the betterChecker in order to do isAnyBetter to only get the useful items
*/
if (betterChecker == null) betterChecker = Group;
else
{
if (isAllBetter(Group.GetStats(), betterChecker.GetStats())) betterChecker = Group;
}
}
}
}
}
}
}
The i < 6 sounds weird but this way i made 2 passes on the same generation of combinations.
In output of the entire algorithm (that embricks 7 of this one) i have about 10M records. I thought by removing the useless items at the first generation i could lower the size of the ouput (1Gb in json).
EDIT :
static bool isAnyBetter(Dictionary<String, int> stats1, Dictionary<String, int> stats2)
{
return stats1["craftmanship"] > stats2["craftmanship"] || stats1["control"] > stats2["control"] || stats1["cp"] > stats2["cp"];
}

Add Int[] array into List<int[]>

I'm having trouble with int[] arrays and adding them to a List<>. I'd like to add the values of my int[] array to something each loop but every time I do this my "something" gets the same value for every element I add. Very annoying. I understand arrays are always reference vars. However even the "new" key word doesn't seem to help. What needs to happen is to add result to some enumerated object like a List or Array or ArrayList.
Here's the codility question:
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 zero-indexed 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),
if A[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.
I copied some code from others and the variable "result" does indeed load the data correctly. I just wanted to copy it back to the main program so I could see it. The only method that works is += add it into a string. Thus losing any efficiency I might have gained.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testarray
{
class Program
{
static void Main(string[] args)
{
int[] A = new int[7];
A[0] = 3;
A[1] = 4;
A[2] = 4;
A[3] = 6;
A[4] = 1;
A[5] = 4;
A[6] = 4;
List<int[]> finish = solution(5, A);
}
public static List<int[]> solution(int N, int[] A)
{
int[] result = new int[N];
int maximum = 0;
int resetlimit = 0;
int iter = 0;
List<int[]> collected_result = new List<int[]>;
for (int K = 0; K < A.Length; K++)
{
if (A[K] < 1 || A[K] > N + 1)
{
throw new InvalidOperationException();
}
if (A[K] >= 1 && A[K] <= N)
{
if (result[A[K] - 1] < resetlimit)
{
result[A[K] - 1] = resetlimit + 1;
}
else
{
result[A[K] - 1]++;
}
if (result[A[K] - 1] > maximum)
{
maximum = result[A[K] - 1];
}
}
else
{
resetlimit = maximum;
result = Enumerable.Repeat(maximum, result.Length).ToArray<int>();
}
collected_result.Add(result);
}
// for (int i = 0; i < result.Length; i++)
//result[i] = Math.max(resetLimit, result[i]);
return collected_result;
}
}
}
This doesn't work, the collected_result ends up like:
(0,0,1,2,0)
(0,0,1,2,0)
(0,0,1,2,0)
(3,2,2,4,2)
(3,2,2,4,2)
(3,2,2,4,2)
(3,2,2,4,2)
I know it's the line collected_result.Add(result); adding the reference each time to every instance of result in the List<>. Bother. I've tried adding "new" which is a compiler error. Finally in desperation I just added everything to a very long string. Can someone help me figure out how to properly load an object to pass back to main?
Easiest way to go:
Get a copy of your array before adding it to list:
collected_result.Add(result.ToArray());
Here is a Python solution:
def solution(A, N):
lenA = len(A)
k = 0
max_counter_value = 0
counters = [0 for x in range(0, N)]
for k in range(0, lenA):
if A[k] >= 1 and A[k] <= N:
counters[A[k] - 1] += 1
max_counter_value = max(counters)
if A[k] == N + 1:
counters = [max_counter_value for x in range(0, N)]
print counters
A = [3, 4, 4, 6, 1, 4, 4]
N = 5
solution(A, N)

Find number of ways in a maze non recursively

Given a matrix[n,n] I want to find out how many ways we can reach from [0,0] to [n,n] non recursively.
My approach is to
Create a stuct Node to store row, col and path travelled so far
Add node to a Queue
Iterate thru queue till not empty . Increment row, increment col. Add to Queue
Print the path if row=n, col=n
Question
Is there a different way of storing row,col and path
If n is very large, storing nodes in Queue can be a problem. How can we avoid this?
Please not I am not looking for recursive solution.
I see such questions in many interview forums and so want to know if this would be the right approach.
Below is the structure of Node and the function
struct Node
{
public int row;
public int col;
public string path;
public Node(int r, int c, string p)
{
this.row = r;
this.col = c;
this.path = p;
}
}
public static void NextMoveNonRecursive(int max)
{
int rowPos;
int colPos;
string prevPath = "";
Node next;
while (qu.Count > 0)
{
Node current = qu.Dequeue();
rowPos = current.row;
colPos = current.col;
prevPath = current.path;
if (rowPos + 1 == max && colPos + 1 == max)
{
Console.WriteLine("Path = ..." + prevPath);
TotalPathCounter++;
}
if (rowPos + 1 < max)
{
if (prevPath == "")
prevPath = current.path;
prevPath = prevPath + ">" + (rowPos + 1) + "" + (colPos);
next = new Node(rowPos + 1, colPos, prevPath);
qu.Enqueue(next);
prevPath = "";
}
if (colPos + 1 < max)
{
if (prevPath == "")
prevPath = current.path;
prevPath = prevPath + ">" + (rowPos) + "" + (colPos+1);
next = new Node(rowPos, colPos+1, prevPath);
qu.Enqueue(next);
prevPath = "";
}
}
}
Let dp[i, j] be the number of paths from [0, 0] to [i, j].
We have:
dp[0, i] = dp[i, 0] = 1 for all i = 0 to n
dp[i, j] = dp[i - 1, j] + come down from all paths to [i - 1, j]
dp[i, j - 1] + come down from all paths to [i, j - 1]
dp[i - 1, j - 1] come down from all paths to [i - 1, j - 1]
for i, j > 0
Remove dp[i - 1, j - 1] from the above sum if you cannot increase both the row and the column.
dp[n, n] will have your answer.
Given a matrix [n,n], how many ways we can reach from [0,0] to [n,n] by increasing either a col or a row?
(n*2-2) choose (n*2-2)/2
If you can only go down or right (i.e., increase row or col), it seems like a binary proposition -- we can think of 'down' or 'right' as '0' or '1'.
In an nxn matrix, every path following the down/right condition will be n*2-2 in length (for example, in a 3x3 square, paths are always length 4; in a 4x4 square, length 6).
The number of total combinations for 0's and 1's in binary numbers of x digits is 2^x. In this case, our 'x' is n*2-2, but we cannot use all the combinations since the number of 'down's or 'right's cannot exceed n-1. It seems we need all binary combinations that have an equal number of 0's and 1's. And the solution is ... tada:
(n*2-2) choose (n*2-2)/2
In Haskell, you could write the following non-recursive function to list the paths:
import Data.List
mazeWays n = nub $ permutations $ concat $ replicate ((n*2-2) `div` 2) "DR"
if you want the number of paths, then:
length $ mazeWays n
Javascript solutions with sample
var arr = [
[1, 1, 1, 0, 0, 1, 0],
[1, 0, 1, 1, 1, 1, 0],
[1, 0, 1, 0, 1, 0, 0],
[1, 1, 0, 0, 1, 0, 0],
[1, 0, 0, 0, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1]
];
function sols2(arr){
var h = arr.length,
w = arr[0].length,
i, j, current, left, top;
for(i = 0; i < h; i++){
for(j = 0; j < w; j++){
current = arr[i][j];
top = i === 0 ? 0.5 : arr[i - 1][j];
left = j === 0 ? 0.5 : arr[i][j-1];
if(left === 0 && top === 0){
arr[i][j] = 0;
} else if(current > 0 && (left > 0 || top > 0)){
arr[i][j] = (left + top) | 0;
} else {
console.log('a6');
arr[i][j] = 0;
}
}
}
return arr[h-1][w-1];
}
sols2(arr);

Printing out 3 elements in array per line

I have an array with x number of elements and want to print out three elements per line (with a for-loop).
Example:
123 343 3434
342 3455 13355
3444 534 2455
I guess i could use %, but I just can't figure out how to do it.
For loop is more suitable:
var array = Enumerable.Range(0, 11).ToArray();
for (int i = 0; i < array.Length; i++)
{
Console.Write("{0,-5}", array[i]);
if (i % 3 == 2)
Console.WriteLine();
}
Outputs:
0 1 2
3 4 5
6 7 8
9 10
Loop through the array 3 at a time and use String.Format().
This should do it...
for (int i = 0; i < array.Length; i += 3)
Console.WriteLine(String.Format("{0,6} {1,6} {2,6}", array[i], array[i + 1], array[i + 2]));
But if the number of items in the array is not divisable by 3, you'll have to add some logic to make sure you don't go out of bounds on the final loop.
You perhaps need to fix the format spacing...
for(int i=0;i<array.Length;i++)
{
Console.Write(array[i] + " ");
if((i+1)%3==0)
Console.WriteLine();
}
Long... but with comments:
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int count = list.Count;
int numGroups = list.Count / 3 + ((list.Count % 3 == 0) ? 0 : 1); // A partially-filled group is still a group!
for (int i = 0; i < numGroups; i++)
{
int counterBase = i * 3;
string s = list[counterBase].ToString(); // if this a partially filled group, the first element must be here...
if (counterBase + 1 < count) // but the second...
s += list[counterBase + 1].ToString(", 0");
if (counterBase + 2 < count) // and third elements may not.
s += list[counterBase + 2].ToString(", 0");
Console.WriteLine(s);
}

C#, LINQ. How to find an element within group of elements

Imagine you have int[] data = new int [] { 1, 2, 1, 1, 3, 2 }
I need sub-array with only those which conform to a condition data[i] > data[i-1] && data[i] > data[i + 1]... i.e. I need all items which stick over their immediate neighbours.
From example above I should get { 2, 3 }
Can it be done in LINQ?
Thanks
data.Where((val, index)=>(index == 0 || val > data[index - 1])
&& (index == data.Length - 1 || val > data[index + 1]));

Categories

Resources