I failed the tech challenge for an interview. How do I improve?

using NUnit.Framework;

using System;

using System.Collections.Generic;

using System.Linq;

namespace ConsoleApp1

{

class Program

{

    static void Main()

    {

        void assert(int expected, DateTime first, DateTime second)

=> Assert.AreEqual(expected, WeekdaysBetweenTwoDates(first, second));

        void assertWithHolidays(int expected, DateTime first, DateTime second)

=> Assert.AreEqual(expected, BusinessDaysBetweenTwoDates(first, second, new List<DateTime> {

new DateTime(2013, 12, 25),

new DateTime(2013, 12, 26),

new DateTime(2014, 1, 1)}));

        HolidayRule anzacDay = new AnnualSameDateHolidayRule(month: 4, day: 25);

        HolidayRule newYearsDay = new AnnualSameDayPostponedIfOnWeekendHolidayRule(month: 1, day: 1);

        HolidayRule queensBirthday = new AnnualSameNthDayOfWeekInMonthHolidayRule(DayOfWeek.Monday, occurence: 2, month: 6);

        void assertWithHolidayRules(int expected, DateTime first, DateTime second)

=> Assert.AreEqual(expected, BusinessDaysBetweenTwoDates(first, second, new List<DateTime>(), new List<HolidayRule> { anzacDay, newYearsDay, queensBirthday }));

        assert(0, new DateTime(2013, 10, 7), new DateTime(2013, 10, 8));

        assert(1, new DateTime(2013, 10, 7), new DateTime(2013, 10, 9));

        assert(5, new DateTime(2013, 10, 5), new DateTime(2013, 10, 14));

        assert(61, new DateTime(2013, 10, 7), new DateTime(2014, 1, 1));

        assert(0, new DateTime(2013, 10, 7), new DateTime(2013, 10, 5));

        assertWithHolidays(1, new DateTime(2013, 10, 7), new DateTime(2013, 10, 9));

        assertWithHolidays(0, new DateTime(2013, 12, 24), new DateTime(2013, 12, 27));

        assertWithHolidays(59, new DateTime(2013, 10, 7), new DateTime(2014, 1, 1));

        assertWithHolidayRules(3, new DateTime(2019, 4, 23), new DateTime(2019, 4, 30));

        assertWithHolidayRules(0, new DateTime(2017, 1, 1), new DateTime(2017, 1, 3));

        assertWithHolidayRules(1, new DateTime(2019, 6, 9), new DateTime(2019, 6, 12));

        Assert.AreEqual(1287, 

BusinessDaysBetweenTwoDates(

new DateTime(2010, 1, 1), new DateTime(2015, 1, 1),

new List<DateTime> { new DateTime(2012, 4, 4), new DateTime(2014, 2, 13), new DateTime(2011, 3, 2)},

new List<HolidayRule> { anzacDay, newYearsDay, queensBirthday }));

    }

    private static int WeekdaysBetweenTwoDates(DateTime firstDate, DateTime secondDate)

    {

        return BusinessDaysBetweenTwoDates(firstDate, secondDate, new List<DateTime>());

    }

    private static int BusinessDaysBetweenTwoDates(DateTime firstDate, DateTime secondDate, IList<DateTime> publicHolidays)

    {

        return BusinessDaysBetweenTwoDates(firstDate, secondDate, publicHolidays, new List<HolidayRule>());

    } 

    private static int BusinessDaysBetweenTwoDates(DateTime firstDate, DateTime secondDate, IList<DateTime> publicHolidays, IList<HolidayRule> publicHolidayRules)

    {

        return firstDate >= secondDate ? 0 :

Enumerable.Range(1, (secondDate.AddDays(-1) - firstDate).Days)

.Select(offset => firstDate.AddDays(offset))

.Count(day =>

day.DayOfWeek != DayOfWeek.Saturday

&& day.DayOfWeek != DayOfWeek.Sunday

&& !publicHolidays.Contains(day)

&& !publicHolidayRules.Any(rule => rule.IsHoliday(day)));

    } 

    protected abstract class HolidayRule

    {

        internal abstract bool IsHoliday(DateTime datetime);

    }

    private class AnnualSameDateHolidayRule : HolidayRule

    {

        protected readonly int \_month;

        protected readonly int \_day;

        internal AnnualSameDateHolidayRule(int month, int day)

        {

_month = month;

_day = day;

        }

        internal override bool IsHoliday(DateTime dateTime) => dateTime.Month == \_month && [dateTime.Day](https://dateTime.Day) == \_day;

    }

    private class AnnualSameDayPostponedIfOnWeekendHolidayRule : AnnualSameDateHolidayRule

    {

        internal AnnualSameDayPostponedIfOnWeekendHolidayRule(int month, int day) : base(month, day) { }

        internal override bool IsHoliday(DateTime dateTime)  {

var holiday = new DateTime(dateTime.Year, _month, _day);

if (holiday.DayOfWeek == DayOfWeek.Saturday) return holiday.AddDays(2) == dateTime;

if (holiday.DayOfWeek == DayOfWeek.Sunday) return holiday.AddDays(1) == dateTime;

return holiday == dateTime;

        }

    }

    private class AnnualSameNthDayOfWeekInMonthHolidayRule : HolidayRule

    {

        protected readonly DayOfWeek \_dayOfWeek;

        protected readonly int \_occurrence;

        protected readonly int \_month;

        internal AnnualSameNthDayOfWeekInMonthHolidayRule(DayOfWeek dayOfWeek, int occurence, int month)

        {

_dayOfWeek = dayOfWeek;

_occurrence = occurence;

_month = month;

        }

        internal override bool IsHoliday(DateTime dateTime)

        {

if (dateTime.Month != _month || dateTime.DayOfWeek != _dayOfWeek) return false;

return Enumerable.Range(1, dateTime.Day)

.Select(dayOfMonth => new DateTime(dateTime.Year, dateTime.Month, dayOfMonth))

.Count(day => day.DayOfWeek == _dayOfWeek) == _occurrence;

        }

    }

}

}

/r/dotnet Thread Parent