Specific Odd Numbered Inverted Triangle Question in C# - c#

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

Related

Unicode have different width when printing

I am developing a chess engine in C#/Unity and want to print the board on a nice format. Preferably I want to print with some Unicode pieces but they end up making the board uneven, see image below:
The same seems to go for normal numbers since each row starts slightly off one another, row 1 starts more left than the others for example.
Why does my Debug.Log/prints end up like this, and how can I print them so that each character takes up the same amount of space?
EDIT:
Here is the code I use to Debug.Log the board if that helps:
public static void PrintBitboard(ulong bitboard)
{
string zero = " 0 ";
string one = " 1 ";
string printString = "";
// Loop through all squares and print a 1 if piece and 0 if not a piece on the square
for (int row = 0; row < 8; row++)
{
// Add numbering on the left side
printString += (8 - row) + " ";
for (int col = 0; col < 8; col++)
{
int currentSquare = row * 8 + col;
printString += BitOperations.GetBit(bitboard, currentSquare) != 0 ? one : zero;
}
// Change to new row
printString += "\n";
}
// Print bottom letters
printString += "\n" + " a b c d e f g h";
// Send message to the console
Debug.Log(printString);
}
What you are looking for is not "unicode" but monospace
-> As GiacomoCatenazzi already said, the only thing responsible for that is the font you are using
As a "quick and dirty" fix / alternative you could try and simply use tabs (\t) instead of spaces like (in general for larger string based concatenations I would recommend to use a StringBuider)
public static void PrintBitboard(ulong bitboard)
{
const string zero = "0\t";
const string one = "1\t";
var stringBuilder = new StringBuilder();
// Loop through all squares and print a 1 if piece and 0 if not a piece on the square
for (int row = 0; row < 8; row++)
{
// Add numbering on the left side
stringBuilder.Append((8 - row)).Append('\t');
for (int col = 0; col < 8; col++)
{
int currentSquare = row * 8 + col;
stringBuilder.Append(BitOperations.GetBit(bitboard, currentSquare) != 0 ? one : zero);
}
// Change to new row
stringBuilder.Append('\n');
}
// Print bottom letters
stringBuilder.Append("\n \ta\tb\tc\td\te\tf\tg\th");
// Send message to the console
Debug.Log(stringBuilder.ToString());
}
See .Net Fiddle which in the Unity console would look like
(in both I had to tricks a bit since I don't know what BitOperations implementation you are using)

Obtain the lexicographically smallest string possible, by using at most P points

⦁ Replace and/or re-arrange characters of this given string to get the lexicographically smallest string possible. For this, you can perform the following two operations any number of times.
⦁ Swap any two characters in the string. This operation costs 1 point. (any two, need not be adjacent)
⦁ Replace a character in the string with any other lower case English letter. This operation costs 2 points.
Obtain the lexicographically smallest string possible, by using at most P points.
Input:
⦁ Two lines of input, first-line containing two integers N, P.
⦁ The second line contains a string S consisting of N characters.
Output:
Lexicographically smallest string obtained.
for e.g
Sample Input:
3 3
bba
Sample Output:
aab
Ive tried this but it doesnt contain P points i dont know how to do that can you guys please help me with that:
namespace Lexicographical
{
class GFG
{
// Function to return the lexicographically
// smallest String that can be formed by
// swapping at most one character.
// The characters might not necessarily
// be adjacent.
static String findSmallest(char[] s)
{
int len = s.Length;
// Store last occurrence of every character
int[] loccur = new int[26];
// Set -1 as default for every character.
for (int i = 0; i < 26; i++)
loccur[i] = -1;
for (int i = len - 1; i >= 0; --i)
{
// char index to fill
// in the last occurrence array
int chI = s[i] - 'a';
if (loccur[chI] == -1)
{
// If this is true then this
// character is being visited
// for the first time from the last
// Thus last occurrence of this
// character is stored in this index
loccur[chI] = i;
}
}
char[] sorted_s = s;
Array.Sort(sorted_s);
for (int i = 0; i < len; ++i)
{
if (s[i] != sorted_s[i])
{
// char to replace
int chI = sorted_s[i] - 'a';
// Find the last occurrence
// of this character.
int last_occ = loccur[chI];
// Swap this with the last occurrence
char temp = s[last_occ];
s[last_occ] = s[i];
s[i] = temp;
break;
}
}
return String.Join("", s);
}
// Driver code
public static void Main(String[] args)
{
String s = "abb";
Console.Write(findSmallest(s.ToCharArray()));
}
}
}
The output for this is abb but it should be aab...
I want to know how i can use above Question in this

How to generate a number from first or last digits of an array and check if it is divisible by a certain number in C#?

I am a beginner in C# and I am struck with this problem. To question is as follows
You are given an array of size n that contains integers. Here, n is an even number. You are required to perform the following operations:
1. Divide the array of numbers in two equal halves
Note: Here, two equal parts of a test case are created by dividing the array into two equal parts.
2. Take the first digit of the numbers that are available in the first half of the array (first 50% of
the test case)
3. Take the last digit of the numbers that are available in the second half of the array (second 50% of
the test case)
4. Generate a number by using the digits that have been selected in the above steps
Your task is to determine whether the newly-generated number is divisible by 11.
And this is my code-
using System;
namespace IsDivisible
{
class Program
{
static void Main(string[] args)
{
int n = Convert.ToInt32(Console.ReadLine());
int div = 0, digit;
string str = " ";
string[] numArray = Console.ReadLine().Split(' ');
int[] arr = new int[n];
for (int i = 0; i < n; i++)
{
arr[i] = Convert.ToInt32(str[i]);
if (i <= n / 2)
{
while (arr[i] >= 10)
{
div = arr[i] / 10;
}
str += div;
}
else
{
digit = arr[i] % 10;
str += digit;
}
}
long newNumber = Convert.ToInt64(str);
if (newNumber % 11 == 0)
Console.WriteLine("YES");
else
Console.WriteLine("NO");
Console.Read();
}
}
}```
It has no errors during compile time in visual studio. The code is not printing anything after I input the array and I am unable to figure out what's wrong. Please help.

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

Masking all characters of a string except for the last n characters

I want to know how can I replace a character of a string with condition of "except last number characters"?
Example:
string = "4111111111111111";
And I want to make it that
new_string = "XXXXXXXXXXXXX1111"
In this example I replace the character to "X" except the last 4 characters.
How can I possibly achieve this?
Would that suit you?
var input = "4111111111111111";
var length = input.Length;
var result = new String('X', length - 4) + input.Substring(length - 4);
Console.WriteLine(result);
// Ouput: XXXXXXXXXXXX1111
How about something like...
new_string = new String('X', YourString.Length - 4)
+ YourString.Substring(YourString.Length - 4);
create a new string based on the length of the current string -4 and just have it all "X"s. Then add on the last 4 characters of the original string
Here's a way to think through it. Call the last number characters to leave n:
How many characters will be replaced by X? The length of the string minus n.
How can we replace characters with other characters? You can't directly modify a string, but you can build a new one.
How to get the last n characters from the original string? There's a couple ways to do this, but the simplest is probably Substring, which allows us to grab part of a string by specifying the starting point and optionally the ending point.
So it would look something like this (where n is the number of characters to leave from the original, and str is the original string - string can't be the name of your variable because it's a reserved keyword):
// 2. Start with a blank string
var new_string = "";
// 1. Replace first Length - n characters with X
for (var i = 0; i < str.Length - n; i++)
new_string += "X";
// 3. Add in the last n characters from original string.
new_string += str.Substring(str.Length - n);
This might be a little Overkill for your ask. But here is a quick extension method that does this.
it defaults to using x as the masking Char but can be changed with an optional char
public static class Masking
{
public static string MaskAllButLast(this string input, int charsToDisplay, char maskingChar = 'x')
{
int charsToMask = input.Length - charsToDisplay;
return charsToMask > 0 ? $"{new string(maskingChar, charsToMask)}{input.Substring(charsToMask)}" : input;
}
}
Here a unit tests to prove it works
using Xunit;
namespace Tests
{
public class MaskingTest
{
[Theory]
[InlineData("ThisIsATest", 4, 'x', "xxxxxxxTest")]
[InlineData("Test", 4, null, "Test")]
[InlineData("ThisIsATest", 4, '*', "*******Test")]
[InlineData("Test", 16, 'x', "Test")]
[InlineData("Test", 0, 'y', "yyyy")]
public void Testing_Masking(string input, int charToDisplay, char maskingChar, string expected)
{
//Act
string actual = input.MaskAllButLast(charToDisplay, maskingChar);
//Assert
Assert.Equal(expected, actual);
}
}
}
StringBuilder sb = new StringBuilder();
Char[] stringChar = string.toCharArray();
for(int x = 0; x < stringChar.length-4; x++){
sb.append(stringChar[x]);
}
sb.append(string.substring(string.length()-4));
string = sb.toString();
I guess you could use Select with index
string input = "4111111111111111";
string new_string = new string(input.Select((c, i) => i < input.Length - 4 ? 'X' : c).ToArray());
Some of the other concise answers here did not account for strings less than n characters. Here's my take:
var length = input.Length;
input = length > 4 ? new String('*', length - 4) + input.Substring(length - 4) : input;
lui,
Please Try this one...
string dispString = DisplayString("4111111111111111", 4);
Create One function with pass original string and no of digit.
public string DisplayString(string strOriginal,int lastDigit)
{
string strResult = new String('X', strOriginal.Length - lastDigit) + strOriginal.Substring(strOriginal.Length - lastDigit);
return strResult;
}
May be help you....
Try this:
String maskedString = "...."+ (testString.substring(testString.length() - 4, testString.length()));
Late to the party but I also wanted to mask all but the last 'x' characters, but only mask numbers or letters so that any - ( ), other formatting, etc would still be shown. Here's my quick extension method that does this - hopefully it helps someone. I started with the example from Luke Hammer, then changed the guts to fit my needs.
public static string MaskOnlyChars(this string input, int charsToDisplay, char maskingChar = 'x')
{
StringBuilder sbOutput = new StringBuilder();
int intMaskCount = input.Length - charsToDisplay;
if (intMaskCount > 0) //only mask if string is longer than requested unmasked chars
{
for (var intloop = 0; intloop < input.Length; intloop++)
{
char charCurr = Char.Parse(input.Substring(intloop, 1));
byte[] charByte = Encoding.ASCII.GetBytes(charCurr.ToString());
int intCurrAscii = charByte[0];
if (intloop <= (intMaskCount - 1))
{
switch (intCurrAscii)
{
case int n when (n >= 48 && n <= 57):
//0-9
sbOutput.Append(maskingChar);
break;
case int n when (n >= 65 && n <= 90):
//A-Z
sbOutput.Append(maskingChar);
break;
case int n when (n >= 97 && n <= 122):
//a-z
sbOutput.Append(maskingChar);
break;
default:
//Leave other characters unmasked
sbOutput.Append(charCurr);
break;
}
}
else
{
//Characters at end to remain unmasked
sbOutput.Append(charCurr);
}
}
}
else
{
//if not enough characters to mask, show unaltered input
return input;
}
return sbOutput.ToString();
}

Categories