so I wrote some C# code and I am trying to test it incrementally, do to something that would take a while to explain, but bottom line, I'm new to c# and not understanding the online compiler error messages. Here is the error message I get when I try and compile, but the strings look good to me.
string solutionSet = "white|black|beige|pink|green|blue|red|yellow|orange|cyan|purple|brown";
string[] solutionSetArray = new string[12];
string ret = "";
string delimeter = "|";
int tempPos = 0;
int counter = 0;
int successFlag = 0;
int patternLength = 5;
for (int index = 0; index < solutionSet.Length; index++)
{
if (solutionSet[index] == delimeter)
{
solutionSetArray[counter] = solutionSet.Substring(tempPos, index);
tempPos = index + 1;
counter++;
}
if (solutionSet.Length - index == 1)
{
solutionSetArray[solutionSetArray.Length-1] = solutionSet.Substring(tempPos, solutionSet.Length);
}
}
for (int i = 0; i < patternLength; i++)
{
Random rnd = new Random();
int randIndex = rnd.Next(solutionSetArray.Length);
if (i != patternLength - 1)
{
ret += solutionSetArray[randIndex] + "|";
successFlag++;
}
else
{
ret += solutionSetArray[randIndex];
}
}
if (successFlag == patternLength - 1)
{
Console.WriteLine(ret);
}
else
{
Console.WriteLine("ERROR");
}
The error (which, according to the message, is on line 1, column 11) is being caused by your very first line of code, which begins string.
I can't tell the context from just your post, but my guess is that you are declaring solutionSet in a block that is not inside of a class or function. You should enclose your code in a class or method, e.g.
public class MyClass
{
static public void Main()
{
string solutionSet = "white|black|beige|pink|green|blue|red|yellow|orange|cyan|purple|brown";
//Rest of code goes here
}
}
By the way, if you're trying to convert solutionSet to an array, you can just write
var solutionSetArray = solutionSet.Split("|");
the problem with your code is
solutionSetArray[counter] = solutionSet.Substring(tempPos, index);
after 6 iterations tempPos=34 and index=37 which is running out of bounds of solutionSet. I would suggest to use var solutionSetArray = solutionSet.Split("|"); and also use LinqPad which can be easy for you to debug if possible,.
Related
I can't permanently replace the array members. When I change the value of String Clue, the string being displayed only displays the current value of clue. I think the problem us on the initialization of char[]. I tried to put them in other parts of the code but it produces error. Beginner here! Hope you can help me. Thanks! :)
private void clues(String clue)
{
int idx = numb[wordOn]+4;
char[] GuessHide = Words[idx].ToUpper().ToCharArray();
char[] GuessShow = Words[idx].ToUpper().ToCharArray();
for (int a = 0; a < GuessHide.Length; a++)
{
if (GuessShow[a] != Convert.ToChar(clue.ToUpper()))
GuessHide[a] = '*';
else
GuessHide[a] = Convert.ToChar(clue.ToUpper());
}
Guess(string.Join("", GuessHide));
}
Edited - because you initalize GuessHide at each call of calls in your code and you do not store its current state you basically reset it each time. Still, you can make some small changes in your code like this:
private static void clues(string clue, char[] GuessHide, char[] GuessShow)
{
for (int a = 0; a < GuessHide.Length; a++)
{
if (GuessShow[a] == Convert.ToChar(clue.ToUpper()))
{
GuessHide[a] = Convert.ToChar(clue.ToUpper());
}
}
Console.WriteLine(string.Join("", GuessHide));
}
Call it like this:
clues("p", GuessHide, GuessShow);
clues("a", GuessHide, GuessShow);
Initialise GuessShow and GuessHide in the outside code like this:
char[] GuessHide = new string('*', Words[idx].Length).ToCharArray();
char[] GuessShow = Words[idx].ToUpper().ToCharArray();
public class Program
{
static string[] Words;
static string[] HiddenWords;
public static void Main()
{
Words = new string[] { "Apple", "Banana" };
HiddenWords = new string[Words.Length];
for (int i = 0; i < Words.Length; i++)
{
HiddenWords[i] = new string('*', Words[i].Length);
}
Guess('P', 0);
Guess('a', 0);
Guess('A', 1);
Guess('N', 1);
Console.ReadLine();
}
private static void Guess(char clue, int idx)
{
string originalWord = Words[idx];
string upperedWord = Words[idx].ToUpper();
char[] foundSoFar = HiddenWords[idx].ToCharArray();
clue = char.ToUpper(clue);
for (int i = 0; i < upperedWord.Length; i++)
{
if (upperedWord[i] == clue)
{
foundSoFar[i] = originalWord[i];
}
}
HiddenWords[idx] = new string(foundSoFar);
Console.WriteLine(HiddenWords[idx]);
}
}
I am creating a word list of possible uppercase letters to prove how insecure 8 digit passwords are this code will write aaaaaaaa to aaaaaaab to aaaaaaac etc. until zzzzzzzz using this code:
class Program
{
static string path;
static int file = 0;
static void Main(string[] args)
{
new_file();
var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
var q = alphabet.Select(x => x.ToString());
int size = 3;
int counter = 0;
for (int i = 0; i < size - 1; i++)
{
q = q.SelectMany(x => alphabet, (x, y) => x + y);
}
foreach (var item in q)
{
if (counter >= 20000000)
{
new_file();
counter = 0;
}
if (File.Exists(path))
{
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(item);
Console.WriteLine(item);
/*if (!(Regex.IsMatch(item, #"(.)\1")))
{
sw.WriteLine(item);
counter++;
}
else
{
Console.WriteLine(item);
}*/
}
}
else
{
new_file();
}
}
}
static void new_file()
{
path = #"C:\" + "list" + file + ".txt";
if (!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
}
}
file++;
}
}
The Code is working fine but it takes Weeks to run it. Does anyone know a way to speed it up or do I have to wait? If anyone has a idea please tell me.
Performance:
size 3: 0.02s
size 4: 1.61s
size 5: 144.76s
Hints:
removed LINQ for combination generation
removed Console.WriteLine for each password
removed StreamWriter
large buffer (128k) for file writing
const string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
var byteAlphabet = alphabet.Select(ch => (byte)ch).ToArray();
var alphabetLength = alphabet.Length;
var newLine = new[] { (byte)'\r', (byte)'\n' };
const int size = 4;
var number = new byte[size];
var password = Enumerable.Range(0, size).Select(i => byteAlphabet[0]).Concat(newLine).ToArray();
var watcher = new System.Diagnostics.Stopwatch();
watcher.Start();
var isRunning = true;
for (var counter = 0; isRunning; counter++)
{
Console.Write("{0}: ", counter);
Console.Write(password.Select(b => (char)b).ToArray());
using (var file = System.IO.File.Create(string.Format(#"list.{0:D5}.txt", counter), 2 << 16))
{
for (var i = 0; i < 2000000; ++i)
{
file.Write(password, 0, password.Length);
var j = size - 1;
for (; j >= 0; j--)
{
if (number[j] < alphabetLength - 1)
{
password[j] = byteAlphabet[++number[j]];
break;
}
else
{
number[j] = 0;
password[j] = byteAlphabet[0];
}
}
if (j < 0)
{
isRunning = false;
break;
}
}
}
}
watcher.Stop();
Console.WriteLine(watcher.Elapsed);
}
Try the following modified code. In LINQPad it runs in < 1 second. With your original code I gave up after 40 seconds. It removes the overhead of opening and closing the file for every WriteLine operation. You'll need to test and ensure it gives the same results because I'm not willing to run your original code for 24 hours to ensure the output is the same.
class Program
{
static string path;
static int file = 0;
static void Main(string[] args)
{
new_file();
var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
var q = alphabet.Select(x => x.ToString());
int size = 3;
int counter = 0;
for (int i = 0; i < size - 1; i++)
{
q = q.SelectMany(x => alphabet, (x, y) => x + y);
}
StreamWriter sw = File.AppendText(path);
try
{
foreach (var item in q)
{
if (counter >= 20000000)
{
sw.Dispose();
new_file();
counter = 0;
}
sw.WriteLine(item);
Console.WriteLine(item);
}
}
finally
{
if(sw != null)
{
sw.Dispose();
}
}
}
static void new_file()
{
path = #"C:\temp\list" + file + ".txt";
if (!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
}
}
file++;
}
}
your alphabet is missing 0
With that fixed there would be 89 chars in your set. Let's call it 100 for simplicity. The set you are looking for is all the 8 character length strings drawn from that set. There are 100^8 of these, i.e. 10,000,000,000,000,000.
The disk space they will take up depends on how you encode them, lets be generous - assume you use some 8 bit char set that contains the these characters, and you don't put in carriage returns, so one byte per char, so 10,000,000,000,000,000 bytes =~ 10 peta byes?
Do you have 10 petabytes of disk? (10000 TB)?
[EDIT] In response to 'this is not an answer':
The original motivation is to create the list? The shows how large the list would be. Its hard to see what could be DONE with the list if it was actualised, i.e. it would always be quicker to reproduce it than to load it. Surely whatever point could be made by producing the list can also be made by simply knowing it's size, which the above shows how to work it out.
There are LOTS of inefficiencies in you code, but if your questions is 'how can i quickly produce this list and write it to disk' the answer is 'you literally cannot'.
[/EDIT]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have a situation where my string can't go past a certain point, so what I want to do is cut it into smaller strings of "x" characters, and then print them one by one on top of each other. They don't all need to be equal, if x is 5, and I have an 11 character string, printing 3 lines with 5, 5, and 1 characters is fine. Is there an easy way to do this in C#?
Example:
string Test = "This is a test string";
stringarray = Cutup(Test, 5);
//Result:
//"This "
//"is a "
//"test "
//"strin"
//"g"
try something like this:
public string[] Cutcup(string s, int l)
{
List<string> result = new List<string>();
for (int i = 0; i < s.Length; i += l)
{
result.Add(s.Substring(i, Math.Min(5, s.Substring(i).Length)));
}
return result.ToArray();
}
You could cut up the strings then do a test.lastIndexOf(' '); If that helps
You can use the String Manipultion function Substring() and a for loop to accomplish this.
here is an example
int maxChars = 5;
String myStr = "This is some text used in testing this method of splitting a string and just a few more chars and the string is complete";
List<String> mySubStrings = new List<String>();
while (myStr.Length > maxChars)
{
mySubStrings.Add(myStr.Substring(0,maxChars));
myStr = myStr.Substring(maxChars);
}
mySubStrings.ToArray();
List<string> result = new List<string>();
string testString = "This is a test string";
string chunkBuilder = "";
int chunkSize = 5;
for (int i = 0; i <= testString.Length-1; i++)
{
chunkBuilder += testString[i];
if (chunkBuilder.Length == chunkSize || i == testString.Length - 1)
{
result.Add(chunkBuilder);
chunkBuilder = "";
}
}
Another try, with less string concatenations
string Test = "This is a test string";
List<string> parts = new List<string>();
int i = 0;
do
{
parts.Add(Test.Substring(i,System.Math.Min(5, Test.Substring(i).Length)));
i+= 5;
} while (i < Test.Length);
Here are a couple more ways. Cutup2 below is more efficient but less pretty. Both pass the test case given.
private static IEnumerable<string> Cutup(string given, int chunkSize)
{
var skip = 0;
var iterations = 0;
while (iterations * chunkSize < given.Length)
{
iterations++;
yield return new string(given.Skip(skip).Take(chunkSize).ToArray());
skip += chunkSize;
}
}
private static unsafe IEnumerable<string> Cutup2(string given, int chunkSize)
{
var pieces = new List<string>();
var consumed = 0;
while (consumed < given.Length)
{
fixed (char* g = given)
{
var toTake = consumed + chunkSize > given.Length
? given.Length - consumed
: chunkSize;
pieces.Add(new string(g, consumed, toTake));
}
consumed += chunkSize;
}
return pieces;
}
All in one line
var size = 5;
var results = Enumerable.Range(0, (int)Math.Ceiling(test.Length / (double)size))
.Select(i => test.Substring(i * size, Math.Min(size, test.Length - i * size)));
I once made an extensionmethod that can be used for this:
public static IEnumerable<IEnumerable<T>> Subsequencise<T>(this IEnumerable<T> input, int subsequenceLength)
{
var enumerator = input.GetEnumerator();
SubsequenciseParameter parameter = new SubsequenciseParameter { Next = enumerator.MoveNext() };
while (parameter.Next)
yield return getSubSequence(enumerator, subsequenceLength, parameter);
}
private static IEnumerable<T> getSubSequence<T>(IEnumerator<T> enumerator, int subsequenceLength, SubsequenciseParameter parameter)
{
do
{
yield return enumerator.Current;
} while ((parameter.Next = enumerator.MoveNext()) && --subsequenceLength > 0);
}
// Needed to let the Subsequencisemethod know when to stop, since you cant use out or ref parameters in an yield-return method.
class SubsequenciseParameter
{
public bool Next { get; set; }
}
then you can do this:
string Test = "This is a test string";
stringarray = Test.Subsequencise(5).Select(subsequence => new String(subsequence.Toarray())).Toarray();
Here's a rather LINQy one-liner:
static IEnumerable<string> SliceAndDice1( string s , int n )
{
if ( s == null ) throw new ArgumentNullException("s");
if ( n < 1 ) throw new ArgumentOutOfRangeException("n");
int i = 0 ;
return s.GroupBy( c => i++ / n ).Select( g => g.Aggregate(new StringBuilder() , (sb,c)=>sb.Append(c)).ToString() ) ;
}
If that gives you a headache, try the more straightforward
static IEnumerable<string> SliceAndDice2( string s , int n )
{
if ( s == null ) throw new ArgumentNullException("s") ;
if ( n < 1 ) throw new ArgumentOutOfRangeException("n") ;
int i = 0 ;
for ( i = 0 ; i < s.Length-n ; i+=n )
{
yield return s.Substring(i,n) ;
}
yield return s.Substring(i) ;
}
I have this code:
int LRLength = LR.Count;
for (int i = 0; i < LR.Count; i++)
{
LRLength = LR.Count;
LR = merge(LR);
if (LR.Count < LRLength)
{
LR = merge(LR);
if (LR.Count == LRLength)
{
break;
}
}
}
And this is the function merge:
private List<Lightnings_Extractor.Lightnings_Region> merge(List<Lightnings_Extractor.Lightnings_Region> Merged)
{
List<Lightnings_Extractor.Lightnings_Region> NewMerged = new List<Lightnings_Extractor.Lightnings_Region>();
Lightnings_Extractor.Lightnings_Region reg;
int dealtWith = -1;
for (int i = 0; i < Merged.Count; i++)
{
if (i != dealtWith)
{
reg = new Lightnings_Extractor.Lightnings_Region();
if (i < Merged.Count - 1)
{
if (Merged[i].end + 1 >= Merged[i + 1].start)
{
reg.start = Merged[i].start;
reg.end = Merged[i + 1].end;
NewMerged.Add(reg);
dealtWith = i + 1;
}
else
{
reg.start = Merged[i].start;
reg.end = Merged[i].end;
NewMerged.Add(reg);
}
}
else
{
reg.start = Merged[i].start;
reg.end = Merged[i].end;
NewMerged.Add(reg);
}
}
}
return NewMerged;
}
In this class: Lightnings_Extractor.Lightnings_Region I have only two int variables.
The idea in this function is to get a List and merge areas that are congruent.
For example once im calling the function and the List LR Length is 8 now I will get it back less. For example if it needed to merge two indexs to one then the List I will get in return the Length will be 7. If it will need to merge another indexs then the Length will be 6 and so on.
What I want to check on the first code above is when I should stop calling the function to merge indexs.
If the length was 8 and the next time it's still 8 do nothing stop the loop.
If the length is 8 and the next time it's 7 then call the function again.
If the length is 7 stop the loop . But if the length is 6 keep calling it once again.
Untill the last length will be the same as the length before !!!
So I tried this code but it's not working good:
int LRLength = LR.Count;
for (int i = 0; i < LR.Count; i++)
{
LRLength = LR.Count;
LR = merge(LR);
if (LR.Count < LRLength)
{
LR = merge(LR);
if (LR.Count == LRLength)
{
break;
}
}
}
Trying to make some assumptions as to what you're trying to accomplish. The following will basically capture the original length of the list for comparison. It will run at least once, and keep running until the LRLength == LR.Count
int LRLength = LR.Count;
do{
LR = merge(LR);
} while(LR.Count != LRLength);
If you were trying to run the loop until you got the same count twice in a row:
int prevCount;
do{
prevCount = LR.Count;
LR = merge(LR);
} while(prevCount != LR.Count);
Here's my code:
StreamReader reader = new StreamReader("war.txt");
string input = null;
while ((input = reader.ReadLine()) != null)
{
Console.WriteLine(input);
}
reader.Close();
The program above reads and prints out from the file “war.txt” line-by-line. I need to re-write the program so that it prints out in reverse order, i.e., last line first and first line last. For example, if “war.txt” contains the following:
Hello.
How are you?
Thank you.
Goodbye.
The program should prints out:
Goodbye.
Thank you.
How are you?
Hello.
I am very new in C# please help! Thanks!
To do that, you are going to have to buffer the data anyway (unless you do some tricky work with the FileStream API to read the file backwards). How about just:
var lines = File.ReadAllLines("war.txt");
for(int i = lines.Length - 1; i >= 0; i--)
Console.WriteLine(lines[i]);
which just loads the file (in lines) into an array, and then prints the array starting from the end.
A LINQ version of that would be:
foreach(var line in File.ReadLines("war.txt").Reverse())
Console.WriteLine(line);
but frankly the array version is more efficient.
You can do it using recursion with something like this:
void printReverse(int n)
{
String line = reader.readLine();
if (n > 0)
printReverse(n-1);
System.out.println(line);
}
Have a look at adding the lines to a List, then using Reverse on the list and then maybe the ForEach to output the items.
Another option: store each line into a Stack as you read them. After reading the file, pop the stack to print the lines in reverse order.
with the enumerable extension functions, this can be done shorter:
foreach(var l in File.ReadAllLines("war.txt").Reverse())
Console.WriteLine(l);
try
File.ReadAllLines(myFile)
.Reverse();
full code
var list = File.ReadAllLines(filepath).Reverse().ToList();
foreach (var l in list)
Console.WriteLine(l);
Implementation detail
Enumerable.Reverse Method - Inverts the order of the elements in a sequence
File.ReadAllLines Method (String) - Opens a text file, reads all lines of the file, and then closes the file.
here is a example mate, remember to add "using System.IO"
try
{
const int Size = 7;
decimal[] numbers = new decimal[Size];
decimal total = 0m;
int index = 0;
StreamReader inputfile;
inputfile = File.OpenText("Sales.txt");
while (index < numbers.Length && !inputfile.EndOfStream)
{
numbers[index] = decimal.Parse(inputfile.ReadLine());
index++;
}
inputfile.Close();
foreach (decimal Sales in numbers)
{
outputlistBox1.Items.Add(Sales);
total = total + Sales;
}
textBox1.Text = total.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Here is another example from a textbook i bought few years ago, this has highest/lowest/average scores..(remember to use 'using System IO;)
private double Average(int[] iArray)
{
int total = 0;
double Average;
for (int index = 0; index < iArray.Length;
index++)
{
total += iArray[index];
}
Average = (double) total / iArray.Length;
return Average;
}
private int Highest(int[] iArray)
{
int highest = iArray[0];
for (int index = 1; index < iArray.Length; index++)
{
if (iArray[index] > highest)
{
highest = iArray[index];
}
}
return highest;
}
private int Lowest(int[] iArray)
{
int lowest = iArray[0];
for (int index = 1; index < iArray.Length; index++)
{
if (iArray[index] < lowest)
{
lowest = iArray[index];
}
}
return lowest;
}
private void button1_Click(object sender, System.EventArgs e)
{
try
{
const int SIZE = 5;
int[] Scores = new int [SIZE];
int index = 0;
int highestScore;
int lowestScore;
double averageScore;
StreamReader inputFile;
inputFile = File.OpenText("C:\\Users\\Asus\\Desktop\\TestScores.txt");
while (!inputFile.EndOfStream && index < Scores.Length)
{
Scores[index] = int.Parse(inputFile.ReadLine());
index++;
}
inputFile.Close();
foreach (int value in Scores)
{
listBox1.Items.Add(value);
}
highestScore = Highest(Scores);
lowestScore = Lowest(Scores);
averageScore = Average(Scores);
textBox1.Text = highestScore.ToString();
textBox2.Text = lowestScore.ToString();
textBox3.Text = averageScore.ToString("n1");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}