Related
How do I repeat generating a random char? I want to make a glitched text effect so I set:
textbox.text = st[Random.Range(0, st.Length)];
in my update method. I do however only get one character out of this line - how would I repeat this process in a string with the length of 5? What I am trying to achieve is to randomly generate 5 characters over and over again. There must be a better way than this:
randomChar + randomChar + randomChar + randomChar + randomChar
Thank you in advance!
Could use something similar:
public static readonly 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' };
static void Main(string[] args)
{
static string GenerateGlitchedString(uint wordCount,uint wordslength)
{
string glitchedString = "";
for (int i = 0; i < wordCount; i++)
{
for (int j = 0; j < wordslength; j++)
{
Random rnd = new Random();
glitchedString += CHARS[rnd.Next(CHARS.Length)];
}
glitchedString += " "; //Add spaces
}
return glitchedString;
}
string output = GenerateGlitchedString(5, 5);
Console.WriteLine(output);
}
You can use Linq to generate any number of random characters from an enumerable:
int howManyChars = 5;
var newString = String.Join("", Enumerable.Range(0, howManyChars).Select(k => st[Random.Range(0, st.Length)]));
textbox.text = newString;
If you want completely glitchy strings, go the way of Mojibake. Take a string, convert it to one encoding and then decode it differently. Most programmers end up familiar with this kind of glitch eventually. For example this code:
const string startWith = "Now is the time for all good men to come to the aid of the party";
var asBytes = Encoding.UTF8.GetBytes(startWith);
var glitched = Encoding.Unicode.GetString(asBytes);
Debug.WriteLine(glitched);
consistently results in:
潎⁷獩琠敨琠浩潦污潧摯洠湥琠潣敭琠桴楡景琠敨瀠牡祴
But, if you just want some text with some random glitches, how about something like this. It uses a set of characters that should be glitched in, a count of how many glitches there should be in a string (based on the string length) and then randomly inserts glitches:
private static Random _rand = new Random();
private const string GlitchChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!##$%&";
public static string GlitchAString(string s)
{
var glitchCount = s.Length / 5;
var buffer = s.ToCharArray();
for (var i = 0; i < glitchCount; ++i)
{
var position = _rand.Next(s.Length);
buffer[position] = GlitchChars[_rand.Next(GlitchChars.Length)];
}
var result = new string(buffer);
Debug.WriteLine(result);
return result;
}
The first two times I ran this (with that same Now is the time... string), I got:
Original String:
Now is the time for all good men to come to the aid of the party
First Two Results:
LowmiW HhZ7time for all good mea to comX to ths aid oV the p1ray
Now is fhO P!me forjall gKod men to #ome to the a#d of F5e Nawty
The algorithm is, to some extent, tunable. You can have more or fewer glitches. You can change the set of glitch chars - whatever you'd like.
I am trying to display the total number of the same vowels when I input a word. For example : cheesecake.
Total vowels are 5 (e,e,e,a,e) and the total number of the same vowels (which is 'e') is 4.
The code I did,is still showing the number of the same vowels to 5.
Is there something wrong on my code?
static void Main()
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine();
char[] listOfVowels = new char[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int vowel = 0;
int sameVowel = 0;
for (int i = 0; i < input.Length; i++)
{
if (listOfVowels.Contains(input[i]))
{
Console.WriteLine(input[i]);
vowel++;
if(input[i] == input[i])
{
sameVowel++;
}
}
}
Console.WriteLine($"The total number of vowel are : {vowel}");
Console.WriteLine($"The total of the same number of vowel are : {sameVowel}");
}
The total number of vowel are : 5
The total of the same number of vowel are : 5
You can try this code, create a list to store vowel, and use linq to count same vowel
static void Main(string[] args)
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine();
char[] listOfVowels = new char[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int vowel = 0;
int sameVowel = 0;
List<char> vowers = new List<char>();
for (int i = 0; i < input.Length; i++)
{
if (listOfVowels.Contains(input[i]))
{
Console.WriteLine(input[i]);
vowel++;
vowers.Add(input[i]);
//if(vowers.Contains(input[i]))
//{
// sameVowel++;
//}
}
}
sameVowel = vowers.GroupBy(_ => _).Where(_ => _.Count() > 1).Sum(_ => _.Count());
Console.WriteLine(string.Format("The total number of vowel are : {0}", vowel));
Console.WriteLine(string.Format("The total of the same number of vowel are : {0}", sameVowel));
Console.ReadLine();
}
Following the pillars of OOP and the Single Responsibility Principle, you could encapsulate this logic into a class that will handle this logic for you
Class
public class VowelStatistics
{
private readonly string word;
public VowelStatistics(string word)
{
this.word = word;
}
public IEnumerable<char> Vowels => word.Where(c => "aeiouAEIOU".Contains(c));
public int VowelCount => Vowels.Count();
public char MostFrequentVowel => Vowels
.GroupBy(c => c)
.OrderByDescending(g => g.Count())
.Select(g => g.Key)
.First();
public int MostFrequentVowelCount => Vowels
.GroupBy(c => c)
.Max(g => g.Count());
// Adding this as per #Everyone's comment, which will give you vowel groupings by frequency.
public IEnumerable<IGrouping<char, char>> VowelsByFrequency => Vowels
.GroupBy(c => c)
.OrderByDescending(g => g.Count());
}
Usage
VowelStatistics vs = new VowelStatistics("cheesecake");
Results
vs.Vowels = { 'e', 'e', 'e', 'a', 'e' }
vs.VowelCount = 5
vs.MostFrequentVowel = 'e'
vs.MostFrequentVowelCount = 4
Your code can be simplified:
static void Main()
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine()/*"cheesecake"*/;
char[] listOfVowels = new char[] { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int vowel = 0;
vowel = input.Count(z => listOfVowels.Contains(z));
var sameVowelPair = input.Where(c => listOfVowels.Contains(c)).GroupBy(c => c).ToDictionary(s1 => s1.Key, s1=> s1.Count()).OrderByDescending(w => w.Value).FirstOrDefault();
Console.WriteLine($"The total number of vowel are : {vowel}");
Console.WriteLine($"The total of the same number of vowel are : {sameVowelPair.Value}");
}
Outputs:
The total number of vowel are : 5
The total of the same number of vowel are : 4
Take a look at this (no LINQ involved):
static (int, char, int) vowelStats(string str)
{
// VOWEL ONLY DICTIONARY
Dictionary<char, int> counts = new Dictionary<char, int>()
{
{'a', 0} , { 'e', 0} , { 'i', 0} , { 'o', 0} , { 'u', 0}
};
int vowels = 0;
char high = '\0';
foreach(char c in str)
{
char c1 = Char.ToLower(c); // convert letter to lowercase first
// if dictionary has the character, then it must be a vowel
if (counts.ContainsKey(c1))
{
counts[c1]++; // vowel itself count
vowels++; // total vowel count
if (!counts.ContainsKey(high)) high = c1; // will only be true once
if(vowels - counts[c1] < vowels - counts[high]) // update current most frequent
high = c1;
}
}
if(!counts.ContainsKey(high)) // if no vowels found, high will be '\0'
return (0, '\0', 0);
return (vowels, high, counts[high]);
}
static void Main(string[] args)
{
Console.Write("Enter a word or phrase : ");
string input = Console.ReadLine();
int vowels, mostFrequentVowelCount;
char mostFrequenctVowel;
(vowels, mostFrequenctVowel, mostFrequentVowelCount) = vowelStats(input);
Console.WriteLine("Total number of vowels: {0}", vowels);
Console.WriteLine("Most frequent vowel: {0}", mostFrequenctVowel);
Console.WriteLine("Most frequent vowel count: {0}", mostFrequentVowelCount);
}
Output:
Enter a word or phrase : cheesecake
Total number of vowels: 5
Most frequent vowel: e
Most frequent vowel count: 4
Notes:
1) I assumed what you meant by "same vowel" is "the most frequent vowel".
2) The code will only work (as is) in .Net Framework 4.7 or higher (tuple functions) OR .Net Core 2 or higher.
3) Time complexity: O(N) where N is the number of characters in the string.
4) Space complexity: O(C) where C is a constant representing the number of vowels and their corresponding integers in the Dictionary, plus the few other variables.
5) In case of two vowels having been the most frequent, this function will pick the one that was encountered first. That is, in case of "woohee" it will be 'o', and in case of "weehoo" it will be 'e'.
6) I updated the code so it does not care about uppercase/lowercase. If it encounters a vowel regardless of its case, it will update one and only one counter.
7) This does not use any LINQ and should be simple enough for basic C#. The reason I used no LINQ is because of its added complexity and overhead to performance.
This is nice and simple for me:
string input = "cheesecake";
var query =
from v in "aeiouAEIOU"
join c in input on v equals c
group c by c into gcs
orderby gcs.Count() descending
select gcs;
Console.WriteLine($"Vowels: {String.Join(", ", query.SelectMany(c => c))}");
Console.WriteLine($"Most Frequent Vowel: {query.First().Key}");
Console.WriteLine($"Most Frequent Vowel Count: {query.First().Count()}");
That gives:
Vowels: e, e, e, e, a
Most Frequent Vowel: e
Most Frequent Vowel Count: 4
Performance testing code:
static (int, char, int) vowelStatsPlain(string str)
{
// VOWEL ONLY DICTIONARY
Dictionary<char, int> counts = new Dictionary<char, int>()
{
{'a', 0} , { 'e', 0} , { 'i', 0} , { 'o', 0} , { 'u', 0}
};
int vowels = 0;
char high = '\0';
foreach (char c in str)
{
char c1 = Char.ToLower(c); // convert letter to lowercase first
// if dictionary has the character, then it must be a vowel
if (counts.ContainsKey(c1))
{
counts[c1]++; // vowel itself count
vowels++; // total vowel count
if (!counts.ContainsKey(high)) high = c1; // will only be true once
if (vowels - counts[c1] < vowels - counts[high]) // update current most frequent
high = c1;
}
}
if (!counts.ContainsKey(high)) // if no vowels found, high will be '\0'
return (0, '\0', 0);
return (vowels, high, counts[high]);
}
static (int, char, int) vowelStatsLinq(string str)
{
var query =
(
from v in "aeiouAEIOU"
join c in str on v equals c
group c by c into gcs
orderby gcs.Count() descending
select gcs
).ToArray();
var first = query.First();
return (query.SelectMany(c => c).Count(), first.Key, first.Count());
}
static void Main(string[] args)
{
string input = "The information contained in this email is confidential and for the addressee only; If you are not the intended recipient of this email, please reply and let us know that an incorrect address may have been used. If you do not wish to be communicated with by email, please respond so that we may remove your address from our records. Your co-operation is appreciated.";
Func<TimeSpan> callPlain = () =>
{
var sw = Stopwatch.StartNew();
(int vowels, char mostFrequenctVowel, int mostFrequentVowelCount) = vowelStatsPlain(input);
sw.Stop();
return sw.Elapsed;
};
Func<TimeSpan> callLinq = () =>
{
var sw = Stopwatch.StartNew();
(int vowels, char mostFrequenctVowel, int mostFrequentVowelCount) = vowelStatsLinq(input);
sw.Stop();
return sw.Elapsed;
};
var trials = Enumerable.Range(0, 1000000).Select(x => new { plain = callPlain(), linq = callLinq() }).ToArray();
Console.WriteLine(trials.Skip(2).Average(x => x.plain.TotalMilliseconds));
Console.WriteLine(trials.Skip(2).Average(x => x.linq.TotalMilliseconds));
Console.WriteLine(trials.Skip(2).Average(x => x.linq.TotalMilliseconds) / trials.Skip(2).Average(x => x.plain.TotalMilliseconds));
}
I have a string composes of Slovenian characters such as (žiga, špela, črt, ...) and i need to sort this string alphabetically, the problem i want to do that using loops only without using any builtin function in .NET like array.Sort().
static string[] SortByName(string[] fullname)
{
char[] abc =
{
'a', 'b', 'c', 'č', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 'š','t', 'u', 'v', 'z', 'ž'
};
int counter = 0;
for (int i = 0; i<abc.Length;i++)
{
for (int j = 0; j < fullname[counter].Length; j++)
{
// I still cant figure out what i can do here
}
counter++;
}
}
In your program, the char array abc stores all the Slovenian alphabets in order. You can use this array as a reference to the ranks of all the Slovene alphabets to compare the Slovene words. In the code below, I have defined a method CompareSl() to compare Slovene words, just like the Compare() method of the String class compares English words. (The method index() returns the index of a character in the array abc.)
The Compare() method of the String class takes two strings s1 and s2 as arguments and
♦ Returns 0 if the strings are equal
♦ Returns (+)ve if s1 > s2
♦ Returns (-)ve if s1 < s2
using System;
class Sl_Sort{
static void Main(){
string[] words = new string[]{"žiga", "špela", "črt"};
Console.WriteLine("Unsorted array is");
foreach(String st in words)
Console.Write(st+" , ");
//do selection sort to sort in ascending order
for(int i=0; i<words.Length-1;i++){
int min = i;
for(int j=i+1; j<words.Length;j++){
if(CompareSl(words[min], words[j]) > 0)
min = j;
}
string temp = words[i];
words[i] = words[min];
words[min] = temp;
}
Console.WriteLine("\nSorted array is");
foreach(String st in words)
Console.Write(st+" , ");
Console.ReadKey(); //waits till user presses a key before terminating
}
public static int CompareSl(string s1, string s2){
if(s1.Length == s2.Length){
for(int i=0; i<s1.Length; i++){
if(s1[i] != s2[i])
return index(s1[i]) - index(s2[i]);
}
}
else{
String s = s1.Length<s2.Length?s1:s2;
for(int i=0; i<s.Length; i++){
if(s1[i] != s2[i])
return index(s1[i]) - index(s2[i]);
}
if(s == s1)
return -1;
else
return 1;
}
return 0;
}
private static int index(char c){
char[] abc = { 'a', 'b', 'c', 'č', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 'š', 't', 'u', 'v', 'z', 'ž' };
for(int i=0; i<abc.Length; i++){
if(abc[i]==c)
return i;
}
return -1;
}
}
OUTPUT:
Unsorted array is
ziga , spela , crt ,
Sorted array is
crt , spela , ziga
Note: The characters ž, š and č got converted to z, s and c respectively because the platform I ran the code on was not set to UTF-8 or Unicode, which support Slovene, but ANSI, which does not support Slovene. Make sure your system supports Slovene to get the correct output.
Hope this helps.
Maybe you could do something like this:
private char[] charList = { 'a', 'b', 'c', 'č', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 'š', 't', 'u', 'v', 'z', 'ž' };
public string[] Sort(string inputStr)
{
string[] sortedChars = new string[inputStr.Length];
int index = 0;
for (int i = 0; i < charList.Length; i++)
{
for (int u = 0; u < inputStr.Length; u++)
{
sortedChars[index] = inputStr[u];
index++;
}
if (index == inputStr.Length)
return sortedChars;
}
return sortedChars;
}
I haven't tested the code, so not sure it works, but what it does is:
Iterate trough the chars, so it searches for "a" on each char of the inputString, if it's there it will be added to the sorted string[], then when it finishes with the first char, the next...etc.
Probably there's some error, maybe you can improve the code.
I've recently made a simple bruteforcer. Everything goes properly as I've expected, but not when I try to make everything multi-tasked.
This is the current code I have:
private static void startBruteForce(int keyLength)
{
var keyChars = createCharArray(keyLength, charactersToTest[0]);
var indexOfLastChar = keyLength - 1;
createNewKey(0, keyChars, keyLength, indexOfLastChar);
}
private static char[] createCharArray(int length, char defaultChar)
{
return (from c in new char[length] select defaultChar).ToArray();
}
private static void createNewKey(int currentCharPosition, char[] keyChars, int keyLength, int indexOfLastChar)
{
var nextCharPosition = currentCharPosition + 1;
for (int i = 0; i < charactersToTestLength; i++)
{
keyChars[currentCharPosition] = charactersToTest[i];
if (currentCharPosition < indexOfLastChar)
{
createNewKey(nextCharPosition, keyChars, keyLength, indexOfLastChar);
}
else
{
computedKeys++;
Console.WriteLine(new string(keyChars));
if (new string(keyChars) == "hola")
{
if (!isMatched)
{
isMatched = true;
result = new string(keyChars);
}
}
}
if (isMatched) return;
}
}
my current code to call the bruteforcer:
var estimatedPasswordLength = 3;
while (!isMatched)
{
estimatedPasswordLength++;
startBruteForce(estimatedPasswordLength);
}
these are the chars I use to combine the password to test:
'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','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','1','2','3','4','5',
'6','7','8','9','0','!','$','#','#','-'
To get the password hola I must to wait most likely ~10 mins. So to reduce the minutes to wait, I'm trying to split the work like this using multiple tasks, and so maybe doing this
estimatedPasswordLength++;
startBruteForce(estimatedPasswordLength);
synchronously without checking the same password at the time...
I appreciate any suggestion - how would I do it?
EDIT:
Regarding to #Cicero suggestion, this is what I tried:
Parallel.For(0, 4, i => // what should 0 and 4 be?
{
if (isMatched) return;
Task task = Task.Factory.StartNew(() => startBruteForce(estimatedPasswordLength));
estimatedPasswordLength++;
});
but length is now disproportionate, I get writed on the console strings like:
aaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaab
aaaaaaaaaaaaaaaac
while estimatedPasswordLength would be 4. How can I get a solution to make this with a proportionate length?
Ubbi Dubbi is a program where before the first vowel in a word, the letters “ub” are inserted. On my code, it doesn't do it before the first vowel it does the second vowel. If I put "hello" the output is "hellubo", when it should be "hubello". Sorry if my english is bad, i'm still learning.
Console.Write("Enter word: ");
string word = Console.ReadLine();
var loc = word.IndexOfAny(new char[] {'a', 'e', 'i', 'o', 'u'});
int aloc = word.IndexOf('a');
int eloc = word.IndexOf('e');
int iloc = word.IndexOf('i');
int oloc = word.IndexOf('o');
int uloc = word.IndexOf('u');
if (aloc!= -1 && aloc > loc)
{
loc = aloc;
}
if (eloc!= -1 && eloc > loc)
{
loc = eloc;
}
if (iloc!= -1 && iloc > loc)
{
loc = iloc;
}
if (oloc!= -1 && oloc > loc)
{
loc = oloc;
}
if (uloc!= -1 && uloc > loc)
{
loc = uloc;
}
string word1 = word.Insert(loc, "ub");
Console.WriteLine(word1);
After calling of IndexOfAny all work is done. So you can skip most of your code. But you should insert a check, if there is any vowel at all:
Console.Write("Enter word: ");
string word = Console.ReadLine();
var loc = word.IndexOfAny(new char[] { 'a', 'e', 'i', 'o', 'u' });
string word1 = loc >= 0 ? word.Insert(loc, "ub") : word;
Console.WriteLine(word1);
In your code an 'e' is found, so loc = eloc is executed. But there also 'o' is found and loc = oloc is executed AFTER the 'e'-check. So the final value of loc is that one of oloc.
You can achieve it easily by below API.
private static string processWord(string word)
{
// Vowels array
char[] vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
//Find the index of your first vowel in your 'word'
int index = word.IndexOfAny(vowels);
//Insert 'ub' at above location
word = word.Insert(index, "ub");
//Return the word
return word;
}
or
private static string processWord(string word)
{
return word.Insert(word.IndexOfAny(new char[] { 'a', 'e', 'i', 'o', 'u' }), "ub");
}
Chose any method whichever easy for you to understand