grahams scan to implement polygon partition in c# - c#

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);
}

Related

Longest Ascending Sequence C#

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.

Timeout issues in Array rotation. What is so slow about this solution?

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;
}

Drawing an ASCII tree using nested for-loops

I am practising my programming skills with a rather common problem, to draw an ASCII tree composed of a letter (let's say x's) to draw a tree.
Ie:
Prompt: Enter the number of lines for your tree: 5
Output:
x
xxx
xxxxx
xxxxxxx
x
The solution I have is currently working as I want it to. I am only missing one feature (which is part of my question). The issue is, I do not understand the for-loop conditionals I have used. Yes, I did get help from another individual and I still do not understand their logic, but it works. Please, please, please explain to me how the for loop conditionals are actually working for me to draw what I want. x.x
Furthermore, I am unable to draw the last "stump" of the tree, the final x in the last row.
Here is my code.
static void Main(string[] args)
{
int lines = 0;
Console.WriteLine("Enter number of lines: ");
string LinesAsString = Console.ReadLine();
lines = Convert.ToInt32(LinesAsString);
print(lines);
}
public static void print(int lines)
{
for (int i = 0; i < lines; i++)
{
for (int a = 0; a < lines-i-1; a++)
{
Console.Write(" ");
}
for (int y = 0; y < i*2 + 1; y++)
{
Console.Write("x");
}
Console.WriteLine();
}
}
Any help is appreciated.
Thanks.
The first for loop prints the left padding (all spaces). The expression lines - i - 1 comes form the fact that you need to center the tree and you know that line 0 has a single x, line 1 has 3 (xxx), line 2 has 5 (xxxxx) and so on. But the number of left spaces depends on the total number of lines the tree has, therefore you need to take the lines into account as well as the index of the current line (which is the value of the variable i). To figure out the relationship between these two, you can just try with a small number of levels, let's say 3:
__x 2 for the 1st line.
_xxx 1 for the 2nd line.
xxxxx 0 for the 3rd line.
The second for loop prints the xs. It knows that for the first line (i = 0) it needs to print a single x, so when i is 0, y needs to be 1, therefore the + 1. The * 2 comes from the progression i * 2 + 1 = {1, 3, 5, 7...} which is the number of xs in each line.
To print the last stub character you can use the same logic as in the first for loop, inserting the number of spaces for the first line followed by a single x.
Console.Write(new String(' ', lines - 1) + "x");
This should be added just after the for loop that contains the two other loops.
It's quite simple:
Each iteration of the first for loop draws a line. Supposing you have 4 lines (I am not considering the one with the lonely x):
line 1 (i=0): 3 spaces 1 x
line 2 (i=1): 2 spaces 3 x
line 3 (i=2): 1 spaces 5 x
line 4 (i=3): 0 spaces 7 x
From these, you can obtain a relation between the number of spaces, x's, the line index i and the number of lines.
spaces = (lines - i) - 1 // decreases by one every iteration starting at lines - 1
x = i * 2 + 1 // the odd numbers in increasing order
The first loop draw the spaces and the second one the x's
int count = 0;
for (int i = 0; i < 8; i++)
{
for (int x = 0; x < 8-i-1; x++)
{
Console.Write(" ");
}
for (int j = 0; j < i*2+1; j++)
{
Console.Write("X");
}
Console.WriteLine();
}
//solution to your stump problem
for (int i = 0; i < 4; i++)//the no. 4 means that you stump will be made from four X's
{
for (int x = 0; x < 8-count-1; x++)
{
Console.Write(" ");
}
Console.Write("X");
Console.WriteLine();
}
Console.ReadKey();

Index outside array inside loop

