so I'm making an Anagram Decoder, and basically, it goes through, picks a unique version of the anagram, and then it adds it to a list and clears it. That way, when it runs through again, if it tries to make that word, it loops back through and tries again. However, when it gets to the end, it adds onto the previous string.
By this I mean if the string was "hey", the first time it might do "yeh", and the second time it'd do "yehhye". It adds on the new one to the end of the last one. This doesn't make sense though since I clear the variables that would store that (except for the one that stores the before anagrams).
Here's the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Anagram_Decoder {
class Program {
static void Main(string[] args) {
Random random = new Random();
// Create string, count it, and split it
string anagram = "hey";
int anagramLength = anagram.Length;
int result = anagramLength;
// Find possibilities
for (int i = 1; i < anagramLength; i++) {
result = result * i;
}
int anagramPossibilities = result;
List<string> anagramsFound = new List<string>();
char[] anagramSplit = anagram.ToCharArray();
int[] numbers = new int[anagram.Length];
for (int l = 0; l < anagramPossibilities; l++) {
string endResult = "";
bool failed = false;
while (true) {
numbers = new int[anagram.Length];
for (int i = 0; i < anagram.Length; i++) {
while (true) {
System.Threading.Thread.Sleep(15);
int randomNumber = random.Next(1, anagram.Length + 1);
foreach (int n in numbers) {
if (n == randomNumber && failed == false) {
failed = true;
}
}
if (failed == true) {
failed = false;
continue;
}
else {
numbers[i] = randomNumber;
endResult += randomNumber;
break;
}
}
}
numbers = new int[anagram.Length];
failed = false;
char[] endResultChars = endResult.ToCharArray();
string finalResult = "";
foreach (char i in endResultChars) {
finalResult += anagram[Convert.ToInt32(Convert.ToString(i)) - 1];
}
foreach (string n in anagramsFound) {
if (n == finalResult && failed == false) {
failed = true;
}
}
if (failed == true) {
failed = false;
continue;
}
else {
anagramsFound.Add(finalResult);
finalResult = "";
Console.ReadKey();
}
}
}
Console.ReadKey();
}
}
}
Related
I'm preparing for my interview, faced the problem with the task. The case is that we're having a string:
test12pop90java989python
I need to return new string where words will be reversed and numbers will stay in the same place:
test12pop90java989python ==> tset12pop90avaj989nohtyp
What I started with:
Transferring string to char array
Use for loop + Char.IsNumber
??
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
....
}
}
but currently I'm stuck and don't know how to proceed, any tips how it can be done?
You can't reverse a run of letters until you've observed the entire run; until then, you need to keep track of the pending letters to be reversed and appended to the final output upon encountering a number or the end of the string. By storing these pending characters in a Stack<> they are naturally returned in the reverse order they were added.
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
Stack<char> pending = new Stack<char>();
foreach (char c in input)
if (char.IsNumber(c))
{
// In the reverse order of which they were added, consume
// and append pending characters as long as they are available
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
// Alternatively...
//foreach (char p in pending)
// outputBuilder.Append(p);
//pending.Clear();
outputBuilder.Append(c);
}
else
pending.Push(c);
// Handle pending characters when input does not end with a number
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
return outputBuilder.ToString();
}
A similar but buffer-free way is to do it is to store the index of the start of the current run of letters, then walk back through and append each character when a number is found...
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
int lettersStartIndex = -1;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (char.IsNumber(c))
{
if (lettersStartIndex >= 0)
{
// Iterate backwards from the previous character to the start of the run
for (int j = i - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
lettersStartIndex = -1;
}
outputBuilder.Append(c);
}
else if (lettersStartIndex < 0)
lettersStartIndex = i;
}
// Handle remaining characters when input does not end with a number
if (lettersStartIndex >= 0)
for (int j = input.Length - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
return outputBuilder.ToString();
}
For both implementations, calling Transform() with...
string[] inputs = new string[] {
"test12pop90java989python",
"123test12pop90java989python321",
"This text contains no numbers",
"1a2b3c"
};
for (int i = 0; i < inputs.Length; i++)
{
string input = inputs[i];
string output = Transform(input);
Console.WriteLine($" Input[{i}]: \"{input }\"");
Console.WriteLine($"Output[{i}]: \"{output}\"");
Console.WriteLine();
}
...produces this output...
Input[0]: "test12pop90java989python"
Output[0]: "tset12pop90avaj989nohtyp"
Input[1]: "123test12pop90java989python321"
Output[1]: "123tset12pop90avaj989nohtyp321"
Input[2]: "This text contains no numbers"
Output[2]: "srebmun on sniatnoc txet sihT"
Input[3]: "1a2b3c"
Output[3]: "1a2b3c"
A possible solution using Regex and Linq:
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
var result = "";
var matchList = Regex.Matches("test12pop90java989python", "([a-zA-Z]*)(\\d*)");
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
foreach (var el in list)
{
if (el.All(char.IsDigit))
{
result += el;
}
else
{
result += new string(el.Reverse().ToArray());
}
}
Console.WriteLine(result);
}
}
I've used code from stackoverflow.com/a/21123574/1037948 to create a list of Regex matches on line 11:
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
Hey you can do something like:
string test = "test12pop90java989python", tempStr = "", finalstr = "";
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
tempStr += charArray[i];
}
else
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
finalstr += charArray[i];
}
}
if(tempStr != "" && tempStr != null)
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
}
I hope this helps
I'm solving Kattis' bokforing problem and one of the test cases fails due to execution time being too long (> 2 sec). Can anyone give me any advice on how I can improve?
class Program
{
static void Main(string[] args)
{
/* Inputs
3 5
SET 1 7
PRINT 1
PRINT 2
RESTART 33
PRINT 1
*/
string first = Console.ReadLine();
int N = Convert.ToInt32(first.Split(" ")[0]);
int Q = Convert.ToInt32(first.Split(" ")[1]);
int[] Accounts = new int[N];
string[] Operations = new string[Q];
for (int i = 0; i < Operations.Length; i++)
{
Operations[i] = Console.ReadLine();
}
for (int i = 0; i < Operations.Length; i++)
{
string[] op = Operations[i].Split(" ");
string operation = op[0];
int accountId = 0;
int ammont = 0;
if (operation == "SET")
{
accountId = Convert.ToInt32(op[1]);
ammont = Convert.ToInt16(op[2]);
Accounts[accountId - 1] = ammont;
}
if (operation == "PRINT")
{
accountId = Convert.ToInt32(op[1]);
Console.WriteLine(Accounts[accountId - 1]);
}
if (operation == "RESTART")
{
ammont = Convert.ToInt16(op[1]);
for (int j = 0; j <= N - 1; j++)
{
Accounts[j] = ammont;
}
}
}
}
}
First of all I copied recommended IO classes from FAQ to the solution, removed double loop (there is no need to loop twice - reading inputs first and then processing them) and then the main trick was to use Dictionary instead of array so there is no need to manually clear it/set amount to all items in it every time:
var scanner = new Scanner();
using(var writer = new BufferedStdoutWriter())
{
var N = scanner.NextInt();
var Q = scanner.NextInt();
var amount = 0;
var Accounts = new Dictionary<int, int>();
for (var i = 0; i < Q; i++)
{
var s = scanner.Next();
var accountId = 0;
if (s == "SET")
{
accountId = scanner.NextInt();
Accounts[accountId] = scanner.NextInt();
}
else if (s == "PRINT")
{
accountId = scanner.NextInt();
if (!Accounts.TryGetValue(accountId, out var value))
{
value = amount;
}
writer.WriteLine(value);
}
else if (s == "RESTART")
{
amount = scanner.NextInt();
Accounts = new Dictionary<int, int>();
}
}
}
I am currently trying to make a random password generator.
My code works fine if I only pick one type of symbols.
What's the best way to make my code to word for more than one type?
Also what parameters would you add to make the password more secured?
I am thinking of adding an if loop to check if there are more than two same letters, symbols or numbers in a row.
That's how my interface looks like:
and that is my code:
public partial class Form1 : Form
{
// Max number of identical characters in a row
const int Maximum_Identical = 2;
// lower case chars
const string lower_chars = "abcdefghijklmnopqrstuvwxyz";
// capital chars
const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// numbers
const string numbers = "0123456789";
// symbols
const string symbols = #"!#$%&*#\";
// password lenght
int lenght;
private void button1_Click(object sender, EventArgs e)
{
//use stringbuilder so I can add more chars later
StringBuilder password = new StringBuilder();
//take max lenght from numericUpDown
lenght = Convert.ToInt32(numericUpDown1.Value);
// random instance so I can use Next and don't get loops
Random rdm = new Random();
if (small_letters__Box.Checked)
{
//add a random small character to pass untill it reaches the selected lenght
while (lenght-- > 0 )
{
password.Append(lower_chars[rdm.Next(lower_chars.Length)]);
}
}
if (capital_letters__Box.Checked)
{
//add a random capital character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(capital_chars[rdm.Next(capital_chars.Length)]);
}
}
if (numbers_Box.Checked)
{
//add a random character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(numbers[rdm.Next(numbers.Length)]);
}
}
if (symbols_Box.Checked)
{
//add a random character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(symbols[rdm.Next(symbols.Length)]);
}
}
textBox1.Text = password.ToString();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
}
Your password generation has 2 steps.
Determine the character set
Create a password randomly from the character set of length n
Function 1 creates the character set:
// Make sure you have using System.Linq;
private List<char> GetCharacterSet()
{
IEnumerable<char> returnSet = new char[]{};
if (small_letters__Box.Checked)
{
returnSet = returnSet.Append(lower_chars);
}
if (capital_letters__Box.Checked)
{
returnSet = returnSet.Append(capital_chars);
}
if (numbers_Box.Checked)
{
returnSet = returnSet.Append(numbers);
}
if (symbols_Box.Checked)
{
returnSet = returnSet.Append(symbols);
}
return returnSet.ToList();
}
Function 2 creates a password of given length from your character set
private string GetPassword(int length, List<char> characterSet)
{
if(characterSet.Count < 1)
{
throw new ArgumentException("characterSet contains no items!");
}
if(length < 1)
{
return "";
}
Random rdm = new Random();
StringBuilder password = new StringBuilder();
for(int i = 0; i < length; i++){
int charIndex = rdm.Next(0, characterSet.Count)
password.Append(characterSet[charIndex]);
}
return password.ToString();
}
Then simply rig your button click event handler to call these functions and display the resulting password.
below code is my already written code which I wrote more than a couple of years ago and I still use it in my many of my projects where needed, it covers all you are in need of
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;
public static class ArrayExtentions
{
public static object[] Shuffle(this object[] array)
{
var alreadySwaped = new HashSet<Tuple<int, int>>();
var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(array.Length / 4), Convert.ToInt32((array.Length / 2) + 1));
for (var i = 0; i <= rndLoopCount; i++)
{
int rndIndex1 = 0, rndIndex2 = 0;
do
{
rndIndex1 = RandomUtils.GetRandom(0, array.Length);
rndIndex2 = RandomUtils.GetRandom(0, array.Length);
} while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));
alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
var swappingItem = array[rndIndex1];
array[rndIndex1] = array[rndIndex2];
array[rndIndex2] = swappingItem;
}
return array;
}
}
public class RandomUtils
{
private static readonly ThreadLocal<Random> RndLocal = new ThreadLocal<Random>(() => new Random(GetUniqueSeed()));
private static int GetUniqueSeed()
{
long next, current;
var guid = Guid.NewGuid().ToByteArray();
var seed = BitConverter.ToInt64(guid, 0);
do
{
current = Interlocked.Read(ref seed);
next = current * BitConverter.ToInt64(guid, 3);
} while (Interlocked.CompareExchange(ref seed, next, current) != current);
return (int)next ^ Environment.TickCount;
}
public static int GetRandom(int min, int max)
{
Contract.Assert(max >= min);
return RndLocal.Value.Next(min, max);
}
public static int GetRandom(int max)
{
return RndLocal.Value.Next(max);
}
public static double GetRandom()
{
return RndLocal.Value.NextDouble();
}
}
public class StringUtility
{
private const string UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
private const string LowerAlpha = "abcdefghijklmnopqrstuwxyz";
private const string Numbers = "0123456789";
private const string SpecialChars = "~!##$%^&*()_-+=.?";
private static string CreateSourceString(bool includeLowerCase, bool includeUpperCase, bool includenumbers, bool includeSpChars)
{
Contract.Assert(includeLowerCase || includeUpperCase || includenumbers || includeSpChars);
var sb = new StringBuilder();
if (includeLowerCase) sb.Append(LowerAlpha);
if (includeUpperCase) sb.Append(UpperAlpha);
if (includenumbers) sb.Append(Numbers);
if (includeSpChars) sb.Append(SpecialChars);
return sb.ToString();
}
private static string GenerateString(string sourceString, int length = 6)
{
var rndString = Shuffle(sourceString);
var builder = new StringBuilder();
for (var i = 0; i < length; i++)
builder.Append(rndString[RandomUtils.GetRandom(0, rndString.Length)]);
return builder.ToString();
}
public static string GenerateRandomString(int length = 6,
bool includenumbers = false,
bool includeSpChars = false)
{
var sourceStr = CreateSourceString(true, true, includenumbers, includeSpChars);
return GenerateString(sourceStr, length);
}
public static string GenerateRandomString(int minLength,
int maxLength,
bool includenumbers = false,
bool includeSpChars = false)
{
if (maxLength < minLength) maxLength = minLength;
var len = RandomUtils.GetRandom(minLength, maxLength + 1);
return GenerateRandomString(len, includenumbers, includeSpChars);
}
public static string Shuffle(string str)
{
var alreadySwaped = new HashSet<Tuple<int, int>>();
var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(str.Length / 4), Convert.ToInt32((str.Length / 2) + 1));
var strArray = str.ToArray();
for (var i = 0; i <= rndLoopCount; i++)
{
int rndIndex1 = 0, rndIndex2 = 0;
do
{
rndIndex1 = RandomUtils.GetRandom(0, str.Length);
rndIndex2 = RandomUtils.GetRandom(0, str.Length);
} while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));
alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
var swappingChar = strArray[rndIndex1];
strArray[rndIndex1] = strArray[rndIndex2];
strArray[rndIndex2] = swappingChar;
}
return new string(strArray);
}
public static string GeneratePassword(PasswordComplexity complexityLevel)
{
switch (complexityLevel)
{
case PasswordComplexity.Simple: return GenerateSimplePassword();
case PasswordComplexity.Medium: return GenerateMediumPassword();
case PasswordComplexity.Strong: return GenerateStrongPassword();
case PasswordComplexity.Stronger: return GenerateStrongerPassword();
}
return null;
}
private static string GenerateSimplePassword()
{
return GenerateRandomString(6, 9);
}
private static string GenerateMediumPassword()
{
var passLen = RandomUtils.GetRandom(6, 10);
var numCount = RandomUtils.GetRandom(1, 3);
var alphaStr = GenerateRandomString(passLen - numCount);
var numStr = GenerateString(Numbers, numCount);
var pass = alphaStr + numStr;
return Shuffle(pass);
}
private static string GenerateStrongPassword()
{
var lowerCharCount = RandomUtils.GetRandom(2, 5);
var upperCharCount = RandomUtils.GetRandom(2, 5);
var numCount = RandomUtils.GetRandom(2, 4);
var spCharCount = RandomUtils.GetRandom(2, 4);
var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
var spCharStr = GenerateString(SpecialChars, spCharCount);
var numStr = GenerateString(Numbers, numCount);
var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
return Shuffle(pass);
}
private static string GenerateStrongerPassword()
{
var lowerCharCount = RandomUtils.GetRandom(5, 12);
var upperCharCount = RandomUtils.GetRandom(4, 8);
var numCount = RandomUtils.GetRandom(4, 6);
var spCharCount = RandomUtils.GetRandom(4, 6);
var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
var spCharStr = GenerateString(SpecialChars, spCharCount);
var numStr = GenerateString(Numbers, numCount);
var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
return Shuffle(Shuffle(pass));
}
public enum PasswordComplexity
{
Simple, Medium, Strong, Stronger
}
}
I write this code for you. You can just copy and use it. All of my code is just a method that you can pass appropriate arguments and it gives you back a completely randomized password. I test it several times before answering your question, It works well.
private string GeneratePassword(bool useCapitalLetters, bool useSmallLetters, bool useNumbers, bool useSymbols, int passLenght)
{
Random random = new Random();
StringBuilder password = new StringBuilder(string.Empty);
//This for loop is for selecting password chars in order
for (int i = 0;;)
{
if (useCapitalLetters)
{
password.Append((char)random.Next(65, 91)); //Capital letters
++i; if (i >= passLenght) break;
}
if (useSmallLetters)
{
password.Append((char)random.Next(97, 122)); //Small letters
++i; if (i >= passLenght) break;
}
if (useNumbers)
{
password.Append((char)random.Next(48, 57)); //Number letters
++i; if (i >= passLenght) break;
}
if (useSymbols)
{
password.Append((char)random.Next(35, 38)); //Symbol letters
++i; if (i >= passLenght) break;
}
}
//This for loop is for disordering password characters
for (int i = 0; i < password.Length; ++i)
{
int randomIndex1 = random.Next(password.Length);
int randomIndex2 = random.Next(password.Length);
char temp = password[randomIndex1];
password[randomIndex1] = password[randomIndex2];
password[randomIndex2] = temp;
}
return password.ToString();
}
an answer with complete randomize char and using the max repeat of char, i have added a shuffle string function:
const int Maximum_Identical = 2; // Max number of identical characters in a row
const string lower_chars = "abcdefghijklmnopqrstuvwxyz"; // lower case chars
const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //capital chars
const string numbers = "0123456789"; //numbers
const string symbols = #"!#$%&*#\"; //symbols
int lenght = 6; //
bool lowercase = true, capital=true, num=true, sym=true;
List<char[]> PasswordSet = new List<char[]>();
List<char[]> charSet = new List<char[]>();
List<int[]> countSet = new List<int[]>();
if (lowercase) charSet.Add(lower_chars.ToArray());
if (capital) charSet.Add(capital_chars.ToArray());
if (num) charSet.Add(numbers.ToArray());
if (sym) charSet.Add(symbols.ToArray());
foreach(var c in charSet)
countSet.Add(new int[c.Length]);
Random rdm = new Random();
//we create alist with each type with a length char (max repeat char included)
for(int i = 0; i < charSet.Count;i++)
{
var lng = 1;
var p0 = "";
while (true)
{
var ind = rdm.Next(0, charSet[i].Length);
if (countSet[i][ind] < Maximum_Identical )
{
countSet[i][ind] += 1;
lng++;
p0 += charSet[i][ind];
}
if (lng == lenght) break;
}
PasswordSet.Add(p0.ToArray());
}
//generate a password with the desired length with at less one char in desired type,
//and we choose randomly in desired type to complete the length of password
var password = "";
for(int i = 0; i < lenght; i++)
{
char p;
if (i < PasswordSet.Count)
{
int id;
do
{
id = rdm.Next(0, PasswordSet[i].Length);
p = PasswordSet[i][id];
} while (p == '\0');
password += p;
PasswordSet[i][id] = '\0';
}
else
{
int id0;
int id1;
do
{
id0 = rdm.Next(0, PasswordSet.Count);
id1 = rdm.Next(0, PasswordSet[id0].Length);
p = PasswordSet[id0][id1];
} while (p == '\0');
password += p;
PasswordSet[id0][id1] = '\0';
}
}
//you could shuffle the final password
password = Shuffle.StringMixer(password);
shuffle string function:
static class Shuffle
{
static System.Random rnd = new System.Random();
static void Fisher_Yates(int[] array)
{
int arraysize = array.Length;
int random;
int temp;
for (int i = 0; i < arraysize; i++)
{
random = i + (int)(rnd.NextDouble() * (arraysize - i));
temp = array[random];
array[random] = array[i];
array[i] = temp;
}
}
public static string StringMixer(string s)
{
string output = "";
int arraysize = s.Length;
int[] randomArray = new int[arraysize];
for (int i = 0; i < arraysize; i++)
{
randomArray[i] = i;
}
Fisher_Yates(randomArray);
for (int i = 0; i < arraysize; i++)
{
output += s[randomArray[i]];
}
return output;
}
}
There you go :
string[] charList =
{
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"#\"!#$%&*#\\"
};
int desiredPasswordLength = 12;
var randomNumberGenerator = new Random();
string generatedPassword = "";
for (int i = randomNumberGenerator.Next() % 4; desiredPasswordLength > 0; i = (i+1) % 4)
{
var takeRandomChars = randomNumberGenerator.Next() % 3;
for (int j = 0; j < takeRandomChars; j++)
{
var randomChar = randomNumberGenerator.Next() % charList[i].Length;
char selectedChar = charList[i][randomChar % charList[i].Length];
generatedPassword = string.Join("", generatedPassword, selectedChar);
}
desiredPasswordLength -= takeRandomChars;
}
Console.WriteLine("Generated password: {0}",generatedPassword);
private static string GeneratorPassword(UInt16 length = 8)
{
const string chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0";
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Random rnd = new Random();
System.Threading.Thread.Sleep(2);
for (int i = 0; i < length; i++)
{
int index = 0;
if (i % 3 == 0)
{
index = rnd.Next(0, 10);
}
else if (i % 3 == 1)
{
index = rnd.Next(10, 36);
}
else
{
index = rnd.Next(36, 62);
}
sb.Insert(rnd.Next(0, sb.Length), chars[index].ToString());
}
return sb.ToString();
}
static void Main(string[] args)
{
for (int j= 0; j < 100; j++)
{
Console.WriteLine( GeneratorPassword());
}
Console.ReadLine();
}
For example:
I have this:
string commaSeparatedString = "124,45415,1212,4578,233,968,6865,32545,4545";
I want to do that for each 4 found comma add a new line
124-45415-1212-4578
233-968-6865-32545
4545
What about this:
string str = "124,45415,1212,4578,233,968,6865,32545,4545";
var result = string.Join("-", sss.Split(',').Select((c, index) => (index + 1) % 4 == 0 ?
c + Environment.NewLine : c));
Just don't forget to add LINQ to your using directives first:
using System.Linq;
Try this:
const int batch = 4;
var target = "124,45415,1212,4578,233,968,6865,32545,4545";
var items = target.Split(',');
var results = new List<string>();
var continue = false;
var step = 0;
do
{
var slide = items.Skip(step++ * batch).Take(batch);
continue = slide.Count() == batch;
results.Add(string.Join('-', slide));
}while(continue);
Here you go :
using System;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Console.Write(SplitOnChar("124,45415,1212,4578,233,968,6865,32545,4545",',',4));
Console.ReadKey();
}
private static string SplitOnChar(string input, char theChar, int number)
{
string result = "";
int seen = 0;
int lastSplitIndex = 0;
for(int i = 0; i< input.Length;i++)
{
char c = input[i];
if (c.Equals(theChar))
{
seen++;
if (seen == number)
{
result += input.Substring(lastSplitIndex + 1, i - lastSplitIndex -1);
result += Environment.NewLine;
lastSplitIndex = i;
seen = 0;
}
}
}
result += input.Substring(lastSplitIndex + 1);
result = result.Replace(theChar, '-');
return result;
}
}
}
I keep getting this message "System.IndexOutOfRangeException: Index was outside the bounds of the array." when attempting to run a program I built, that utilized an exception catcher.
class StudentS
{
private List theStudentList;
public bool PopulateStudents(string path)
{
theStudentList = new List<Student>();
bool flag = false;
try
{
List<string[]> strArrayList = new List<string[]>();
using (StreamReader streamReader = new StreamReader(path))
{
string str;
while ((str = streamReader.ReadLine()) != null)
{
string[] strArray = str.Split(',');
strArrayList.Add(strArray);
}
}
for (int index1 = 0; index1 < strArrayList.Count; ++index1)
{
string[] strArray = strArrayList[index1];
Student student = new Student(strArray[0], strArray[1], strArray[2]); **where the error is**
int index2 = 3;
while (index2 < strArray.Length)
{
student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
index2 += 2;
}
student.CalGrade();
theStudentList.Add(student);
}
}
catch (Exception e)
{
flag = true;
Console.WriteLine(e);
}
return flag;
}
public int ListLength
{
get
{
return theStudentList.Count;
}
}
public float StudentAverage(int index)
{
return theStudentList.ElementAt(index).Average;
}
public string StudentGrade(int index)
{
return theStudentList.ElementAt(index).LetterGrade;
}
public string StudentID(int index)
{
return theStudentList.ElementAt(index).ID;
}
public string StudentLastName(int index)
{
return theStudentList.ElementAt(index).NameLast;
}
}
class Student
{
private float average;
private ArrayList Earned;
private string letterGrade;
private string nameFirst;
private string nameLast;
private ArrayList Possible;
private string studentID;
public Student(string id)
{
studentID = null;
nameFirst = null;
nameLast = null;
Earned = new ArrayList();
Possible = new ArrayList();
}
public Student(string id, string first)
{
studentID = id;
nameFirst = null;
nameLast = null;
Earned = new ArrayList();
Possible = new ArrayList();
}
public Student(string id, string first, string last)
{
nameFirst = first;
nameLast = last;
studentID = id;
Earned = new ArrayList();
Possible = new ArrayList();
}
public float Average
{
get
{
return average;
}
}
public string ID
{
get
{
return studentID;
}
}
public string LetterGrade
{
get
{
return letterGrade;
}
}
public string NameFirst
{
get
{
return nameFirst;
}
set
{
nameFirst = value;
}
}
public string NameLast
{
get
{
return nameLast;
}
set
{
nameLast = value;
}
}
public void CalGrade()
{
int num1 = 0;
int num2 = 0;
foreach (int num3 in Earned)
num1 += num3;
foreach (int num3 in Possible)
num2 += num3;
average = num1 / (float)num2;
average = (float)Math.Round(average, 2);
if (average >= 0.9)
letterGrade = "A";
if (average >= 0.8 && average < 0.9)
letterGrade = "B";
if (average >= 0.7 && average < 0.8)
letterGrade = "C";
if (average >= 0.6 && average < 0.7)
letterGrade = "D";
if (average >= 0.6)
return;
letterGrade = "U";
}
public void EnterGrade(int earnedValue, int possValue)
{
Earned.Add(earnedValue);
Possible.Add(possValue);
}
}
I am unsure as to what I have done wrong. Thanks for any help!
Edit: I went ahead and added a majority of the code here, in hopes that this answers your questions better. The data set I am dealing with is 4 rows, that are grabbed into the student array.
index2 + 1 may be out of range in the expression strArray[index2 + 1] below:
while (index2 < strArray.Length)
{
student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
index2 += 2;
}
To process two elements at a time, use index2 < strArray.Length - 1
You may have a problem if the file from your path has an empty row as last row.
You access strArray[0], strArray[1], strArray[2] no matter if it is an empty array or not.
Maybe you are missing an Array.resize(). // This worked for me
Array.Resize<string[]>(ref strArrayList , count+ 1); // Count is the current length of strArrayList
Flagged the two spots where you could run into trouble:
public bool PopulateStudents(string path)
{
theStudentList = new List<Student>();
bool flag = false;
try
{
List<string[]> strArrayList = new List<string[]>();
using (StreamReader streamReader = new StreamReader(path))
{
string str;
while ((str = streamReader.ReadLine()) != null)
{
string[] strArray = str.Split(',');
strArrayList.Add(strArray);
}
}
for (int index1 = 0; index1 < strArrayList.Count; ++index1)
{
string[] strArray = strArrayList[index1];
// below that, what makes you believe strArray's length is >= 3 ?
Student student = new Student(strArray[0], strArray[1], strArray[2]);
int index2 = 3;
while (index2 < strArray.Length)
{
// here index2 will be < strArray.Length, but index2+1 might be ==
student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
index2 += 2;
}
student.CalGrade();
theStudentList.Add(student);
}
}
catch (Exception e)
{
flag = true;
Console.WriteLine(e);
}
return flag;
}
Note that your while loop could be replaced with:
for(int index2 = 3; index2 < strArray.Length - 1; index2 += 2)
{
student.EnterGrade(...);
}
This is difficult to diagnose because you provided limited information. If I could see the file you are running through your program, fed in as path, I would be able to compare what the function is attempting to do to the data it is trying to do it on. That said, this looks familiar to me so I will give solving it a try and at least give you a tool to try on it.
I experienced a similar issue with a program that needed to read a CSV file for a graphics program. The problem was that when the CSV file was created, an empty line was left at the end. This left me with an empty array to represent the last line in the file.
Also, have you verified that the arrays that are added to strArrayList are consistently sized?
If you check for this empty line at the end of your file and it does not exist and if you check for commas left at the end of the lines in your file passed in as path then you can try the edits I made above to get an idea of which line(s) in your CSV file is causing the problem. I commented all the edits I made with “EDIT:” so they would be easy to find. Without more information, I cannot fix the problem, but I can maybe help you look in the right direction.
The edited code with the output for line numbers in your file which are associated with errors is below. Good luck!
public bool PopulateStudents(string path)
{
theStudentList = new List<Student>();
bool flag = false;
// EDIT: NEW VARIABLE int lineCounter declared and initialized before try block so it remains in scope when the catch block is called
int counter = 0;
try
{
List<string[]> strArrayList = new List<string[]>();
using (StreamReader streamReader = new StreamReader(path))
{
string str;
while ((str = streamReader.ReadLine()) != null)
{
string[] strArray = str.Split(',');
strArrayList.Add(strArray);
}
}
for (int index1 = 0; index1 < strArrayList.Count; ++index1)
{
// EDIT: UPDATE lineCounter
++lineCounter;
string[] strArray = strArrayList[index1];
Student student = new Student(strArray[0], strArray[1], strArray[2]);
int index2 = 3;
while (index2 < strArray.Length)
{
student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
index2 += 2;
}
student.CalGrade();
theStudentList.Add(student);
}
}
catch (Exception e)
{
flag = true;
Console.WriteLine(e);
// EDIT: PRINT CURRENT LINE
Console.WriteLine(“error at line in file = “ + lineCounter);
}
return flag;
}