Peter’s solutions: week 103 — 8 March 2021

THE WEEKLY CHALLENGE
Zodiac and music

The Perl Camel

Task 2

What’s playing?

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)

Examples


Example 1
Streamer started at 1606134123 ms after the epoch.
Track list as shown in the DATA of the source listing.

Analysis

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:

  • Calculates how long ago, in seconds, the stream started.
  • Calculates the length in seconds of the playlist.
  • From that, calculates the number of complete iterations of the playlist have occurred, and the time since the last iteration completed.
  • Finds out how far along the current iteration has got, and thus which track is playing right now.

Try it 

Try running the script now:

Script


#!/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

Output


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