diff options
| author | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2021-03-14 23:58:24 +1000 |
|---|---|---|
| committer | PerlMonk Athanasius <PerlMonk.Athanasius@gmail.com> | 2021-03-14 23:58:24 +1000 |
| commit | 11a2b09f72fd99fe67b57cb8b23cf4b4a6157040 (patch) | |
| tree | 7eb4aac5ee5484a116dabcb0fabe3f5b0d30d11e | |
| parent | 4a289a702db8c240e4362ae01c10c203cb19c968 (diff) | |
| download | perlweeklychallenge-club-11a2b09f72fd99fe67b57cb8b23cf4b4a6157040.tar.gz perlweeklychallenge-club-11a2b09f72fd99fe67b57cb8b23cf4b4a6157040.tar.bz2 perlweeklychallenge-club-11a2b09f72fd99fe67b57cb8b23cf4b4a6157040.zip | |
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #103
On branch branch-for-challenge-103
Changes to be committed:
new file: challenge-103/athanasius/perl/ch-1.pl
new file: challenge-103/athanasius/perl/ch-2.pl
new file: challenge-103/athanasius/perl/filelist.csv
new file: challenge-103/athanasius/raku/ch-1.raku
new file: challenge-103/athanasius/raku/ch-2.raku
new file: challenge-103/athanasius/raku/filelist.csv
| -rw-r--r-- | challenge-103/athanasius/perl/ch-1.pl | 139 | ||||
| -rw-r--r-- | challenge-103/athanasius/perl/ch-2.pl | 239 | ||||
| -rw-r--r-- | challenge-103/athanasius/perl/filelist.csv | 7 | ||||
| -rw-r--r-- | challenge-103/athanasius/raku/ch-1.raku | 125 | ||||
| -rw-r--r-- | challenge-103/athanasius/raku/ch-2.raku | 193 | ||||
| -rw-r--r-- | challenge-103/athanasius/raku/filelist.csv | 7 |
6 files changed, 710 insertions, 0 deletions
diff --git a/challenge-103/athanasius/perl/ch-1.pl b/challenge-103/athanasius/perl/ch-1.pl new file mode 100644 index 0000000000..1c25e07fa6 --- /dev/null +++ b/challenge-103/athanasius/perl/ch-1.pl @@ -0,0 +1,139 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 103 +========================= + +Task #1 +------- +*Chinese Zodiac* + +Submitted by: Mohammad S Anwar + +You are given a year $year. + +Write a script to determine the Chinese Zodiac for the given year $year. Please +check out [ https://en.wikipedia.org/wiki/Chinese_zodiac |wikipage] for more +information about it. + +The animal cycle: Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, +Rooster, Dog, Pig. +The element cycle: Wood, Fire, Earth, Metal, Water. + +Example 1: + + Input: 2017 + Output: Fire Rooster + +Example 2: + + Input: 1938 + Output: Earth Tiger + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +Assumptions +----------- +1. Years are AD (= CE), Gregorian calendar, only. +2. Each year begins on Chinese New Year. For example, "1954" actually begins on + 5th February, 1954, and ends on 23rd January, 1955. + +Algorithm +--------- +The Chinese lunar calendar is a sexagenary (60 year) cycle comprising two +lesser cycles: a 12-year cycle of animal signs and a 10-year cycle in which +each of 5 elements is repeated for 2 consecutive years. + +Given any "start year" (i.e., a year on which the sexagenary cycle begins, with +animal sign Rat and element Wood) such as 1924 or 1984, the animal sign's +index (zero-based) is calculated by finding the difference between the given +year and the start year, then calculating that difference modulus 12. For +example, 2017 - 1984 = 33, and 33 mod 12 = 9, so the animal sign for 2017 is +the tenth in the series, namely Rooster. + +The element calculation is similar except that elements change biennially, so +the difference must first be halved (and the remainder, if any, discarded) +before the index is calculated as halved-difference modulus 5. Using 2017 again +as an example, floor(33 / 2) = 16, and 16 mod 5 = 1, so the element for 2017 is +the second in the series, namely Fire. + +Note that Perl's modulus operator produces the correct result for negative +differences. From perlop: "If $n is positive, then $m % $n is $m minus the +largest multiple of $n less than or equal to $m." So for (1938 - 1984) = -46, +-46 % 12 = -46 - -48 = 2, which is the same result as would be obtained if the +"start year" were 1924: 1938 - 1924 = 14, and 14 mod 12 = 2. + +=cut +#============================================================================== + +use strict; +use warnings; +use Const::Fast; +use Regexp::Common qw( number ); + +const my @ELEMENTS => qw( Wood Fire Earth Metal Water ); +const my @ANIMALS => qw( Rat Ox Tiger Rabbit Dragon Snake + Horse Goat Monkey Rooster Dog Pig ); +const my $START_YEAR => 1984; +const my $USAGE => +"Usage: + perl $0 <year> + + <year> Year AD (positive integer)\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 103, Task #1: Chinese Zodiac (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my $year = parse_command_line(); + + print "Input: $year\n"; + + my $el_index = int( ($year - $START_YEAR) / 2 ) % scalar @ELEMENTS; + my $an_index = ($year - $START_YEAR) % scalar @ANIMALS; + + printf "Output: %s %s\n", $ELEMENTS[ $el_index ], $ANIMALS[ $an_index ]; +} + +#------------------------------------------------------------------------------ +sub parse_command_line +#------------------------------------------------------------------------------ +{ + my $args = scalar @ARGV; + $args == 1 or error( "Expected 1 command-line argument, found $args" ); + + my $year = $ARGV[ 0 ]; + $year =~ / ^ $RE{num}{int} $ /x && $year > 0 + or error( qq["$year" is not a positive integer] ); + + return $year; +} + +#------------------------------------------------------------------------------ +sub error +#------------------------------------------------------------------------------ +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +############################################################################### diff --git a/challenge-103/athanasius/perl/ch-2.pl b/challenge-103/athanasius/perl/ch-2.pl new file mode 100644 index 0000000000..a03b25d564 --- /dev/null +++ b/challenge-103/athanasius/perl/ch-2.pl @@ -0,0 +1,239 @@ +#!perl + +############################################################################### +=comment + +Perl Weekly Challenge 103 +========================= + +Task #2 +------- +*What's playing?* + +Submitted by: Albert Croft + +Working from home, you decided that on occasion you wanted some background +noise while working. You threw together a network streamer to continuously loop +through the files and launched it in a tmux (or screen) session, giving it a +directory tree of files to play. During the day, you connected an audio player +to the stream, listening through the workday, closing it when done. + +For weeks you connect to the stream daily, slowly noticing a gradual drift of +the media. After several weeks, you take vacation. When you return, you are +pleasantly surprised to find the streamer still running. Before connecting, +however, if you consider the puzzle of determining which track is playing. + +After looking at a few modules to read info regarding the media, a quick bit of +coding gave you a file list. The file list is in a simple CSV format, each line +containing two fields: the first the number of milliseconds in length, the +latter the media's title (this example is of several episodes available from +the MercuryTheatre.info): + + 1709363,"Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" + 1723781,"Les Miserables Episode 2: Javert (broadcast date: 1937-07-30)" + 1723781,"Les Miserables Episode 3: The Trial (broadcast date: 1937-08-06)" + 1678356,"Les Miserables Episode 4: Cosette (broadcast date: 1937-08-13)" + 1646043,"Les Miserables Episode 5: The Grave (broadcast date: 1937-08-20)" + 1714640,"Les Miserables Episode 6: The Barricade (broadcast date: 1937-08-27)" + 1714640,"Les Miserables Episode 7: Conclusion (broadcast date: 1937-09-03)" + +For this script, you can assume to be provided the following information: + + * the value of $^T ($BASETIME) of the streamer script, + * the value of time(), and + * a CSV file containing the media to play consisting of the length in + milliseconds and an identifier for the media (title, filename, or other). + +Write a program to output which file is currently playing. For purposes of this +script, you may assume gapless playback, and format the output as you see fit. + +Optional: Also display the current position in the media as a time-like value. + +Example: + +UPDATED: Input parameters as reported by many members [2021-03-08 16:20 UK +TIME]. + + Input: 3 command line parameters: start time, current time, file name + + # starttime + 1606134123 + + # currenttime + 1614591276 + + # filelist.csv + + Output: + + "Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" + 00:10:24 + +=cut +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=comment + +Notes +----- +1. Although it would be quite straightforward to hand-craft file-reading code + for this particular exercise, as a general rule it is advisable to use a + dedicated module for reading CSV files. The module chosen here is the + excellent Text::CSV (which automatically uses Text::CSV_XS if the latter is + available). +2. The easiest way to determine the file currently playing is to begin by + calculating the total time elapsed modulo the total duration of the media + files. Perl's built-in mod operator "%" does not give the desired result + when the operands are real (i.e., floating point) numbers, so the subroutine + POSIX::fmod() is used for this purpose. +3. The user may find it convenient to let the script determine the current + time, so an input value of zero for the current_time parameter is inter- + preted as "now". + +=cut +#============================================================================== + +use strict; +use warnings; +use Const::Fast; +use POSIX qw( fmod ); +use Regexp::Common qw( number ); +use Text::CSV; + +use enum qw( Length Name Cum_length ); + +const my $USAGE => +"Usage: + perl $0 <start_time> <current_time> <file> + + <start_time> Start time in seconds since the epoch + <current_time> Current time in seconds (0 means now) + <file> CSV filename\n"; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + $| = 1; + print "\nChallenge 103, Task #2: What's playing? (Perl)\n\n"; +} + +#============================================================================== +MAIN: +#============================================================================== +{ + my ($start_time, $current_time, $file) = parse_command_line(); + + my $current = $current_time || time; + + print "Input:\n\n Start time: $start_time\n" . + " Current time: $current\n" . + " File list: $file\n\n"; + + my $data = read_data( $file ); + my $total_s = int( $data->[ $#$data ][ Cum_length ] ) / 1e3; + my $difference = $current - $start_time; + my $offset = int( fmod($difference, $total_s) * 1e3 ); + my $index = 0; + + for (@$data) + { + last if $_->[ Cum_length ] > $offset; + ++$index; + } + + $offset -= $data->[ $index - 1 ][ Cum_length ] if $index > 0; + + printf "Output:\n\n %s\n %s\n", + $data->[ $index ][ Name ], hms( $offset ); +} + +#------------------------------------------------------------------------------ +sub read_data +#------------------------------------------------------------------------------ +{ + my ($file) = @_; + + open( my $fh, '<', $file ) + or error( qq[Cannot open file "$file" for reading] ); + + my $csv = Text::CSV->new; + my $data = $csv->getline_all( $fh ); + + close $fh or error( qq[Cannot close file "$file"] ); + + my $cum_total = 0; + + for my $i (0 .. $#$data) + { + $cum_total += $data->[ $i ][ Length ]; + + push @{ $data->[ $i ] }, $cum_total; + } + + return $data; +} + +#------------------------------------------------------------------------------ +sub hms +#------------------------------------------------------------------------------ +{ + my ($ms) = @_; + my $seconds = int( $ms / 1e3 ); + my $minutes = int( $seconds / 60 ); + my $hours = int( $minutes / 60 ); + + $minutes -= $hours * 60; + $seconds -= $minutes * 60; + + return sprintf '%02d:%02d:%02d', $hours, $minutes, $seconds; +} + +#------------------------------------------------------------------------------ +sub parse_command_line +#------------------------------------------------------------------------------ +{ + my $args = scalar @ARGV; + $args == 3 + or error( "Expected 3 command-line arguments, found $args" ); + + my ($start_time, $current_time, $file) = @ARGV; + + for ($start_time, $current_time) + { + / ^ $RE{num}{int} $ /x && $_ >= 0 + or error( qq["$_" is not a positive integer] ); + } + + if ($current_time > 0) + { + $current_time >= $start_time + or error( 'Current time is earlier than start time' ); + } + + $file =~ / \. csv $ /ix + or error( qq[File "$file" does not have a ".csv" extension] ); + + open( my $fh, '<', $file ) + or error( qq[Cannot open file "$file" for reading] ); + + close $fh or die qq[Cannot close file "$file", stopped]; + + return ($start_time, $current_time, $file); +} + +#------------------------------------------------------------------------------ +sub error +#------------------------------------------------------------------------------ +{ + my ($message) = @_; + + die "ERROR: $message\n$USAGE"; +} + +############################################################################### diff --git a/challenge-103/athanasius/perl/filelist.csv b/challenge-103/athanasius/perl/filelist.csv new file mode 100644 index 0000000000..9428b93004 --- /dev/null +++ b/challenge-103/athanasius/perl/filelist.csv @@ -0,0 +1,7 @@ +1709363,"Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" +1723781,"Les Miserables Episode 2: Javert (broadcast date: 1937-07-30)" +1723781,"Les Miserables Episode 3: The Trial (broadcast date: 1937-08-06)" +1678356,"Les Miserables Episode 4: Cosette (broadcast date: 1937-08-13)" +1646043,"Les Miserables Episode 5: The Grave (broadcast date: 1937-08-20)" +1714640,"Les Miserables Episode 6: The Barricade (broadcast date: 1937-08-27)" +1714640,"Les Miserables Episode 7: Conclusion (broadcast date: 1937-09-03)" diff --git a/challenge-103/athanasius/raku/ch-1.raku b/challenge-103/athanasius/raku/ch-1.raku new file mode 100644 index 0000000000..9ed901dbdf --- /dev/null +++ b/challenge-103/athanasius/raku/ch-1.raku @@ -0,0 +1,125 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 103 +========================= + +Task #1 +------- +*Chinese Zodiac* + +Submitted by: Mohammad S Anwar + +You are given a year $year. + +Write a script to determine the Chinese Zodiac for the given year $year. Please +check out [ https://en.wikipedia.org/wiki/Chinese_zodiac |wikipage] for more +information about it. + +The animal cycle: Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, +Rooster, Dog, Pig. +The element cycle: Wood, Fire, Earth, Metal, Water. + +Example 1: + + Input: 2017 + Output: Fire Rooster + +Example 2: + + Input: 1938 + Output: Earth Tiger + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Assumptions +----------- +1. Years are AD (= CE), Gregorian calendar, only. +2. Each year begins on Chinese New Year. For example, "1954" actually begins on + 5th February, 1954, and ends on 23rd January, 1955. + +Algorithm +--------- +The Chinese lunar calendar is a sexagenary (60 year) cycle comprising two +lesser cycles: a 12-year cycle of animal signs and a 10-year cycle in which +each of 5 elements is repeated for 2 consecutive years. + +Given any "start year" (i.e., a year on which the sexagenary cycle begins, with +animal sign Rat and element Wood) such as 1924 or 1984, the animal sign's +index (zero-based) is calculated by finding the difference between the given +year and the start year, then calculating that difference modulus 12. For +example, 2017 - 1984 = 33, and 33 mod 12 = 9, so the animal sign for 2017 is +the tenth in the series, namely Rooster. + +The element calculation is similar except that elements change biennially, so +the difference must first be halved (and the remainder, if any, discarded) +before the index is calculated as halved-difference modulus 5. Using 2017 again +as an example, floor(33 / 2) = 16, and 16 mod 5 = 1, so the element for 2017 is +the second in the series, namely Fire. + +Note that Raku's modulus operator produces the correct result for negative +differences. From https://docs.raku.org/routine/$PERCENT_SIGN :- + + $x % $y == $x - floor($x / $y) * $y + +So for (1938 - 1984) = -46, -46 % 12 = -46 - floor(-46 / 12) * 12 + = -46 - (-4 * 12) = -46 - -48 = 2 + +which is the same result as would be obtained if the "start year" were 1924: +1938 - 1924 = 14, and 14 mod 12 = 2. + +=end comment +#============================================================================== + +my constant @ELEMENTS = Array[Str].new( < Wood Fire Earth Metal Water > ); + +my constant @ANIMALS = Array[Str].new\ + ( + < Rat Ox Tiger Rabbit Dragon Snake Horse Goat Monkey Rooster Dog Pig > + ); + +my UInt constant $START-YEAR = 1984; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 103, Task #1: Chinese Zodiac (Raku)\n".put; +} + +#============================================================================== +sub MAIN +( + UInt:D $year where { $year > 0 } #= Year AD (positive integer) +) +#============================================================================== +{ + "Input: $year".put; + + my UInt $el-index = floor( ($year - $START-YEAR) / 2 ) % @ELEMENTS.elems; + my UInt $an-index = ($year - $START-YEAR) % @ANIMALS\.elems; + + "Output: %s %s\n".printf: @ELEMENTS[ $el-index ], @ANIMALS[ $an-index ]; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +############################################################################## diff --git a/challenge-103/athanasius/raku/ch-2.raku b/challenge-103/athanasius/raku/ch-2.raku new file mode 100644 index 0000000000..fe4fca9ccf --- /dev/null +++ b/challenge-103/athanasius/raku/ch-2.raku @@ -0,0 +1,193 @@ +use v6d; + +############################################################################### +=begin comment + +Perl Weekly Challenge 103 +========================= + +Task #2 +------- +*What's playing?* + +Submitted by: Albert Croft + +Working from home, you decided that on occasion you wanted some background +noise while working. You threw together a network streamer to continuously loop +through the files and launched it in a tmux (or screen) session, giving it a +directory tree of files to play. During the day, you connected an audio player +to the stream, listening through the workday, closing it when done. + +For weeks you connect to the stream daily, slowly noticing a gradual drift of +the media. After several weeks, you take vacation. When you return, you are +pleasantly surprised to find the streamer still running. Before connecting, +however, if you consider the puzzle of determining which track is playing. + +After looking at a few modules to read info regarding the media, a quick bit of +coding gave you a file list. The file list is in a simple CSV format, each line +containing two fields: the first the number of milliseconds in length, the +latter the media's title (this example is of several episodes available from +the MercuryTheatre.info): + + 1709363,"Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" + 1723781,"Les Miserables Episode 2: Javert (broadcast date: 1937-07-30)" + 1723781,"Les Miserables Episode 3: The Trial (broadcast date: 1937-08-06)" + 1678356,"Les Miserables Episode 4: Cosette (broadcast date: 1937-08-13)" + 1646043,"Les Miserables Episode 5: The Grave (broadcast date: 1937-08-20)" + 1714640,"Les Miserables Episode 6: The Barricade (broadcast date: 1937-08-27)" + 1714640,"Les Miserables Episode 7: Conclusion (broadcast date: 1937-09-03)" + +For this script, you can assume to be provided the following information: + + * the value of $^T ($BASETIME) of the streamer script, + * the value of time(), and + * a CSV file containing the media to play consisting of the length in + milliseconds and an identifier for the media (title, filename, or other). + +Write a program to output which file is currently playing. For purposes of this +script, you may assume gapless playback, and format the output as you see fit. + +Optional: Also display the current position in the media as a time-like value. + +Example: + +UPDATED: Input parameters as reported by many members [2021-03-08 16:20 UK +TIME]. + + Input: 3 command line parameters: start time, current time, file name + + # starttime + 1606134123 + + # currenttime + 1614591276 + + # filelist.csv + + Output: + + "Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" + 00:10:24 + +=end comment +############################################################################### + +#--------------------------------------# +# Copyright © 2021 PerlMonk Athanasius # +#--------------------------------------# + +#============================================================================== +=begin comment + +Notes +----- +1. Although it would be quite straightforward to hand-craft file-reading code + for this particular exercise, as a general rule it is advisable to use a + dedicated module for reading CSV files. The module chosen here is the + excellent Text::CSV. +2. The easiest way to determine the file currently playing is to begin by + calculating the total time elapsed modulo the total duration of the media + files. Unlike Perl's built-in mod operator, Raku's "%" gives the desired + result when the operands are real (i.e., floating point) numbers. +3. The user may find it convenient to let the script determine the current + time, so an input value of zero for the current_time parameter is inter- + preted as "now". + +=end comment +#============================================================================== + +use Text::CSV; + +enum Data-Fields < Length Name Cum-length >; + +#------------------------------------------------------------------------------ +BEGIN +#------------------------------------------------------------------------------ +{ + "\nChallenge 103, Task #2: What's playing? (Raku)\n".put; +} + +#============================================================================== +sub MAIN +( + UInt:D $start-time, #= Start time in seconds since the epoch + UInt:D $current-time #= Current time in seconds (0 means now) + where { $_ == 0 || $_ >= $start-time }, + Str:D $file where { $_ ~~ / \.csv $ / && .IO ~~ :r } #= CSV filename +) +#============================================================================== +{ + my UInt $current = $current-time || now.floor; + + ("Input:\n\n Start time: $start-time\n" ~ + " Current time: $current\n" ~ + " File list: $file\n").put; + + my Array[Str] @data = read-data( $file.IO ); + my Real $total-s = @data[ @data.end; Cum-length ].Int / 1e3; + my UInt $difference = $current - $start-time; + my UInt $offset = floor( ($difference % $total-s) * 1e3 ); + my UInt $index = 0; + + for @data + { + last if $_[ Cum-length ] > $offset; + ++$index; + } + + $offset -= @data[ $index - 1; Cum-length ] if $index > 0; + + "Output:\n\n %s\n %s\n".printf: + @data[ $index; Name ], hms( $offset ); +} + +#------------------------------------------------------------------------------ +sub read-data( IO::Path:D $file --> Array:D[Array:D[Str:D]] ) +#------------------------------------------------------------------------------ +{ + my Text::CSV $csv = Text::CSV.new; + my IO::Handle $io = $file.open: :r, chomp => True; + my Array[Str] @data; + + for $csv.getline_all( $io ) + { + my Str @entry = $_<>; + @data.push: @entry; + } + + my UInt $cum-total = 0; + + for @data + { + $cum-total += $_[ Length ]; + .push: $cum-total.Str; + } + + return @data; +} + +#------------------------------------------------------------------------------ +sub hms( UInt:D $ms --> Str:D ) +#------------------------------------------------------------------------------ +{ + my UInt $seconds = floor( $ms / 1000 ); + my UInt $minutes = floor( $seconds / 60 ); + my UInt $hours = floor( $minutes / 60 ); + + $minutes -= $hours * 60; + $seconds -= $minutes * 60; + + return '%02d:%02d:%02d'.sprintf: $hours, $minutes, $seconds; +} + +#------------------------------------------------------------------------------ +sub USAGE() +#------------------------------------------------------------------------------ +{ + my Str $usage = $*USAGE; + + $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/; + $usage.put; +} + +############################################################################## diff --git a/challenge-103/athanasius/raku/filelist.csv b/challenge-103/athanasius/raku/filelist.csv new file mode 100644 index 0000000000..9428b93004 --- /dev/null +++ b/challenge-103/athanasius/raku/filelist.csv @@ -0,0 +1,7 @@ +1709363,"Les Miserables Episode 1: The Bishop (broadcast date: 1937-07-23)" +1723781,"Les Miserables Episode 2: Javert (broadcast date: 1937-07-30)" +1723781,"Les Miserables Episode 3: The Trial (broadcast date: 1937-08-06)" +1678356,"Les Miserables Episode 4: Cosette (broadcast date: 1937-08-13)" +1646043,"Les Miserables Episode 5: The Grave (broadcast date: 1937-08-20)" +1714640,"Les Miserables Episode 6: The Barricade (broadcast date: 1937-08-27)" +1714640,"Les Miserables Episode 7: Conclusion (broadcast date: 1937-09-03)" |
