What am I doing wrong when using string.join in my code? - c#

I have the code below, which I need to separate the result with ", ". I have so far used different methods because whenever I try to use String.Join, it doesn't work as expected. What am I doing wrong?
Code:
using System;
using System.Collections.Generic;
using System.Linq;
namespace _5._PrintEvenNumbers
{
class Program
{
public static void Main()
{
var input = Console.ReadLine().Split().Select(int.Parse).ToList();
var numbers = new Queue<int>();
for (int i = 0; i < input.Count(); i++)
{
if (input[i] % 2 == 0)
{
numbers.Enqueue(input[i]);
}
}
while (numbers.Any())
{
Console.Write(string.Join(", ", numbers.Dequeue()));
}
}
}
}
Expected result should be "2, 4, 6" for example. Currently it prints it "246"

Just replace
while (numbers.Any())
{
Console.Write(string.Join(", ", numbers.Dequeue()));
}
with
Console.Write(string.Join(", ", numbers));
Unless you really need to dequeue.

Related

Permutation Algorithm OutOfMemory Exception

Please help me to how to fix OutOfMemory exception using below code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Permutation
{
class Program
{
static void Main(string[] args)
{
CreatePartsByFreezingEachElementOnce("abcedfghijk");
PrintPossiblePermutations(false);
Console.WriteLine("---------------");
PrintPossiblePermutations(true);
Console.ReadLine();
}
static void PrintPossiblePermutations(bool unique)
{
var allPermutations = new List<string>();
foreach (var item in _listWithFreezedKey)
if (item.Item2.Count() == 2)
{
allPermutations.Add(Swap(String.Join(",", item.Item1), item.Item2[0], item.Item2[1]));
allPermutations.Add(Swap(String.Join(",", item.Item1), item.Item2[1], item.Item2[0]));
}
if (unique)
{
var uniuePermutations = allPermutations.Distinct();
// PrintPermutations(uniuePermutations.ToList());
Console.WriteLine(uniuePermutations.Count());
}
else
{
// PrintPermutations(allPermutations);
Console.WriteLine(allPermutations.Count());
}
}
static void PrintPermutations(List<string> permutations)
{
int i = 1;
foreach (var item in permutations)
{
Console.WriteLine(string.Format("{0} :{1}", i, item));
i++;
}
}
static List<Tuple<List<char>, List<char>>> _listWithFreezedKey = new List<Tuple<List<char>, List<char>>>();
static void CreatePartsByFreezingEachElementOnce(string str, List<char> indexToFreeze = null)
{
List<Tuple<List<char>, List<char>>> _innerlistWithFreezedKey = new List<Tuple<List<char>, List<char>>>();
var arr = str.ToCharArray().ToList();
var copy = arr;
if (indexToFreeze == null)
{
indexToFreeze = new List<char>();
}
for (int i = 0; i < arr.Count(); i++)
{
copy = str.ToCharArray().ToList();
var nth = arr[i];
copy.RemoveAt(i);
indexToFreeze.Add(nth);
_listWithFreezedKey.Add(new Tuple<List<char>, List<char>>(indexToFreeze.ToList(), copy));
_innerlistWithFreezedKey.Add(new Tuple<List<char>, List<char>>(indexToFreeze.ToList(), copy));
indexToFreeze.RemoveAt(indexToFreeze.Count() - 1);
}
foreach (var item in _innerlistWithFreezedKey)
{
List<char> l = item.Item2;
CreatePartsByFreezingEachElementOnce(String.Join("", l), item.Item1);
}
}
static string Swap(string frezedPart, char swapChar1, char swapChar2)
{
return frezedPart + "," + swapChar1 + "," + swapChar2;
}
}
}
If you run this code using 10 chrs, it throws out of memory exception. But for 9 chars , it returns result.
It was my interview question to write a code such that it should not go out of memory if big data passed.
Thanks,
Your problem is that you want to generate all permutations at once, instead of generating them one-by-one. You are looking for an algorithm which produces the next permutation.
See the first page of Knuth's book on generating permutations.
I would like to answer my question by myself because it may help someone as well.
I will use Iterator Design Pattern to remove unused elements from memory and will convert collection into sequence.
Thanks,

Async Await Loop/Math problems

