Task: Cheryl's birthday
C: #include <stdbool.h>
#include <stdio.h>

char *months[] = {
    "ERR", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};

struct Date {
    int month, day;
    bool active;
} dates[] = {
    {5,15,true}, {5,16,true}, {5,19,true},
    {6,17,true}, {6,18,true},
    {7,14,true}, {7,16,true},
    {8,14,true}, {8,15,true}, {8,17,true}
};
#define UPPER_BOUND (sizeof(dates) / sizeof(struct Date))

void printRemaining() {
    int i, c;
    for (i = 0, c = 0; i < UPPER_BOUND; i++) {
        if (dates[i].active) {
            c++;
        }
    }
    printf("%d remaining.\n", c);
}

void printAnswer() {
    int i;
    for (i = 0; i < UPPER_BOUND; i++) {
        if (dates[i].active) {
            printf("%s, %d\n", months[dates[i].month], dates[i].day);
        }
    }
}

void firstPass() {
    
    int i, j, c;
    for (i = 0; i < UPPER_BOUND; i++) {
        c = 0;

        for (j = 0; j < UPPER_BOUND; j++) {
            if (dates[j].day == dates[i].day) {
                c++;
            }
        }

        if (c == 1) {
            for (j = 0; j < UPPER_BOUND; j++) {
                if (!dates[j].active) continue;
                if (dates[j].month == dates[i].month) {
                    dates[j].active = false;
                }
            }
        }
    }
}

void secondPass() {
    
    int i, j, c;
    for (i = 0; i < UPPER_BOUND; i++) {
        if (!dates[i].active) continue;
        c = 0;

        for (j = 0; j < UPPER_BOUND; j++) {
            if (!dates[j].active) continue;
            if (dates[j].day == dates[i].day) {
                c++;
            }
        }

        if (c > 1) {
            for (j = 0; j < UPPER_BOUND; j++) {
                if (!dates[j].active) continue;
                if (dates[j].day == dates[i].day) {
                    dates[j].active = false;
                }
            }
        }
    }
}

void thirdPass() {
    
    int i, j, c;
    for (i = 0; i < UPPER_BOUND; i++) {
        if (!dates[i].active) continue;
        c = 0;

        for (j = 0; j < UPPER_BOUND; j++) {
            if (!dates[j].active) continue;
            if (dates[j].month == dates[i].month) {
                c++;
            }
        }

        if (c > 1) {
            for (j = 0; j < UPPER_BOUND; j++) {
                if (!dates[j].active) continue;
                if (dates[j].month == dates[i].month) {
                    dates[j].active = false;
                }
            }
        }
    }
}

int main() {
    printRemaining();
    
    firstPass();

    printRemaining();
    
    secondPass();

    printRemaining();
    
    thirdPass();

    printAnswer();
    return 0;
}

Java: import java.time.Month;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Main {
    private static class Birthday {
        private Month month;
        private int day;

        public Birthday(Month month, int day) {
            this.month = month;
            this.day = day;
        }

        public Month getMonth() {
            return month;
        }

        public int getDay() {
            return day;
        }

        @Override
        public String toString() {
            return month + " " + day;
        }
    }

    public static void main(String[] args) {
        List<Birthday> choices = List.of(
            new Birthday(Month.MAY, 15),
            new Birthday(Month.MAY, 16),
            new Birthday(Month.MAY, 19),
            new Birthday(Month.JUNE, 17),
            new Birthday(Month.JUNE, 18),
            new Birthday(Month.JULY, 14),
            new Birthday(Month.JULY, 16),
            new Birthday(Month.AUGUST, 14),
            new Birthday(Month.AUGUST, 15),
            new Birthday(Month.AUGUST, 17)
        );
        System.out.printf("There are %d candidates remaining.\n", choices.size());

        
        Set<Month> uniqueMonths = choices.stream()
            .collect(Collectors.groupingBy(Birthday::getDay))
            .values()
            .stream()
            .filter(g -> g.size() == 1)
            .flatMap(Collection::stream)
            .map(Birthday::getMonth)
            .collect(Collectors.toSet());
        List<Birthday> f1List = choices.stream()
            .filter(birthday -> !uniqueMonths.contains(birthday.month))
            .collect(Collectors.toList());
        System.out.printf("There are %d candidates remaining.\n", f1List.size());

        
        List<Birthday> f2List = f1List.stream()
            .collect(Collectors.groupingBy(Birthday::getDay))
            .values()
            .stream()
            .filter(g -> g.size() == 1)
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
        System.out.printf("There are %d candidates remaining.\n", f2List.size());

        
        List<Birthday> f3List = f2List.stream()
            .collect(Collectors.groupingBy(Birthday::getMonth))
            .values()
            .stream()
            .filter(g -> g.size() == 1)
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
        System.out.printf("There are %d candidates remaining.\n", f3List.size());

        if (f3List.size() == 1) {
            System.out.printf("Cheryl's birthday is %s\n", f3List.get(0));
        } else {
            System.out.println("No unique choice found");
        }
    }
}