Why do I get a stack overflow exception in unmanaged error - c#

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

Related

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

rewrite c# Stopwatch to c++

I'm rewriting this stopwatch code from C# to C++.
I have rewritten some of the code (I can attach it if you think it's helpful) but confused about the lines after var watch = Stopwatch.StartNew(). Does C++ have similar things like this? What kind of variable type should I put for watch in C++?
namespace BruteForcePasswordGeneration
{
class Program
{
static void Main(string[] args)
{
char[] chars = { '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'};
int passwordLength=0;
Console.WriteLine("Enter the password length");
passwordLength = Convert.ToInt32(Console.ReadLine());
BigInteger iPossibilities = (BigInteger)Math.Pow((double)chars.Length, (double)passwordLength);
Console.WriteLine("{0} words total. Press enter to continue;", iPossibilities);
Console.ReadLine();
var watch = Stopwatch.StartNew();
for (BigInteger i = 0; i < iPossibilities; i++)
{
string theword = "";
BigInteger val = i;
for (int j = 0; j < passwordLength; j++)
{
BigInteger ch = val % chars.Length;
theword = chars[(int)ch] + theword;
val = val / chars.Length;
}
Console.WriteLine(theword);
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("It took {0} seconds to generate {1} possible combinations", elapsedMs / 1000, iPossibilities);
Console.ReadLine();
}
}
}
Although you can write a "stopwatch" class in C++ if you want, the usual is to just use high_resolution_clock::now() to get the start and stop times. You then use duration_cast to get the difference in the form you want.
If you'll forgive me, I don't see any real point in requiring the user to enter the password length after starting the program. At least to me, it seems easier to use something like "gen_passwords 4" to generate all the passwords of length 4.
That gives code something on this general order:
#include <iostream>
#include <chrono>
#include <string>
int main(int argc, char **argv) {
static const std::string chars{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
if (argc != 2) {
std::cerr << "Usage: generate <password length>\n";
return EXIT_FAILURE;
}
int passwordLength = std::stoi(argv[1]);
unsigned long long iPossibilities = std::pow(chars.size(), passwordLength);
using namespace std::chrono;
auto start = high_resolution_clock::now();
for (unsigned long long i = 0; i < iPossibilities; i++) {
std::string theword;
unsigned long long val = i;
for (int j = 0; j < passwordLength; j++) {
size_t ch = val % chars.size();
theword = chars[ch] + theword;
val /= chars.size();
}
std::cout << theword << '\n';
}
auto stop = high_resolution_clock::now();
double elapsed = duration_cast<milliseconds>(stop - start).count() / 1000.0;
std::cerr << "It took " << elapsed << " seconds to generate " << iPossibilities << " combinations\n";
}

Checking to see the char equivalent of my int value

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

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.

How to print a diamond shape composed of letters? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I want to learn how can I print diamond as follows: I am beginner, so many many thanks for Help
Given a letter print a diamond starting with 'A'
with the supplied letter at the widest point.
For example: print-diamond 'E' prints
A
B B
C C
D D
E E
D D
C C
B B
A
For example: print-diamond 'C' prints
A
B B
C C
B B
A
Actually, your code has two errors (I'm not considering efficiency of your code and algorhims).
First: when you are constructing diamond, for-loop should be not for (int i = 0; i < letter_number + i; i++) but for (int i = 0; i <= letter_number; i++).
Second: when you are drawing diamond - variable j should be placed out of loop, and you should use WriteLine instead of Write.
For example, drawing part of your code can be something like this:
Console.WriteLine();
int jj = 1;
for (int i = 0; i < 2 * letter_number + 1; i++)
{
if (i < letter_number + 1)
Console.WriteLine(diamond[i]);
else
{
Console.WriteLine(diamond[i - 2 * jj]);
jj++;
}
}
Side note: int letter_number; should be initialized as int letter_number = 0; or something like this, because you are assigning it's value under condition and not in every case later in the code, and actually code you've provided even don't compile without this explicit initialization.
Try this. Tested working.
using System;
namespace ConsoleApplication
{
internal class Program
{
private static void Main(string[] args)
{
char[] letter = new char[26]
{
'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'
};
int letter_number = 0;
//array of strings
string[] diamond = new string[52];
//get the letter
Console.WriteLine("User enters a Letter between A and Z ");
char user_letter = Console.ReadKey().KeyChar;
Console.WriteLine("");
//search for letter number in the array letter
for (int i = 0; i < letter.Length; i++)
{
if (letter[i] == user_letter)
{
letter_number = i;
break;
}
}
//construct diamond
for (int i = 0; i <= letter_number; i++)
{
//add initial spaces
for (int j = 0; j < letter_number - i; j++)
{
diamond[i] += " ";
}
//add letter (first time)
diamond[i] += letter[i];
//add space between letters
if (letter[i] != 'A')
{
for (int j = 0; j < 2*i - 1; j++)
{
diamond[i] += " ";
}
//add letter (second time)
diamond[i] += letter[i];
}
// Draw the first part of the diamond as it's composing.
Console.WriteLine(diamond[i]);
}
for (int i = letter_number - 1; i >= 0; i--)
{
// Draw the second part of the diamond
// Writing the diamondArray in reverse order.
Console.WriteLine(diamond[i]);
}
// Mark a pause
Console.ReadKey();
}
}
}
Output :
User enters a Letter between A and Z
K
A
B B
C C
D D
E E
F F
G G
H H
I I
J J
K K
J J
I I
H H
G G
F F
E E
D D
C C
B B
A

Categories

Resources