I'm making a little program to practice with WPF and Async/Await for multithreading, and what the program does is:
Find all the prime numbers between two numbers "a" and "b", and spit them out to a textbox called "Prime1".
Simultaneously in a different task, find all the prime numbers between "c" and "d", and spit them out to a textbox called "Prime2".
A button in the window will allow the user to click it, and it will keep track of how many times it has been clicked, whilst the other two tasks find prime numbers, to demonstrate asynchronous operations.
The code is as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF_Asynch_Project
{
public partial class MainWindow : Window
{
public int ClickAmount = 0;
public MainWindow()
{
InitializeComponent();
DelegationIsAwesome();
}
private void Test_Click(object sender, RoutedEventArgs e)
{
ClickAmount++;
MessageBox.Show("You clicked me " + ClickAmount.ToString() + " times!");
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
}
private async void DelegationIsAwesome()
{
Task enumtask = new Task(() => FindPrimes(100000, 100000000));
Task[] enumall = new Task[2];
enumall[0] = enumtask;
enumall[1] = new Task(() => FindPrimes2(1000, 10000));
enumall.ToList().ForEach(t => t.Start());
await Task.WhenAll(enumall).ConfigureAwait(false);
}
private void FindPrimes(long lower, long upper)
{
for (long i = lower; i < upper; i++)
{
long primeornot = 1;
for (long q = 2; q < i; q++)
{
if (i % q == 0)
{
primeornot = 0;
}
}
if (primeornot == 1)
{
System.Threading.Thread.Sleep(6);
Prime1.Dispatcher.BeginInvoke(
(Action)(()=>{ Prime1.Text += i.ToString() + ", "; }));
}
}
}
private void FindPrimes2(int lower, long upper)
{
for (int i = lower; i < upper; i++)
{
int primeornot = 1;
for (int q = 2; q < i; q++)
{
if (i % q == 0)
{
primeornot = 0;
}
}
if (primeornot == 1)
{
System.Threading.Thread.Sleep(5);
Prime2.Dispatcher.BeginInvoke(
(Action)(() => { Prime2.Text += i.ToString() + ", "; }));
}
}
}
}
}
However I get odd results. The following is a picture from the program:
Obviously the output from the prime-finding methods is incorrect. But why does it keep repeating those same numbers? It also sometimes spits out a number equal to UpperBound even though "i" should never equal or be greater than UpperBound.
What is happening to my output, and how do I fix it?
This has nothing to do with async/await, really.
You're calling BeginInvoke here:
Prime1.Dispatcher.BeginInvoke(
(Action)(()=>{ Prime1.Text += i.ToString() + ", "; }));
... and your lambda expression uses i, which means it will append the current value of i when the delegate executes. That's not necessarily the value of i when you call BeginInvoke.
If you want to capture the value (rather than the variable) you basically need to instantiate a new variable each time. You might as well do the conversion to a string:
string textToAppend = i + ", ";
// No need for braces here...
Prime1.Dispatcher.BeginInvoke((Action)(() => Prime1.Text += textToAppend));
Because you've declared the variable textToAppend inside the loop, each iteration will create a delegate capturing a separate variable.
You need to do this in both of your methods.

Store the outcome of an algorithm that looks for prime numbers in a file (C#)

I am trying to make a program that looks for prime numbers, displays them in the console and stores the numbers in a file. The program already stores the numbers in a file, but it doesn't display the numberrs in the console. Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Priemgetallen
{
class Program
{
static void Main()
{
using (StreamWriter writer = new StreamWriter("C://Users//mens//Documents//PriemGetallen.txt"))
{
Console.SetOut(writer);
Act();
}
}
static void Act()
{
double maxGetal = double.MaxValue;
Console.WriteLine("--- Primes between 0 and 100 ---");
for (int i = 0; i < maxGetal; i++)
{
bool prime = PrimeTool.IsPrime(i);
if (prime)
{
Console.Write("Prime: ");
Console.WriteLine(i);
}
}
}
public static class PrimeTool
{
public static bool IsPrime(int candidate)
{
// Test whether the parameter is a prime number.
if ((candidate & 1) == 0)
{
if (candidate == 2)
{
return true;
}
else
{
return false;
}
}
// Note:
// ... This version was changed to test the square.
// ... Original version tested against the square root.
// ... Also we exclude 1 at the end.
for (int i = 3; (i * i) <= candidate; i += 2)
{
if ((candidate % i) == 0)
{
return false;
}
}
return candidate != 1;
}
}
}
}
That's because of the line Console.SetOut(writer);. You are sending console output to the file.
Rather than do it the way you are, ditch the StreamWriter and instead use:
if (prime)
{
var primeText = string.Format("Prime: {0}", i);
Console.WriteLine(primeText );
File.AppendAllText(#"C:\Users\mens\Documents\PriemGetallen.txt",
primeText + Environment.NewLine);
}

c# parallel arrays data from text file

Here's the problem: Index was outside the bounds of the array. Assignment: Write a program that determines the number of students who can still enroll in a given class. Design your solution using parallel arrays. Test your solution by retrieving the following data from a text file. Define a exception class for this problem if the current enrollment exceeds the maximum enrollment by more than three. Halt the program and display a message indicating which course is over-enrolled.
Here's the original code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
private static string[] classes = { "CS150", "CS250", "CS270", "CS300", "CS350" };
private static int[] currentEnrolled = { 18, 11, 9, 4, 20 };
private static int[] maxEnrollment = { 20, 20, 20, 20, 20 };
private static int currentEnrollment()
{
int enrolled = 0;
foreach (int i in currentEnrolled)
{
enrolled += i;
}
return enrolled;
}
private static void listClasses()
{
foreach (string i in classes)
{
Console.WriteLine("Class: {0}", i);
}
}
private static void ClassStatus()
{
for (int i = 0; i < currentEnrolled.Length; i++)
{
Console.WriteLine("Class: {0}, Max: {1}, Current: {2}, remaining: {3}", classes[i], maxEnrollment[i], currentEnrolled[i], maxEnrollment[i] - currentEnrolled[i]);
}
}
static void Main(string[] args)
{
Console.WriteLine("Currently Enrolled: {0}", currentEnrollment());
ClassStatus();
Console.ReadKey(false);
}
}
}
Now, I've been editing the above code to take a text file instead, however I get an error. Here's what I'm working with:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
private static string[] classes = new string[900];
private static int[] currentEnrolled = new int[900];
private static int[] maxEnrollment = new int[900];
private static int currentEnrollment()
{
int enrolled = 0;
foreach (int i in currentEnrolled)
{
enrolled += i;
}
return enrolled;
}
private static void listClasses()
{
foreach (string i in classes)
{
Console.WriteLine("Class: {0}", i);
}
}
private static void ClassStatus()
{
for (int i = 0; i < currentEnrolled.Length; i++)
{
Console.WriteLine("Class: {0}, Max: {1}, Current: {2}, remaining: {3}", classes[i], maxEnrollment[i], currentEnrolled[i], maxEnrollment[i] - currentEnrolled[i]);
}
}
static void Main(string[] args)
{
string[] lines = File.ReadAllLines("classes.txt");
int i = 0;
foreach (string line in File.ReadAllLines("classes.txt"))
{
string[] parts = line.Split(',');
while (i < 900 && i < parts.Length)
{
classes[i] = parts[1];
currentEnrolled[i] = int.Parse(parts[2]);
maxEnrollment[i] = int.Parse(parts[3]);
}
i++;
}
Console.WriteLine("Currently Enrolled: {0}", currentEnrollment());
ClassStatus();
Console.ReadKey(false);
}
}
}
Some of the components used in the above code were taken from this article: Splitting data from a text file into parallel arrays
Text file looks like this:
CS150,18,20
CS250,11,20
CS270,32,25
CS300,4,20
CS350,20,20
Any assistance will be appreciated. And yes, this is an assignment. Programming is most definitely not my strong suit.
There seem to be multiple problems with your while loop.
First, parts.Length will always be 3, since you have 2 commas and split on that. So the condition i < 900 && i < parts.Length does not really make sense, it's like i < 900 and i < 3, so it will always stop at 3. The intent is not really clear here, I think you meant to loop on each 900 values, but fi soforeach already does that for you.
Next, since there's 3 parts and C# arrays are 0-based, it should be parts[0], parts[1] and parts[2]. That's what causing your 'out of range' exception.
Finally, i++; should be in your while loop. If you leave it outside, you will loop forever as the index will never increase.
Basically, it should be something like this :
while (i < 900)
{
classes[i] = parts[0];
currentEnrolled[i] = int.Parse(parts[1]);
maxEnrollment[i] = int.Parse(parts[2]);
i++;
}
Again, the 900 is not really clear since you don't have 900 values per line (remember you're in a foreach). In my opinion you might as well scratch all that and redo it carefully.
What you need to do, is the following :
Read the file and store all the lines
Foreach line do:
Split the line in 3 parts
Store each separate part
Write results
For the "custom exception" part, you can add:
For the length of currentEnrollment do:
If currentEnrollment at current index is superior than maxEnrollment at current index do:
Throw a new exception with the className at current index

how to point to back of generic list c#

Is there a way to point to the last item added to a generic list in c# ? Like the back() for a vector in c++
If you're using the 3.5 framework
using System.Linq;
using System.Collections.Generic;
public static class Program {
public static void Main() {
Console.WriteLine(new List<int> { 1, 2, 3 }.Last()); // outputs - 3
}
}
List<int> myList = new List<int>();
for( int i = 0; i < 5; i++ )
{
myList.Add (i);
}
Console.WriteLine (String.Format ("Last item: {0}", myList[myList.Count - 1]));
list.Last() ?

Categories

Resources