Checking to see the char equivalent of my int value - c#

Okay i might not have explained it to the best of my ability but i'm a beginner and i would like to make a piece of code that does this :
you have a string and you need to find each vowel in it and multiply each vowel's position in the string by its position in the alphabet and add all the sums together
example : steve: has 2 vowels the first e's position is 3 and its position in the alphabet is 5. and the second's position in the alphabet and the string is 5
so the sum is 5*3 + 5*5 = 40
this is what i did . idk what to do now or how to approach it
var vowels = new char[] {'a', 'e', 'i', 'o', 'u', 'y', 'A','E','I', 'O', 'U','Y'};
var chars = new List<char>();
List<int> indexes = new List<int>();
Console.WriteLine("Write something : ");
var input = Console.ReadLine();
int index;
foreach (var vowel in vowels)
{
if (input.Contains(vowel))
{
index = input.IndexOf(vowel);
indexes.Add(index + 1);
chars.Add(vowel);
}
}

Consider this approach:
using System;
using System.Linq;
using System.Collections.Generic;
namespace Whatever
{
class Program
{
static void Main(string[] args)
{
var vowels = new Dictionary<string, int>(5, StringComparer.OrdinalIgnoreCase) { { "a", 1 }, { "e", 5 }, { "i", 9 }, { "o", 15 }, { "u", 21 } };
Console.WriteLine("Write something : ");
var input = Console.ReadLine();
var sum = input.Select((value, index) => new { value, index })
.Sum(x =>
{
vowels.TryGetValue(x.value.ToString(), out var multiplier);
return (x.index + 1) * multiplier;
});
Console.ReadLine();
}
}
}
The Select projects the original string as an anonymous type with the char and its index included.
The Sum checks if the string is a vowel - and if it is it multiplies the position (index + 1) by the position in the alphabet (from vowels).
vowels is case insensitive so that "A" and "a" are treated the same.
If the compiler complains about the out var then use:
int multiplier = 0;
vowels.TryGetValue(x.value.ToString(), out multiplier);
return (x.index + 1) * multiplier;
instead.

i figured it out right here
for (int i = 0; i < indexes.Count; i++)
{
sumofone += indexes[i] * (char.ToUpper(chars[i]) - 64);
}

You can do this (Reference is from here):
var vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
Console.WriteLine("Write something : ");
var input = Console.ReadLine().ToLower();
int total = 0;
for (int temp = 1; temp <= input.Length; temp++)
{
if (vowels.Contains(input[temp - 1]))
{
total += temp * (char.ToUpper(input[temp -1]) - 64);
}
}
Console.WriteLine("The length is " + total);

Related

C# Convert Integer into Roman Numeral and Number in Words

