Task: Cheryl's birthday


C++: #include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

const vector<string> MONTHS = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

struct Birthday {
    int month, day;

    friend ostream &operator<<(ostream &, const Birthday &);
};

ostream &operator<<(ostream &out, const Birthday &birthday) {
    return out << MONTHS[birthday.month - 1] << ' ' << birthday.day;
}

template <typename C>
bool monthUniqueIn(const Birthday &b, const C &container) {
    auto it = cbegin(container);
    auto end = cend(container);
    int count = 0;
    while (it != end) {
        if (it->month == b.month) {
            count++;
        }
        it = next(it);
    }
    return count == 1;
}

template <typename C>
bool dayUniqueIn(const Birthday &b, const C &container) {
    auto it = cbegin(container);
    auto end = cend(container);
    int count = 0;
    while (it != end) {
        if (it->day == b.day) {
            count++;
        }
        it = next(it);
    }
    return count == 1;
}

template <typename C>
bool monthWithUniqueDayIn(const Birthday &b, const C &container) {
    auto it = cbegin(container);
    auto end = cend(container);
    while (it != end) {
        if (it->month == b.month && dayUniqueIn(*it, container)) {
            return true;
        }
        it = next(it);
    }
    return false;
}

int main() {
    vector<Birthday> choices = {
        {5, 15}, {5, 16}, {5, 19}, {6, 17}, {6, 18},
        {7, 14}, {7, 16}, {8, 14}, {8, 15}, {8, 17},
    };

    
    
    vector<Birthday> filtered;
    for (auto bd : choices) {
        if (!monthUniqueIn(bd, choices)) {
            filtered.push_back(bd);
        }
    }

    
    
    vector<Birthday> filtered2;
    for (auto bd : filtered) {
        if (!monthWithUniqueDayIn(bd, filtered)) {
            filtered2.push_back(bd);
        }
    }

    
    
    vector<Birthday> filtered3;
    for (auto bd : filtered2) {
        if (dayUniqueIn(bd, filtered2)) {
            filtered3.push_back(bd);
        }
    }

    
    
    vector<Birthday> filtered4;
    for (auto bd : filtered3) {
        if (monthUniqueIn(bd, filtered3)) {
            filtered4.push_back(bd);
        }
    }

    if (filtered4.size() == 1) {
        cout << "Cheryl's birthday is " << filtered4[0] << '\n';
    } else {
        cout << "Something went wrong!\n";
    }

    return 0;
}










Ada: with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   type Months is
     (January, February, March, April, May, June, July, August, September,
      November, December);
   type day_num is range 1 .. 31;
   type birthdate is record
      Month  : Months;
      Day    : day_num;
      Active : Boolean;
   end record;

   type birthday_list is array (Positive range <>) of birthdate;

   Possible_birthdates : birthday_list :=
     ((May, 15, True), (May, 16, True), (May, 19, True), (June, 17, True),
      (June, 18, True), (July, 14, True), (July, 16, True), (August, 14, True),
      (August, 15, True), (August, 17, True));

   procedure print_answer is
   begin
      for the_day of Possible_birthdates loop
         if the_day.Active then
            Put_Line (the_day.Month'Image & "," & the_day.Day'Image);
         end if;
      end loop;
   end print_answer;

   procedure print_remaining is
      count : Natural := 0;
   begin
      for date of Possible_birthdates loop
         if date.Active then
            count := count + 1;
         end if;
      end loop;
      Put_Line (count'Image & " remaining.");
   end print_remaining;

   
   procedure first_pass is
      count : Natural;
   begin
      for first_day of Possible_birthdates loop
         count := 0;
         for next_day of Possible_birthdates loop
            if first_day.Day = next_day.Day then
               count := count + 1;
            end if;
         end loop;

         if count = 1 then
            for the_day of Possible_birthdates loop
               if the_day.Active and then first_day.Month = the_day.Month then
                  the_day.Active := False;
               end if;
            end loop;
         end if;
      end loop;
   end first_pass;

   
   procedure second_pass is
      count : Natural;
   begin
      for first_day of Possible_birthdates loop
         if first_day.Active then
            count := 0;
            for next_day of Possible_birthdates loop
               if next_day.Active then
                  if next_day.Day = first_day.Day then
                     count := count + 1;
                  end if;
               end if;
            end loop;

            if count > 1 then
               for next_day of Possible_birthdates loop
                  if next_day.Active and then next_day.Day = first_day.Day then
                     next_day.Active := False;
                  end if;
               end loop;
            end if;
         end if;
      end loop;
   end second_pass;

   
   procedure third_pass is
      count : Natural;
   begin
      for first_day of Possible_birthdates loop
         if first_day.Active then
            count := 0;
            for next_day of Possible_birthdates loop
               if next_day.Active and then next_day.Month = first_day.Month
               then
                  count := count + 1;
               end if;
            end loop;
            if count > 1 then
               for next_day of Possible_birthdates loop
                  if next_day.Active and then next_day.Month = first_day.Month
                  then
                     next_day.Active := False;
                  end if;
               end loop;
            end if;
         end if;
      end loop;
   end third_pass;

begin
   print_remaining;
   first_pass;

   print_remaining;
   second_pass;

   print_remaining;
   third_pass;

   print_answer;
end Main;