Worthwhile task shaving

Recreate https://xkcd.com/1205/ which shows a (humorous) table of how long you can work on making a routine task more efficient before spending more time than saved, for various s(h)avings against how often the task is run (over the course of five years).

Worthwhile task shaving is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

There are of course several possible interpretations of "day" and "week" in this context. The Phix implementation assumes 8 hour days and 5 day weeks might be more realistic, whereas it seems the original author worked with 24 hour days and 7 day weeks, and, tbh, my interest is piqued to see what built-in facilities other languages might have for handling such non-standard terms, if any. Extra kudos awarded for getting into the mind of the original author and reproducing their results exactly (see talk page), or drumming up non-trivial (but still elegant) and potentially actually useful routines. This task can be made as trivial or as convoluted as you please, and should aim more for a little playfulness than rigid scientific accuracy.


ALGOL 68

Translation of: Wren
BEGIN # xkcd 1205, translated from the Wren sample #
    []INT    shaved  = ( 1, 5, 30, 60, 300, 1800, 3600, 21600, 86400 );
                                                            # time shaved off in seconds #
    []STRING columns = ( "1 SECOND", "5 SECONDS", "30 SECONDS", "1 MINUTE", "5 MINUTES"
                       , "30 MINUTES", "1 HOUR", "6 HOURS", "1 DAY"
                       );
    REAL diy    = 365.25;
    INT  minute = 60;
    INT  hour   = minute * 60;
    INT  day    = hour * 24;
    INT  week   = day * 7;
    REAL month  = day * diy / 12;
    REAL year   = day * diy;

    []REAL freq = ( 50 * diy, 5 * diy, diy, diy/7, 12, 1 ); # frequency per year #
    INT    mult = 5;                                        # multiplier for table #

    PROC pad right = ( STRING s, INT w )STRING:
         IF INT len = ( UPB s - LWB s ) + 1; len >= w THEN s ELSE s + ( ( w - len ) * " " ) FI;
    PROC center = ( STRING s, INT w )STRING:
         IF INT len = ( UPB s - LWB s ) + 1; len >= w THEN s ELSE ( ( ( w - len ) OVER 2 ) * " " ) + s FI;
 
    PROC fmt time = ( REAL tf, STRING interval )VOID:
         BEGIN
            INT t  = ENTIER tf;
            print( ( pad right( whole( t, 0 ) + " " + interval + IF t = 1 THEN "" ELSE "S" FI, 13 ) ) )
         END # fmt time # ;

    print( ( center( "HOW OFTEN YOU DO THE TASK", 93 ), newline ) );
    print( ( pad right( "SHAVED OFF", 12 ), " | "
           , pad right( "50/DAY",     13 ), pad right( "5/DAY",   13 ), pad right( "DAILY",  13 )
           , pad right( "WEEKLY",     13 ), pad right( "MONTHLY", 13 ), pad right( "YEARLY", 13 )
           , newline
           )
         );
    print( ( "-" * 93, newline ) );
    FOR y FROM LWB columns TO UPB columns DO
        print( ( pad right( columns[ y ], 12 ), " | " ) );
        FOR x FROM LWB freq TO UPB freq DO
            REAL t = freq[ x ] * shaved[ y ] * mult;
            IF   t < minute THEN
                 fmt time( t,          "SECOND" )
            ELIF t < hour THEN
                 fmt time( t / minute, "MINUTE" )
            ELIF t < day THEN
                 fmt time( t / hour,   "HOUR"   )
            ELIF t < 14 * day THEN
                 fmt time( t / day,    "DAY"    )
            ELIF t < 9 * week THEN
                 fmt time( t / week,   "WEEK"   )
            ELIF t < year THEN
                 fmt time( t / month,  "MONTH"  )
            ELSE
                 print( ( " " * 13 ) )
            FI
        OD;
        print( ( newline ) )
    OD
END
Output:
                                  HOW OFTEN YOU DO THE TASK
SHAVED OFF   | 50/DAY       5/DAY        DAILY        WEEKLY       MONTHLY      YEARLY
---------------------------------------------------------------------------------------------
1 SECOND     | 1 DAY        2 HOURS      30 MINUTES   4 MINUTES    1 MINUTE     5 SECONDS
5 SECONDS    | 5 DAYS       12 HOURS     2 HOURS      21 MINUTES   5 MINUTES    25 SECONDS
30 SECONDS   | 4 WEEKS      3 DAYS       15 HOURS     2 HOURS      30 MINUTES   2 MINUTES
1 MINUTE     | 2 MONTHS     6 DAYS       1 DAY        4 HOURS      1 HOUR       5 MINUTES
5 MINUTES    | 10 MONTHS    4 WEEKS      6 DAYS       21 HOURS     5 HOURS      25 MINUTES
30 MINUTES   |              6 MONTHS     5 WEEKS      5 DAYS       1 DAY        2 HOURS
1 HOUR       |                           2 MONTHS     10 DAYS      2 DAYS       5 HOURS
6 HOURS      |                                        2 MONTHS     2 WEEKS      1 DAY
1 DAY        |                                        8 MONTHS     8 WEEKS      5 DAYS

