Weekly Challenge 103
Tags: perl, perlweeklychallenge, weeklychallenge
Published: 2021-03-09 13:10:57

[My solutions](https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-103/sgreen) to the [Challenge](https://perlweeklychallenge.org/blog/perl-weekly-challenge-103/)

# TASK #1 › Chinese Zodiac

## Task
You are given a year `$year`.

Write a script to determine the [Chinese Zodiac](https://en.wikipedia.org/wiki/Chinese_zodiac) for the given year.

Unfortunately I don't come from an Asian background, so had to rely on the task to give me clues. There seems to be some confusion / difference around the timing of the elements. The linked page has each element linked to a certain animal. This [page](https://www.chinahighlights.com/travelguide/chinese-zodiac/china-five-elements-philosophy.htm) has a 60 year cycle for the elements (12 years each), while this [page](https://www.liveabout.com/find-your-chinese-zodiac-sign-206588) has a 10 year cycle (2 years for each element). Using the two examples given in the task only the last link provides the expected solutions.

With that sorted out (hopefully), it is then a matter of creating two arrays `@zodiacs` and `@elements` and using simple arithmetic to display the correct element and animal.

## Examples

```
» ./ch-1.pl 2017
Fire Rooster

» ./ch-1.pl 1938
Earth Tiger
```

# TASK #2 › What’s playing?

## The task

[Full description here](https://perlweeklychallenge.org/blog/perl-weekly-challenge-103/#TASK2) ... Write a program to output which file is currently playing ... Optional: Also display the current position in the media as a time-like value.

## My solution

As regular readers of my blog would know I have two rules about these challenges. Firstly, never read other peoples solutions before doing my pull request. And secondly, don't use modules that aren't part of core Perl. Well I broke the second rule this week, and used [Text::CSV](https://metacpan.org/pod/Text::CSV#csv) to read the CSV file. Parsing CSV files correctly is not easy, and since it's not a core part of the task, I'm leaving it to a module that does things correctly.

The original task had the time specified as a formatted string, and I was going to write a blurb about converting that to epoch time (non-leap seconds since midnight 1/1/1970 UTC) and dealing with the weird parts of the world that change their clocks during summer (For the record, we haven't done this since 1992). By the time I wrote the code, the inputs are now expressed as epoch time.

Having said that, the output does not factor in any [leap seconds](https://en.wikipedia.org/wiki/Leap_second) between the start and current times.

Anyway, enough blabbering. On to the solution. My solution takes the following steps. All times are recorded as milliseconds (1/1000th of one second).

1. Read the input values and makes sure they are correct.
1. Reads the csv file into `$tracks` (an array of arrays)
1. Calculate the length of the playlist as `$playlist_length`
1. Calculate how far we are through the playlist as `$playlist_position`. This is the remainder of `($current-$start)*100` and the playlist length.
1. Work my way through the tracks. If the `$track_length` is less than the `$playlist_position` we subtract the first number from the second and continue on.
1. We now know what tracks is playing, and the position (milliseconds since the start) we are of the track. With some more simple algebra, we can display the time in a suitable format.

I have to say it does feel good when the output from your code matches the examples given :)

## Example

```
» ./ch-2.pl 1606134123 1614591276 ~/wasteland/filelist.csv                                                                                                                                                                                    
Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23) 00:10:24
```