June 2023 Archives

Perl Weekly Challenge #223 - Count Primes? I've Never Met the Man

Hello everybody! It's another week with a new Perl Weekly Challenge. This week I'm only doing the first challenge, not because of time, but because the second challenge makes absolutely no sense to me. Perhaps a clarification will come out, but I'm not going to bother at the moment.

This week the challenge is to find the number of primes under the provided number. This is a challenge that really isn't worth rebuilding, and so I would recommend using Math::Prime::Util. You have to know when to just trust the professionals and use modules. With the use of M::P::U, we can essentially do the challenge in one line.

use Math::Prime::Util 'primes';
say scalar @{primes(shift)};

primes() returns an array reference, so we have to dereference the array after calling the function. We shift the number that is entered, call primes (which provides an array of the primes under that number), and dereference it and count it to print the answer.

It's that simple! This is a case where I definitely wouldn't recommend writing your own custom prime finder. I'll hopefully see you next week with the next challenge!

Perl Weekly Challenge #222 - Checking Against My List of Members

Hi everybody! Just doing the first weekly challenge task again this week. This week we're sorting a list of numbers and then checking whether the number matches the same position in the unsorted list. It's a very simple challenge and easily written in about 4 actual lines of clean code.

Here's the code:

#!/usr/bin/perl
use strict;
use v5.24;
my @sorted = sort @ARGV;
my $matches;
for (my $i = 0; $i <= $#ARGV; $i++) {$matches++ if $ARGV[$i] == $sorted[$i]}
say $matches // 0;

This obviously doesn't have any error-checking to make sure the values are integers, so they could be text that's sorted differently, but we're assuming the input is trustworthy. For anyone new to programming reading this, never assume user input is trustworthy. Always do your safety checks and sanitize inputs.

Very simply, we're making a sorted copy of the inputs to the script, initializing $matches, looping through both lists checking for identical values (for which we need an index counter, which is why we use the 3-part loop structure) and add to $matches if we find one. Then we print either the number of matches or 0 if we didn't find any. The // 0 is necessary just so it doesn't print an empty line if the variable is still uninitialized.

Hope to see you all again next week with the next weekly challenge! Join the challenges if you find them interesting to read about.

Perl Weekly Challenge #221 - Good Strings, Bad Strings

Hi everybody! Very limited time this week so just a brief blog post.

This week we're looking for any words in the list that can be created only using letters from a dictionary string. Then print the number of characters in the good words.

Here's the code:

#!/usr/bin/perl

use strict;
use v5.24;

my %chars;
$chars{$_}++ for (split(//, shift));

my $total;

foreach (@ARGV) {
    my @currWordChars = split(//, $_);
    my %list = %chars;
    my $notFound;

    for my $char (@currWordChars) {
        if ($list{$char}) {
            $list{$char}--;
        } else {
            $notFound = 1;
            last;
        }
    }
    $total += ($notFound ? 0 : @currWordChars);
}
say $total;

So we try every single word against a hash of the dictionary letters, and if we're missing a letter we skip that word. We do this by making a copy of the dictionary hash and removing letters as we use them to create the word we're currently looking at.

A very simple solution and I started work on the second one but didn't have enough time available. Have a good week and I'll hopefully see you next week!

Perl Weekly Challenge #220 - I've Seen These Characters 'Round These Parts

Hi everybody, just a quick one this week. Again it's been a very busy week, so I wrote this one quick to print the sorted list of all common characters in all the words provided. That's the simple explanation of this week's challenge.

Here's the code:

my @results;
my $first_word = shift;
for my $letter (split(//, $first_word)) {
    push(@results, lc($letter)) if (grep {$_ =~ /$letter/i} @ARGV) == @ARGV;
}
@results = sort @results;
say $_ foreach @results;

So, for how it works. We take the first word, split it up into its letters, and look through it. All common characters have to appear in the first word, so we can just limit ourselves to those letters. We loop through each letter in the word, and do a regex grep to find any words containing the letter. If every word matches, we add the letter to the resulting list, then sort and print each one.

I got to learn more about grep this week, so that will help me be more idiomatic with it.

Stay safe and I'll hopefully see you next week!

Perl Weekly Challenge #219 - Squaring Up

Hi everybody! This week again because of time I only finished the first challenge of The Weekly Challenge. However, because work for my client requires Python, I'm busy learning Python and I thought "Why not do Python for a simple weekly challenge task?" This is the first Python code I've ever truly written and not just modified!

First, the Perl:

say $_ for (sort {$a <=> $b} (map {$_ * $_} @ARGV));

Yep, a one-liner. Normally I prefer to write longer, more readable code, but this time the task was so simple it made sense just to write it on one line.

We map each argument on the command line into its square, then sort (with a numerical sort because map defaults to strings) and then just say() them.

Originally I was sorting with a custom sort routine based on absolute values, but then I realized (thanks to other blog posts) that it would be more efficient not to abs() anything and just to replace everything with its square first, then sort.

Now for Python:

list = [int(input("Num1:")), int(input("Num2:")), int(input("Num3:")), int(input("Num4:")), int(input("Num5:"))]
for index in range(len(list)):
    list[index] = list[index] ** 2
list.sort()
for square in list:
    print(square)

It essentially does the same thing by replacing everything with its square, then sorting, then printing. It only takes 5 arguments because I'm not familiar with Python argument methods. I do like the simple input() command. It's quite a nice feature compared to Perl.

Hope to see you all next week!

About oldtechaa

user-pic Just getting back into Perl programming. I have a personal project, SeekMIDI, a small graphical MIDI sequencer.