FreeBASIC

Translation of: Wren
'Rosetta Code problem: https://rosettacode.org/wiki/Worthwhile_task_shaving
'by Jjuanhdez, 02/2023

Dim As Integer shaved(0 To 8) = {1, 5, 30, 60, 300, 1800, 3600, 21600, 86400}
Dim As String columns(0 To 8) = {" 1 SECOND", " 5 SECONDS", "30 SECONDS", _
" 1 MINUTE", " 5 MINUTES", "30 MINUTES", " 1 HOUR", " 6 HOURS", " 1 DAY"}
Dim As Single diy = 365.25
Dim As Integer minuto = 60
Dim As Integer hora = minuto * 60
Dim As Integer dia = hora * 24
Dim As Integer semana = dia * 7
Dim As Integer mes = dia * diy \ 12
Dim As Integer anno = dia * diy

Dim As Integer freq(0 To 5) = {50 * diy, 5 * diy, diy, diy\7, 12, 1}
Dim As Integer y, x, t, mult = 5

Sub fmtTime(t As Single, interval As String)
    t = Int(t + .5)
    Dim As String pl = Iif(t = 1, "", "S")
    Print Using " ## \       \"; t; interval & pl;
End Sub

Print Spc(34); "HOW OFTEN YOU DO THE TASK"
Print " SHAVED OFF   | 50/DAY        5/DAY       DAILY        WEEKLY       MONTHLY      YEARLY"
Print String (92, "-")
For y = 0 To Ubound(columns)
    Print Using "\        \    |"; columns(y);
    For x = 0 To Ubound(freq)
        t = freq(x) * shaved(y) * mult
        If (t < minuto) Then
            fmtTime (t, "SECOND")
        Elseif (t < hora) Then
            fmtTime (t/minuto, "MINUTE")
        Elseif (t < dia) Then
            fmtTime (t/hora, "HOUR")
        Elseif (t < 14 * dia) Then
            fmtTime (t/dia, "DAY")
        Elseif (t < 9 * semana) Then
            fmtTime (t/semana, "WEEK")
        Elseif (t < anno) Then
            fmtTime (t/mes, "MONTH")
        Else
            Print String (13, " ");
        End If
    Next
    Print
Next
Output:
                                  HOW OFTEN YOU DO THE TASK
 SHAVED OFF   | 50/DAY        5/DAY       DAILY        WEEKLY       MONTHLY      YEARLY
--------------------------------------------------------------------------------------------
 1 SECOND     |  1 DAY        3 HOURS     30 MINUTES    4 MINUTES    1 MINUTE     5 SECONDS
 5 SECONDS    |  5 DAYS      13 HOURS      3 HOURS     22 MINUTES    5 MINUTES   25 SECONDS
30 SECONDS    |  5 WEEKS      3 DAYS      15 HOURS      2 HOURS     30 MINUTES    3 MINUTES
 1 MINUTE     |  2 MONTHS     6 DAYS       1 DAY        4 HOURS      1 HOUR       5 MINUTES
 5 MINUTES    | 10 MONTHS     5 WEEKS      6 DAYS      22 HOURS      5 HOURS     25 MINUTES
30 MINUTES    |               6 MONTHS     5 WEEKS      5 DAYS       1 DAY        3 HOURS
 1 HOUR       |                            2 MONTHS    11 DAYS       3 DAYS       5 HOURS
 6 HOURS      |                                         2 MONTHS     2 WEEKS      1 DAY
 1 DAY        |                                         9 MONTHS     9 WEEKS      5 DAYS

Julia

Translation of: Perl
shaved  = [1, 5, 30, 60, 300, 1800, 3600, 21600, 86400]
columns = [" 1 Second", " 5 Seconds", "30 Seconds", " 1 Minute", " 5 Minutes", "30 Minutes", " 1 Hour", " 6 Hours", " 1 Day"]
diy, minute, hour, day, week = 365.25, 60, 60 * 60, 60 * 60 * 24, 60 * 60 * 24 * 7
month, year = day * diy / 12, day * diy
freq = [50 * diy, 5 * diy, diy, diy / 7, 12, 1]

