Worthwhile task shaving: Difference between revisions
SqrtNegInf (talk | contribs) m (→{{header|Perl}}: column width adjustable) |
(julia example) |
||
Line 13: | Line 13: | ||
This task can be made as trivial or as convoluted as you please, and should aim more for a little |
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. |
playfulness than rigid scientific accuracy. |
||
=={{header|Julia}}== |
|||
{{trans|Perl}} |
|||
<lang julia>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 |
|||
</lang>{{out}} |
|||
<pre> |
|||
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 |
|||
</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
Revision as of 09:09, 9 February 2022
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).
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.
Julia
<lang julia>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
</lang>
- 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
Perl
<lang 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;
}</lang>
- 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," 50/day 5/day daily weekly monthly yearly\n") 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.
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
Raku
<lang perl6># 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"
}</lang>
- 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
Wren
This is quite close to the original table but no cigar. <lang ecmascript>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()
}</lang>
- 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