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();
Related
I Would really appreciate some help on this question I will sum it up myself but also include the actual instruction and my code so far.
Write a console C# program to do the following:
Ask user max number of characters. This should be an odd number if user enters even number add 1 to it to convert it to odd number.
Ask user the character to print
Your program should then output two inverted vertical triangles of base equal to number entered in #1 and made of characters in #2
Number of characters in one line of the triangle should differ by 2 from its next line such that the top of the triangle has only 1 character.
The top of the triangle (single character) should be centralized appropriately
Make sure your code follows these guidelines
-The output string should be returned as a single string variable from a class
-Class should have a public function that will returns the string and takes the input for #1 and #2 as argument
-Code should be well commented and indented
-Check for all invalid input values (e.g. for #1 no character should be accepted). Suitable message should be displayed to user for incorrect input
-All 5 requirements should be met
-Code should compile and run without any error or warnings
Example:
If user enters 9 for #1 and enters the character ‘*’ for #2 the program should print the following:
*
***
*****
*******
*********
*********
*******
*****
***
*
Thus far I can get the code to print out the correct number of characters, but not to align correctly into this shape.
I will attach my code at the bottom of this post. Whoever may respond, can you explain exactly how the for loop is working on order to achieve this? I know this is not an extremely difficult question, but C# is a new language to me, the course is entirely online, and I feel lost in such conceptual thinking. Thank you so much to whoever responds.
public class Class1
{
public void Main(string[] args)
{
int n;
char ch;
try
{
Console.Write("Enter the Max Number of Characters ::");
n = int.Parse(Console.ReadLine());
if (n % 2 == 0)
n++;
Console.Write("Enter Character Which You Want to Print ::");//output message for display
ch = char.Parse(Console.ReadLine());//value to get from user
Console.WriteLine(PatternPrint(n, ch));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public string PatternPrint(int n, char ch)
{
int i, j, k, l;//variable to declare
string str = "";//string to display
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n - i; j++)
{
str = str + " ";
}
for (k = 1; k <= i; k++)
{
str = str + ch;
}
for (l = i -1; l >= 1; l--)
{
str = str + ch;
}
str = str + "\n";
}
return str;//return string
}
}
}
You have a problem with your logic, as it prints only in one direction. Whereas, as per your requirement you need reverse direction pattern as well.
Your code output is :
*
***
*****
*******
*********
***********
*************
***************
*****************
Please try below code as it prints in both direction.
using System;
public class Test
{
public static void Main()
{
Console.Write("Enter the Max Number of Characters ::");
int totalChar = Convert.ToInt32(Console.ReadLine());
Console.Write("Enter Character Which You Want to Print ::")
char character = char.Parse(Console.ReadLine());
totalChar = (totalChar % 2 == 0) ? totalChar += 1 : totalChar;
int mainIndex, spaceIndex, charIndex;
for(mainIndex = 1; mainIndex <= totalChar; mainIndex += 2)
{
for(spaceIndex = totalChar; spaceIndex >= mainIndex; spaceIndex -= 2)
Console.Write(" ");
for(charIndex = 1; charIndex <= mainIndex; charIndex++)
Console.Write(character);
Console.WriteLine();
}
for(mainIndex = totalChar; mainIndex >= 1; mainIndex -= 2)
{
for(spaceIndex = mainIndex; spaceIndex <= totalChar; spaceIndex += 2)
Console.Write(" ");
for(charIndex = 1; charIndex <= mainIndex; charIndex++)
Console.Write(character);
Console.WriteLine();
}
}
}
Sample Input : 9 & *
Sample Output:
*
***
*****
*******
*********
*********
*******
*****
***
*
This code works for me:
public string PatternPrint(int n, char ch) =>
String.Join(
Environment.NewLine,
Enumerable
.Range(1 - n / 2, n - 1)
.Select(x => Math.Abs(x))
.Select(i => "".PadLeft(i) + "".PadLeft(n - 2 * i - 1, ch)));
Given 5 and # I get:
#
###
#####
###
#
Here's brief explanation from me -
Observing example -
Input => Character to use '*', Maximum it can appear is 9 times (triangle's base).
Each line in triangle can be formatted in two ways -
White spaces, then characters.
White spaces, then characters, then again white spaces.
Observing your code -
You seem to using the first approach.
Your 1st loop add white spaces.
You may find this surprising, but your 2nd and 3rd do the same thing, they add characters, except 3rd loop has 1 less character.
What we need based on the example -
If max character usage per line is n, we need to have n+1 lines. (One more because lower triangle does not share base)
A triangle completes in (n+1)/2 lines.
To complete upper triangle, each line needs, each line needs
White spaces starting from (n-1)/2, decreasing by 1.
Characters starting from 1, increasing by 2.
To complete lower triangle, each line needs
White spaces starting from 0, increasing by 1.
Characters starting from n, decreasing by 2.
I would encourage you try yourself, but after you are done, here's the reference code -
public static string PatternPrint(int n, char ch)
{
StringBuilder sb = new StringBuilder();
int spaces, characters;
// Upper triangle
spaces = (n - 1) / 2;
characters = 1;
for (int i = 0; i < (n+1)/2; i++)
{
Enumerable.Repeat(' ', spaces).ToList().ForEach(space => sb.Append(space));
Enumerable.Repeat(ch, characters).ToList().ForEach(character => sb.Append(character));
sb.Append('\n');
spaces -= 1;
characters += 2;
}
// Lower triangle
spaces = 0;
characters = n;
for (int i = 0; i < (n+1)/2; i++)
{
Enumerable.Repeat(' ', spaces).ToList().ForEach(space => sb.Append(space));
Enumerable.Repeat(ch, characters).ToList().ForEach(character => sb.Append(character));
sb.Append('\n');
spaces += 1;
characters -= 2;
}
return sb.ToString();
}
Above code related notes -
Use StringBuilder to manipulate your string. It is more efficient, and easy I would say. Available in namespace System.Text
C# offers Linq library in namespace System.Linq. Enumerable used in code is part of it. It offers many more things, and extension methods. Really cool.
There's always room for improvement. My solution works based on assumptions. It silently fails when those assumptions are broken. Hint: evens
This program is to create a wave like structure using C# with the fibonnaci sequence and arrays. With the number of the sequence being at the end and asterisks equaling what number is on the current line in front. This is all done using the For loops and having the upper limiter done by the Array, I solve that limiter problem by using the .Length aspect of Arrays but I don't grasp the concept of how to properly use the array within this sequence.
This first part of code I have the sequence building up using my array with 12 index as I only need the 11 first fibonacci sequences.
The problem I am running into is within the second part of the code.
class Program
{
static void Main(string[] args)
{
int a = 0, b = 1;
int[] fibArray = new int[12];
fibArray[0] = 0;
fibArray[1] = 1;
Console.WriteLine("0");
Console.WriteLine("*1");
for (int i = 3; i <= fibArray.Length; i++)
{
fibArray[i] = a + b;
a = b;
b = fibArray[i];
for(int y = 1; y <= fibArray[i]; y++)
{
Console.Write("*");
}
Console.Write("" + fibArray[i]);
Console.WriteLine();
}
With this second part of code I am unable to get it to register and output the sequence. Mostly I am unsure of how to properly set up my array to ensure that the fibonacci sequence is able to go reverse as well. I understand the sequence is typically f(n)=f(n-1)+f(n-2), I cannot wrap my head around how to properly use arrays in this context.
for (int p = fibArray[11]; p >= fibArray.Length; p--)
{
for (int k = 1; k <= p; k++)
{
Console.Write("*");
}
Console.Write(""+ b);
Console.WriteLine();
}
}
}
}
Sorry for ranting, just trying to explain the code as a whole but to give a sum of what I am asking about.
It would be how to use the Arrays, what I did wrong with my current code, and what aspect I could use to control the loops using the Array itself.
To give an overall example of the desired output it would be like so:
0
*1
*1
**2
***3
***3
**2
*1
*1
0
Some things to note about your original code. You manually set the first two values in the sequence at elements 0 and 1, but then skipped over element 2 and started from element 3. Your loop was including the length of the array as valid index when it should start at (array length - 1) since arrays are zero based in .Net.
You can output the correct length of asterisks by using this string constructor.
I'd separate the generation of the sequence from the output:
static void Main(string[] args)
{
// building the Fibonacci sequence (no output at this time)
int[] fibArray = new int[12];
for (int i = 0; i < fibArray.Length; i++)
{
switch (i)
{
case 0:
fibArray[i] = 0;
break;
case 1:
fibArray[i] = 1;
break;
default:
fibArray[i] = fibArray[i - 1] + fibArray[i - 2];
break;
}
}
// increasing curve
for (int i = 0; i < fibArray.Length; i++)
{
Console.WriteLine(new String('*', fibArray[i]) + fibArray[i].ToString());
}
// decreasing curve
for (int i = (fibArray.Length-1); i >= 0; i--)
{
Console.WriteLine(new String('*', fibArray[i]) + fibArray[i].ToString());
}
Console.WriteLine();
Console.Write("Press Enter to Quit");
Console.ReadLine();
}
Output:
0
*1
*1
**2
***3
*****5
********8
*************13
*********************21
**********************************34
*******************************************************55
*****************************************************************************************89
*****************************************************************************************89
*******************************************************55
**********************************34
*********************21
*************13
********8
*****5
***3
**2
*1
*1
0
Press Enter to Quit
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'm trying to learn C# by solving mathematical problems. For example, I'm working on finding the sum of factors of 3 or 5 in the first 1000 positive numbers. I have the basic shell of the code laid out, but it isn't behaving how I'm expecting it to.
Right now, instead of getting a single output of 23, I am instead getting 1,1,3,3,5,5,7,7,9,9. I imagine I messed up the truncate function somehow. Its a bloody mess, but its the only way I can think of checking for factors. Second, I think that the output is writing during the loop, instead of patiently waiting for the for() loop to finish.
using System;
namespace Problem1
{
class Problem1
{
public static void Main()
{
//create a 1000 number array
int[] numberPool = new int[10];
//use for loop to assign the first 1000 positive numbers to the array
for (int i = 0; i < numberPool.Length; i++)
{
numberPool[i] = i + 1;
}
//check for factors of 3 or 5 using if/then statment
foreach (int i in numberPool)
if ((i / 3) == Math.Truncate((((decimal)(i / 3)))) || ((i / 5) == Math.Truncate(((decimal)(i / 5)))))
{
numberPool[i] = i;
}
else
{
numberPool[i] = 0;
}
//throw the 0s and factors together and get the sum!
int sum = 0;
for (int x = 0;x < numberPool.Length;x++)
{
sum = sum + numberPool[x];
}
Console.WriteLine(sum);
Console.ReadLine();
//uncomment above if running in vbs
}
}
}
The foreach loop has a few errors.
If you want to modify the array you are looping through use a for loop. Also, use modulus when checking remainders.
for (int i = 0; i < numberPool.Length; i++)
{
if (numberPool[i] % 3 == 0 || numberPool[i] % 5 == 0)
{
// Do nothing
}
else
{
numberPool[i] = 0;
}
}
Modulus (%) will give the remainder when dividing two integers.
Another useful shortcut, variable = variable + x can be replaced with variable += x
Please note that there are more concise ways of doing this but since you are learning the language I will leave that for you to find.
#kailanjian gave some great advice for you but here is another way your initial logic can be simplified for understanding:
//the sum of factors
int sum = 0;
//the maximum number we will test for
int maxNum = 1000;
//iterate from 1 to our max number
for (int i = 1; i <= maxNum; i++)
{
//the number is a factor of 3 or 5
if (i % 3 == 0 || i % 5 == 0)
{
sum += i;
}
}
//output our sum
Console.WriteLine(sum);
You also stated:
Second, I think that the output is writing during the loop, instead of patiently waiting for the for() loop to finish.
Your program logic will execute in the order that you list it and won't move on to the next given command until it is complete with the last. So your sum output will only be printed once it has completed our for loop iteration.
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]);
}
}
}
}
}