fmt(t, interval) = rpad(lpad(Int(round(t)), 3) * " $interval" * (t > 1 ? "s" : ""), 15)

println(' '^34, "How Often You Do the Task\n")
foreach(s -> print(rpad(s, 15)), ["Shaved-off  |", " 50/Day", " 5/Day", " Daily", " Weekly", " Monthly", " Yearly"])
println("\n", '-'^100)

for y in 1:9
   row = lpad(columns[y] * " | ", 14)
   for x in 1:6
      t = freq[x] * shaved[y] * 5
      row *= t < minute ? fmt(t, "Second") : t < hour ? fmt(t / minute, "Minute") : t < day ? fmt(t / hour,   "Hour") :
         t < day * 14 ? fmt(t / day, "Day") : t < week * 9 ? fmt(t / week, "Week") : t < year ? fmt(t / month, "Month") : "   n/a         "
   end
   println(row)
end
Output:
                                  How Often You Do the Task

Shaved-off  |   50/Day         5/Day          Daily          Weekly         Monthly        Yearly
----------------------------------------------------------------------------------------------------
   1 Second |   1 Days         3 Hours       30 Minutes      4 Minutes      1 Minute       5 Seconds
  5 Seconds |   5 Days        13 Hours        3 Hours       22 Minutes      5 Minutes     25 Seconds
 30 Seconds |   5 Weeks        3 Days        15 Hours        2 Hours       30 Minutes      2 Minutes
   1 Minute |   2 Months       6 Days         1 Days         4 Hours        1 Hour         5 Minutes
  5 Minutes |  10 Months       5 Weeks        6 Days        22 Hours        5 Hours       25 Minutes
 30 Minutes |    n/a           6 Months       5 Weeks        5 Days         1 Days         2 Hours
     1 Hour |    n/a            n/a           2 Months      11 Days         2 Days         5 Hours
    6 Hours |    n/a            n/a            n/a           2 Months       2 Weeks        1 Days
      1 Day |    n/a            n/a            n/a           9 Months       9 Weeks        5 Days

Nim

Translation of: Wren
import std/[strformat, strutils]

const Shaved = [float 1, 5, 30, 60, 300, 1800, 3600, 21600, 86400]  # Time shaved off in seconds.
const Columns = ["1 SECOND", "5 SECONDS", "30 SECONDS", "1 MINUTE", "5 MINUTES",
                 "30 MINUTES", "1 HOUR", "6 HOURS", "1 DAY"]
const
  Diy = 365.25
  Minute = 60
  Hour = Minute * 60
  Day = Hour * 24
  Week = Day * 7
  Month = Day * Diy / 12
  Year = Day * Diy

const Freqs = [50 * Diy, 5 * Diy, Diy, Diy / 7, 12, 1]  # Frequency per year.
const Mult = 5    # Multiplier for table.

proc fmtTime(t: float; interval: string): string =
  let t = t.int
  let pl = if t == 1: "" else: "S"
  result = &"{$t & ' ' & interval & pl:<12} "

echo &"""{"HOW OFTEN YOU DO THE TASK":^93}"""
stdout.write &"""{"SHAVED OFF":<12} |"""
for text in ["50/DAY", "5/DAY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY"]:
  stdout.write &" {text:<12}"
echo()
echo repeat('-', 93)
for y in 0..8:
  stdout.write &"{Columns[y]:<12} | "
  for x in 0..5:
    let t = Freqs[x] * Shaved[y] * Mult
    stdout.write if t < Minute:
                   fmtTime(t, "SECOND")
                 elif t < Hour:
                   fmtTime(t / Minute, "MINUTE")
                 elif t < Day:
                   fmtTime(t / Hour, "HOUR")
                 elif t < 14 * Day:
                   fmtTime(t / Day, "DAY")
                 elif t < 9 * Week:
                   fmtTime(t / Week, "WEEK")
                 elif t < Year:
                   fmtTime(t / Month, "MONTH")
                 else:
                   repeat(' ', 13)
  echo()
Output:
                                  HOW OFTEN YOU DO THE TASK                                  
SHAVED OFF   | 50/DAY       5/DAY        DAILY        WEEKLY       MONTHLY      YEARLY      
---------------------------------------------------------------------------------------------
1 SECOND     | 1 DAY        2 HOURS      30 MINUTES   4 MINUTES    1 MINUTE     5 SECONDS    
5 SECONDS    | 5 DAYS       12 HOURS     2 HOURS      21 MINUTES   5 MINUTES    25 SECONDS   
30 SECONDS   | 4 WEEKS      3 DAYS       15 HOURS     2 HOURS      30 MINUTES   2 MINUTES    
1 MINUTE     | 2 MONTHS     6 DAYS       1 DAY        4 HOURS      1 HOUR       5 MINUTES    
5 MINUTES    | 10 MONTHS    4 WEEKS      6 DAYS       21 HOURS     5 HOURS      25 MINUTES   
30 MINUTES   |              6 MONTHS     5 WEEKS      5 DAYS       1 DAY        2 HOURS      
1 HOUR       |                           2 MONTHS     10 DAYS      2 DAYS       5 HOURS      
6 HOURS      |                                        2 MONTHS     2 WEEKS      1 DAY        
1 DAY        |                                        8 MONTHS     8 WEEKS      5 DAYS   

