The number n is entered from the keyboard (in this case, n = 7), you need to output such a figure
How to beautifully combine these 2 functions into one?
static void printD(int N, int k)
{
for (int i = 1; i <= k / 2; i++)
Console.Write(" ");
for (int i = 1; i <= N - k + 1; i++)
Console.Write("*");
Console.WriteLine();
if (k < N)
printD(N, k + 2);
}
static void printU(int N, int k)
{
for (int c = 1; c <= N / 2 + 1 - k; c++)
Console.Write(" ");
for (int c = 1; c <= k * 2 - 1; c++)
Console.Write("*");
Console.WriteLine();
if (k < N / 2 + 1)
printD(N, k + 1);
}
I suggest extracting a method which prints a single line:
static bool printLine(int N, int k) {
if (k <= 0 || k > N)
return false;
Console.Write(new string(' ', (N - k) / 2));
Console.Write(new string('*', k));
return true;
}
Then we can easily implement recursive printing for down and up triangles:
static void printD(int N, int k) {
if (printLine(N, k)) {
Console.WriteLine();
printD(N, k - 2);
}
}
static void printU(int N, int k) {
if (printLine(N, k)) {
Console.WriteLine();
printU(N, k + 2);
}
}
Finally, to draw a diamond shape figure we have to print up and then down triangles. So in order to combine triangles all we have to do is to call printU and printD:
static void print(int N) {
printU(N, N % 2 == 0 ? 2 : 1);
printD(N, N);
}
Demo:
print(6);
Console.WriteLine();
print(5);
Outcome:
**
****
******
******
****
**
*
***
*****
*****
***
*
Please, fiddle with the code.
Related
I'm solving problems on LeetCode, and referring to this problem: 189. Rotate Array
Given an array, rotate the array to the right by k steps, where k is non-negative.
Example 1:
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
I gave my solution as:
public void Rotate(int[] nums, int k) {
if (k <= 0)
return;
int t = 0;
for (int i = 0; i < k; i++) {
t = nums[nums.Length - 1];
for (int j = nums.Length - 1; j > 0; j--) {
nums[j] = nums[j - 1];
}
nums[0] = t;
}
}
My question is not about the solution, but is about its performance.
Can I improve my solution to be faster? Or is wrong my approach?
Cause it pass all the test cases, but it fail the last one cause is a big array with big numbers, and it fail on being fast enough, it gives me
"Time Limit Exceeded"
You could run it in a single while loop. I don't have leetcode so I can't test it, I just ran it locally but if you run this what do you get? Also, it doesn't do the in place movement so if there is a memory test it might fail that.
public static int[] Rotate(int[] nums, int k) {
if (k <= 0) return nums;
var n = new int[nums.Length];
var stopAt = nums.Length - k;
while(stopAt < 0) {
stopAt = nums.Length - Math.Abs(stopAt);
}
var i = stopAt;
var y = 0;
while (true) {
n[y] = nums[i];
y++;
i++;
if (i >= nums.Length) {
i = 0;
}
if (i == stopAt) break;
}
return n;
}
There's a trick to performing this in place that involves a transformation over two steps. O(n) time, O(1) space.
Example, k = 3:
1234567
First reverse in place each of the two sections delineated by n-k:
4321 765
Now revese the whole array:
5671234
Reversing sections in place left as an exercise to the reader.
If you are looking for performance you can get rid of nested loops to have O(n) time complexity vs. O(n * n):
Compute what each item of the result array should be
Copy result array into initial one
Code:
public void Rotate(int[] nums, int k) {
int[] result = new int[nums.Length];
for (int i = 0; i < nums.Length; ++i) {
int index = (i + k % nums.Length + nums.Length) % nums.Length;
result[index] = nums[i];
}
Array.Copy(result, nums, nums.Length);
}
Note, that in general case we have a quite complex formula for index:
int index = (i + k % nums.Length + nums.Length) % nums.Length;
we should be ready for negative k (while index must not be negative) and huge k (possible integer overflow). If k >= 0 and k <= 1e5 as Leet Code claims we can simplify index into
int index = (i + k) % nums.Length;
and have compact solution as
public void Rotate(int[] nums, int k) {
int[] result = new int[nums.Length];
for (int i = 0; i < nums.Length; ++i)
result[(i + k) % nums.Length] = nums[i];
Array.Copy(result, nums, nums.Length);
}
Edit: Why % (remainder) appears in index formula?
Let's have a look on what's going on. When i + k is less than nums.Length we should write the value just at i + k index. When i + k == nums.Length we should write at index == 0, when i + k == nums.Length + 1 we should write at index == 1, ..., when i + k == nums.Length + r then we should write at index == r, note that r == (i + k) % nums.Length == (nums.Length + r) % nums.Length == 0 + r == r
public void PrintPascalTriangle(int inNumberOfLines)
{
int noOfLines = inNumberOfLines;
int number = 1;
for(int i=0;i<noOfLines;i++)
{
number = 1;
for(int j=0;j<=i;j++)
{
Console.Write(number + " ");
number = number * (i - j) / (j + 1);
}
}
}
how can convert this method into single loop and print values in single row?
I just need Pascal triangle values in a row (no need to worry about spaces or visual rep) upto n.
Rows of Pascal's Triangle are all values of "the combinatorial function", n!/[k!( n-k)!], for a fixed n. The combinatorial function can be computed efficiently as below, see the Choose function, which I ripped from this answer:
class Program
{
static int Choose(int n, int k)
{
if (k > n)
return 0;
if (k * 2 > n)
k = n - k;
if (k == 0)
return 1;
int result = n;
for (int i = 2; i <= k; ++i)
{
result *= (n - i + 1);
result /= i;
}
return result;
}
static List<int> RowOfPascalsTriangle(int n)
{
return Enumerable.Range(0, n).Select(k => Choose(n-1, k)).ToList();
}
static void Main(string[] args)
{
Console.WriteLine(string.Join(" ", RowOfPascalsTriangle(1)));
Console.WriteLine(string.Join(" ", RowOfPascalsTriangle(2)));
Console.WriteLine(string.Join(" ", RowOfPascalsTriangle(3)));
Console.WriteLine(string.Join(" ", RowOfPascalsTriangle(4)));
Console.WriteLine(string.Join(" ", RowOfPascalsTriangle(5)));
}
}
I have to create a program to print pyramid pattern (1 2 33 44 555 666...) and sum the numbers.
Here is my solution:
static void Main(string[] args)
{
int i, j;
i = 1;
int sum = 0;
while (i < 9)
{
for (j = 1; j <= i; j+=2)
{
Console.Write(i);
}
Console.Write("\n");
sum += i;
i++;
}
Console.WriteLine("Summary: " + sum);
Console.ReadLine();
}
And my output:
What am I doing wrong here (wrong summary)?
Here is an optimized and working version of your code:
int sum = 0;
for (int i = 1; i < 9; i++)
{
int current = 0;
for (int j = 1; j <= i; j += 2)
{
Console.Write(i);
current = 10 * current + i;
}
Console.WriteLine();
sum += current;
}
Console.WriteLine("Summary: " + sum);
The main issue is that you were only capturing the value of i (integer being printed) and using that to calculate the summary. As seen here, the current value is captured (for the entire line) within the nested loop and then added to the summary to give you the result you expect.
HTH
Only made small adjustments to your code.
static void Main(string[] args)
{
int i, j;
i = 1;
int sum = 0;
while (i <= 9)
{
for (j = 0; j <= i - 1; j++)
{
Console.Write(i);
sum += i * (int)Math.Pow(10, j);
}
Console.WriteLine();
i++;
}
Console.WriteLine("Sum: " + sum);
Console.ReadLine();
}
If you like to extend your code to let the user pick a number you can do this:
Instead of this line:
while (i <= 9)
You can do this:
Console.WriteLine("Please enter a number between 1 and 9:");
int maxValue = 1;
while (true)
{
if (!int.TryParse(Console.ReadLine(), out maxValue) || maxValue < 1 || maxValue > 9)
{
Console.WriteLine("Wrong input! Try again:");
continue;
}
break;
}
while (i <= maxValue)
Please find not optimized but quick solution
int i, j;
i = 1;
int sum = 0;
while (i < 9)
{
int current = 0;
for (j = 1; j <= i; j += 2)
{
current = 10 * current + i;
Console.Write(i);
}
Console.Write("\n");
sum += current;
i++;
}
Console.WriteLine("Summary: " + sum);
Console.ReadLine();
Hi i am new to programming and i currently have this code:
namespace Patterns
{
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 4; i++)//'rows'
{
for (int h = 1; h <= 9 - (i*2)+1; h++)
{
Console.Write("#");
}
Console.WriteLine("\n" );
}
}
}
}
This produces this output:
########
######
####
##
the number of hashes is correct as i am going from 8, 6, 4, 2 but i need to add an extra space every time i go onto a new line. How do i make it so the output is as follows?
########
######
####
##
Thanks,
Umer
From your code you could modify it to do the following in the inner for loop:
for (int j = 0; j < i - 1; j++) {
Console.Write(" ");
}
for (int h = 1; h <= 9 - (i*2)+1; h++) {
Console.Write("#");
}
Console.WriteLine("\n" );
As a note you should probably use StringBuilder to do this as I believe it is quite inefficient to constantly call Console.WriteLine.
The code could be modified further:
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 4; i++) {
for (int j = 0; j < i - 1; j++) {
sb.append(" ");
}
for (int h = 1; h <= 9 - (i*2)+1; h++) {
sb.append("#");
}
sb.append("\n" );
}
Console.WriteLine(sb.toString());
Introduce variables, start your rows at 0 and repeat the string for each row number.
This can also be applied to the string printing the hashes:
static void Main(string[] args)
{
int rows = 4;
int columns = 9;
for (int i = 0; i < rows; i++)
{
// Print a string with `i` spaces.
Console.Write(new String(' ', i));
int hashes = columns - ((i + 1) * 2) + 1;
Console.Write(new String('#', hashes));
Console.WriteLine();
}
}
Basically, just add space in front of your hash characters.
######## Row 1 (i=1), 0 Space
###### Row 2 (i=2), 1 Space
#### Row 3 (i=3), 2 Spaces
## Row 4 (i=4), 3 Spaces
In this case, you need "i-1" spaces for each rows. (Actually, it's (8 - charater count) / 2) and character count was 9 - (i*2) + 1, so ( 8 - 9 + i * 2 - 1 ) / 2 = (i * 2 - 2) / 2 = i - 1 )
So just make loop to add spaces before print hash chracters.
namespace Patterns
{
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 4; i++)//'rows'
{
for (int j = 0; j < i -1; j++) {
Console.Write(" ");
}
for (int h = 1; h <= 9 - (i*2)+1; h++)
{
Console.Write("#");
}
Console.WriteLine("\n" );
}
}
}
}
You could do something like this:
for (int i = 1; i <= 4; i++)//'rows'
{
for (int h = 1; h <= 9 - (i*2)+1; h++)
{
Console.Write("#");
}
Console.WriteLine("\n" );
for (int y = i; y > 0; y--)
{
Console.Write(" ");
}
}
Hello everyone
I try to solve asterisk tree problem
and found my code is not work correctly and can be improved.
This is output that expected
input : 5
*
* * *
* * * * *
* * *
*
input : 4
* * * *
* *
* * * *
and this is my code
static void Main(string[] args)
{
Console.Write("input:");
char input = Console.ReadKey().KeyChar;
if (char.IsDigit(input))
{
int couter = (int)char.GetNumericValue(input);
Console.WriteLine();
if (couter % 2 != 0)
{
for (int i = 1; i <= couter; i++)
{
for (int j = 3; j > i; j--)
{
Console.Write(" ");
}
for (int k = 1; k <= i; k++)
{
Console.Write(" *");
}
Console.WriteLine();
}
for (int i = couter - 1; i >= 3; i--)
{
for (int j = 1; j <= i; j++)
{
if (j <= couter - i)
{
Console.Write(" ");
}
else
{
Console.Write("* ");
}
}
Console.WriteLine();
}
}
else
{
for (int i = couter; i > 3; i--)
{
for (int j = 1; j <= i; j++)
{
if (couter - i >= j)
{
Console.Write(" ");
}
else
{
Console.Write("* ");
}
}
Console.WriteLine();
}
for (int i = couter - 1; i <= couter; i++)
{
for (int j = 0; j < i; j++)
{
Console.Write("* ");
}
Console.WriteLine();
}
}
}
}
Please could you help me to solve this problem.
Lately, I think I'm poor at algorithms and a little complex problem. Is anybody know useful link or how I can improve this skill, please let me know.
Thanks,
Check this page for input 5 (diamond) : http://www.dreamincode.net/forums/topic/126715-diamond-asterisk/
I've translated it to C# - now it displays diamonds with size that you set in variable 'rows':
int rows = 5;
StringBuilder sb = new StringBuilder();
// top part
for (int i = 1; i <= rows; i++)
{
for (int j = 1; j <= rows - i; j++)
sb.Append(' ');
for (int k = 1; k <= 2 * i - 1; k++)
sb.Append('*');
sb.AppendLine();
}
//bottom part
for (int n = rows - 1; n > 0; n--)
{
for (int l = 1; l <= rows - n; l++)
sb.Append(' ');
for (int m = 1; m <= 2 * n - 1; m++)
sb.Append('*');
sb.AppendLine();
}
Console.Write(sb.ToString());
I was initially reluctant to post it because it definitely smells like homework...
Anyway, here's a piece of working code:
static void Main(string[] args)
{
Console.Write("input:");
char input = Console.ReadKey().KeyChar;
if (char.IsDigit(input))
{
int couter = (int)char.GetNumericValue(input);
Console.WriteLine();
if (couter % 2 != 0)
PrintDiamond(couter);
else
PrintHourGlass(couter);
}
Console.ReadLine();
}
private static void PrintDiamond(int couter)
{
bool moreAsterisks = true;
for (int row = 0; row < couter; row++)
{
int nAsterisks = moreAsterisks ? (2 * row) + 1 : 2 * (couter - row - 1) + 1;
int nSpaces = (couter - nAsterisks) / 2;
if (row == (couter - 1) / 2)
moreAsterisks = false;
for (int i = 0; i < nSpaces; i++)
Console.Write(" ");
for (int i = 0; i < nAsterisks; i++)
Console.Write("*");
for (int i = 0; i < nSpaces; i++)
Console.Write(" ");
Console.WriteLine();
}
}
private static void PrintHourGlass(int couter)
{
bool moreAsterisks = false;
for (int row = 0; row < couter - 1; row++)
{
int nAsterisks = moreAsterisks ? couter - 2 * (couter - row - 2) : couter - (2 * row);
int nSpaces = (couter - nAsterisks) / 2;
if (row == (couter - 2) / 2)
moreAsterisks = true;
for (int i = 0; i < nSpaces; i++)
Console.Write(" ");
for (int i = 0; i < nAsterisks; i++)
Console.Write("*");
for (int i = 0; i < nSpaces; i++)
Console.Write(" ");
Console.WriteLine();
}
}
P.S.:
it works with any number, not just 4-5...
Here's a minified LINQ solution for your problem:
class Program
{
static void Main(string[] args)
{
Console.Write("input: ");
string line = Console.ReadLine();
int n;
if (!int.TryParse(line, out n))
{
Console.WriteLine("Enter a valid integer number.");
return;
}
for (int i = 0; i < n; i++)
{
int l = Math.Abs(n - i * 2 - 1) + 1;
if (n % 2 != 0) l = n - l + 1;
Console.Write(Enumerable.Repeat(" ", n - l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
Console.WriteLine(Enumerable.Repeat("* ", l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
}
}
}
It's pretty simple; inside the loop, first line calculates length of the i-th diamond row if input is even, second one corrects the calculation for odd input. The remaining two lines print i-th row using some LINQ tricks. If you don't like showing off with LINQ, you can replace thoose lines with regular for loops (which is probably going to be faster). Then the code would look like:
class Program
{
static void Main(string[] args)
{
Console.Write("input: ");
string line = Console.ReadLine();
int n;
if (!int.TryParse(line, out n))
{
Console.WriteLine("Enter a valid integer number.");
return;
}
for (int i = 0; i < n; i++)
{
int l = Math.Abs(n - i * 2 - 1) + 1;
if (n % 2 != 0) l = n - l + 1;
//Console.Write(Enumerable.Repeat(" ", n - l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
//Console.WriteLine(Enumerable.Repeat("* ", l).DefaultIfEmpty("").Aggregate((a, b) => a + b));
for (int c = 0; c < n - l; c++) Console.Write(" ");
for (int c = 0; c < l; c++) Console.Write("* ");
Console.WriteLine();
}
}
}