I am looking for a output below with the input n and with number of loops less than (n*(n+1))/2 ,
Example N = 4,
1
2 3
4 5 6
7 8 9 10
Number of loops should be less than 10. Is this possible???
I am looking for a output below with the input n and with number of loops less than (n*(n+1))/2 ,
Example N = 4,
1
2 3
4 5 6
7 8 9 10
Number of loops should be less than 10. Is this possible???
There's also a solution with only one loop.
Print numbers in order, followed by a space, and if the last number was triangular, then print a newline. Keep track of how many newlines you have, and that's it.
Here's the code:
public static void PrintPyramid(int n)
{
var i = 0;
while (n > 0)
{
Console.Write(++i);
if (IsTriangularNumber(i))
{
Console.Write(Environment.NewLine);
n--;
}
else
{
Console.Write(" ");
}
}
}
public static bool IsTriangularNumber(int i)
{
var n = (int)Math.Sqrt(i*2);
return n*(n + 1) / 2 == i;
}
And here's how it works: http://ideone.com/Mx7Cel
For faster triangular number tests, see the answers to this question.
By cheating it is easy:
public static void PrintPyramid(int n)
{
int i = 1;
int row = 1;
int maxNumberInRow = 1;
int cycles = 0;
while (row <= n)
{
cycles++;
if (i == maxNumberInRow)
{
Console.Write(i);
Console.Write(" ");
i++;
}
else
{
Console.Write(i);
Console.Write(" ");
i++;
Console.Write(i);
Console.Write(" ");
i++;
}
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
}
}
Console.WriteLine();
Console.WriteLine("Cycles: {0}", cycles);
}
I did a little loop unrolling, doing up to two numbers in the same cycle. For n == 4
, it is 6 full cycles.
Note that if we want to play the semantic game, a partial loop unrolling is enough:
public static void PrintPyramid3(int n)
{
if (n >= 1)
{
Console.Write("1");
Console.Write(" ");
Console.WriteLine();
}
int i = 2;
int row = 2;
int maxNumberInRow = 3;
int cycles = 0;
while (row <= n)
{
cycles++;
Console.Write(i);
i++;
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
}
else
{
Console.Write(" ");
}
}
Console.WriteLine();
Console.WriteLine("Cycles: {0}", cycles);
}
The first row is "outside" the loop, so for n == 4
, only 9 cycles are necessary.
Based on this code, it is easy to partially loop unroll the first x
cases and do the remaining cases in a loop.
Ok... I was kidding... It is possible to do it in a totally loopless way...
public static void PrintPyramid(int n)
{
PrintPyramidRecursive(n, 1, 1, 1);
}
private static void PrintPyramidRecursive(int n, int i = 1, int row = 1, int maxNumberInRow = 1)
{
Console.Write(i);
Console.Write(" ");
i++;
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
if (row > n)
{
return;
}
}
PrintPyramidRecursive(n, i, row, maxNumberInRow);
}
You only need to use recursion! :-) :-) :-)
This one is a little more devious: no (apparent) cycles and no recursion:
public static void PrintPyramid5(int n)
{
int i = 1;
int row = 1;
int maxNumberInRow = 1;
ManualResetEvent mre = new ManualResetEvent(false);
Timer t = null;
TimerCallback tc = x =>
{
Console.Write(i);
Console.Write(" ");
i++;
if (i > maxNumberInRow)
{
Console.WriteLine();
row++;
maxNumberInRow += row;
if (row > n)
{
t.Dispose();
mre.Set();
}
}
};
t = new Timer(tc, null, 0, 1);
mre.WaitOne();
}
Simply put, the printing method is called by a Timer
:-) So the loop is in the operating system. The printing method (tc
) will clearly be called 10 times for n == 4
.
You could pretend that string.Join()
and Enumerable.Range()
don't do any looping internally, and do it like this:
int n = 4;
for (int i = 1, j = 1; i <= n; ++i, j += i-1)
Console.WriteLine(string.Join(" ", Enumerable.Range(j, i).Select(x => x.ToString("00"))));
The for
loop therefore only loops once per line rather than once per output number. But it's a cheat, because string.Join()
and Enumerable.Range()
do loop internally.
As per xanatos's suggestion, here's a version with no explicit loops at all:
Console.WriteLine(
string.Join("\n", Enumerable.Range(1, n).Select(i =>
string.Join(" ", Enumerable.Range((i*(i-1))/2+1, i).Select(x =>
x.ToString("00"))))));
This is a curiosity only, of course. ;)
Finally, here's a variant of xanatos's recursive solution:
private static string Triangular(int max, int row, int rowEnd, int number)
{
if (row == max)
return "";
else if (number <= rowEnd)
return number.ToString("00") + " " + Triangular(max, row, rowEnd, number + 1);
else
return "\n" + Triangular(max, row + 1, rowEnd + row + 1, number);
}
Which you'd use like this:
Console.WriteLine(Triangular(n, 1, 1, 1));
here i did your homework
public static void PrintPyramid(int n)
{
int t = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
Console.Write(t);
t++;
}
Console.WriteLine();
}
}