Perl

use strict;
use warnings;
use feature <say switch>;
no warnings 'experimental::smartmatch';

use constant CW => '%-11s'; # set column width

#            (     scale  -->    seconds   )  (minutes) (     scale -->  hours )
my @shaved = map { 60 * $_ } 1/60, 1/12, 1/2, 1, 5, 30, map { 60 * $_ } 1, 6, 24;
my @columns = (' 1 Second', ' 5 Seconds', '30 Seconds', ' 1 Minute', ' 5 Minutes', '30 Minutes', ' 1 Hour', ' 6 Hours', ' 1 Day');
my $diy     = 365.25;
my @freq    = ((map { $diy * $_ } 50, 5, 1, 1/7), 12, 1);
my $week    = 7 * (my $day = 24 * (my $hour = 60 * (my $minute = 60)));
my $month   = (my $year = $day * $diy) / 12;
my $mult    = 5;

sub fmt { my($t, $interval) = @_; sprintf CW.' ', (sprintf '%2d', int $t) . ' ' . $interval . ($t > 1 and 's') }

say ' ' x 34 . 'How Often You Do the Task';                                              say '';
say sprintf  CW.' | '.(' '.CW)x6, <Shaved-off 50/Day 5/Day Daily Weekly Monthly Yearly>; say '';

for my $y (0..8) {
   my $row = sprintf CW.' | ', $columns[$y];
   for my $x (0..5) {
      given ($freq[$x] * $shaved[$y] * $mult) {
         when ($_ < $minute) { $row .= fmt $_,         "Second" }
         when ($_ < $hour  ) { $row .= fmt $_/$minute, "Minute" }
         when ($_ < $day   ) { $row .= fmt $_/$hour,   "Hour"   }
         when ($_ < 14*$day) { $row .= fmt $_/$day,    "Day"    }
         when ($_ < 9*$week) { $row .= fmt $_/$week,   "Week"   }
         when ($_ < $year  ) { $row .= fmt $_/$month,  "Month"  }
         default             { $row .= ' ' . sprintf CW, ' '    }
      }
   }
   say $row;
}
Output:
                                  How Often You Do the Task

Shaved-off  |  50/Day      5/Day       Daily       Weekly      Monthly     Yearly

 1 Second   |  1 Days      2 Hours    30 Minutes   4 Minutes   1 Minute    5 Seconds
 5 Seconds  |  5 Days     12 Hours     2 Hours    21 Minutes   5 Minutes  25 Seconds
30 Seconds  |  4 Weeks     3 Days     15 Hours     2 Hours    30 Minutes   2 Minutes
 1 Minute   |  2 Months    6 Days      1 Days      4 Hours     1 Hour      5 Minutes
 5 Minutes  | 10 Months    4 Weeks     6 Days     21 Hours     5 Hours    25 Minutes
30 Minutes  |              6 Months    5 Weeks     5 Days      1 Days      2 Hours
 1 Hour     |                          2 Months   10 Days      2 Days      5 Hours
 6 Hours    |                                      2 Months    2 Weeks     1 Days
 1 Day      |                                      8 Months    8 Weeks     5 Days

Phix

with javascript_semantics
constant SEC = 1,
         MIN = 60,
         HOUR = 60*MIN,
         DAY = 8*HOUR,      -- (allow some sleepage)
         WEEK = 5*DAY,      -- (omit weekends)
         MONTH = 4*WEEK,
         YEAR = 12*MONTH,   -- (as 48 weeks/omit holidays)
         shavings = {1,5,30,MIN,5*MIN,30*MIN,HOUR,6*HOUR,DAY},
         frequencies = {{50,DAY},{5,DAY},{1,DAY},{1,WEEK},{1,MONTH},{1,YEAR}},
         roundto = {SEC, MIN, HOUR, DAY, WEEK, MONTH, YEAR},
         ts = {"sec", "min", "hour", "day", "week", "month", "year"}

