Peter’s solutions: week 103 — 8 March 2021
THE WEEKLY CHALLENGE
Zodiac and music
You have created a playlist containing several audio tracks. It started playing at a known time
in the past $T and continuously repeats when it finishes. There are no gaps between the tracks or
between successive plays of the playlist.
You are given a list of the durations in milliseconds and titles of the tracks.
You are given the time (as seconds since 00:00 on 01.01.1970) when the streamer started and a CSV file containing the tracks in the playlist with one line per track containing the length in milliseconds and the title.
Write a script to show which track is playing now.
(Summarised from the original description)
Example 1 Streamer started at 1606134123 ms after the epoch. Track list as shown in the DATA of the source listing.
This is a simple enough challenge, but it requires a lot of conversions to and fro between seconds since the epoch and conventionally expressed dates and times.
The code:
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2021-03-08 use utf8; # Week 103 - task 2 - What's playing? use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Time::Local; use Encode; whats_playing(); sub whats_playing { my ($current, $d, $list_length, $ms, $start, $t, $this_play, $times, %d, @pd, @t, @track, @track_length); # initialise $t = <DATA>; # find when stream started $t = int($t); @t = localtime($t); $start = qq[Streaming started on ] . sprintf('%02d.%02d.%04d at %02d:%02d:%02d', $t[3], $t[4] + 1, $t[5] + 1900, $t[2], $t[1], $t[0]); # find length of one play of list $list_length = 0; while ($d = <DATA>) { $d =~ m|(\d+),"(.*)"|; push @track_length, $1 / 1000; push @track, $2; $list_length += $1 / 1000; } $list_length = int($list_length); $pd[1] = int($list_length / 60); $pd[0] = $list_length - $pd[1] * 60; $pd[2] = int($pd[1] / 60); $pd[1] -= $pd[2] * 60; # find how often list has been played $times = int(($^T - $t) / $list_length); $this_play = ($^T - $t) - ($times * $list_length); # and find where we are in this play for $t (0 .. $#track) { if ($this_play < $track_length[$t]) { say qq[Input: $start]; say qq[ Playlist length is: ] . sprintf('%d:%02d:%02d', $pd[2], $pd[1], $pd[0]); say qq[Output: Playlist has completed: $times times]; say qq[ Playing now: $track[$t]]; return; } $this_play -= $track_length[$t]; } } __DATA__ 1606134123 1709363,"Les Miserables Episode 1: The Bishop" 1723781,"Les Miserables Episode 2: Javert" 1723781,"Les Miserables Episode 3: The Trial" 1678356,"Les Miserables Episode 4: Cosette" 1646043,"Les Miserables Episode 5: The Grave" 1714640,"Les Miserables Episode 6: The Barricade" 1714640,"Les Miserables Episode 7: Conclusion"
38 lines of code
Completed after the closing date and not submitted to GitHub
Input: Streaming started on 23.11.2020 at 12:22:03 Playlist length is: 3:18:30 Output: Playlist has completed: 14364 times Playing now: Les Miserables Episode 2: Javert
Any content of this website which has been created by Peter Campbell Smith is in the public domain