I want to create a password list.
So far, it works but my list contains only words like D?t1g3+T%J.
Now I want to create words with more sense.
I have a List with words like Banana, Desk and so on.
How is it possible to change randomly the spelling, add numbers and special characters?
For example:
"Banana" -> "baNana123"
Well, I have just come up with this.
string foo = "banana";
List<string> chars = new List<string>();
Random rnd = new Random();
string newPassword = "";
for (int i = 0; i < foo.Length; i++)
{
chars.Add(foo[i].ToString());
}
foreach (var boo in chars)
{
var randomNum = rnd.Next(0, 2);
Debug.WriteLine(randomNum);
if (randomNum == 0)
{
newPassword = newPassword + boo.ToUpper();
}
else
{
newPassword = newPassword + boo.ToLower();
}
}
Debug.WriteLine(newPassword);
What it does: 1)strips the string, in my case "banana" into individual characters
2) for every character program generates randomly 1, or 0. Base on that I just simply convert to lower, or upper case.
All you have to do is to feed the algorithm with strings. And to the adding numbers at the end you can do something like this I quess.
int howMany = rnd.Next(1, 20); //1 to 19 numbers, you can set that manually
for (int i = 0; i < howMany; i++)
{
newPassword = newPassword + rnd.Next(0, 10);
}
Debug.WriteLine(newPassword);
Outcome last run for me: BanANA6469242684
Related
For a string that may have zero or more hyphens in it, I need to extract all the different possibilities with and without hyphens.
For example, the string "A-B" would result in "A-B" and "AB" (two possibilities).
The string "A-B-C" would result in "A-B-C", "AB-C", "A-BC" and "ABC" (four possibilities).
The string "A-B-C-D" would result in "A-B-C-D", "AB-C-D", "A-BC-D", "A-B-CD", "AB-CD", "ABC-D", "A-BCD" and "ABCD" (eight possibilities).
...etc, etc.
I've experimented with some nested loops but haven't been able to get anywhere near the desired result. I suspect I need something recursive unless there is some simple solution I am overlooking.
NB. This is to build a SQL query (shame that SQL Server does't have MySQL's REGEXP pattern matching).
Here is one attempt I was working on. This might work if I do this recursively.
string keyword = "A-B-C-D";
List<int> hyphens = new List<int>();
int pos = keyword.IndexOf('-');
while (pos != -1)
{
hyphens.Add(pos);
pos = keyword.IndexOf('-', pos + 1);
}
for (int i = 0; i < hyphens.Count(); i++)
{
string result = keyword.Substring(0, hyphens[i]) + keyword.Substring(hyphens[i] + 1);
Response.Write("<p>" + result);
}
A B C D are words of varying length.
Take a look at your sample cases. Have you noticed a pattern?
With 1 hyphen there are 2 possibilities.
With 2 hyphens there are 4 possibilities.
With 3 hyphens there are 8 possibilities.
The number of possibilities is 2n.
This is literally exponential growth, so if there are too many hyphens in the string, it will quickly become infeasible to print them all. (With just 30 hyphens there are over a billion combinations!)
That said, for smaller numbers of hyphens it might be interesting to generate a list. To do this, you can think of each hyphen as a bit in a binary number. If the bit is 1, the hyphen is present, otherwise it is not. So this suggests a fairly straightforward solution:
Split the original string on the hyphens
Let n = the number of hyphens
Count from 2n - 1 down to 0. Treat this counter as a bitmask.
For each count begin building a string starting with the first part.
Concatenate each of the remaining parts to the string in order, preceded by a hyphen only if the corresponding bit in the bitmask is set.
Add the resulting string to the output and continue until the counter is exhausted.
Translated to code we have:
public static IEnumerable<string> EnumerateHyphenatedStrings(string s)
{
string[] parts = s.Split('-');
int n = parts.Length - 1;
if (n > 30) throw new Exception("too many hyphens");
for (int m = (1 << n) - 1; m >= 0; m--)
{
StringBuilder sb = new StringBuilder(parts[0]);
for (int i = 1; i <= n; i++)
{
if ((m & (1 << (i - 1))) > 0) sb.Append('-');
sb.Append(parts[i]);
}
yield return sb.ToString();
}
}
Fiddle: https://dotnetfiddle.net/ne3N8f
You should be able to track each hyphen position, and basically say its either there or not there. Loop through all the combinations, and you got all your strings. I found the easiest way to track it was using a binary, since its easy to add those with Convert.ToInt32
I came up with this:
string keyword = "A-B-C-D";
string[] keywordSplit = keyword.Split('-');
int combinations = Convert.ToInt32(Math.Pow(2.0, keywordSplit.Length - 1.0));
List<string> results = new List<string>();
for (int j = 0; j < combinations; j++)
{
string result = "";
string hyphenAdded = Convert.ToString(j, 2).PadLeft(keywordSplit.Length - 1, '0');
// Generate string
for (int i = 0; i < keywordSplit.Length; i++)
{
result += keywordSplit[i] +
((i < keywordSplit.Length - 1) && (hyphenAdded[i].Equals('1')) ? "-" : "");
}
results.Add(result);
}
This works for me:
Func<IEnumerable<string>, IEnumerable<string>> expand = null;
expand = xs =>
{
if (xs != null && xs.Any())
{
var head = xs.First();
if (xs.Skip(1).Any())
{
return expand(xs.Skip(1)).SelectMany(tail => new []
{
head + tail,
head + "-" + tail
});
}
else
{
return new [] { head };
}
}
else
{
return Enumerable.Empty<string>();
}
};
var keyword = "A-B-C-D";
var parts = keyword.Split('-');
var results = expand(parts);
I get:
ABCD
A-BCD
AB-CD
A-B-CD
ABC-D
A-BC-D
AB-C-D
A-B-C-D
I've tested this code and it is working as specified in the question. I stored the strings in a List<string>.
string str = "AB-C-D-EF-G-HI";
string[] splitted = str.Split('-');
List<string> finalList = new List<string>();
string temp = "";
for (int i = 0; i < splitted.Length; i++)
{
temp += splitted[i];
}
finalList.Add(temp);
temp = "";
for (int diff = 0; diff < splitted.Length-1; diff++)
{
for (int start = 1, limit = start + diff; limit < splitted.Length; start++, limit++)
{
int i = 0;
while (i < start)
{
temp += splitted[i++];
}
while (i <= limit)
{
temp += "-";
temp += splitted[i++];
}
while (i < splitted.Length)
{
temp += splitted[i++];
}
finalList.Add(temp);
temp = "";
}
}
I'm not sure your question is entirely well defined (i.e. could you have something like A-BCD-EF-G-H?). For "fully" hyphenated strings (A-B-C-D-...-Z), something like this should do:
string toParse = "A-B-C-D";
char[] toParseChars = toPase.toCharArray();
string result = "";
string binary;
for(int i = 0; i < (int)Math.pow(2, toParse.Length/2); i++) { // Number of subsets of an n-elt set is 2^n
binary = Convert.ToString(i, 2);
while (binary.Length < toParse.Length/2) {
binary = "0" + binary;
}
char[] binChars = binary.ToCharArray();
for (int k = 0; k < binChars.Length; k++) {
result += toParseChars[k*2].ToString();
if (binChars[k] == '1') {
result += "-";
}
}
result += toParseChars[toParseChars.Length-1];
Console.WriteLine(result);
}
The idea here is that we want to create a binary word for each possible hyphen. So, if we have A-B-C-D (three hyphens), we create binary words 000, 001, 010, 011, 100, 101, 110, and 111. Note that if we have n hyphens, we need 2^n binary words.
Then each word maps to the output you desire by inserting the hyphen where we have a '1' in our word (000 -> ABCD, 001 -> ABC-D, 010 -> AB-CD, etc). I didn't test the code above, but this is at least one way to solve the problem for fully hyphenated words.
Disclaimer: I didn't actually test the code
This program prints all possibilities of a string input, for example, if input is abc', the output should be the combinations, this works but when im creating the arraylist it's printing out numbers instead of the string combinations, code:
string input = Console.ReadLine();
int sl = input.Length;
ArrayList arr = new ArrayList();
for (int three = 0; three < sl; three++) {
for (int two = 0; two < sl; two++) {
for (int one = 0; one < sl; one++) {
char onef = input[one];
char twof = input[two];
char threef = input[three];
arr.Add(threef + twof + onef);
Console.Write(threef);
Console.Write(twof);
Console.WriteLine(onef);
}
}
}
Console.WriteLine("The elements of the ArrayList are:");
foreach(object obj in arr) {
Console.WriteLine(obj);
}
the output of the arraylist is numbers and not the string chars, help!
Just change these three lines
From:
char onef = input[one];
char twof = input[two];
char threef = input[three];
To:
string onef = input[one].ToString();
string twof = input[two].ToString();
string threef = input[three].ToString();
Alternate: change one line:
arr.Add(string.Format("{0}{1}{2}", a, b, c));
char cannot be concatenated like string. The + is interpreted numerically.
I'm building a console based lottery game where user enters his/her choice of numbers. I need to check that the numbers are between 1-39 and user has entered exactly 7 valid numbers. I'd like to do this in a way where user writes them in one line of string in console and the program finds any white space, comma or other non-digit characters and ignores them. The remaining lottery numbers should be stored in integer array which doesn't include any duplicates.
My current version is quite horrible since it gets errors very easily if user writes e.g. 2 spaces between numbers.
Console.WriteLine("Choose 7 numbers (1-39) by pressing ENTER after every number:");
string userRow = Console.ReadLine();
int[] userLottery = new int[7];
for(int i = 0; i < userLottery.Length; i++)
{
userLottery = userRow.Split(',', '.', ' ').Select(x => int.Parse(x)).ToArray();
if(userLottery[i] > 7)
{
Array.Resize(ref userLottery, 7);
}
}
I'd like to replace my current way in more convenient way where amount of user errors won't affect the program. If the user writes more than one space the error occures.
I have tried to build regular expression to handle these situations but I can't use it to store them in to array.
string userChoice = Console.ReadLine();
MatchCollection userNumbers = Regex.Matches(userChoice, #"\d+");
int[] userRow;
for(int i = 0; i < userNumbers.Count; i++)
{
userRow[i] = userNumbers[i].Value;
}
That says string can't be converted to int[]...
You could use this LINQ query using String.Split with RemoveEmptyEntries and int.tryParse:
int num = 0;
int[] userLottery = userRow.Trim()
.Split(new[] { '.', ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Where(s => int.TryParse(s.Trim(), out num) && num > 0 && num < 40)
.Select(s => num)
.Distinct()
.ToArray();
if(userLottery.Length != 7)
Console.WriteLine("Enter 7 valid numbers between 1 and 39");
else
Console.WriteLine("You have chosen following numbers: " + string.Join(",", userLottery));
Enumerable.Distinct removes duplicates as requested.
Your code doesn't match the instruction to the user. The following does what you tell the user:
Console.WriteLine("Choose 7 numbers (1-39) by pressing ENTER after every number:");
int[] userLottery = new int[7];
int i = 0;
while (i < 7)
{
Console.Write("Your choice #{0}: ", i+1);
string userRow = Console.ReadLine();
int userNumber;
if (!Int32.TryParse(userRow, out userNumber) || userNumber < 1 || userNumber > 39)
{
Console.WriteLine("Invalid number! Please try again!");
}
else
{
userLottery[i++] = userNumber;
}
}
Use Regex.Split() for this to handle multiple white spaces.
string[] numbers = Regex.Split(userRow, #"\s+");
\s+ means one or more white spaces. You can use [ ]+ only for space if you want.
You can just parse it with RegEx first and then it should work.
using System.Text.RegularExpressions;
Console.WriteLine("Choose 7 numbers (1-39) by pressing ENTER after every number:");
string userRow = Console.ReadLine();
int[] userLottery = new int[7];
string[] userEnter = Regex.Split(userRow, " ");
int n = 0;
int k = 0;
for (int i = 0; i < userEnter.Length; i++)
{
bool isNumeric = int.TryParse(userEnter[i], out n);
if(isNumeric == true)
{
userLottery[k] = int.Parse(userEnter[i]);
k++;
}
}
Use the following code
Console.WriteLine("Choose 7 numbers (1-39) by pressing ENTER after every number:");
string data = Console.ReadLine();
int[] userLottery = new int[7];
int i = 0;
StringBuilder num = new StringBuilder();
foreach (char item in data)
{
if (!Char.IsDigit(item))
{
if (num.Length == 0)
continue;
userLottery[i] = int.Parse(num.ToString());
i++;
num.Clear();
continue;
}
num.Append(item);
}
if(num.Length > 0)
userLottery[i] = int.Parse(num.ToString());
I've been playing around / researching ways to randomize the order of chars in a string. I frankly just don't understand how to do it. I've searched through the C# documentation and a handful of websites. I found one particular way of randomizing the order of chars in a string but I don't understand how it works. I've also read that the Random class isn't truly random, which would explain why the results are so similar.
How exactly does the current method I'm using function (especially the OrderBy() method).
Is there a better way to do this?
Current code
string baseList = "abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
string[] randLists = new string[baseList.Length];
for (int i = 0; i < baseList.Length; i++)
{
randLists[i] = new string(baseList.ToCharArray().OrderBy(s => (random.Next(2) % 2) == 0).ToArray());
Console.WriteLine(randLists[i]);
}
Console.Read();
This is my attempt at randomizing but it doesn't function at all:
*string bL = "abcdefghijklmnopqrstuvwxyz";
string[] rL = new string[bL.Length];
Random randomizer = new Random();
for (int i = 0; i < bL.Length; i++)
{
rL = new string(bL.ToCharArray().OrderBy(c => (randomizer.Next(0, 25)).ToString()));
}*
Thanks in advance for any assistance. I'll continue researching in the meantime.
Although the code that you found is short, it does not make a nicely distributed shuffle of the original string: the randomizer is likely to give you the same numbers in the process of generating a shuffle, increasing a probability that the corresponding characters would remain in the same order relative to each other as in your original string.
One solution to this problem is using Fisher–Yates shuffle. It is easy to implement (you need to stay away from common implementation errors, though).
Since string is immutable, you would need to shuffle an array of characters, and then make a string from it.
To add to the suggestion of the Fisher-Yates shuffle, here's a code sample, just ignore the test assertion, just trying to debug and make sure it's random enough.
[TestMethod]
public void RandomizeText()
{
string baseList = "abcdefghijklmnopqrstuvwxyz";
char[] result = baseList.ToCharArray();
Shuffle<char>(result);
var final = string.Join("", result);
final.Should().NotMatch(baseList);
}
public void Shuffle<T>(T[] array)
{
var random = new Random();
for (int x = 0; x < 100; x++)
{
for (int i = array.Length; i > 1; i--)
{
// Pick random element to swap.
int j = random.Next(i); // 0 <= j <= i-1
// Swap.
T tmp = array[j];
array[j] = array[i - 1];
array[i - 1] = tmp;
}
}
}
Another example...
static void Main(string[] args)
{
string baseList = "abcdefghijklmnopqrstuvwxyz";
Console.WriteLine(baseList);
string shuffled = Shuffle(baseList);
Console.WriteLine(shuffled);
Console.ReadLine();
}
static Random R = new Random();
static string Shuffle(string list)
{
int index;
List<char> chars = new List<char>(list);
StringBuilder sb = new StringBuilder();
while (chars.Count > 0)
{
index = R.Next(chars.Count);
sb.Append(chars[index]);
chars.RemoveAt(index);
}
return sb.ToString();
}
I am currently building a C# application that is generating a random 9 digit number each run through. I am looking for a way to exclude numbers starting with "666". How would I go about writing a statement to exclude numbers starting with certain digits.
Here's the code snippet just in case it helps.
Random SSN = new Random();
string temp = "";
int num = SSN.Next(100000000, 999999999);
temp = num.ToString();
Thanks!
Well, you could write:
int num;
do {
num = SSN.Next(100000000, 999999999);
} while (num >= 666000000 && num < 667000000);
(I originally used a string comparison too, but as we've always got exactly 9 digits, we can make a numeric comparison easily.)
The easy way would be:
Random SSN = new Random();
string temp = "";
do
{
int num = SSN.Next(100000000, 999999999);
temp = num.ToString();
} while (temp.StartsWith("666"));
If you’re really into efficiency and want to avoid the string comparison and unbounded loop at all costs, you could use:
Random SSN = new Random();
int num = SSN.Next(100000000, 998999999);
if (num >= 666000000)
num += 1000000;
Random SSN = new Random();
string temp = "";
double d = 0.6; // This will help on of choosing one half
int n1 = SSN.Next(100000000, 666000000);
int n2 = SSN.Next(667000000, 999999999);
int num = SSN.NextDouble() > d ? n1 : n2;
temp = num.ToString();
Random SSN = new Random();
string temp = "";
do
{
int num = SSN.Next(100000000, 999999999);
temp = num.ToString();
} while(num.IndexOf("666") == 0);
This has complexity of O(1).
string temp = "";
if (SSN.Next(0,999999999) < 588339221)
{
temp = SSN.Next(100000000, 666000000).ToString();
}
else
{
temp = SSN.Next(667000000, 1000000000).ToString();
}