function duration(atom a)
    string es
    for rdx=1 to length(roundto) do
        atom t = trunc(a/roundto[rdx])
        if rdx>1 and t<1 then exit end if
        es = sprintf("%d %s%s",{t,ts[rdx],iff(t=1?"":"s")})
    end for
    return es
end function

printf(1,"""
-------------  How long can you work on making a routine task more  -------------
-------------  efficient before spending more time than you saved?  -------------
------------------------------  (across five years)  ----------------------------
----------+----------------------------------------------------------------------
Shave off |  ------------------- How Often You Do The Task ----------------------
task time |    50/day       5/day       daily      weekly     monthly      yearly
----------+-----------+-----------+-----------+-----------+-----------+----------
""")
for s=1 to length(shavings) do
    integer si = shavings[s]
    string line = sprintf("%10s ",duration(si))
    for f=1 to length(frequencies) do
        integer {per,slot} = frequencies[f]
        if si*per > slot then
            line &= sprintf("%10s  ","n/a")
        else
            atom shaving = (5*YEAR/slot * per) * si
            line &= sprintf("%10s  ",duration(shaving))
        end if
    end for
    printf(1,"%s\n",line)
end for
Output:

One outlier here is 1hr 5/day ==> 3 years vs original 10 months: as per notes above for 5/8ths the cutoff is indeed 3 years.
Note that the standard builtins such as elapsed() have no facilities for non-standard terms such as 8 hour working days.

-------------  How long can you work on making a routine task more  -------------
-------------  efficient before spending more time than you saved?  -------------
------------------------------  (across five years)  ----------------------------
----------+----------------------------------------------------------------------
Shave off |  ------------------- How Often You Do The Task ----------------------
task time |    50/day       5/day       daily      weekly     monthly      yearly
----------+-----------+-----------+-----------+-----------+-----------+----------
     1 sec     2 days      1 hour     20 mins      4 mins       1 min      5 secs
    5 secs    2 weeks       1 day      1 hour     20 mins      5 mins     25 secs
   30 secs   3 months      1 week       1 day     2 hours     30 mins      2 mins
     1 min   6 months     2 weeks      2 days     4 hours      1 hour      5 mins
    5 mins    2 years    3 months     2 weeks      2 days     5 hours     25 mins
   30 mins        n/a      1 year    3 months     3 weeks      3 days     2 hours
    1 hour        n/a     3 years    7 months     1 month      1 week     5 hours
   6 hours        n/a         n/a     3 years    9 months    2 months      3 days
     1 day        n/a         n/a     5 years      1 year    3 months      1 week

Python

Translation of: Julia
row_names = [
    " 1 Second",
    " 5 Seconds",
    "30 Seconds",
    " 1 Minute",
    " 5 Minutes",
    "30 Minutes",
    " 1 Hour",
    " 6 Hours",
    " 1 Day",
]

row_values_in_seconds = [1, 5, 30, 60, 300, 1800, 3600, 21600, 86400]
days_in_a_year = 365.25

seconds_in_minute = 60
seconds_in_hour = seconds_in_minute * 60
seconds_in_day = seconds_in_hour * 24
seconds_in_week = seconds_in_day * 7
seconds_in_year = seconds_in_day * days_in_a_year
seconds_in_month = seconds_in_year / 12

column_names = [
    "Shaved-off |",
    " 50/Day",
    " 5/Day",
    " Daily",
    " Weekly",
    " Monthly",
    " Yearly",
]

# column values
shaves_per_year = [
    50 * days_in_a_year,
    5 * days_in_a_year,
    days_in_a_year,
    days_in_a_year / 7,
    12,
    1,
]


def get_shave_string(amount_of_interval_in, interval_in) -> str:
    plural_string = ""
    if int(amount_of_interval_in) > 1:
        plural_string = "s"

    result = f"{int(amount_of_interval_in)} {interval_in}{plural_string}"
    padded_result = result.ljust(3).rjust(15)

    return padded_result


if __name__ == "__main__":
    print(" " * 34, "How Often You Do the Task\n")

    for column_name in column_names:
        print(str(column_name).rjust(14), end=" ")
    print()
    print("-" * 104)

    for row_number, row_name in enumerate(row_names):
        row = f"{row_name} |".rjust(14)

        for column_value in range(6):
            t = shaves_per_year[column_value] * row_values_in_seconds[row_number] * 5
            if t < seconds_in_minute:
                amount_of_interval, interval = t, "Second"
            elif t < seconds_in_hour:
                amount_of_interval, interval = t / seconds_in_minute, "Minute"
            elif t < seconds_in_day:
                amount_of_interval, interval = t / seconds_in_hour, "Hour"
            elif t < seconds_in_week * 2:
                amount_of_interval, interval = t / seconds_in_day, "Day"
            elif t < seconds_in_month * 2:
                amount_of_interval, interval = t / seconds_in_week, "Week"
            elif t < seconds_in_year:
                amount_of_interval, interval = t / seconds_in_month, "Month"
            else:
                row += "n/a".ljust(3).rjust(15)
                continue
            row += get_shave_string(amount_of_interval, interval)
        print(row)
