DEV Community

Cover image for Let's Party with Stacks and Queues! Pt 2
Arit Developer
Arit Developer

Posted on • Updated on

Let's Party with Stacks and Queues! Pt 2

In Part 1, we configured classes for our stack of meals, and queue of guests. Now let's setup our Party class, which accepts our arrays of meals & guests, and initializes instances of MealStack and GuestQueue.

class Party
  attr_accessor :meals, :guests

  def initialize(meals_array, guest_array)
    self.meals = MealStack.new(meals_array)
    self.guests = GuestQueue.new(guest_array)
  end
end
Enter fullscreen mode Exit fullscreen mode

It would be nice to view the meals and guests at any point during the party, so let's create a view_party method for that:

def view_party
    puts "Party Status:\n Meals: #{meals.display_meals}\n Guests: #{guests.display_queue}\n\n"
end
Enter fullscreen mode Exit fullscreen mode

For a guest to be properly served, the meal at the top of the stack has to match the meal preference of the first guest in the queue. So we create a method match? that checks for this:

def match?
    meals.top_meal == guests.first_guest
end
Enter fullscreen mode Exit fullscreen mode

Next we create a move_queue method that does three things:

  • Shows us the party status
  • Removes guests that have been served successfully
  • Moves guests in front of the queue to the back when the top meal doesn't match their preference

We're also including some statements to clue us in to what is happening.

For a meal-guest match, the top meal is removed and the first guest leaves the queue. For a mismatch, the first guest moves to the back of the queue and the move_queue method is called again for the updated first guest:

def move_queue
    view_party

    if match?
      meals.take_meal
      served = guests.leave_queue
      puts "Guest wanting a #{served} meal has been served\n\n"
    else
      guests.rejoin_queue
      puts "No one was served the last round\n\n"
      move_queue
    end
end
Enter fullscreen mode Exit fullscreen mode

Finally, we'll create a meal_service method that sets everything in motion. The meal service will run until either all meals are gone, or all guests have been served. A cute "party report" is generated after the meal service concludes:

def meal_service
    until meals.stack_empty? || guests.queue_empty?
      move_queue
    end
    puts "Meals Left: #{meals.display_meals}\nUnserved Guests: #{guests.display_queue}"
end
Enter fullscreen mode Exit fullscreen mode

Awesome! Let's build a party with the following meals and guests:

my_party = Party.new(%w[vegetarian vegan normal paleo], %w[normal paleo vegan vegetarian])

my_party.meal_service
Enter fullscreen mode Exit fullscreen mode

And here's the complete file:

class MealStack
  attr_accessor :meals

  def initialize(meals_array)
    self.meals = meals_array
  end

  def top_meal
    meals.last
  end

  def take_meal
    meals.pop
  end

  def stack_empty?
    meals.empty?
  end

  def display_meals
    meals.reverse.inspect
  end

  def size
    meals.length
  end
end

class GuestQueue
  attr_accessor :guests

  def initialize(guest_array)
      self.guests = guest_array
  end

  def first_guest
      guests.first
  end

  def join_queue(guest)
      guests.push(guest)
  end

  def leave_queue
      guests.shift
  end

  def rejoin_queue
      join_queue(leave_queue)
  end

  def queue_empty?
      guests.empty?
  end

  def display_queue
      guests.inspect
  end

  def size
      guests.length
  end
end

class Party
  attr_accessor :meals, :guests

  def initialize(meals_array, guest_array)
    self.meals = MealStack.new(meals_array)
    self.guests = GuestQueue.new(guest_array)
  end

  def view_party
    puts "Party Status:\n Meals: #{meals.display_meals}\n Guests: #{guests.display_queue}\n\n"
  end

  def match?
    meals.top_meal == guests.first_guest
  end

  def move_queue
    view_party

    if match?
      meals.take_meal
      served = guests.leave_queue
      puts "Guest wanting a #{served} meal has been served\n\n"
    else
      guests.rejoin_queue
      puts "No one was served the last round\n\n"
      move_queue
    end
  end

  def meal_service
    until meals.stack_empty? || guests.queue_empty?
      move_queue
    end
    puts "Meals Left: #{meals.display_meals}\nUnserved Guests: #{guests.display_queue}"
  end
end

my_party = Party.new(%w[vegetarian vegan normal paleo], %w[normal paleo vegan vegetarian])

my_party.meal_service
Enter fullscreen mode Exit fullscreen mode

Here is my output after running my program's file in Terminal:

Party Status:
 Meals: ["paleo", "normal", "vegan", "vegetarian"]
 Guests: ["normal", "paleo", "vegan", "vegetarian"]

No one was served the last round

Party Status:
 Meals: ["paleo", "normal", "vegan", "vegetarian"]
 Guests: ["paleo", "vegan", "vegetarian", "normal"]

Guest wanting a paleo meal has been served

Party Status:
 Meals: ["normal", "vegan", "vegetarian"]
 Guests: ["vegan", "vegetarian", "normal"]

No one was served the last round

Party Status:
 Meals: ["normal", "vegan", "vegetarian"]
 Guests: ["vegetarian", "normal", "vegan"]

No one was served the last round

Party Status:
 Meals: ["normal", "vegan", "vegetarian"]
 Guests: ["normal", "vegan", "vegetarian"]

Guest wanting a normal meal has been served

Party Status:
 Meals: ["vegan", "vegetarian"]
 Guests: ["vegan", "vegetarian"]

Guest wanting a vegan meal has been served

Party Status:
 Meals: ["vegetarian"]
 Guests: ["vegetarian"]

Guest wanting a vegetarian meal has been served

Meals Left: []
Unserved Guests: []
Enter fullscreen mode Exit fullscreen mode

YAY! Everyone was served, and our shindig was a success! But let's think for a minute: even though some of our guests had to rejoin the queue due to meal mismatches, everyone eventually got served because there was 1 meal present for every guest.

What if there was a meal on our stack that nobody wanted? Well, due to how stacks work, we can't access any meals under the unwanted meal until we get rid of said meal. However, we don't want to trash any top meal until we know for sure that no guests want it. That's what we'll be looking at in Part 3...

Top comments (0)