I'm doing a question on Hackerrank that is supposed to left shift an array by a certain number of rotations.
For example:
1 2 3 4 5 -> 2 3 4 5 1
After a single rotation. This will be done however many times the test case asks for.
Here is my code:
using System;
using System.Collections.Generic;
using System.IO;
class Solution {
static void Main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution */
string[] firstLine = Console.ReadLine().Split(' ');
int numInts = Convert.ToInt32(firstLine[0]); //Number of ints in list
int rotations = Convert.ToInt32(firstLine[1]); //number of left rotations
int[] numList = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse); //the list to rotate
for(int i = 0; i < rotations; i++){
int[] newArray = new int[numList.Length];
Array.Copy(numList, 1, newArray, 0, numList.Length-1); //copy from index 1 to end
newArray[numList.Length-1] = numList[0]; //end should equal first elem in old array
Array.Copy(newArray, numList, numList.Length);
}
foreach(var i in numList){
Console.Write(i + " ");
}
}
}
I am passing almost all the tests, but am getting timeout issues on the last 2. What exactly is so slow about this solution that i came up with?
Here is a link to the problem if you want more info:
https://www.hackerrank.com/challenges/array-left-rotation/problem
You should realize that if you start reading an array from index n, it means it has been rotated n % length times. With this inference in mind, your entire program can be simplified into
using System;
using System.Collections.Generic;
using System.IO;
class Solution
{
static void Main(String[] args)
{
string[] firstLine = Console.ReadLine().Split(' ');
int numInts = Convert.ToInt32(firstLine[0]); //Number of ints in list
int rotations = Convert.ToInt32(firstLine[1]); //number of left rotations
int[] numList = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse); //the list to rotate
for( var i = 0 ; i < numInts ; ++i )
Console.WriteLine( numList [ (i + rotations) % numInts ] );
}
}
You have too many copies of an array, which takes time. I think that int.parse at the beginning is also unneeded. You shouldn't literally create copy of array after each rotation but rather calculate position of each element after last rotation (calculate how many steps)
Here is example working solution:
int rotations = 22222222; //number of left rotations
string[] numList = "5 1 2 4 3".Split(' '); //the list to rotate
var index = rotations % numInts;
var indexesToWrite = Enumerable.Range(index, numInts - index).Concat(Enumerable.Range(0, index));
foreach (var indexToWrite in indexesToWrite)
{
Console.Write(numList.ElementAt(indexToWrite) + " ");
}
To clarify the code - it is obvious (as other noticed) that each [numInts] time after we rotate we are getting back to star state. So this obviously leads us to a conclusion, that only remainder after dividing is crucial. After that, we must decide what the result of the % operator would be. In fact, this is information where to start (index of the array) "reading" the numList array. After we reach to an end of the table we should read from the beginning of the numList array (index = 0) till the index where we started to read.
- Array a has n number of elements
- d variable used for number of left rotations
static int[] rotLeft(int[] a, int d) {
int l = a.Length, c = 0;
// if the array length is same as number of rotations not need to rotate the array. //we can return the same array as end result would be same
if( l == d)
return a;
// if array length is less the no of rotations, Here I am finding the reminder as //we can skip the l ( length of the array ) rotations as l rotations will give you the same array. //Now just rotate it to the new value d rotations to get the end result.
if ( l < d)
d = d % l;
int[] copy = new int[a.Length];
//In first loop I am copying values of array "a" from d to end of the array
for(int j=d; j< a.Length; j++)
{
copy[c] = a[j];
c++;
}
// Here I am appending the copy array values form 0 to start no of rotations
for(int i=0;i < d; i++ )
{
copy[c]= a[i];
c++;
}
// End result would be the result
return copy;
}
Related
So I am quite new to C# and having face a problem which requires me to:
Search the longest ascending sequence of integers in an array of integers. As sequence of elements xi (1 ≤ i ≤ n) is ascending if xi < xi+1 for all i (1 ≤ i ≤ n - 1). The size of the array is to be chosen by the user. Values of the array are random numbers are between 0 and 1000 generated by the computer. The program shall print the start index and the length of the longest ascending sequence.
Here are my code so far (I can only sort array in ascending order):
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
namespace AscendingSequences
{
class AscendingSequences
{
public static void Main(string[] args)
{
Console.WriteLine("Ascending Sequence!");
GenerateNumber();
}
public static void GenerateNumber()
{
int i, j, n, number;
int[] array = new int[100];
int[] array1 = new int[100];
Random random = new Random();
Console.Write("\nInput the number of element to be store in the array: ");
n = Convert.ToInt32(Console.ReadLine());
Console.Write("\nThe {0} array is generating-----\n", n);
for (i = 0; i < n; i++)
{
array[i] = random.Next(1, 20);
Console.Write("\nThe array|{0}| is {1} ", i, array[i]);
}
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
if(array[j] < array[i])
{
number = array[i];
array[i] = array[j];
array[j] = number;
}
}
}
Console.Write("\nElements of array in sorted ascending order is: ");
for(i=0; i<n;i++)
{
Console.Write("{0} ", array[i]);
}
}
}
}
This is the assignment given to me:
your approach to first order the array was wrong and that caused some people to be confused unfortunately.
if you start by ordering your array you lose the information of the original location of these elements which are important. Instead you should loop through your array and do a check if the current element is bigger than the previous one(ascending).
//start and length are the "current" values and max are the max found
int start = 0, length = 0, maxstart = 0, maxlength = 0;
//loop through array (starting from index 1 to avoid out of bounds)
for (int i = 1; i < array.Length; i++)
{
//check if current sequence is longer than previously recorded
if (length > maxlength)
{
maxstart = start;
maxlength = length;
}
//if previous element <= to current element
if (array[i - 1] <= array[i])
{
//if the current element isn't part of the current sequence, then start a new sequence
if (start + length < i)
{
start = i - 1;
length = 2;
}
else
{
//count the length
length++;
}
}
}
Here is a .net fiddle with working code:
https://dotnetfiddle.net/1GLmEB
EDIT:
to reply to your question in the comments on how this works start + length < i
This condition checks if the current value is part of the sequence.
The variable start is the start of the last/current found sequence and length is the length.
When this condition returns true it means it falls outside the last found sequence and it resets the values of start and length(true = outside, false = inside)
So lets go through some cases and see why this works:
1 2 3 1 1 2 3 1 1
* > > > e ^
start = 3 (*)
length = 4 (>)
i = 8 (^)
3+4 = e
3+4<8 //true : new sequence
so the last found sequence started at 3 and was 4 long.
this means that this sequence will end at index 7.
since we are currently checking for index 8 in our loop we can see that it isn't part of the same sequence.
1 2 3 1 1 2 3 4 1
* > > > > ê
start = 3 (*)
length = 5 (>)
i = 8 (^)
3+4 = e
3+5<8 //false : current sequence
so the last found sequence started at 3 and was 5 long.
this means that this sequence will end at index 8.
since we are currently checking for index 8 in our loop we can see that it is part of the same sequence.
in hindsight it might have been less confusing if this if statement was turned around (true = inside, false = outside). However I won't change the code now to avoid further confusion.
I wish to create a function AllCombnations(d, maxValue) which will create a d-dimensions array of all number combinations from 0 to maxValue.
For example, a hardcoded version of creating all number combinations in 3D space, from 0 to maxValue would possibly be something like:
for (int i = 0; i < maxValue; i++)
for (int j = 0; j < maxValue; j++)
for (int k = 0; k < maxValue; k++)
{
// code here
}
The issue I face is that I cannot nest n for loops, and am unsure how I would go about this. I have considered recursion, but have had no success. Any help would be greatly appreciated.
Actually, you can loop over dimensions. Please, have a look at Array class
Demo:
// [6, 6, 6] array
int rank = 3; // 3D array - 3 dimensions
int maxValue = 6; // Each dimension is of size 6
int[] lengths = Enumerable // {6, 6, 6} - lengths of the dimensions:
.Repeat(maxValue, rank) // rank times maxValue
.ToArray(); // materialized as array
//TODO: put the right type of arrays' items
// In demo, let array be of type string: "string[6, 6, 6] array"
var array = Array.CreateInstance(typeof(string), lengths);
// we can't use hardcoded set (i, j, k) of variables
// we have to address array's item via array of rank length
int[] address = new int[array.Rank];
// Single loop over all array's items (and dimensions)
do {
//TODO: put the right value here by given address:
// (i == address[0], j == address[1], k == address[2] etc.)
array.SetValue(
string.Concat(address.Select(i => (char) (i + 'A'))), // value: "AAA", "AAB" etc.
address); // address: [0,0,0], [0,0,1],
// here we compute next address
for (int i = 0; i < address.Length; ++i)
if (address[i] >= array.GetLength(i) - 1)
address[i] = 0;
else {
address[i] += 1;
break;
}
// if we get {0, 0, ..., 0} address, we've exhausted all the items
}
while (!address.All(index => index == 0));
Let's have a look at the array (20 top items):
Console.WriteLine(string.Join(Environment.NewLine, array.OfType<string>().Take(20)));
Outcome:
AAA
AAB
AAC
AAD
AAE
AAF
ABA
ABB
ABC
ABD
ABE
ABF
ACA
ACB
ACC
ACD
ACE
ACF
ADA
ADB
I know this is an old post now, but I DID create a solution to this problem.
Let me go through this issue with an example script.
class Program
{
static void Main()
{
// Print all combinations from a to b, for n dimensions
// e.g. 0000 to 2222 <- each dimension goes from 0 to 2, with 4 dimensions
// Note that each dimension can have a unique start/end point
// e.g. 1234 to 5678, so the 2nd dimensions is bound 2 <= x <= 6
int dimensions = 4;
int[] startValues = { 0, 0, 0, 0 };
int[] endValues = { 2, 2, 2, 2 };
PrintCombinations(startValues, endValues, dimensions);
Console.ReadKey();
}
/// <summary>
/// Prints all combinations of numbers given inputs
/// </summary>
/// <param name="start">Inclusive stating integers</param>
/// <param name="end">Inclusive ending integers</param>
/// <param name="dimensions">The number of dimensions to iterate</param>
private static void PrintCombinations(int[] startValues, int[] endValues, int dimensions)
{
// Create new array to loop through without disturbing the original array
int[] loopArray = (int[])startValues.Clone();
// Loop through each value
while (!Enumerable.SequenceEqual(loopArray, endValues))
{
// Write array to console
Console.WriteLine($"{string.Join(", ", loopArray)}");
// Increment array
loopArray[0]++;
// Check if a dimension is larger than it's maximum, then set to min, and add +1 to next dimension
// Do not do this for last dimension, as loop will break once the final combination is met
for (int i = 0; i < dimensions - 1; i++)
if (loopArray[i] > endValues[i])
{
loopArray[i] = startValues[i];
loopArray[i + 1]++;
}
}
// Write final array combination to console
Console.WriteLine($"{string.Join(", ", loopArray)}");
}
}
This is a simple enough example to show how exactly I wanted to expand on the idea of "multiple dimensions" represented as an array.
If you look to the bottom of PrintCombinations, you will see the following code:
for (int i = 0; i < dimensions - 1; i++)
if (loopArray[i] > endValues[i])
{
loopArray[i] = startValues[i];
loopArray[i + 1]++;
}
This is the code I come up with the loop through multiple dimensions, removing the need to hard-code loops when you have user submitted dimensions and other information (as shown in the upper example).
Basically, this code stores the VALUE of each dimension in an array.
Let us do an example of 3 dimensions, (x, y, z).
We can say the point (x, y, z) = int[] { x, y, z }
If we say x, y, and z are the upper bound of the array, we can loop through this array by subtracting the array's first dimesnsion, until it reaches zero, then remove one from the following dimension until it reaches zero, etc, all while resetting the dimension to the upper bound when doing so, or as in this example, add from zero to an upper bound, then reset to zero, and increment the following dimension.
By using further arrays for upper and lower bounds, you can essentially make nested loops between two specific ranges. In the above example, I used an upper bound of { 2, 2, 2, 2 }.
I hope I have explained this well. Thanks
I'm trying to take array of numbers (0 or 1 only) and repeatedly transform it as follows:
first and last numbers are always 0;
all the other numbers are
derived from previous state of array: if array[n] and its two neighbours
(array[n-1], array[n] and array[n+1]) have the same value (three 0s or three 1s) then newarray[n] should be be 1, otherwise it should be 0 (that produces nice patterns).
For example, if the array size is 10 and it starts with all zeroes, then program should output this:
0000000000
0111111110
0011111100
0001111000
0100110010
0000000000
0111111110
...and so on
I wrote a code that should do this and it doesn't work as intended. It always does first transformation perfectly but then begins some wrong, asymmetric, crazy stuff:
0000000000
0111111110
0000000000
0101010100
0000000010
0101010000
What makes my code behave the way it does?
Here is the code:
namespace test
{
class Program
{
public static void Main(string[] args)
{
const int leng = 10; //length of array
int[] arrayone = new int[leng];
int[] arraytwo = new int[leng];
for (int i = 0; i<=leng-1; i++)
{
arrayone[i] = 0;
arraytwo[i] = 0;
} //making two arrays and filling them with zeroes
for (int i = 0; i<=leng-1; i++)
{
Console.Write(arrayone[i]);
}
Console.WriteLine(' '); //printing the first state of array
for (int st=1; st<=16; st++) //my main loop
{
arraytwo[0]=0;
arraytwo[leng - 1]=0; //making sure that first and last elements are zero. I'm not sure I need this since I fill both arrays with zeroes in the beginning. But it probably doesn't hurt?
for (int i = 1; i<=leng-2; i++) //calculating new states for elements from second to second-to-last
{
if (((arrayone[i-1]) + (arrayone[i]) + (arrayone[i+1]) == 0) | ((arrayone[i-1]) + (arrayone[i]) + (arrayone[i+1]) == 3) == true)
arraytwo[i] = 1;
else
arraytwo[i] = 0;
}
//by now arraytwo contains transformed version of arrayone
for (int i = 0; i<=leng-1; i++)
{
Console.Write(arraytwo[i]);
} //printing result
arrayone = arraytwo; //copying content of arraytwo to arrayone for the next round of transformation;
Console.WriteLine(' ');
}
Console.Write(" ");
Console.ReadKey(true);
}
}
}
Tweakable version: https://dotnetfiddle.net/8htp9N
As pointed out you're talking an object and working on it, at the end of that you're assigning the reference not the values. one way to combat that would be
for your line: arrayone = arraytwo;
change it to : arrayone = (int[])arraytwo.Clone();
this will copy the values - for integers this will be sufficient.
Please, notice how your current code is complex and thus diffcult to debug. Make it simpler, extract a method:
using System.Linq;
...
private static IEnumerable<int[]> Generate(int width) {
int[] item = new int[width];
while (true) {
yield return item.ToArray(); // .ToArray() - return a copy of the item
int[] next = new int[width];
for (int i = 1; i < item.Length - 1; ++i)
if (item[i - 1] == item[i] && item[i] == item[i + 1])
next[i] = 1;
item = next;
}
}
Then you can put
public static void Main(string[] args) {
var result = Generate(10) // each line of 10 items
.Take(7) // 7 lines
.Select(item => string.Concat(item));
Console.Write(string.Join(Environment.NewLine, result));
}
Outcome:
0000000000
0111111110
0011111100
0001111000
0100110010
0000000000
0111111110
I am trying to solve polygon partition problem using graham scan
below is the problem statement and input and expected output
I have implemented graham scan logic but i need to display output
according to the sets formed and display all the points with indexes;
The first line will contain a single integer ().
The next lines will contain two integers (), denoting a point with coordinates . Note that points are not guaranteed to be distinct.
SAMPLE INPUT
3
0 0
0 1
1 0
On the first line, output a single integer (), the number of sets in your partition.
On the next lines, print the elements of the partition. On the -th of these lines, first print the integer (), and then indices of points forming the -th set. Points are numbered starting from . Each index from to must appear in exactly one set.
SAMPLE OUTPUT
1
3 1 2 3
below is the code implemented according to the output mentioned above,
how to print for more sets?
private static void convexHull(Point[] points, int N, int set)
{
int index = 0;
List<int> result = new List<int>();
// There must be at least 3 points
if (N < 3) return;
// Initialize Result
MyStack<Point> hull = new MyStack<Point>(N);
// Find the leftmost point
int l = 0;
for (int i = 1; i < N; i++)
if (points[i].x < points[l].x)
l = i;
// Start from leftmost point, keep moving
// counterclockwise until reach the start point
// again. This loop runs O(h) times where h is
// number of points in result or output.
int p = l, q;
do
{
// Add current point to result
hull.push(points[p]);
// Search for a point 'q' such that
// orientation(p, x, q) is counterclockwise
// for all points 'x'. The idea is to keep
// track of last visited most counterclock-
// wise point in q. If any point 'i' is more
// counterclock-wise than q, then update q.
q = (p + 1) % N;
for (int i = 0; i < N; i++)
{
// If i is more counterclockwise than
// current q, then update q
if (orientation(points[p], points[i], points[q])
== 2)
q = i;
}
// Now q is the most counterclockwise with
// respect to p. Set p as q for next iteration,
// so that q is added to result 'hull'
p = q;
} while (p != l); // While we don't come to first
set += 1;
var ele = hull.GetAllStackElements();
foreach (Point pt in ele)
{
index += 1;
}
Console.WriteLine(set);
Console.Write(string.Format("{0} ", index));
for (int s = 1; s <= index; s++)
{
Console.Write(string.Format("{0} ", s));
}
Console.Write(Environment.NewLine);
}
I was having this discussion with my friend who had this question asked to him in the Interview. The Question goes like this. Write a Function which takes in a byte array(2 dimensional) as input along with an Integer n, The initial assumption is all the elements of M*N byte array is zero and the problem is to fill 'n' Byte array elements with value 1, For instance if M=5 and N=5 and the n value is 10 the Byte array should've 10/25 elements to be 1 and rest of the 15 values to be 0. The values filled should be random and one cell in byte array should be filled only once. I was fascinated to try solving this on my own. I've attached the code I've come up with so far.
public Boolean ByteArrayFiller(int a,int b, int n)
{
int count = n;
int iLocalCount = 0;
byte[,] bArray= new byte[a,b];
for (int i = 0; i <a; i++)
for (int j = 1; j <b; j++)
bArray[i, j] = 0;
Random randa= new Random();
int iRandA = randa.Next(a);
int iRandB = randa.Next(b);
while (iLocalCount < n)
{
if (bArray[iRandA, iRandB] == 0)
{
bArray[iRandA, iRandB] = 1;
iLocalCount++;
}
iRandA = randa.Next(a);
iRandB = randa.Next(b);
continue;
}
//do
//{
// //iRandA = randa.Next(a);
// //iRandB = randa.Next(b);
// bArray[iRandA,iRandB]=1;
// iLocalCount++;
//} while (iLocalCount<=count && bArray[iRandA,iRandB]==0);
return true;
}
The code i wrote is in C# but it's straight forward to understand. It's able to do the purpose of the question( I did some trials runs and results came out correctly) perfectly but I have used Random object in C#(Equivalent to Math.Rand in Java) to fill up the byte array and I keep thinking if Rand returns the same values for a and b. There is a good chance for this to go indefinitely. Is that the purpose of the question? or Does the solution that i came up for this question is good enough!
I am curious to see how experts here solve this problem? I am just looking for new ideas to expand my horizon. Any pointers would be greatly appreciated. Thanks for taking the time to read this post!
A while loop trying random locations until it finds a good one is generally a very bad approach. If n = M*N, then the last one will have a probability of 1/(M*N) of finding a match. If M*N are sufficiently large, this can be extremely inefficient.
If M*N is not too large, I would create a temporary array of M*N size, fill it with the numbers 0 through (M*N)-1, and then permutate it - i.e. you walk through it and swap the current value with that of a random other value.
Then you go to the first n elements in your array and set the appropriate cell. (row = value / columns, col = value % columns).
I would treat the array, logically, as a one-dimensional array. Fill the first n positions with the prescribed value, and then shuffle the array.
Given a byte array, and the number of rows and columns in the array, and assuming that the array is already filled with 0:
int NumElements = NumRows * NumCols;
for (int i = 0; i < NumElementsToFill; ++i)
{
int row = i / NumRows;
int col = i % NumCols;
array[row, col] = 1;
}
// Now shuffle the array
Random rnd = new Random();
for (int i = 0; i < NumElements; ++i)
{
int irow = i / NumRows;
int icol = i % NumCols;
int swapWith = rnd.Next(i+1);
int swapRow = swapWith / NumRows;
int swapCol = swapWith % NumCols;
byte temp = array[irow, icol];
array[irow, icol] = array[swapRow, swapCol];
array[swapRow, swapCol] = temp;
}
The key here is converting the one-dimensional index into row/col values. I used / and %. You could also use Math.DivRem. Or create Action methods that do the get and set for you.
Choose a number, which is larger than both N and M and is prime (or co-prime to both N and M). Let's call this number p.
Loop until you've set x numbers:
Generate a random number less than N*M. Call this number `l`.
Then the next place to put the number will be `p*l%(N*M)`, if that position hasn't been set.
A downside to this approach is that if the array is filling up, you'll have more collisions.
Bascially, you need to choose n unique random numbers from range [0, p) (where p = M * N), and map them to positions of 2-dimensional array.
Naive approaches are 1) generate non-unique numbers with retry 2) fill an array with numbers from 0 to p-1, shuffle it and take first n numbers (takes O(p) time, O(p) memory).
Another approach is to choose them with the following algorithm (O(n2) time, O(n) memory, code in Java):
public Set<Integer> chooseUniqueRandomNumbers(int n, int p) {
Set<Integer> choosen = new TreeSet<Integer>();
Random rnd = new Random();
for (int i = 0; i < n; i++) {
// Generate random number from range [0, p - i)
int c = rnd.nextInt(p - i);
// Adjust it as it was choosen from range [0, p) excluding already choosen numbers
Iterator<Integer> it = choosen.iterator();
while (it.hasNext() && it.next() <= c) c++;
choosen.add(c);
}
return choosen;
}
Mapping of generated numbers to positions of 2-dimensional array is trivial.