Output:
                                   How Often You Do the Task

  Shaved-off |         50/Day          5/Day          Daily         Weekly        Monthly         Yearly 
--------------------------------------------------------------------------------------------------------
    1 Second |          1 Day        2 Hours     30 Minutes      4 Minutes       1 Minute      5 Seconds
   5 Seconds |         5 Days       12 Hours        2 Hours     21 Minutes      5 Minutes     25 Seconds
  30 Seconds |        4 Weeks         3 Days       15 Hours        2 Hours     30 Minutes      2 Minutes
    1 Minute |       2 Months         6 Days          1 Day        4 Hours         1 Hour      5 Minutes
   5 Minutes |      10 Months        4 Weeks         6 Days       21 Hours        5 Hours     25 Minutes
  30 Minutes |            n/a       6 Months        5 Weeks         5 Days          1 Day        2 Hours
      1 Hour |            n/a            n/a       2 Months        10 Days         2 Days        5 Hours
     6 Hours |            n/a            n/a            n/a       2 Months        2 Weeks          1 Day
       1 Day |            n/a            n/a            n/a       8 Months        8 Weeks         5 Days

Raku

Translation of: Wren
# 20220207 Raku programming solution 

my \shaved  = [1, 5, 30, 60, 300, 1800, 3600, 21600, 86400]; # time shaved off in seconds
my \columns = [ "1 SECOND", "5 SECONDS", "30 SECONDS", "1 MINUTE", "5 MINUTES",
                "30 MINUTES", "1 HOUR", "6 HOURS", "1 DAY" ];
my \diy     = 365.25;
my \minute  = 60;
my \hour    = minute * 60;
my \day     = hour * 24;
my \week    = day * 7;
my \month   = day * diy / 12;
my \year    = day * diy;
my \freq    = [50 * diy, 5 * diy, diy, diy/7, 12, 1]; # frequency per year
my \mult    = 5; # multiplier for table

sub fmtTime (\t, \interval) { printf "%-12s ", t.floor~" "~interval~(t == 1 ?? "" !! "S") }

say ' ' x 34~"HOW OFTEN YOU DO THE TASK";
printf("%-12s | %-12s %-12s %-12s %-12s %-12s %-12s\n", 
   ["SHAVED OFF", "50/DAY", "5/DAY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY"]);
say '-' x 93;

for ^9 -> \y {
   printf "%-12s | ", columns[y];
   for ^6 -> \x {
      given my \t = freq[x] * shaved[y] * mult {
         when t < minute  { fmtTime t,        "SECOND" } 
         when t < hour    { fmtTime t/minute, "MINUTE" } 
         when t < day     { fmtTime t/hour,   "HOUR"   } 
         when t < 14*day  { fmtTime t/day,    "DAY"    } 
         when t < 9*week  { fmtTime t/week,   "WEEK"   }
         when t < year    { fmtTime t/month,  "MONTH"  }
         default          { print   '   N/A       '    }
      }
   }
   print "\n"
}
Output:
                                  HOW OFTEN YOU DO THE TASK
SHAVED OFF   | 50/DAY       5/DAY        DAILY        WEEKLY       MONTHLY      YEARLY
---------------------------------------------------------------------------------------------
1 SECOND     | 1 DAYS       2 HOURS      30 MINUTES   4 MINUTES    1 MINUTE     5 SECONDS
5 SECONDS    | 5 DAYS       12 HOURS     2 HOURS      21 MINUTES   5 MINUTES    25 SECONDS
30 SECONDS   | 4 WEEKS      3 DAYS       15 HOURS     2 HOURS      30 MINUTES   2 MINUTES
1 MINUTE     | 2 MONTHS     6 DAYS       1 DAYS       4 HOURS      1 HOUR       5 MINUTES
5 MINUTES    | 10 MONTHS    4 WEEKS      6 DAYS       21 HOURS     5 HOURS      25 MINUTES
30 MINUTES   |    N/A       6 MONTHS     5 WEEKS      5 DAYS       1 DAYS       2 HOURS
1 HOUR       |    N/A          N/A       2 MONTHS     10 DAYS      2 DAYS       5 HOURS
6 HOURS      |    N/A          N/A          N/A       2 MONTHS     2 WEEKS      1 DAYS
1 DAY        |    N/A          N/A          N/A       8 MONTHS     8 WEEKS      5 DAYS

