Peter
Peter Campbell Smith

Working years
and square sums

Weekly challenge 138 — 8 November 2021

Week 138 - 8 Nov 2021

Task 1

Task — 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.

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;
}

Output


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