2

We've been asked to create a program which takes 2 input (which I have parsed) for seats and passengers in a plane and randomly place passengers on seats in a plane in one output as well as placing the remaining seats in a secondary output.

I was wondering if there is a simple way to replace the remaining values in HashSet, into the listBoxLedige.

As it works now, the seats are being distributing but the values in the secondary output arent related the the first output.

if(passengers > seats)
{
    MessageBox.Show("For mange passagerer");
}
else
{
    HashSet<int> check = new HashSet<int>();
    for(int i = 0; i <= passengers - 1; i++)
    {
        int resultat = rnd.Next(1, seats + 1);
        while(check.Contains(resultat))
        {
            resultat = rnd.Next(1, seats + 1);
        }
        check.Add(resultat);
        int[] passagerer01 = new int[passengers];
        passagerer01[i] = i+1;
        listBoxFulde.Items.Add("Passager #" + passagerer01[i] + "på sæde #" + resultat);
    }
    HashSet<int> ledige01 = new HashSet<int>();
    for(int i = 0; i <= (seats - passengers - 1); i++)
    {
        int tilbage = rnd.Next(1, seats + 1);
        while(ledige01.Contains(tilbage))
        {
            ledige01.Add(tilbage);
        }
        listBoxLedige.Items.Add("Sæde #" + tilbage);
Szymon
  • 42,577
  • 16
  • 96
  • 114
user2821342
  • 73
  • 1
  • 1
  • 3
  • Couldn't you use [`HashSet.ExceptWith`](http://msdn.microsoft.com/en-us/library/bb299875.aspx) which removes all elements from the set that are in the collection? So the remaining values are all items that you want to add to the listbox. – Tim Schmelter Sep 26 '13 at 22:17

3 Answers3

2

I'm not exactly sure I understand your problem, but have you taken a look at the Except LINQ extension method? Judging by your wording ("remaining values"), it might be the right method for you.

Edit Here's how it's done:

 IEnumerable<int> empty = allSeats.Except(check);

Note how empty is now a deferred enumerator (unless you do a .ToArray(), .ToList() or similar on it).

sehe
  • 374,641
  • 47
  • 450
  • 633
Marius Schulz
  • 15,976
  • 12
  • 63
  • 97
  • It's not. You should always prefer member functions over generic Extension Methods. In this case because it's way more efficient given that things are already in a HashSet. Then again, until a plane has several hundreds of thousands of seats, it shouldn't become a bottleneck for this exercise. The principle holds: teach people to **use the correct data structures /correctly/** – sehe Sep 26 '13 at 22:25
  • @sehe I agree, people should know how to use data structures correctly, I'm definitely with you on that point. Still, `Except` should work fine, too. For more detail, refer to http://msdn.microsoft.com/en-us/library/bb397728.aspx. – Marius Schulz Sep 26 '13 at 22:33
  • excellent link. I'll +1 as with the caveat discussed, it is informative. – sehe Sep 26 '13 at 22:35
1

Here's what I'd do (see Range and ExceptWith):

HashSet<int> ledige01 = new HashSet<int>(
    Enumerable.Range(1, seats));

ledige01.ExceptWith(taken);

Note in generating the seeds you can remove the trial and error by simply shuffling the seats and taking the first N:

var taken = HashSet<int>(Enumerable.Range(1,seats).Shuffle().Take(passengers));

For hints on how to do shuffle, see e.g. Optimal LINQ query to get a random sub collection - Shuffle


As an aside:

    int[] passagerer01 = new int[passengers];
    passagerer01[i] = i+1;
    listBoxFulde.Items.Add("Passager #" + passagerer01[i] + "på sæde #" + resultat);

looks to be something other than you need :) But I'm assuming it's unfinished and you're likely aware of that

A 'fully' edited take:

if(passengers > seats)
{
    MessageBox.Show("For mange passagerer");
}
else
{
    HashSet<int> taken = new HashSet<int>();
    for(int i = 0; i <= passengers - 1; i++)
    {
        int resultat;
        do {
            resultat = rnd.Next(1, seats + 1);
        } while(taken.Contains(resultat));

        taken.Add(resultat);

        listBoxFulde.Items.Add("Passager #" + (i+1) + "på sæde #" + resultat);
    }

    HashSet<int> ledige01 = new HashSet<int>(
        Enumerable.Range(1, seats));

    ledige01.ExceptWith(taken);

if(passengers > seats)
{
    MessageBox.Show("For mange passagerer");
}
else
{
    HashSet<int> taken = new HashSet<int>();
    for(int i = 0; i <= passengers - 1; i++)
    {
        int resultat;
        do {
            resultat = rnd.Next(1, seats + 1);
        } while(taken.Contains(resultat));

        taken.Add(resultat);

        listBoxFulde.Items.Add("Passager #" + (i+1) + "på sæde #" + resultat);
    }

    HashSet<int> ledige01 = new HashSet<int>(Enumerable.Range(1, seats));

    ledige01.ExceptWith(taken);

    foreach(var tilbage in ledige01)
        listBoxLedige.Items.Add("Sæde #" + tilbage);
Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Really appreciate the answer. I used the int array to produce the passenger numbers. As I mentioned I am a complete newbie. I did indeed consider ExceptWith but I havent been able to figure out how to use it to produce an output in the listBox. – user2821342 Sep 26 '13 at 22:36
  • Oh, lol. I thought that was trivial, I've expanded the bit under `// etc` now. Cheers (ps. I'm assuming `tilbage` means _available_ or _empty_ or something. We don't all speak Mandarin :)) – sehe Sep 26 '13 at 22:40
  • Again, its 4 hours totally without any experience coding anything before so most of us are pretty clueless. I really appreciate the help! – user2821342 Sep 26 '13 at 22:46
0

Not a hundred percent sure I understand your problem or solution, but are you aware that you declare and initialize passagerer01 once for each passenger, then deterministically (not randomly) assign seat i+1 to passenger i and afterwards throw away that array? If you wanted to keep the information, you'd have to declare the array outside the for loop.

Also, it doesn't really seem like you're doing anything meaningful in that second part of your code. To determine the empty seats, it would make sense to go through numbers 1 to passengers, check if they are in the set check and, if not, add them to set ledige01. Or, of course, to do something equivalent using a library method as suggested by sehe.

As a last note, in computer science you usually start counting from zero. Thus, you would usually have seat numbers 0 to seats-1 and choose seats randomly like so: rnd.Next(0, seats). And you would usually loop like this: for(int i = 0; i < passengers; i++) instead of for(int i = 0; i <= passengers - 1; i++).

Johannes Bauer
  • 462
  • 5
  • 15
  • Thanks, I'll try and take note of those tips for future projects. Most of this has been learning by doing so thats why the code is rather sloppy. – user2821342 Sep 26 '13 at 23:42