V (Vlang)

Translation of: Wren
import math
const (
    shaved = [1, 5, 30, 60, 300, 1800, 3600, 21600, 86400] // time shaved off in seconds
    columns = ["1 SECOND", "5 SECONDS", "30 SECONDS", "1 MINUTE", "5 MINUTES",
                   "30 MINUTES", "1 HOUR", "6 HOURS", "1 DAY"]
    diy = 365.25
    minute = 60
    hour = minute * 60
    day = hour * 24
    week = day * 7
    month = day * diy / 12
    year = day * diy
    freq = [50 * diy, 5 * diy, diy, diy/7, 12, 1] // frequency per year
    mult = 5 // multiplier for table
)

fn fmt_time(t f64, interval string) {
    f := int(math.floor(t))
    mut s := interval
    if f>1 {
        s = '${interval}S'
    }
    print(' ${f:-2} ${s:-9}')
}

fn main(){
    title := 'HOW OFTEN YOU DO THE TASK'
    println("${title:58}")
    println('SHAVED OFF   | 50/DAY       5/DAY        DAILY        WEEKLY       MONTHLY      YEARLY')
    println([]string{init:'-',len:93}.join(''))
    for y in 0..columns.len {
    print('${columns[y]:-12} |')
    for x in 0..6 {
       t := freq[x] * shaved[y] * mult
       if t < minute {
            fmt_time(t, "SECOND")
       } else if t < hour {
            fmt_time(t/minute, "MINUTE")
       } else if t < day {
            fmt_time(t/hour, "HOUR")
       } else if t < 14 * day {
            fmt_time(t/day, "DAY")
       } else if t < 9 * week {
            fmt_time(t/week, "WEEK")
       } else if t < year {
            fmt_time(t/month, "MONTH")
       } else {
            print('             ')
       }
    }
    println('')
    }
}
Output:
                                 HOW OFTEN YOU DO THE TASK
SHAVED OFF   | 50/DAY       5/DAY        DAILY        WEEKLY       MONTHLY      YEARLY
---------------------------------------------------------------------------------------------
1 SECOND     | 1  DAY       2  HOURS     30 MINUTES   4  MINUTES   1  MINUTE    5  SECONDS
5 SECONDS    | 5  DAYS      12 HOURS     2  HOURS     21 MINUTES   5  MINUTES   25 SECONDS
30 SECONDS   | 4  WEEKS     3  DAYS      15 HOURS     2  HOURS     30 MINUTES   2  MINUTES
1 MINUTE     | 2  MONTHS    6  DAYS      1  DAY       4  HOURS     1  HOUR      5  MINUTES
5 MINUTES    | 10 MONTHS    4  WEEKS     6  DAYS      21 HOURS     5  HOURS     25 MINUTES
30 MINUTES   |              6  MONTHS    5  WEEKS     5  DAYS      1  DAY       2  HOURS
1 HOUR       |                           2  MONTHS    10 DAYS      2  DAYS      5  HOURS
6 HOURS      |                                        2  MONTHS    2  WEEKS     1  DAY
1 DAY        |                                        8  MONTHS    8  WEEKS     5  DAYS  

Wren

Library: Wren-fmt

This is quite close to the original table but no cigar.

import "./fmt" for Fmt

var shaved = [1, 5, 30, 60, 300, 1800, 3600, 21600, 86400] // time shaved off in seconds
var columns = ["1 SECOND", "5 SECONDS", "30 SECONDS", "1 MINUTE", "5 MINUTES",
               "30 MINUTES", "1 HOUR", "6 HOURS", "1 DAY"]
var diy = 365.25
var minute = 60
var hour = minute * 60
var day = hour * 24
var week = day * 7
var month = day * diy / 12
var year = day * diy

var freq = [50 * diy, 5 * diy, diy, diy/7, 12, 1] // frequency per year
var mult = 5 // multiplier for table

var fmtTime = Fn.new { |t, interval|
   t = t.floor
   var pl = (t == 1) ? "" : "S"
   Fmt.write("$-12s ", t.toString + " " + interval + pl)
}