I need a help because I've created a program wherein if the user inputs enter an integer number then it will convert the number into Roman Numerals and in Words. But here in my codes, it's only converting it into roman numerals. How can I include literal words of the user input integer into words below the roman numeral.
For example:
Enter a number: 1
Roman Numeral: I
Number in Words: One
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lab_Activity_2
{
internal class Program
{
static void Main(string[] args)
{
string[] units = { "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
string[] decs = { "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" };
string[] cents = { "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" };
string[] mills = { "", "M", "MM", "MMM" };
Console.WriteLine("Enter a number: ");
int n = int.Parse(Console.ReadLine());
if (!(n >= 1 && n <= 3999))
{
Console.WriteLine("Number not valid!");
return;
}
int m = n / 1000;
int mig = n % 1000;
int c = mig / 100;
mig = mig % 100;
int d = mig / 10;
mig = mig % 10;
int u = mig;
Console.WriteLine(mills.ElementAtOrDefault(m) + cents.ElementAtOrDefault(c) + decs.ElementAtOrDefault(d) + units.ElementAtOrDefault(u));
}
}
}
I tried to convert the numbers into roman numerals but I don't know how to code the literal words of an integer and where to put it.
Try following IntToRoman() and RomanToInt() APIs:
You can also find other solution via leetcode discussion tab :
https://leetcode.com/problems/integer-to-roman/
https://leetcode.com/problems/roman-to-integer/
/// 12. Integer to Roman
/// Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
/// I 1
/// V 5
/// X 10
/// L 50
/// C 100
/// D 500
/// M 1000
/// CM 900
/// CD 400
/// XC 90
/// XL 40
/// IX 9
/// IV 4
public string IntToRoman(int num)
{
if (num >= 1000) return "M" + IntToRoman(num - 1000);
if (num >= 900) return "CM" + IntToRoman(num - 900);
if (num >= 500) return "D" + IntToRoman(num - 500);
if (num >= 400) return "CD" + IntToRoman(num - 400);
if (num >= 100) return "C" + IntToRoman(num - 100);
if (num >= 90) return "XC" + IntToRoman(num - 90);
if (num >= 50) return "L" + IntToRoman(num - 50);
if (num >= 40) return "XL" + IntToRoman(num - 40);
if (num >= 10) return "X" + IntToRoman(num - 10);
if (num >= 9) return "IX" + IntToRoman(num - 9);
if (num >= 5) return "V" + IntToRoman(num - 5);
if (num >= 4) return "IV" + IntToRoman(num - 4);
if (num > 1) return "I" + IntToRoman(num - 1);
if (num == 1) return "I";
return string.Empty;
}
///13. Roman to Integer
///Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
///It is guaranteed that s is a valid roman numeral in the range [1, 3999]
public int RomanToInt(string s)
{
Dictionary<char, int> dictionary = new Dictionary<char, int>()
{
{ 'I', 1},
{ 'V', 5},
{ 'X', 10},
{ 'L', 50},
{ 'C', 100},
{ 'D', 500},
{ 'M', 1000}
};
int number = 0;
for (int i = 0; i < s.Length; i++)
{
if (i + 1 < s.Length && dictionary[s[i]] < dictionary[s[i + 1]])
{
number -= dictionary[s[i]];
}
else
{
number += dictionary[s[i]];
}
}
return number;
}

Counter goes down by 4 at the time instead of one (C#)

I am new at C# and after learning the basics I've decided that I wanna make a Hangman game. The problem is that a counter that normally counts down from 8 by 1 each time I miss a letter is counting down by 4 and I have no idea why.
static void Main(string[] args)
{
int Chances= 8;
bool key = false;
int N= 10;
char[] Word = { 'P', 'R', 'O', 'G', 'R', 'A', 'M' };
Console.WriteLine("The word is:_ _ _ _ _ _ _");
Console.Write("Please input a letter:");
while (key == false)
{
char letter = Convert.ToChar(Console.Read());
N = Numberofletter(letter);
Console.WriteLine(N);
while (N == 0 && Chances > 0)
{
Chances--;
Console.WriteLine("The letter is incorrect you have " + K + " tries Remaining");
letter = Convert.ToChar(Console.Read());
};
if (Chances == 0)
{
Console.WriteLine("Gameover");
return;
}
static int Numberofletter(char letter)
{
int N = 0;
char[] Word = { 'P', 'R', 'O', 'G', 'R', 'A', 'M' };
if (Word[0] == letter)
{ N = 1; }
else if (Word[1] == letter)
{ N = 2; }
else if (Word[2] == letter)
{ N = 3; }
else if (Word[3] == letter)
{ N = 4; }
else if (Word[5] == letter)
{ N = 6; }
else if (Word[6] == letter)
{ N = 7; }
else { N = 0; }
return N;
}
The problem is in your while loop.
You enter the loop with N = position of the guessed letter = 0.
INSIDE the loop, you ask for another letter, but NEVER calculate its position.
So even if the letter is in the word, you've never re-assigned the value of N. This means the loop will keep running and decrementing chances until chances < 0;
Simply add
N = Numberofletter(letter);
after you read in the next letter.
I don't know if anyone else will have the same problem as me but I will post my mistake here so at least I hope it will not be repeated
instead of letter=Convert.ToChar(Console.Read());
you should use letter=Convert.ToChar(Console.ReadLine());
i don't know why was that the problem but it happend try it out randomly and it worked

Why do I get a stack overflow exception in unmanaged error

The program needs to check if the array is palindrome using recursion, but I get stack overflow exception in unmanaged. Been stuck on it for over a day, please help
public static void Main(string[] args)
{
char[] arr = { 'd', 'a', 'd' };
int ind = 0;
Rowpalindrome(arr, ind);
}
static bool Rowpalindrome(char[] arr, int index)
{
if (index == arr.Length % 2)
return true;
int i = index;
if (arr[i] != arr[(arr.Length - index - 1)])
return false;
else
return Rowpalindrome(arr, index++);
}
You have error in the increment; it should be ++indexinstead of index++:
return Rowpalindrome(arr, ++index);
you should increment and pass modified value of index (++index), not increment and pass initial value (index++). Even better implementation is to put it simple:
return Rowpalindrome(arr, index + 1);
Edit: You have some logical errors as well (thanks to Fildor who's pointed it out): the condition should be
if (arr.Length <= 1 || index > arr.Length % 2 + 1)
return true;
The final recoursive code can be
static bool Rowpalindrome(char[] arr, int index) {
if (arr.Length <= 1 || index > arr.Length % 2 + 1)
return true;
// Let's get rid of "i" (which is index) and exploit short circuit of &&:
// .Net tests arr[index] != arr[(arr.Length - index - 1)]
// and only if it's true call for Rowpalindrome(arr, index + 1)
return arr[index] != arr[(arr.Length - index - 1)] && Rowpalindrome(arr, index + 1);
}
Test cases: (Let's use Linq to query for each test)
using System.Linq;
...
var tests = new char[][] {
new char[] { },
new char[] { 'a' },
new char[] { 'a', 'a' },
new char[] { 'a', 'b' },
new char[] { 'a', 'b', 'a' },
new char[] { 'a', 'b', 'c' },
new char[] { 'a', 'b', 'b', 'a' },
new char[] { 'a', 'b', 'c', 'a' },
new char[] { 'a', 'b', 'b', 'c' },
};
var result = tests
.Select(test => $"{"[" +string.Join(", ", test) + "]", -15} : {(Rowpalindrome(test, 0) ? "Palindrome" : "Not")}");
Console.Write(string.Join(Environment.NewLine, result));
Outcome:
[] : Palindrome
[a] : Palindrome
[a, a] : Palindrome
[a, b] : Not
[a, b, a] : Palindrome
[a, b, c] : Not
[a, b, b, a] : Palindrome
[a, b, c, a] : Not
[a, b, b, c] : Not
Edit 2: In case of multidimensional array (see comments below) you can extract column of interest into an array and run the routine, e.g. for 2D array:
char[,] c = new char[,] {
{ 'a', 'b', 'c'},
{ 'x', 'y', 'z'},
{ 'x', 'p', 'q'},
{ 'a', 'm', 'n'},
};
int colIndex = 0; // should be {'a', 'x', 'x', 'a'} column
// c.GetLength(0) - number of lines (length of the 1st dimension) - 4
char[] a = new char[c.GetLength(0)];
for (int i = 0; i < a.Length; ++i)
a[i] = c[i, colIndex];
bool result = Rowpalindrome(a, 0);

Best way to randomize two identical arrays without overlap?

Suppose we have two identical arrays {"A", "B", "C", "D", "E", "F"}. Is there a quick way to randomize the order of each that ensures when the two are lined up, the same letters are never at the same indices? (Obviously we can just generate a new index if it will cause a match but I'm wondering if there's a way that produces less repetition).
This works, and I think it is fairly easy to understand.
var source = new [] { "A", "B", "C", "D", "E", "F" };
var output1 = (string[])null;
var output2 = (string[])null;
var rnd = new Random();
Action shuffle = () =>
{
output1 = source.OrderBy(x => rnd.Next()).ToArray();
output2 = source.OrderBy(x => rnd.Next()).ToArray();
};
shuffle();
while (output1.Zip(output2, (o1, o2) => new { o1, o2 })
.Where(x => x.o1 == x.o2)
.Any())
{
shuffle();
}
You could do it in two steps with O(n) complexity.
[Step 1]
Shuffle just one array in a way that every letter changes its original position, something like this:
var rnd = new Random(0);
var x = new char[] { 'A', 'B', 'C', 'D', 'E', 'F' };
for(int i = 0; i < x.Length; i++)
{
var j0 = (i == x[i] - 'A')? i + 1: i;
var j = rnd.Next(j0, x.Length);
// x[i] ⟷ x[j]
var t = x[i]; x[i] = x[j]; x[j] = t;
}
It ensures that the first and the second arrays are different in every position.
[Step 2]
Use Fisher–Yates shuffle for both arrays synchronously:
var y = new char[] { 'A', 'B', 'C', 'D', 'E', 'F' };
for(int i = 0; i < x.Length; i++)
{
var j = rnd.Next(i, x.Length);
// x[i] ⟷ x[j]; y[i] ⟷ y[j]
var
t = x[i]; x[i] = x[j]; x[j] = t;
t = y[i]; y[i] = y[j]; y[j] = t;
}
It ensures randomization of both, keeping difference at every position.
My best advice would be to make your own randomizer method that takes 2 arguments: array to be shuffled and array that its not allowed to match.
Here is a quick example of a class that has 2 string arrays that it will be shuffling by calling (objectName).Shuffle();
public class ArrayShuffler {
public String[] arr1;
public String[] arr2;
public ArrayShuffler() {
arr1 = new String[] { "A", "B", "C", "D", "E", "F" };
arr2 = new String[] { "A", "B", "C", "D", "E", "F" };
}
public void Shuffle() {
shuffleArr(arr1);
shuffleArr(arr2, arr1);
}
/// <summary>
/// Can shuffle array, maching against a second array to prevent dublicates in same intex spot.
/// </summary>
/// <param name="arr">Array to be shuffled</param>
/// <param name="validate">Array to mach against</param>
private void shuffleArr(String[] arr, String[] validate = null) {
Random r = new Random();
int indx = 0;
while(indx < arr.Length){
int rIndx = r.Next(indx, arr.Length);
string tmp = arr[indx];
if(validate != null) { //Will only be performed if you specify an array to be matched against.
if(arr[rIndx] != validate[indx]) {
arr[indx] = arr[rIndx];
arr[rIndx] = tmp;
indx++;
}
else if(indx == arr.Length - 1) {
shuffleArr(arr, validate);
}
}
else { //Default operation
arr[indx] = arr[rIndx];
arr[rIndx] = tmp;
indx++;
}
}
}
}
Assuming you're trying to minimize the quantity of unnecessary re-rolls, and that it's the two results that must not match one another (permitting an output character at a particular index to match the character in the input at that index), I think I've got a solution for you.
The gist of it is that we build the resulting strings on-the-fly keeping track of which characters have not been picked in each list and temporarily removing the one we picked first for a particular index from the candidates we select from for the second one. I don't think this method has any bias to it, but I'm admittedly not an expert in that regard.
public void Shuffle(int seed)
{
char[] orig = { 'A', 'B', 'C', 'D', 'E', 'F' };
List<char> buffer1 = new List<char>();
List<char> buffer2 = new List<char>();
// Keep track of which indexes haven't yet been used in each buffer.
List<int> availableIndexes1 = new List<int>(orig.Length);
List<int> availableIndexes2 = new List<int>(orig.Length);
for (int i = 0; i < orig.Length; i++)
{
availableIndexes1.Add(i);
availableIndexes2.Add(i);
}
Random rand = new Random(seed);
// Treat the last 2 specially. See after the loop for details.
for (int i = 0; i < orig.Length - 2; i++)
{
// Choose an arbitrary available index for the first buffer.
int rand1 = rand.Next(availableIndexes1.Count);
int index1 = availableIndexes1[rand1];
// Temporarily remove that index from the available indices for the second buffer.
// We'll add it back in after if we removed it (note that it's not guaranteed to be there).
bool removed = availableIndexes2.Remove(index1);
int rand2 = rand.Next(availableIndexes2.Count);
int index2 = availableIndexes2[rand2];
if (removed)
{
availableIndexes2.Add(index1);
}
// Add the characters we selected at the corresponding indices to their respective buffers.
buffer1.Add(orig[index1]);
buffer2.Add(orig[index2]);
// Remove the indices we used from the pool.
availableIndexes1.RemoveAt(rand1);
availableIndexes2.RemoveAt(rand2);
}
// At this point, we have 2 characters remaining to add to each buffer. We have to be careful!
// If we didn't do anything special, then we'd end up with the last characters matching.
// So instead, we just flip up to a fixed number of coins to figure out the swaps that we need to do.
int secondToLastIndex1Desired = rand.Next(2);
int secondToLastIndex2Desired = rand.Next(2);
// If the "desired" (i.e., randomly chosen) orders for the last two items in each buffer would clash...
if (availableIndexes1[secondToLastIndex1Desired] == availableIndexes1[secondToLastIndex2Desired] ||
availableIndexes1[(secondToLastIndex1Desired + 1) % 2] == availableIndexes2[(secondToLastIndex2Desired + 1) % 2])
{
// ...then swap the relative order of the last two elements in one of the two buffers.
// The buffer whose elements we swap is also chosen at random.
if (rand.Next(2) == 0)
{
secondToLastIndex1Desired = (secondToLastIndex1Desired + 1) % 2;
}
else
{
secondToLastIndex2Desired = (secondToLastIndex2Desired + 1) % 2;
}
}
else if (rand.Next(2) == 0)
{
// Swap the last two elements in half of all cases where there's no clash to remove an affinity
// that the last element has for the last index of the output, and an affinity that the first
// element has for the second-to-last index of the output.
int t = secondToLastIndex1Desired;
secondToLastIndex1Desired = secondToLastIndex2Desired;
secondToLastIndex2Desired = t;
}
buffer1.Add(orig[availableIndexes1[secondToLastIndex1Desired]]);
buffer1.Add(orig[availableIndexes1[(secondToLastIndex1Desired + 1) % 2]]);
buffer2.Add(orig[availableIndexes2[secondToLastIndex2Desired]]);
buffer2.Add(orig[availableIndexes2[(secondToLastIndex2Desired + 1) % 2]]);
Console.WriteLine(new string(buffer1.ToArray()));
Console.WriteLine(new string(buffer2.ToArray()));
}
Note that if this were used for particularly long arrays, then the data moving from List<T>.Remove / List<T>.RemoveAt and the linear searching done by the former may not scale well.

Increment an index that uses numbers and characters (aka Base36 numbers)

I have a string based code that can be either two or three characters in length and I am looking for some help in creating a function that will increment it.
Each 'digit' of the code has a value of 0 to 9 and A to Z.
some examples:
the first code in the sequence is 000
009 - next code is - 00A
00D - next code is - 00E
AAZ - next code is - AB0
the last code is ZZZ.
Hope this makes some sense.
Thanks for the advice guys.
This is what I independently came up with.
private static String Increment(String s)
{
String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char lastChar = s[s.Length - 1];
string fragment = s.Substring(0, s.Length - 1);
if (chars.IndexOf(lastChar) < 35)
{
lastChar = chars[chars.IndexOf(lastChar) + 1];
return fragment + lastChar;
}
return Increment(fragment) + '0';
}
I don't know if it is better/worse but seems to work. If anyone can suggest improvements then that is great.
Maintain the counter as an int and increment this. Convert the int to your character representation by modding and dividing by 36 iterativly. Map the modded range (0-35) to 0-Z.
Example
Updated with functions to go in either direction:
internal class Program
{
const int Base = 36;
public static void Main()
{
Console.WriteLine(ToInt("0AA"));
Console.WriteLine(ToString(370));
}
private static string ToString(int counter)
{
List<char> chars = new List<char>();
do
{
int c = (counter % Base);
char ascii = (char)(c + (c < 10 ? 48 : 55));
chars.Add(ascii);
}
while ((counter /= Base) != 0);
chars.Reverse();
string charCounter = new string(chars.ToArray()).PadLeft(3, '0');
return charCounter;
}
private static int ToInt(string charCounter)
{
var chars = charCounter.ToCharArray();
int counter = 0;
for (int i = (chars.Length - 1), j = 0; i >= 0; i--, j++)
{
int chr = chars[i];
int value = (chr - (chr > 57 ? 55 : 48)) * (int)Math.Pow(Base, j);
counter += value;
}
return counter;
}
For more variants of conversion code see Quickest way to convert a base 10 number to any base in .NET?.
Does this do what you need?
public class LetterCounter
{
private static readonly string[] _charactersByIndex = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
public string GetStr(int i)
{
if (i < _charactersByIndex.Length)
return _charactersByIndex[i];
int x = i / (_charactersByIndex.Length - 1) - 1;
string a = _charactersByIndex[x];
string b = GetStr(i - (_charactersByIndex.Length - 1));
return a + b;
}
}
}
Based on #Martin answer, I found some error when two ZZ comes, this makes exception in code
private static String Increment(String s,bool IsFromRecursion=false)
{
String chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//Added this condition
if (IsFromRecursion && string.IsNullOrEmpty(number))
{
return "1";
}
//Added this condition
char lastChar = s[s.Length - 1];
string fragment = s.Substring(0, s.Length - 1);
if (chars.IndexOf(lastChar) < 35)
{
lastChar = chars[chars.IndexOf(lastChar) + 1];
return fragment + lastChar;
}
return Increment(fragment,true) + '0';
}
When we call this method we pass first parameter only.

Categories

Resources