perl-weekly-challenge Archives

Perl Weekly Challenge 030: Sunday Christmas and Series with sum 12

Sunday Christmas

Write a script to list dates for Sunday Christmas between 2019 and 2100. For example, 25 Dec 2022 is Sunday.

I used the core module Time::Piece to check the dates.

It’s easy to create a string representing Christmas: just concatenate the year with '-12-25'. The module’s strptime method can be used to create an object if we provide a format of the input string, in this case it’s '%Y-%m-%d'. The object’s method day_of_week now tells us what day the object represents, 0 corresponds to Sunday, which is the day we’re interested in.

Perl Weekly Challenge 029: Brace expansion and calling a C function

Brace expansion

Write a script to demonstrate brace expansion. For example, the script would take the command line argument Perl {Daily,Weekly,Monthly,Yearly} Challenge and should expand it and print like below:
Perl Daily Challenge
Perl Weekly Challenge
Perl Monthly Challenge
Perl Yearly Challenge

You’ve probably heard about the glob function. It can expand wildcards like * or ?, so you e.g. can easily check what files correspond to p*.p?. But glob can do one more thing for us: brace expansion.

Perl Weekly Challenge 028: File Content and Digital Clock

File Content

Write a script to check the file content without explicitly reading the content. It should accept file name with path as command line argument and print “The file content is binary.” or else “The file content is ascii.” accordingly.

Frankly, I had no idea how to solve this. I had to google the solution, and I was quite surprised Perl had the operators designed for exactly this purpose. During my approximately 20 years of Perl programming, I’ve never needed the -T and -B operators—probably because all my scripts and programs expect either a text or a binary file as the input, and it’s upon the user to provide it in the expected format.

use warnings;
use strict;
use feature qw{ say };

say 'The file content is ', (-T shift) ? 'ascii' : 'binary', '.';

Perl Weekly Challenge 027: Intersection of Straight Lines and Historical Data

Intersection of Straight Lines

Write a script to find the intersection of two straight lines. The coordinates of the two lines should be provided as command line parameter.

I vaguely remember we did the general form of the equation of a straight line at secondary school. The formula itself is pretty simple:

Ax + By + C = 0

Now, clearly, if we have two straight lines A1, B1, C1 and A2, B2, C2, their intersection are the x and y such that A1x + B1y + C = A2x + B2y + C2. From the general formula we know that

x = (-B1y - C1) / A1

It takes a bit of pen and paper work to find out that

y = (A2C1 - C2A1) / (A1B2 - A2B1)

Perl Weekly Challenge 026: Stones and Jewels; Mean of Angles

Stones and Jewels

Create a script that accepts two strings, let’s call them “stones” and “jewels”. It should print the count of “letters” from the string “stones” found in the string “jewels”. For example, if your stones is “chancellor” and “jewels” is “chocolate”, then the script should print 8. To keep it simple, only A-Z, a-z characters are acceptable. Also, make the comparison case sensitive.

The most important thing is to realise that we only want to consider unique characters in the “stones”. My initial idea was for each character of the “stones” to count how many times it appears in the “jewels”. Remember that the global matching operator m//g returns the number of matches in list context.

Let’s call the subroutine with two names parameters, stones and jewels, each of them containing a string.

use List::Util qw{ uniq };

sub count1 {
    my %args = @_;
    my $count = 0;
    $count += () = $args{jewels} =~ /$_/g
        for uniq(split //, $args{stones});
    return $count

Perl Weekly Challenge 025: Pokemon Sequence and Chaocipher

The longest sequence

Generate a longest sequence of the following “English Pokemon” names where each name starts with the last letter of previous name.

I’m not sure whether the term “sequence” has a unique and generally accepted definition. For example, does it have to contain each element just once? If not, the longest sequence might be

girafarig girafarig girafarig girafarig girafarig girafarig girafarig girafarig...

If we want each element to appear just once in the sequence, we are in the graph theory and we search for the longest simple path. For a general graph, this is an NP-hard problem, but fortunately, our input is small enough to be solved in reasonable time.

We can implement a brute-force search (i.e. trying all the possible sequences) recursively. The recursive steps takes the sequence constructed so far and tries to extend it by all the possible next steps, calling itself to extend each of them further.

Perl Weekly Challenge 024: Inverted Index and Shortest Oneliner

I’ll start with the second task, as the first one is somehow different (see below).

Inverted Index

Create a script to implement full text search functionality using Inverted Index.

An inverted index is an index storing a mapping from content to its location. I chose to store the filename and line number for all words in a given list of files.

Perl Weekly Challenge 023: Forward difference series & Prime decomposition

Forward difference series

Create a script that prints nth order forward difference series. You should be a able to pass the list of numbers and order number as command line parameters.

Perl Weekly Challenge 020: Split on change + amicable numbers

I spent this week in Rīga at the Perl Conference. I had two talks there, a standard 20-minutes one and a lightning talk (5 minutes). I dedicated all my free time to the preparation of the slides, but fortunately the assignments were rather easy this week, so I submitted the solutions on Monday already before leaving for Rīga.

Perl Weekly Challenge 019: Five Weekends and Paragraph Wrapping

This week’s challenge was a bit easier than the recent ones, but I was glad for that. The Perl Conference in Riga is coming and I still don’t have my slides ready!

Five Weekends

Write a script to display months from the year 1900 to 2019 where you find 5 weekends, i.e. 5 Fridays, 5 Saturdays, and 5 Sundays.

I started by running the cal utility (part of the util-linux package) to see how such months might look. For example, this is the output of cal 1904 (5 weekends highlighted manually be me):

About E. Choroba

user-pic I blog about Perl.