Fmt.print("$93m", "HOW OFTEN YOU DO THE TASK")
Fmt.lprint("$-12s | $-12s $-12s $-12s $-12s $-12s $-12s", ["SHAVED OFF", "50/DAY", "5/DAY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY"])
System.print("-" * 93)
for (y in 0..8) {
    Fmt.write("$-12s | ", columns[y])
    for (x in 0..5) {
        var t = freq[x] * shaved[y] * mult
        if (t < minute) {
             fmtTime.call(t, "SECOND")
        } else if (t < hour) {
             fmtTime.call(t/minute, "MINUTE")
        } else if (t < day) {
             fmtTime.call(t/hour, "HOUR")
        } else if (t < 14 * day) {
             fmtTime.call(t/day, "DAY")
        } else if (t < 9 * week) {
             fmtTime.call(t/week, "WEEK")
        } else if (t < year) {
             fmtTime.call(t/month, "MONTH")
        } else {
             System.write(" " * 13)
        }
    }
    System.print()
}
Output:
                                  HOW OFTEN YOU DO THE TASK                                  
SHAVED OFF   | 50/DAY       5/DAY        DAILY        WEEKLY       MONTHLY      YEARLY      
---------------------------------------------------------------------------------------------
1 SECOND     | 1 DAY        2 HOURS      30 MINUTES   4 MINUTES    1 MINUTE     5 SECONDS    
5 SECONDS    | 5 DAYS       12 HOURS     2 HOURS      21 MINUTES   5 MINUTES    25 SECONDS   
30 SECONDS   | 4 WEEKS      3 DAYS       15 HOURS     2 HOURS      30 MINUTES   2 MINUTES    
1 MINUTE     | 2 MONTHS     6 DAYS       1 DAY        4 HOURS      1 HOUR       5 MINUTES    
5 MINUTES    | 10 MONTHS    4 WEEKS      6 DAYS       21 HOURS     5 HOURS      25 MINUTES   
30 MINUTES   |              6 MONTHS     5 WEEKS      5 DAYS       1 DAY        2 HOURS      
1 HOUR       |                           2 MONTHS     10 DAYS      2 DAYS       5 HOURS      
6 HOURS      |                                        2 MONTHS     2 WEEKS      1 DAY        
1 DAY        |                                        8 MONTHS     8 WEEKS      5 DAYS       

Yabasic

Translation of: Phix
// Rosetta Code problem: http://rosettacode.org/wiki/Worthwhile_task_shaving
// by Galileo, 02/2022

SEC = 1 : MINU = 60 : HOUR = 60 * MINU
DAY = 8 * HOUR : WEEK = 5 * DAY : MONTH = 4 * WEEK : YEAR = 12 * MONTH   // (as 48 weeks/omit holidays)
dim shavings$(1) : ls = token("1, 5, 30, MINU, 5 * MINU, 30 * MINU, HOUR, 6 * HOUR, DAY", shavings$(), ",")
dim frequencies$(1) : lf = token("50, DAY, 5, DAY, 1, DAY, 1, WEEK, 1, MONTH, 1, YEAR", frequencies$(), ",")
dim roundto$(1) : lr = token("SEC, MINU, HOUR, DAY, WEEK, MONTH, YEAR", roundto$(), ",")
dim ts$(1) : lt = token("sec, min, hour, day, week, month, year", ts$(),  ",")

sub format$(line$, n)
    return right$("                                                                                           " + line$, n)
end sub

sub duration$(a)
    local es$, rdx, t
    
    for rdx = 1 to lr
        t = int(a/eval(roundto$(rdx)))
        if rdx > 1 and t < 1 break
        es$ = str$(t) + " " + ts$(rdx) : if t > 1 es$ = es$ + "s" : es$ = es$
    next
    
    return es$
end sub

print "                50/day       5/day       daily      weekly     monthly      yearly\n"

for s = 1 to ls
    si = eval(shavings$(s))
    line$ = format$(duration$(si), 10) + "  "
    for f = 1 to lf step 2
        per = eval(frequencies$(f)) : slot = eval(frequencies$(f + 1))
        if si * per > slot then
            line$ = line$ + format$("n/a", 10) + "  "
        else
            shaving = (5 * YEAR / slot * per) * si
            line$ = line$ + format$(duration$(shaving), 10) + "  "
        end if
    next
    print line$
next
Output:
                50/day       5/day       daily      weekly     monthly      yearly

     1 sec     2  days     1  hour    20  mins     4  mins      1  min      5 secs
    5 secs    2  weeks      1  day     1  hour    20  mins     5  mins     25 secs
   30 secs   3  months     1  week      1  day    2  hours    30  mins     2  mins
    1  min   6  months    2  weeks     2  days    4  hours     1  hour     5  mins
   5  mins    2  years   3  months    2  weeks     2  days    5  hours    25  mins
  30  mins         n/a     1  year   3  months    3  weeks     3  days    2  hours
   1  hour         n/a    3  years   7  months    1  month     1  week    5  hours
  6  hours         n/a         n/a    3  years   9  months   2  months     3  days
    1  day         n/a         n/a    5  years     1  year   3  months     1  week
---Program done, press RETURN---