I get an error Index was outside the bounds of the array, im trying to do some simple math and holding it in my list.
List<int> integerList = new List<int>();
for (int a = 0; a < textBox1.Text.Length; a++)
{
for (int b = 8; b > 1 ; b--)
{
integerList.Add(int.Parse(textBox1.Text[a * b].ToString())); //this line
}
}
listBox1.DataSource = integerList;
What I am trying to achieve is this, a user must enter a 7 digit number into the textbox say for instance 4565457, I wanted to store this number in my integerList, then take each number starting from the beginning of the users input and multiply down from 8 untill 2 is reached.
For instance:
4 x 8
5 x 7
6 x 6
5 x 5
4 x 4
5 x 3
7 x 2
I wanted to then store the sum of these multiplications for later use.
It's probably the textBox1.Text that's out of bounds. Try adding a check before using the indexer:
if (a*b < textBox1.Length)
integerList.Add(int.Parse(textBox1.Text[a * b].ToString())); //this line
Try this (since you probably want to calc the value of your a number by the value of b):
List<int> integerList = new List<int>();
for (int a = 0; a < textBox1.Text.Length; a++)
{
for (int b = 8; b > 1 ; b--)
{
integerList.Add(int.Parse(textBox1.Text[a].ToString()) * b); //this line
}
}
listBox1.DataSource = integerList;
The index a*b is outside the bounds of the TextBox content. You have to put in place safeguards to make sure you don't index the string content of the textbox using an index that is out of bounds
This line textBox1.Text[a * b] is likely the source of the problem. There's no bounds checking and a * b likely evaluates to an integer greater than the final index of textBox1. I don't have an great solution for you because I don't really understand what you're trying to do... The expression inside the inner for loop just generally does not make much sense.
You could simply check that a * b is less than textBox1.Text.Length in order to prevent the exception but that probably won't make the code do what you actually want it to.
Sorry didn't got time to read the edited question. According to new description, if user enters 4565457 you want to multiply each character in that string from position 0 to last (6 in this case) with 8 - position. Following loop single for loop will do the trick.
List<int> integerList = new List<int>();
var l = textBox1.Text.Length;
for (int a = 0, b = 8; a < l && b > 1; a++, b--)
{
integerList.Add((Convert.ToInt16(textBox1.Text[a]) * b)); //this line
}
listBox1.DataSource = integerList;
At the end of loop, listBox1 will contain following values:
416
371
324
265
208
159
110
Try this:
List<int> integerList = new List<int>();
var l = textBox1.Text.Length;
for (int a = 0; a < l; a++)
{
for (int b = 8; b > 1 && (a*b) < l ; b--)
{
integerList.Add(int.Parse(textBox1.Text[a * b].ToString())); //this line
}
}
listBox1.DataSource = integerList;
a * b is getting past the length of text in textbox so adding && (a*b) > l will keep this in control.

How to write groups of numbers using Console.Write?

I'm very new to C# (And Stack Overflow, forgive me for any poor etiquette here), and I'm writing the game Mastermind in a console application. I'm trying to show a list of the user's guesses at the end of the game, and I know that using Console.WriteLine(); will just give me 30-odd lines off numbers which don't tell the user anything.
How can I alter my code so that the program displays 4 numbers in a group, at a time? For example:
1234
1234
1234
//Store numbers in a history list
ArrayList guesses = new ArrayList(); //This is the ArrayList
Console.WriteLine("Please enter your first guess.");
guess1 = Convert.ToInt32(Console.ReadLine());
guesses.Add(guess1);
foreach (int i in guesses)
{
Console.Write(i);
}
I assume that each element of your byte array is a single digit (0-9). If that assumption is invalid -- please let me know, I'll modify the code :)
Action<IEnumerable<int>> dump = null;
dump = items =>
{
if(items.Any())
{
var head = String.Join("", items.Take(4));
Console.WriteLine(head);
var tail = items.Skip(4);
dump(tail);
}
};
dump(guesses);
It looks like you're most of the way there, you have a console write that writes them all out without linebreaks. Next add an integer count and set it to zero. Increment it by one in the foreach loop. count % 4 == 0 will then be true for all counts that are a multiple of four. This means you can stick an if block there with a write-line to give you your groups of four.
List<int> endResult = new List<int>();
StringBuilder tempSb = new StringBuilder();
for(int i=0; i < groups.Count; i++)
{
if(i % 4 == 0) {
endResult.Add(int.Parse(sb.ToString()));
tempSb.Clear(); // remove what was already added
}
tempSb.Append(group[i]);
}
// check to make sure there aren't any stragglers left in
// the StringBuilder. Would happen if the count of groups is not a multiple of 4
if(groups.Count % 4 != 0) {
groups.Add(int.Parse(sb.ToString()));
}
This will give you a list of 4 digit ints and make sure you don't lose any if your the number of ints in your groups list is not a multiple of 4. Please note that I am continuing based on what you provided, so groups is the ArrayList of ints.
This is some thing I quickly put together:
Update:
ArrayList guesses = new ArrayList(); //This is the ArrayList
// Four or more
guesses.Add(1); guesses.Add(2);
guesses.Add(3);guesses.Add(4);
guesses.Add(5); guesses.Add(6); guesses.Add(7);guesses.Add(8); guesses.Add(9);
//Uncomment-Me for less than four inputs
//guesses.Add(1); guesses.Add(2);
int position = 0;
if (guesses.Count < 4)
{
for (int y = 0; y < guesses.Count; y++)
{
Console.Out.Write(guesses[y]);
}
}
else
{
for (int i = 1; i <= guesses.Count; i++)
{
if (i%4 == 0)
{
Console.Out.WriteLine(string.Format("{0}{1}{2}{3}", guesses[i - 4], guesses[i - 3],
guesses[i - 2], guesses[i - 1]));
position = i;
}
else
{
if (i == guesses.Count)
{
for (int j = position; j < i; j++)
{
Console.Out.Write(guesses[j]);
}
}
}
}
}

Categories