aboutsummaryrefslogtreecommitdiff
path: root/challenge-237/kjetillll/perl/ch-1.pl
blob: 77857a7fba00dc4f1471f25bc6e92963f16e6788 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#https://theweeklychallenge.org/blog/perl-weekly-challenge-237/
use strict; use warnings;

sub the_day {
  my($year, $month, $weekday_of_month, $day_of_week) = @_;
  my $want_month = $year*100+$month;
  my $test_day = ($year-1970)*365+($month-1)*28;   #choose a conservative enough start day
  while(1) {                                       #Don't Stop 'Til You Get Enough
    my @lt = gmtime $test_day++ * 24 * 3600;       #get time elems for test_day num, increase test_day
    my($se, $mi, $ho, $mday, $m, $y, $dow) = @lt;  #y=0 for 1900, m=0 for January
    my $test_month = 190001+$y*100+$m;             #i.e. 202309 for Sep 2023, 
    return 0     if  $test_month >  $want_month;   #the wanted month is now passed without a find
    return $mday if  $test_month == $want_month    #same year and month
                 and $day_of_week%7 == $dow        #same weekday, Sun=7=0
	         and --$weekday_of_month == 0      #the wanted count
  }
}

my @tests = (
  '{Year => 2024, Month => 4,  Weekday_of_month => 3, Day_of_week => 2}' => 16, #The 3rd Tue_of_Apr 2024 is the 16th
  '{Year => 2025, Month => 10, Weekday_of_month => 2, Day_of_week => 4}' => 9,  #The 2nd Thu_of_Oct 2025 is the 9th
  '{Year => 2026, Month => 8,  Weekday_of_month => 5, Day_of_week => 3}' => 0,  #There isn't a 5th Wed in Aug 2026
  '{Year => 1970, Month => 1,  Weekday_of_month => 4, Day_of_week => 7}' => 25, #25th was 4th Sun in Jan 1970
  '{Year => 1970, Month => 1,  Weekday_of_month => 5, Day_of_week => 5}' => 30, #30th was 5th Fri in Jan 1970
);

while(@tests){
  my($data, $expected) = splice@tests,0,2;
  my $got = the_day( @{eval$data}{qw(Year Month Weekday_of_month Day_of_week)} );
  print $got  == $expected ? 'ok' : '***NOT OK';
  print "    data: $data    expected: $expected    got: $got\n";
}