Peter’s blog ✴ Week 138 ✴ 8 November 2021

THE WEEKLY CHALLENGE
Working years and square sums

The Perl Camel

Task 1

Workdays

You are given a year, $year in 4-digit form. Write a script to calculate the total number of workdays in the given year. For this task, we consider Monday - Friday as workdays.

Examples


Example 1
Input: $year = 2021
Output: 261

Example 2
Input: $year = 2020
Output: 262

Analysis

A non-leap year contains 52 weeks plus one day (52 * 7 + 1 = 365). 52 weeks between 1 January and 30 December will contain 52 * 5 = 260 working days. If 31 December is a working day then the year will contain 261 working days, and if it isn't, then the year will contain just 260.

A leap year contains 52 weeks plus 2 days, so similarly the number of working days in the year is 260 plus 1 if 30 December is a working day and plus another 1 if 31 December is a working day.

Armed with those facts all I need to do is to establish whether 31, and 30 in a leap year, December are working days. I split the task into a main task applying the above logic furnished with two functions is_leap() and is_working_day() which do what they say.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 1984

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2021-11-08
# PWC 138 task 1

use v5.20;
use warnings;
use strict;
use Time::Local;

my ($year, @years, $working_days);

@years = (2010 .. 2030);

for $year (@years) {
    $working_days = 5 * 52;
    $working_days++ if is_working_day($year, 12, 31);
    $working_days++ if (is_leap($year) and is_working_day($year, 12, 30)); 
    say qq[Input: \$year = $year\nOutput: $working_days\n];
}

sub is_working_day {  # ($year, $month, $day)

    # returns 1 if date is a working day, else returns 0
    #                           s  m  h   d      m         y
    my @t = localtime(timelocal(0, 0, 12, $_[2], $_[1] - 1, $_[0] - 1900));
    return ($t[6] >= 1 and $t[6] <= 5) ? 1 : 0;
}

sub is_leap {
    
    # returns 1 if given year is leap or 0 if not
    my ($test);
    
    $test = $_[0];
    $test = $test / 100 if $test % 100 == 0;  # xx00 years
    return $test % 4 == 0 ? 1 : 0;
}

8 lines of code

Output from script


Input: $year = 2010
Output: 261

Input: $year = 2011
Output: 260

Input: $year = 2012
Output: 261

Input: $year = 2013
Output: 261

Input: $year = 2014
Output: 261

Input: $year = 2015
Output: 261

Input: $year = 2016
Output: 261

Input: $year = 2017
Output: 260

Input: $year = 2018
Output: 261

Input: $year = 2019
Output: 261

Input: $year = 2020
Output: 262

Input: $year = 2021
Output: 261

Input: $year = 2022
Output: 260

Input: $year = 2023
Output: 260

Input: $year = 2024
Output: 262

Input: $year = 2025
Output: 261

Input: $year = 2026
Output: 261

Input: $year = 2027
Output: 261

Input: $year = 2028
Output: 260

Input: $year = 2029
Output: 261

Input: $year = 2030
Output: 261

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain