{"@attributes":{"version":"2.0"},"channel":{"title":"DEV Community: Simon Green","description":"The latest articles on DEV Community by Simon Green (@simongreennet).","link":"https:\/\/dev.to\/simongreennet","image":{"url":"https:\/\/media2.dev.to\/dynamic\/image\/width=90,height=90,fit=cover,gravity=auto,format=auto\/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F472699%2Feb7bd146-a3b0-41a6-a0b4-22653730bb55.png","title":"DEV Community: Simon Green","link":"https:\/\/dev.to\/simongreennet"},"language":"en","item":[{"title":"Happy 7th birthday TWC!","pubDate":"Mon, 23 Mar 2026 12:34:59 +0000","link":"https:\/\/dev.to\/simongreennet\/happy-7th-birthday-twc-lpk","guid":"https:\/\/dev.to\/simongreennet\/happy-7th-birthday-twc-lpk","description":"<h2>\n  \n  \n  Weekly Challenge 366\n<\/h2>\n\n<p>It was seven years ago that Mohammad sent out the <a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-001\/\" rel=\"noopener noreferrer\">first challenge<\/a> to Team PWC (as it was then known). Thank you very much for all your work over the seven years.<\/p>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-366\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-366\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Count Prefixes\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given an array of words and a string (contains only lowercase English letters).<\/p>\n\n<p>Write a script to return the number of words in the given array that are a prefix of the given string.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This is a one-liner in Python. It should be pretty self-explanatory. Given a list called <code>array<\/code> and a string called <code>prefix<\/code>, it counts the number of items in the list where the first letters of the prefix match the word.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">count_prefixes<\/span><span class=\"p\">(<\/span><span class=\"n\">array<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">,<\/span> <span class=\"n\">prefix<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">sum<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span> <span class=\"k\">for<\/span> <span class=\"n\">word<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">array<\/span> <span class=\"k\">if<\/span> <span class=\"n\">prefix<\/span><span class=\"p\">[:<\/span><span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">word<\/span><span class=\"p\">)]<\/span> <span class=\"o\">==<\/span> <span class=\"n\">word<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution uses the grep function to perform the counting. In a scalar context, grep returns the number of matching items.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">(@array) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$prefix<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">pop<\/span><span class=\"p\">(<\/span><span class=\"nv\">@array<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$count<\/span>  <span class=\"o\">=<\/span> <span class=\"nb\">grep<\/span> <span class=\"p\">{<\/span> <span class=\"nb\">substr<\/span><span class=\"p\">(<\/span> <span class=\"nv\">$prefix<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"nb\">length<\/span><span class=\"p\">(<\/span><span class=\"vg\">$_<\/span><span class=\"p\">)<\/span> <span class=\"p\">)<\/span> <span class=\"ow\">eq<\/span> <span class=\"vg\">$_<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@array<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$count<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py a ap app apple banana apple\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"nb\">cat <\/span>dog fish bird\n0\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py hello he hello heaven he hello\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"\"<\/span> code coding cod coding\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py p <span class=\"nb\">pr <\/span>pro prog progr progra program program\n7\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Valid Times\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a time in the form <code>HH:MM<\/code>. The earliest possible time is <code>00:00<\/code> and the latest possible time is <code>23:59<\/code>. In the string time, the digits represented by the <code>?<\/code> symbol are unknown, and must be replaced with a digit from 0 to 9.<\/p>\n\n<p>Write a script to return the count different ways we can make it a valid time.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This is an interesting challenge as the solution is not straight forward. There are a few approaches that can be taken. One option is to calculate all 1440 minutes in a day and see if it matched the expected pattern.<\/p>\n\n<p>The approach I took was to calculate the possible hours and possible minutes, and multiplying both figures to return a result.<\/p>\n\n<p>I start by using a regular expression to check if the time is valid. As the question mark <code>?<\/code> is within square brackets <code>[ ]<\/code> this is taken as a literal character.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">valid_times<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"nf\">search<\/span><span class=\"p\">(<\/span><span class=\"sa\">r<\/span><span class=\"sh\">'<\/span><span class=\"s\">^([0-1?][0-9?]|2[0-3?]):[0-5?][0-9?]$<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">):<\/span>\n        <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Input is not in the expected format (HH:MM)<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The next task is calculating the number of valid hours.<\/p>\n\n<ol>\n<li>If the hours is <code>??<\/code>, then there are 24 valid hours.<\/li>\n<li>If the first character is a question there are 3 valid hours if the second digit is less than four (e.g. 02 12 22), or 2 if it is 4 or greater (e.g. 04 14).<\/li>\n<li>If the second character is a question mark, there are 4 valid hours if the first digit is 2, or 10 valid hours otherwise.<\/li>\n<li>If hours have no questions marks, there is only one valid hour.\n<\/li>\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"c1\"># Compute the hours\n<\/span>    <span class=\"k\">if<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[:<\/span><span class=\"mi\">2<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">??<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">hours<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">24<\/span>\n    <span class=\"k\">elif<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[:<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">?<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">hours<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">3<\/span> <span class=\"k\">if<\/span> <span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:<\/span><span class=\"mi\">2<\/span><span class=\"p\">])<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">4<\/span> <span class=\"k\">else<\/span> <span class=\"mi\">2<\/span>\n    <span class=\"k\">elif<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:<\/span><span class=\"mi\">2<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">?<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">hours<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">4<\/span> <span class=\"k\">if<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[:<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">2<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"mi\">10<\/span>\n    <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">hours<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Thankfully calculating the number of valid minutes is a little easier.<\/p>\n\n<ol>\n<li>If the minutes is <code>??<\/code>, then there are sixty valid minutes.<\/li>\n<li>If the first character is a question mark, then there are six valid minutes (e.g. 06 16 26 36 46 56).<\/li>\n<li>If the second characters is a question mark, there are ten valid minutes (e.g. 50 51 ... 58 59).<\/li>\n<li>If the minutes have no question marks, there is only one valid minute.\n<\/li>\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"k\">if<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[<\/span><span class=\"mi\">3<\/span><span class=\"p\">:]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">??<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">minutes<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">60<\/span>\n    <span class=\"k\">elif<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[<\/span><span class=\"mi\">3<\/span><span class=\"p\">:<\/span><span class=\"mi\">4<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">?<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">minutes<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">6<\/span>\n    <span class=\"k\">elif<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">[<\/span><span class=\"mi\">4<\/span><span class=\"p\">:]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">?<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">minutes<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">10<\/span>\n    <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">minutes<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">hours<\/span> <span class=\"o\">*<\/span> <span class=\"n\">minutes<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution follows the same logic as the Python solution.<\/p>\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py ?2:34\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py ?4:?0\n12\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py ??:??\n1440\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py ?3:45\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 2?:15\n4\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","perl","theweeklychallenge"]},{"title":"Weekly Challenge: Counting the index","pubDate":"Thu, 19 Mar 2026 07:30:11 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-counting-the-index-oe1","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-counting-the-index-oe1","description":"<h2>\n  \n  \n  Weekly Challenge 365\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-365\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-365\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Alphabet Index Digit Sum\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string <code>$str<\/code> consisting of lowercase English letters, and an integer <code>$k<\/code>.<\/p>\n\n<p>Write a script to convert a lowercase string into numbers using alphabet positions (a=1 \u2026 z=26), concatenate them to form an integer, then compute the sum of its digits repeatedly <code>$k<\/code> times, returning the final value.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This is a task of two parts. The first is to take the letters from <code>input_string<\/code> (as <code>str<\/code> is a reserved word in Python) to create a number. For this I use <code>string.ascii_lowercase.index(letter)+1<\/code> to get each letter and append it to the <code>digits<\/code> variable. The <code>+1<\/code> is because the letters start at <code>1<\/code>, not <code>0<\/code>.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">aid_sum<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">k<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">digits<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">''<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">letter<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">digits<\/span> <span class=\"o\">+=<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">string<\/span><span class=\"p\">.<\/span><span class=\"n\">ascii_lowercase<\/span><span class=\"p\">.<\/span><span class=\"nf\">index<\/span><span class=\"p\">(<\/span><span class=\"n\">letter<\/span><span class=\"p\">)<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">except<\/span> <span class=\"nb\">ValueError<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span>\n                <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">The character <\/span><span class=\"sh\">'<\/span><span class=\"si\">{<\/span><span class=\"n\">letter<\/span><span class=\"si\">}<\/span><span class=\"sh\">'<\/span><span class=\"s\"> does not appear to be a lower case letter<\/span><span class=\"sh\">\"<\/span>\n            <span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The second part is to compute the sums of all the digits a specified number of times. For this I have a loop that performs this. It's a little clunky as Python treats strings and integers differently. If I have a single digit, I exit the loop early as further repetitions won't change the result.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"k\">for<\/span> <span class=\"n\">_<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">range<\/span><span class=\"p\">(<\/span><span class=\"n\">k<\/span><span class=\"p\">):<\/span>\n        <span class=\"n\">digits<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"nf\">sum<\/span><span class=\"p\">(<\/span><span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">i<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">i<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">digits<\/span><span class=\"p\">))<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">digits<\/span><span class=\"p\">)<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">1<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">break<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">digits<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>As Perl doesn't care about strings vs integers (with a few exceptions), the code is more straight forward. The <a href=\"https:\/\/perldoc.perl.org\/functions\/index\" rel=\"noopener noreferrer\">index<\/a> function is used to find the position of the letter in the alphabet.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">( $input_string, $k ) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$alphabet<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">join<\/span><span class=\"p\">(<\/span> <span class=\"p\">\"\",<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">a<\/span><span class=\"p\">\"<\/span> <span class=\"o\">..<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">z<\/span><span class=\"p\">\"<\/span> <span class=\"p\">);<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$digits<\/span>   <span class=\"o\">=<\/span> <span class=\"p\">'';<\/span>\n\n    <span class=\"k\">foreach<\/span> <span class=\"k\">my<\/span> <span class=\"nv\">$letter<\/span> <span class=\"p\">(<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$input_string<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">my<\/span> <span class=\"nv\">$idx<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">index<\/span><span class=\"p\">(<\/span> <span class=\"nv\">$alphabet<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$letter<\/span> <span class=\"p\">);<\/span>\n        <span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"nv\">$idx<\/span> <span class=\"o\">==<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"nb\">die<\/span>\n              <span class=\"p\">\"<\/span><span class=\"s2\">The character '<\/span><span class=\"si\">$letter<\/span><span class=\"s2\">' does not appear to be a lower case letter<\/span><span class=\"se\">\\n<\/span><span class=\"p\">\";<\/span>\n        <span class=\"p\">}<\/span>\n\n        <span class=\"nv\">$digits<\/span> <span class=\"o\">.=<\/span> <span class=\"nv\">$idx<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">foreach<\/span> <span class=\"p\">(<\/span> <span class=\"mi\">1<\/span> <span class=\"o\">..<\/span> <span class=\"nv\">$k<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">$digits<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">sum<\/span><span class=\"p\">(<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$digits<\/span> <span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$digits<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py abc 1\n6\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py az 2\n9\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"nb\">cat <\/span>1\n6\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py dog 2\n8\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py perl 3\n6\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Valid Token Counter\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a sentence.<\/p>\n\n<p>Write a script to split the given sentence into space-separated tokens and count how many are valid words. A token is valid if it contains no digits, has at most one hyphen surrounded by lowercase letters, and at most one punctuation mark (<code>!<\/code>, <code>.<\/code>, <code>,<\/code>) appearing only at the end.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This is a challenge where regular expression can be used to solve the problem. In both the Python and Perl solution, the regular expression used is <code>^[a-z]+(\\-[a-z]+)?[!,\\.]?$<\/code>.<\/p>\n\n<p>Breaking each part down:<\/p>\n\n<ul>\n<li>\n<code>^<\/code> indicate the start of the string<\/li>\n<li>\n<code>[a-z]+<\/code> means one or more lower case letters<\/li>\n<li>\n<code>(\\-[a-z]+)?<\/code> means optionally (the question mark) a hyphen and one or more lowercase letters.<\/li>\n<li>\n<code>[!,\\.]?<\/code> means optionally a exclamation mark, comma or full stop.<\/li>\n<li>\n<code>$<\/code> means the end of the string.<\/li>\n<\/ul>\n\n<p>This is a one liner in Python<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">valid_token_counter<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">sum<\/span><span class=\"p\">(<\/span>\n        <span class=\"mi\">1<\/span> <span class=\"k\">for<\/span> <span class=\"n\">word<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">()<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"nf\">search<\/span><span class=\"p\">(<\/span><span class=\"sa\">r<\/span><span class=\"sh\">'<\/span><span class=\"s\">^[a-z]+(\\-[a-z]+)?[!,\\.]?$<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"n\">word<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution is also one line (and an extra one to display the answer). The <code>grep<\/code> function returns the number of matches in a scalar context.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($input_string) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$count<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">grep<\/span> <span class=\"p\">{<\/span> <span class=\"sr\">\/^[a-z]+(\\-[a-z]+)?[!,\\.]?$\/<\/span> <span class=\"p\">}<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\\s+\/<\/span><span class=\"p\">,<\/span>\n      <span class=\"nv\">$input_string<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$count<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"cat and dog\"<\/span>\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"a-b c! d,e\"<\/span>\n2\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"hello-world! this is fun\"<\/span>\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"ab- cd-ef gh- ij!\"<\/span>\n2\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"wow! a-b-c nice.\"<\/span>\n2\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","perl","theweeklychallenge"]},{"title":"Weekly Challenge: It's all about the translation","pubDate":"Thu, 12 Mar 2026 07:29:35 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-its-all-about-the-translation-17li","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-its-all-about-the-translation-17li","description":"<h2>\n  \n  \n  Weekly Challenge 364\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-364\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-364\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Decrypt String\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string formed by digits and <code>#<\/code>. Write a script to map the given string to English lowercase characters following the given rules.<\/p>\n\n<ul>\n<li>Characters <code>a<\/code> to <code>i<\/code> are represented by <code>1<\/code> to <code>9<\/code> respectively.<\/li>\n<li>Characters <code>j<\/code> to <code>z<\/code> are represented by <code>10#<\/code> to <code>26#<\/code> respectively.<\/li>\n<\/ul>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This task calls for regular expressions to be used. Both Python and Perl allow call back functions in the replacement section (i.e. you can call a function to find the new string).<\/p>\n\n<p>For the Python solution, I have a (callback) function called <code>replace_digits<\/code>. It takes a Match object as input and returns a string.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">replace_digits<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">:<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"n\">Match<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">c<\/span> <span class=\"o\">=<\/span> <span class=\"n\">m<\/span><span class=\"p\">.<\/span><span class=\"nf\">group<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">chr<\/span><span class=\"p\">(<\/span><span class=\"mi\">96<\/span> <span class=\"o\">+<\/span> <span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span><span class=\"p\">[:<\/span><span class=\"mi\">2<\/span><span class=\"p\">]))<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The variable <code>c<\/code> has the matching string (either a single digit or two digits (10-26) followed by a hash character. Things to note:<\/p>\n\n<ul>\n<li>\n<code>c[:2]<\/code> will remove the hash if it is present.<\/li>\n<li>\n<code>int(...)<\/code> will convert this into a number<\/li>\n<li>\n<code>chr(...)<\/code> will turn this into a letter of the alphabet. The ASCII code for the letter <code>a<\/code> is <code>97<\/code>.<\/li>\n<\/ul>\n\n<p>The main function checks that the input is valid. It then uses <code>re.sub<\/code> to perform the substitution in the <code>replace_digits<\/code> function.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">decrypt_string<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"nf\">search<\/span><span class=\"p\">(<\/span><span class=\"sa\">r<\/span><span class=\"sh\">'<\/span><span class=\"s\">^(1\\d#|2[0-6]#|\\d)*$<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">):<\/span>\n        <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">String not in expected format<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"nf\">sub<\/span><span class=\"p\">(<\/span><span class=\"sa\">r<\/span><span class=\"sh\">'<\/span><span class=\"s\">(1\\d#|2[0-6]#|\\d)<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"n\">replace_digits<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution follows the same logic, except that the replacement value can be code (not just a function call). This negates the need for a separate function. The <code>substr<\/code> function is used to remove the hash character.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($input_string) {<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"nv\">$input_string<\/span> <span class=\"o\">!~<\/span> <span class=\"sr\">\/^(1\\d#|2[0-6]#|\\d)*$\/<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nb\">die<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">String not in expected format<\/span><span class=\"se\">\\n<\/span><span class=\"p\">\";<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$output_string<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$input_string<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">$output_string<\/span> <span class=\"o\">=~<\/span> <span class=\"sr\">s\/(1\\d#|2[0-6]#|\\d)\/chr(96 + substr($1,0,2))\/<\/span><span class=\"nv\">eg<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$output_string<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>In the regular expression, <code>\/e<\/code> indicates that the replacement value is a expression (as opposed to the literal string), and <code>\/g<\/code> means to run the regular expression globally (on all occurrences).<\/p>\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py 10#11#12\njkab\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1326#\nacz\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 25#24#123\nyxabc\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 20#5\nte\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1910#26#\naijz\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Goal Parser\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string, <code>$str<\/code>.<\/p>\n\n<p>Write a script to interpret the given string using Goal Parser. The Goal Parser interprets <code>G<\/code> as the string <code>G<\/code>, <code>()<\/code> as the string <code>o<\/code>, and <code>(al)<\/code> as the string <code>al<\/code>. The interpreted strings are then concatenated in the original order.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>For this task, I use a regular expression to check that the <code>input_string<\/code> is in the expected format. I then use the replace function to change the string to the required output.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">good_parser<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"nf\">search<\/span><span class=\"p\">(<\/span><span class=\"sa\">r<\/span><span class=\"sh\">'<\/span><span class=\"s\">^(G|\\(\\)|\\(al\\))*$<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">):<\/span>\n        <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Unexpected input received<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">.<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sh\">'<\/span><span class=\"s\">()<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"sh\">'<\/span><span class=\"s\">o<\/span><span class=\"sh\">'<\/span><span class=\"p\">).<\/span><span class=\"nf\">replace<\/span><span class=\"p\">(<\/span><span class=\"sh\">'<\/span><span class=\"s\">(al)<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"sh\">'<\/span><span class=\"s\">al<\/span><span class=\"sh\">'<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Perl doesn't have a replace function, so I use a regular expression to perform the replacement.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($input_string) {<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$input_string<\/span> <span class=\"o\">!~<\/span> <span class=\"sr\">\/^(G|\\(\\)|\\(al\\))*$\/<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nb\">die<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">Unexpected input received<\/span><span class=\"se\">\\n<\/span><span class=\"s2\">;<\/span><span class=\"p\">\"<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$output_string<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$input_string<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">$output_string<\/span> <span class=\"o\">=~<\/span><span class=\"sr\">s\/\\(\\)\/o\/g<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">$output_string<\/span> <span class=\"o\">=~<\/span> <span class=\"sr\">s\/\\(al\\)\/al\/g<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$output_string<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n<p>Parentheses have special meaning in bash, so quotes are used to handle this.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.pl <span class=\"s2\">\"G()(al)\"<\/span>\nGoal\n\n<span class=\"nv\">$ <\/span>.\/ch-2.pl <span class=\"s2\">\"G()()()()(al)\"<\/span>\nGooooal\n\n<span class=\"nv\">$ <\/span>.\/ch-2.pl <span class=\"s2\">\"(al)G(al)()()\"<\/span>\nalGaloo\n\n<span class=\"nv\">$ <\/span>.\/ch-2.pl <span class=\"s2\">\"()G()G\"<\/span>\noGoG\n\n<span class=\"nv\">$ <\/span>.\/ch-2.pl <span class=\"s2\">\"(al)(al)G()()\"<\/span>\nalalGoo\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","perl","theweeklychallenge"]},{"title":"Weekly Challlenge: The subnet detector","pubDate":"Sun, 08 Mar 2026 13:43:08 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challlenge-the-subnet-detector-1d9l","guid":"https:\/\/dev.to\/simongreennet\/weekly-challlenge-the-subnet-detector-1d9l","description":"<h2>\n  \n  \n  Weekly Challenge 363\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, CoPilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-363\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-363\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: String Lie Detector\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string.<\/p>\n\n<p>Write a script that parses a self-referential string and determines whether its claims about itself are true. The string will make statements about its own composition, specifically the number of vowels and consonants it contains.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This was relatively straight forward in Python. I took the following steps:<\/p>\n\n<ol>\n<li>Use a regular expression to extract the necessary parts of the <code>input_string<\/code>, and store this as the value <code>match<\/code>.<\/li>\n<li>Count the number of vowels and consonants in the first value and store it as <code>vowel_count<\/code> and <code>const_count<\/code>.<\/li>\n<li>Use the <a href=\"https:\/\/pypi.org\/project\/word2num\/\" rel=\"noopener noreferrer\">word2num<\/a> module to convert the numbers in <code>input_string<\/code> to integers, stored as <code>expected_vowel<\/code> and <code>expected_const<\/code>.<\/li>\n<li>Compare the count and expected values match, and return the result.\n<\/li>\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">import<\/span> <span class=\"n\">re<\/span>\n<span class=\"kn\">from<\/span> <span class=\"n\">word2num<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">word2num<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">string_lie_detector<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">bool<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">match<\/span> <span class=\"o\">=<\/span> <span class=\"n\">re<\/span><span class=\"p\">.<\/span><span class=\"nf\">match<\/span><span class=\"p\">(<\/span>\n        <span class=\"sa\">r<\/span><span class=\"sh\">\"<\/span><span class=\"s\">(\\w+) . (\\w+) vowels? and (\\w+) consonants?<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">match<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Input string not in expected format<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">vowel_count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"n\">const_count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">c<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">match<\/span><span class=\"p\">.<\/span><span class=\"nf\">group<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">).<\/span><span class=\"nf\">lower<\/span><span class=\"p\">():<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">c<\/span> <span class=\"ow\">in<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">aeiou<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">vowel_count<\/span> <span class=\"o\">+=<\/span> <span class=\"mi\">1<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">const_count<\/span> <span class=\"o\">+=<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"n\">expected_vowel<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">word2num<\/span><span class=\"p\">(<\/span><span class=\"n\">match<\/span><span class=\"p\">.<\/span><span class=\"nf\">group<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">))<\/span>\n    <span class=\"n\">expected_const<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">word2num<\/span><span class=\"p\">(<\/span><span class=\"n\">match<\/span><span class=\"p\">.<\/span><span class=\"nf\">group<\/span><span class=\"p\">(<\/span><span class=\"mi\">3<\/span><span class=\"p\">))<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">vowel_count<\/span> <span class=\"o\">==<\/span> <span class=\"n\">expected_vowel<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">const_count<\/span> <span class=\"o\">==<\/span> <span class=\"n\">expected_const<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution is a little more complex. Maybe my Google-foo isn't up to scratch (and I don't use Copilot when working on solutions) that there doesn't appear to be a CPAN module that will convert words into numbers. As this is a coding exercise only I have a hash called <code>%word2num<\/code> that maps words to number (from zero to twenty).<\/p>\n\n<p>The next problem is four of the examples use a long dash as the separator. This is a UTF-8 character. The result of <code>perl -E 'say length(\"\u2014\")'<\/code> is 3. After numerous searches of the Internet, it turns out I need to include <code>use utf8:all<\/code> in the code. With this change, I get the expected result of <code>1<\/code>.<\/p>\n\n<p>The rest of the code follows the same logic as the Python solution.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">use<\/span> <span class=\"nn\">utf8::<\/span><span class=\"nv\">all<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($input_string) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">%word2num<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"sx\">qw\/\n        zero 0 one 1 two 2 three 3 four 4 five 5 six 6 seven 7 eight 8\n        nine 9 ten 10 eleven 11 twelve 12 thirteen 13 fourteen 14\n        fifteen 15 sixteen 16 seventeen 17 eighteen 18 nineteen 19 twenty 20\n    \/<\/span><span class=\"p\">);<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"p\">(<\/span> <span class=\"nv\">$word<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$v<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$c<\/span> <span class=\"p\">)<\/span> <span class=\"o\">=<\/span>\n      <span class=\"p\">(<\/span> <span class=\"nv\">$input_string<\/span> <span class=\"o\">=~<\/span> <span class=\"sr\">\/(\\w+) . (\\w+) vowels? and (\\w+) consonants?\/<\/span> <span class=\"p\">);<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"o\">!<\/span><span class=\"nv\">$word<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nb\">die<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">Input string not in expected format<\/span><span class=\"se\">\\n<\/span><span class=\"p\">\";<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$vowel_count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$const_count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">foreach<\/span> <span class=\"k\">my<\/span> <span class=\"nv\">$c<\/span> <span class=\"p\">(<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nb\">lc<\/span><span class=\"p\">(<\/span><span class=\"nv\">$word<\/span><span class=\"p\">)<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"nb\">index<\/span><span class=\"p\">(<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">aeiou<\/span><span class=\"p\">\",<\/span> <span class=\"nv\">$c<\/span> <span class=\"p\">)<\/span> <span class=\"o\">==<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"nv\">$const_count<\/span><span class=\"o\">++<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n            <span class=\"nv\">$vowel_count<\/span><span class=\"o\">++<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$expected_vowel<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$word2num<\/span><span class=\"p\">{<\/span> <span class=\"nb\">lc<\/span> <span class=\"nv\">$v<\/span> <span class=\"p\">}<\/span> <span class=\"sr\">\/\/<\/span> <span class=\"nb\">die<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">Don't know what <\/span><span class=\"si\">$v<\/span><span class=\"s2\"> is<\/span><span class=\"se\">\\n<\/span><span class=\"p\">\";<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$expected_const<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$word2num<\/span><span class=\"p\">{<\/span> <span class=\"nb\">lc<\/span> <span class=\"nv\">$c<\/span> <span class=\"p\">}<\/span> <span class=\"sr\">\/\/<\/span> <span class=\"nb\">die<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">Don't know what <\/span><span class=\"si\">$c<\/span><span class=\"s2\"> is<\/span><span class=\"se\">\\n<\/span><span class=\"p\">\";<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$truth<\/span> <span class=\"o\">=<\/span>\n      <span class=\"p\">(<\/span> <span class=\"nv\">$vowel_count<\/span> <span class=\"o\">==<\/span> <span class=\"nv\">$expected_vowel<\/span> <span class=\"ow\">and<\/span> <span class=\"nv\">$const_count<\/span> <span class=\"o\">==<\/span> <span class=\"nv\">$expected_const<\/span> <span class=\"p\">);<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$truth<\/span> <span class=\"p\">?<\/span> <span class=\"p\">'<\/span><span class=\"s1\">true<\/span><span class=\"p\">'<\/span> <span class=\"p\">:<\/span> <span class=\"p\">'<\/span><span class=\"s1\">false<\/span><span class=\"p\">';<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n<p>There was an issue with the examples, and I raised a <a href=\"https:\/\/github.com\/manwar\/theweeklychallenge\/pull\/207\" rel=\"noopener noreferrer\">pull request<\/a> to fix it.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"aa \u2014 two vowels and zero consonants\"<\/span>\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"iv \u2014 one vowel and one consonant\"<\/span>\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"hello - three vowels and two consonants\"<\/span>\nFalse\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"aeiou \u2014 five vowels and zero consonants\"<\/span>\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"aei \u2014 three vowels and zero consonants\"<\/span>\nTrue\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Subnet Sheriff\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given an IPv4 address and an IPv4 network (in CIDR format).<\/p>\n\n<p>Write a script to determine whether both are valid and the address falls within the network. For more information see the <a href=\"https:\/\/en.wikipedia.org\/wiki\/IPv4\" rel=\"noopener noreferrer\">Wikipedia article<\/a>.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This one was the easier of the two to complete. Maybe because I have worked at many IPSs in the past :-)<\/p>\n\n<p>Python has the <a href=\"https:\/\/docs.python.org\/3\/library\/ipaddress.html\" rel=\"noopener noreferrer\">ipaddress<\/a> module which makes it easy to confirm if an IPv4 address is in a particular IP address block.<\/p>\n\n<p>I use a try\/except block to handle situations (like the second example) where the IP address or net block is invalid. This follows the Python philosophy of <a href=\"https:\/\/www.geeksforgeeks.org\/python\/eafp-principle-in-python\/\" rel=\"noopener noreferrer\">Easier to Ask for Forgiveness than Permission<\/a>.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">import<\/span> <span class=\"n\">ipaddress<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">subnet_sheriff<\/span><span class=\"p\">(<\/span><span class=\"n\">ip_addr<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">domain<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">bool<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">try<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">ipaddress<\/span><span class=\"p\">.<\/span><span class=\"nc\">IPv4Address<\/span><span class=\"p\">(<\/span><span class=\"n\">ip_addr<\/span><span class=\"p\">)<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">ipaddress<\/span><span class=\"p\">.<\/span><span class=\"nc\">IPv4Network<\/span><span class=\"p\">(<\/span><span class=\"n\">domain<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">except<\/span> <span class=\"n\">ipaddress<\/span><span class=\"p\">.<\/span><span class=\"n\">AddressValueError<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"bp\">False<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Perl has the <a href=\"https:\/\/docs.python.org\/3\/library\/ipaddress.html\" rel=\"noopener noreferrer\">Net::IP<\/a> module in CPAN that performs similar functionality. If the IP address or net block is invalid, the variable will be <code>undef<\/code>, and the else block will be used.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">use<\/span> <span class=\"nn\">Net::<\/span><span class=\"nv\">IP<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">( $ip_addr, $domain ) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$addr<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Net::<\/span><span class=\"nv\">IP<\/span><span class=\"o\">-&gt;<\/span><span class=\"k\">new<\/span><span class=\"p\">(<\/span><span class=\"nv\">$ip_addr<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$block<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Net::<\/span><span class=\"nv\">IP<\/span><span class=\"o\">-&gt;<\/span><span class=\"k\">new<\/span><span class=\"p\">(<\/span><span class=\"nv\">$domain<\/span><span class=\"p\">);<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"nv\">$addr<\/span> <span class=\"ow\">and<\/span> <span class=\"nv\">$block<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">my<\/span> <span class=\"nv\">$overlaps<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span> <span class=\"nv\">$addr<\/span><span class=\"o\">-&gt;<\/span><span class=\"nv\">overlaps<\/span><span class=\"p\">(<\/span><span class=\"nv\">$block<\/span><span class=\"p\">)<\/span> <span class=\"o\">!=<\/span> <span class=\"nv\">$IP_NO_OVERLAP<\/span> <span class=\"p\">);<\/span>\n        <span class=\"nv\">say<\/span> <span class=\"nv\">$overlaps<\/span>  <span class=\"p\">?<\/span> <span class=\"p\">'<\/span><span class=\"s1\">true<\/span><span class=\"p\">'<\/span> <span class=\"p\">:<\/span> <span class=\"p\">'<\/span><span class=\"s1\">false<\/span><span class=\"p\">';<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">say<\/span> <span class=\"p\">'<\/span><span class=\"s1\">false<\/span><span class=\"p\">';<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py 192.168.1.45 192.168.1.0\/24\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 10.0.0.256 10.0.0.0\/24\nFalse\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 172.16.8.9 172.16.8.9\/32\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 172.16.4.5 172.16.0.0\/14\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 192.0.2.0 192.0.2.0\/25\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 1.1.1.1 10.0.0.0\/8\nFalse\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","perl","theweeklychallenge"]},{"title":"Weekly Challenge: The one liners","pubDate":"Sun, 01 Mar 2026 12:57:45 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-the-one-liners-14lo","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-the-one-liners-14lo","description":"<h2>\n  \n  \n  Weekly Challenge 362\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, CoPilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-362\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-362\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Echo Chamber\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string containing lowercase letters.<\/p>\n\n<p>Write a script to transform the string based on the index position of each character (starting from <code>0<\/code>). For each character at position <code>i<\/code>, repeat it <code>i + 1<\/code> times.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>Both of this weeks solutions are a one-liner in Python. For this task, the function is<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">echo_chamber<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"sh\">''<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span>\n        <span class=\"n\">letter<\/span> <span class=\"o\">*<\/span> <span class=\"n\">pos<\/span>\n        <span class=\"k\">for<\/span> <span class=\"n\">pos<\/span><span class=\"p\">,<\/span> <span class=\"n\">letter<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">enumerate<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">,<\/span> <span class=\"n\">start<\/span><span class=\"o\">=<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Multiplying a string (<code>letter<\/code>) by an integer (<code>pos<\/code>) will repeat the string the specified number of times.<\/p>\n\n<p>The <a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#enumerate\" rel=\"noopener noreferrer\">enumerate<\/a> function in Python returns the index and the value from a iterator (in this case characters in a string). A little-used feature of this function is the <code>start<\/code> parameter which will start counting at a value other than the default of zero.<\/p>\n\n<p>The Perl solution is a little more verbose, as I build the string a letter at a time. By using <code>++$cnt<\/code>, the value is incremented before it is evaluated (as opposed to <code>$cnt++<\/code>). The <code>x<\/code> operator will repeat the string the required number of times.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($input_string) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$output_string<\/span> <span class=\"o\">=<\/span> <span class=\"p\">'';<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$cnt<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">foreach<\/span> <span class=\"k\">my<\/span> <span class=\"nv\">$letter<\/span> <span class=\"p\">(<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$input_string<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">$output_string<\/span> <span class=\"o\">.=<\/span> <span class=\"nv\">$letter<\/span> <span class=\"nv\">x<\/span> <span class=\"o\">++<\/span><span class=\"nv\">$cnt<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$output_string<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py abca\nabbcccaaaa\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py xyz\nxyyzzz\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py code\ncoodddeeee\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py hello\nheelllllllooooo\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py a\na\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Spellbound Sorting\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given an array of integers.<\/p>\n\n<p>Write a script to return them in alphabetical order, in any language of your choosing. Default language is English.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>Thankfully the perfectly round wheels have already been invented for converting integers into strings. To make this task a little easier on myself, I'm only using English.<\/p>\n\n<p>Python has the <a href=\"https:\/\/pypi.org\/project\/num2words\/\" rel=\"noopener noreferrer\">num2words<\/a> module. The <a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#sorted\" rel=\"noopener noreferrer\">sorted<\/a> function has the key parameter to determine how the integers should be sorted.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">from<\/span> <span class=\"n\">num2words<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">num2words<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">spellbound_sorting<\/span><span class=\"p\">(<\/span><span class=\"n\">ints<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">int<\/span><span class=\"p\">])<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">int<\/span><span class=\"p\">]:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">sorted<\/span><span class=\"p\">(<\/span><span class=\"n\">ints<\/span><span class=\"p\">,<\/span> <span class=\"n\">key<\/span><span class=\"o\">=<\/span><span class=\"n\">num2words<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Perl has the <a href=\"https:\/\/metacpan.org\/pod\/Lingua::EN::Numbers\" rel=\"noopener noreferrer\">Lingua::EN::Numbers<\/a> module. The <a href=\"https:\/\/perldoc.perl.org\/functions\/sort\" rel=\"noopener noreferrer\">sort<\/a> function in Perl also has built in features to determine the sort order.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">use<\/span> <span class=\"nn\">Lingua::EN::<\/span><span class=\"nv\">Numbers<\/span> <span class=\"p\">'<\/span><span class=\"s1\">num2en<\/span><span class=\"p\">';<\/span>\n\n<span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">(@ints) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">@sorted_ints<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">sort<\/span> <span class=\"p\">{<\/span> <span class=\"nv\">num2en<\/span><span class=\"p\">(<\/span><span class=\"nv\">$a<\/span><span class=\"p\">)<\/span> <span class=\"ow\">cmp<\/span> <span class=\"nv\">num2en<\/span><span class=\"p\">(<\/span><span class=\"nv\">$b<\/span><span class=\"p\">)<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@ints<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nb\">join<\/span><span class=\"p\">(<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">, <\/span><span class=\"p\">\",<\/span> <span class=\"nv\">@sorted_ints<\/span> <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py 6 7 8 9 10\n<span class=\"o\">[<\/span>8, 9, 7, 6, 10]\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"nt\">-3<\/span> 0 1000 99\n<span class=\"o\">[<\/span><span class=\"nt\">-3<\/span>, 99, 1000, 0]\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 1 2 3 4 5\n<span class=\"o\">[<\/span>5, 4, 1, 3, 2]\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 0 <span class=\"nt\">-1<\/span> <span class=\"nt\">-2<\/span> <span class=\"nt\">-3<\/span> <span class=\"nt\">-4<\/span>\n<span class=\"o\">[<\/span><span class=\"nt\">-4<\/span>, <span class=\"nt\">-1<\/span>, <span class=\"nt\">-3<\/span>, <span class=\"nt\">-2<\/span>, 0]\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 100 101 102\n<span class=\"o\">[<\/span>100, 101, 102]\n\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["perl","python","theweeklychallenge"]},{"title":"Weekly Challenge: Representing a celebrity","pubDate":"Mon, 16 Feb 2026 06:58:38 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-representing-a-celebrity-1cfe","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-representing-a-celebrity-1cfe","description":"<h2>\n  \n  \n  Weekly Challenge 361\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, GitHub Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-361\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-361\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Zeckendorf Representation\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a positive integer (&lt;= 100).<\/p>\n\n<p>Write a script to return Zeckendorf Representation of the given integer. Every positive integer can be uniquely represented as sum of non-consecutive Fibonacci numbers.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>My original solution was to use a recursive function to calculate the  numbers. This attempt is recorded in <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/blob\/master\/challenge-361\/sgreen\/python\/ch-1-recursive.py\" rel=\"noopener noreferrer\">ch-1-recursive.py<\/a>. However, I realized when looking at larger numbers, this was not required. There is a reason this is the first task and not the second :)<\/p>\n\n<p>My solution starts with a function called <code>generate_fibonacci<\/code> which generates a list of Fibonacci numbers that are less than or equal to the target number. This is stored in a list called <code>seq<\/code>.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">generate_fibonacci<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">int<\/span><span class=\"p\">]:<\/span>\n    <span class=\"n\">seq<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n    <span class=\"k\">while<\/span> <span class=\"n\">seq<\/span><span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"n\">number<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">seq<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">(<\/span><span class=\"n\">seq<\/span><span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">2<\/span><span class=\"p\">]<\/span> <span class=\"o\">+<\/span> <span class=\"n\">seq<\/span><span class=\"p\">[<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">])<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">seq<\/span><span class=\"p\">[:<\/span><span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>I create an a variable called <code>remaining<\/code> which is set to the input number, and an empty list called <code>result<\/code> which has the numbers that make up the solution.<\/p>\n\n<p>Next I have a loop that runs until a solution is found, or it the <code>seq<\/code> list is empty (which should never happen). For each iteration, I take the last value from the list and assign it to a variable called <code>value<\/code>. If this is larger than <code>remaining<\/code>, the loop starts again with no further action.<\/p>\n\n<p>I subtract <code>value<\/code> from <code>remaining<\/code>, and append <code>value<\/code> to the <code>result<\/code> list. If <code>remaining<\/code> is zero, the solution is found, and is returned. If the is still a remainder, I remove another value from the <code>seq<\/code> list (as we cannot use consecutive numbers), and the loop starts again.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">zeckendorf_representation<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">int<\/span><span class=\"p\">]<\/span> <span class=\"o\">|<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"n\">number<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">1<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">The number must be a positive integer<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">seq<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">generate_fibonacci<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">remaining<\/span> <span class=\"o\">=<\/span> <span class=\"n\">number<\/span>\n    <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\n\n    <span class=\"k\">while<\/span> <span class=\"n\">seq<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">value<\/span> <span class=\"o\">=<\/span> <span class=\"n\">seq<\/span><span class=\"p\">.<\/span><span class=\"nf\">pop<\/span><span class=\"p\">()<\/span>\n\n        <span class=\"k\">if<\/span> <span class=\"n\">value<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"n\">remaining<\/span><span class=\"p\">:<\/span>\n            <span class=\"n\">remaining<\/span> <span class=\"o\">-=<\/span> <span class=\"n\">value<\/span>\n            <span class=\"n\">result<\/span><span class=\"p\">.<\/span><span class=\"nf\">append<\/span><span class=\"p\">(<\/span><span class=\"n\">value<\/span><span class=\"p\">)<\/span>\n\n            <span class=\"k\">if<\/span> <span class=\"n\">remaining<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">return<\/span> <span class=\"n\">result<\/span>\n\n            <span class=\"n\">seq<\/span><span class=\"p\">.<\/span><span class=\"nf\">pop<\/span><span class=\"p\">()<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"bp\">None<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py 4\n<span class=\"o\">[<\/span>3, 1]\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 12\n<span class=\"o\">[<\/span>8, 3, 1]\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 20\n<span class=\"o\">[<\/span>13, 5, 2]\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 96\n<span class=\"o\">[<\/span>89, 5, 2]\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 100\n<span class=\"o\">[<\/span>89, 8, 3]\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Bonus\n<\/h3>\n\n<p>I'm not sure why there is a restriction on numbers less than 100. Even calculating the Zeckendorf Representation of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Googol\" rel=\"noopener noreferrer\">Googol<\/a> (10<sup>100<\/sup>) takes less than 0.2 seconds.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span><span class=\"nb\">time<\/span> .\/ch-1.py 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\n<span class=\"o\">[<\/span>9216845717656874712980450562726202415567360565980794777111390850331644813674856981646960226192287360, 513637207677450246125760857023446893186481668075116373246321641937144993869266524849692790595738232, 196191955446197556957565929345772792668594307949581132632670453793550007197467505024573547039776939, 46314638123912707463692067318029823029991796402327083329291014906539951751195524576517845992591769, 17690617586682990180447203622188161240682337031027142006892310369574875779255058929007841461590953, 6757214636136263077649543548534660692055214690754342691385916202184675586569652210505678392181090, 1595161992684664972646689501703019021088600608282570556855039728226373625661856805487290962276456, 609297663643530892791951979990217206693894175329255046444641219473596270869815908465388209600595, 232730998245927705729166438267632598993081917705194582478883930194415186947590919908873666525329, 88895331094252224395547334812680590285351577786328700992010571109649289972956851261232789975392, 33954995036828967457475566170409171862972815653791520497147783134532682971279633874824703400847, 1892247019390521442608211077147886839616506438992322504018876947992022613217501281456451614651, 446698926797525733283994464723773897373051547730509482206718754667074636645528022516256487945, 170623807298553611905880623235491323624375649830112453507358412671675285005069415562415412537, 65172495098135102433647404982700073500075401759827878315356483347951218369680224170989749666, 24893677995851695395061591712608896875850555449371181438711037372178370103971256950553836461, 5876600217011727891986851402355662620898026272799849437157779835010586219504163589210317027, 2244661544603472032436332649584708114319787957314032873538930901437280496774780497748874337, 125090700579089545268174422433569433531336921195894847055310250098200676237081739043824861, 6971065820139782390806954219541689244276624212074373456653600330331675492690805039973161, 2662710205480735617346452022100755074809023407208374441801919604845563638678145849451440, 91708675472160090711036102616287632089318911882123915231537729562617689923506638302133, 35029596967131343602213497450232647402139968983372205851566400021802909132390757909314, 745648276861993189984204820755333242001144560869101973859680384188513887852280667477, 9809463517264670023038788649658295091956272699959366635620342487725314342549664567, 3746881652193013001948452031301618270087167924331813432662649918207032018665867029, 1431181439314368982806567444246559718305231073036073662367607266895781713447936520, 546662665750093946471250301438060884828525294776407554440171882480313121677942531, 129049549878268233256883381302815012467835672190109552534355121389997818506160385, 49292541820623609906583302538007088755326533087070104115801862234837985426429697, 7191684930184179482016276395611672639105248126232175323349533708710427892956421, 2746979206949941983182302875628764119171817307595766156998135811615145905740557, 648473825618649048121038413079524682351409714485519861708388359345126257210057, 58472848379039952684853851736901133239741266891456844557261755914039063645794, 22334640661774067356412331900038009953045351020683823507202893507476314037053, 1244666864935793005828156005589143096022236302705537193166716344690085611761, 475420437734698220747368027166749382927701417016557193662268716376935476241, 181594448268301656413948075911105052760867948344134387820089804440720816962, 16374361185569570355515148989381228747223756609038926650176124155306760699, 6254449428820551641549772190170184190608177514674331726439961915653414425, 1476475227036382503281437027911536541406625644706194668152438732346449273, 133133688169362819419341682354326791750874517270785300499298099495818696, 50852543833066829834000968538942350270948615962802847667687312219838755, 19423943329837670082661223262500259061971330617623242503763837163697569, 7419286156446180413982701248558426914965375890066879843604199271253952, 1751455877444438095408940282208383549115781784912085789506677971125378, 157928677948851033162880158208040021697730983590298819190379481318411, 60323387178125067141700354899227346590944200352359771993651057202793, 23041483585524168262220906489642018075101617466780496790573690289968, 8801063578447437644962364569698707634360652047981718378070013667111, 3361707149818144672666187219454104827980338677164658343636350711365, 1284057871006996373036197088663606849580363983512256652839038466984, 490466463202844446442404046536715720760753273372111614880764689587, 44225333398004061429732838340729878012027363723832270745251370289, 16892574194241670428824570378554538679120491007541580961500624834, 6452389184720949856740872794933738025334109298792472139250504213, 137347080577163115432025771710279131845700275212767467264610201, 32423247527351544763402471792982538876233052554697128188128597, 12384578529797304192493293627316781267732493780359086838016392, 690168906931029935139391829792095612517948949963798093315456, 38461794961234640015759308940939757590587318989278841661816, 14691098406862188148944207245954912110548093601382197697835, 5611500259351924431073312796924978741056961814867751431689, 2143402371193585144275731144820024112622791843221056597232, 119447720249892581203851665820676436622934188700177088360, 45624969256769882625644229676772632057353264935332782291, 6656593304481317393598839952151746590023553382130993248, 370959230771131880927453318055001997489772178180790104, 87571595343018854458033386304178158174356588264390370, 33449372971981195681356806732944396691005381570580873, 712011255569818855923257924200496343807632829750245, 271964099255182923543922814194423915162591622175362, 24522987531716273545293036474970821924473060471519, 3577855662560905981638959513147239988861837901112, 199387062373213542599493807777207997205533596336, 76159080909572301618801306271765994056795952743, 6867260041627791953052057353082063289320596021, 619220451666590135228675387863297874269396512, 236521166007575960984144537828161815236311727, 90343046356137747723758225621187571439538669, 21327100234463183349497947550385773274930109, 5034645418285014325766435419644478339818233, 173402521172797813159685037284371942044301, 25299086886458645685589389182743678652930, 9663391306290450775010025392525829059713, 1409869790947669143312035591975596518914, 538522340430300790495419781092981030533, 205697230343233228174223751303346572685, 18547707689471986212190138521399707760, 7084593923980518516849609894969925639, 244006547798191185585064349218729154, 93202207781383214849429075266681969, 35600075545958458963222876581316753, 13598018856492162040239554477268290, 5193981023518027157495786850488117, 1983924214061919432247806074196061, 757791618667731139247631372100066, 178890334785183168257455287891792, 16130531424904581415797907386349, 3807901929474025356630904134051, 555565404224292694404015791808, 131151201344081895336534324866, 659034621587630041982498215, 251728825683549488150424261, 96151855463018422468774568, 14028366653498915298923761, 3311648143516982017180081, 781774079430987230203437, 298611126818977066918552, 70492524767089125814114, 16641027750620563662096, 2427893228399975082453, 573147844013817084101, 12200160415121876738, 1100087778366101931, 259695496911122585, 99194853094755497, 37889062373143906, 14472334024676221, 3416454622906707, 806515533049393, 308061521170129, 117669030460994, 2504730781961, 365435296162, 139583862445, 4807526976, 701408733, 165580141, 63245986, 14930352, 121393, 4181, 987, 233, 55, 3]\n\nreal    0m0.017s\nuser    0m0.011s\nsys 0m0.006s\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Celebrity list\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a binary matrix (<code>m \u00d7 n<\/code>).<\/p>\n\n<p>Write a script to find the celebrity, return -1 when none found. A celebrity is someone, everyone knows and knows nobody.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>For input from the command line, I take a JSON string, and convert it to a list of lists of integers (arrays in Perl). The first thing I do is check that the matrix is valid (each row is the same length). Even though the task suggests that <code>m<\/code> and <code>n<\/code> could be different values, it makes no sense if it is not square, so I check this as well.<\/p>\n\n<p>I then have a loop with the index called <code>row_idx<\/code> and <code>row<\/code> as the row from the matrix. If this row has any <code>1<\/code> (meaning they know someone), I skip to the next row.<\/p>\n\n<p>I then check that all other people know this person (column <code>row_idx<\/code> is <code>1<\/code>) or is the person themselves (<code>row_idx == col_idx<\/code>). If they are, I return the current <code>row_idx<\/code> value.<\/p>\n\n<p>If the list is exhausted, I return <code>-1<\/code>.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">find_celebrity<\/span><span class=\"p\">(<\/span><span class=\"n\">matrix<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">int<\/span><span class=\"p\">]])<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">row_length<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">matrix<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">])<\/span>\n    <span class=\"k\">for<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">matrix<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">)<\/span> <span class=\"o\">!=<\/span> <span class=\"n\">row_length<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">All rows must have the same length<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">for<\/span> <span class=\"n\">row_idx<\/span><span class=\"p\">,<\/span> <span class=\"n\">row<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">enumerate<\/span><span class=\"p\">(<\/span><span class=\"n\">matrix<\/span><span class=\"p\">):<\/span>\n        <span class=\"k\">if<\/span> <span class=\"nf\">sum<\/span><span class=\"p\">(<\/span><span class=\"n\">row<\/span><span class=\"p\">):<\/span>\n            <span class=\"k\">continue<\/span>\n\n        <span class=\"n\">is_celebrity<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">all<\/span><span class=\"p\">(<\/span>\n            <span class=\"n\">col_idx<\/span> <span class=\"o\">==<\/span> <span class=\"n\">row_idx<\/span> <span class=\"ow\">or<\/span> <span class=\"n\">matrix<\/span><span class=\"p\">[<\/span><span class=\"n\">col_idx<\/span><span class=\"p\">][<\/span><span class=\"n\">row_idx<\/span><span class=\"p\">]<\/span>\n            <span class=\"k\">for<\/span> <span class=\"n\">col_idx<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">range<\/span><span class=\"p\">(<\/span><span class=\"n\">row_length<\/span><span class=\"p\">)<\/span>\n        <span class=\"p\">)<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">is_celebrity<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"n\">row_idx<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"[[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 0]]\"<\/span>\n<span class=\"nt\">-1<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"[[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]\"<\/span>\n0\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"[[0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 0], [1, 0, 1, 1, 0, 0]]\"<\/span>\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"[[0, 1, 1, 0], [1, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0]]\"<\/span>\n<span class=\"nt\">-1<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"[[0, 0, 1, 1], [1, 0, 0, 0], [1, 1, 0, 1], [1, 1, 0, 0]]\"<\/span>\n<span class=\"nt\">-1<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"[[0, 1, 0, 1, 0, 1], [1, 0, 1, 1, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 0], [1, 0, 1, 1, 0, 0]]\"<\/span>\n3\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","theweeklychallenge"]},{"title":"Weekly Challenge: Padding and sorting","pubDate":"Mon, 09 Feb 2026 06:53:44 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-padding-and-sorting-3oj8","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-padding-and-sorting-3oj8","description":"<h2>\n  \n  \n  Weekly Challenge 360\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-360\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-360\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Text Justifier\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string and a width.<\/p>\n\n<p>Write a script to return the string that centers the text within that width using asterisks <code>*<\/code> as padding.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>If the <code>input_string<\/code> length is larger or equal to the <code>width<\/code> variable, I simply return the original string, as no padding is required.<\/p>\n\n<p>I then create a variable called <code>asterisks<\/code> which is half the difference in length. Finally, I use the <code>floor<\/code> and <code>ceil<\/code> function to add the required number of asterisks. Doing this way ensure that if there is an odd number of asterisks required, the right side will have the additional asterisk.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"kn\">from<\/span> <span class=\"n\">math<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ceil<\/span><span class=\"p\">,<\/span> <span class=\"n\">floor<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">text_justifier<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">width<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">string_len<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">if<\/span> <span class=\"n\">string_len<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"n\">width<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">input_string<\/span>\n\n    <span class=\"n\">asterisks<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"n\">width<\/span><span class=\"o\">-<\/span><span class=\"n\">string_len<\/span><span class=\"p\">)<\/span> <span class=\"o\">\/<\/span> <span class=\"mi\">2<\/span>\n    <span class=\"n\">output_string<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">*<\/span><span class=\"sh\">\"<\/span> <span class=\"o\">*<\/span> <span class=\"nf\">floor<\/span><span class=\"p\">(<\/span><span class=\"n\">asterisks<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"n\">input_string<\/span> <span class=\"o\">+<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">*<\/span><span class=\"sh\">\"<\/span> <span class=\"o\">*<\/span> <span class=\"nf\">ceil<\/span><span class=\"p\">(<\/span><span class=\"n\">asterisks<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">output_string<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution follows the same logic. The <code>floor<\/code> and <code>ceil<\/code> functions come from the <a href=\"https:\/\/perldoc.perl.org\/POSIX\" rel=\"noopener noreferrer\">POSIX<\/a> module.<\/p>\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py Hi 5\n<span class=\"k\">*<\/span>Hi<span class=\"k\">**<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py Code 10\n<span class=\"k\">***<\/span>Code<span class=\"k\">***<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py Hello 9\n<span class=\"k\">**<\/span>Hello<span class=\"k\">**<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py Perl 4\nPerl\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py A 7\n<span class=\"k\">***<\/span>A<span class=\"k\">***<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"\"<\/span> 5\n<span class=\"k\">*****<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Word Sorter\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are give a sentence. Write a script to order words in the given sentence alphabetically but keeps the words themselves unchanged.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This can be achieved as a one-liner in both Python and Perl.<\/p>\n\n<p>The Python solution is<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">word_sorter<\/span><span class=\"p\">(<\/span><span class=\"n\">sentence<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\"> <\/span><span class=\"sh\">\"<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"nf\">sorted<\/span><span class=\"p\">(<\/span><span class=\"n\">sentence<\/span><span class=\"p\">.<\/span><span class=\"nf\">split<\/span><span class=\"p\">(),<\/span> <span class=\"n\">key<\/span><span class=\"o\">=<\/span><span class=\"k\">lambda<\/span> <span class=\"n\">x<\/span><span class=\"p\">:<\/span> <span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"nf\">lower<\/span><span class=\"p\">()))<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Breaking this down:<\/p>\n\n<ul>\n<li>\n<code>sentence.split()<\/code> will split the original sentence into a list of strings. The separator is one or more white space characters.<\/li>\n<li>\n<code>sorted(..., key=lambda x: x.lower())<\/code> will sort the list alphabetically in a case insensitive manner.<\/li>\n<li>\n<code>join(\" \", ...)<\/code> will turn the list into a string, separated by a single space.<\/li>\n<\/ul>\n\n<p>The Perl solution uses the same logic, but a slightly different syntax.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($str) {<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nb\">join<\/span><span class=\"p\">(<\/span> <span class=\"p\">\"<\/span><span class=\"s2\"> <\/span><span class=\"p\">\",<\/span> <span class=\"nb\">sort<\/span> <span class=\"p\">{<\/span> <span class=\"nb\">lc<\/span><span class=\"p\">(<\/span><span class=\"nv\">$a<\/span><span class=\"p\">)<\/span> <span class=\"ow\">cmp<\/span> <span class=\"nb\">lc<\/span><span class=\"p\">(<\/span><span class=\"nv\">$b<\/span><span class=\"p\">)<\/span> <span class=\"p\">}<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\\s+\/<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$str<\/span> <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"The quick brown fox\"<\/span>\nbrown fox quick The\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"Hello    World!   How   are you?\"<\/span>\nare Hello How World! you?\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"Hello\"<\/span>\nHello\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"Hello, World! How are you?\"<\/span>\nare Hello, How World! you?\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py <span class=\"s2\">\"I have 2 apples and 3 bananas!\"<\/span>\n2 3 and apples bananas! have I\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","theweeklychallenge"]},{"title":"Weekly Challenge: Digital reduction","pubDate":"Mon, 02 Feb 2026 07:10:55 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-digital-reduction-1aci","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-digital-reduction-1aci","description":"<h2>\n  \n  \n  Weekly Challenge 359\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-359\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-359\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Digital Root\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a positive integer, $int.<\/p>\n\n<p>Write a function that calculates the additive persistence of a positive integer and also return the digital root.<\/p>\n\n<ul>\n<li>Digital root is the recursive sum of all digits in a number until a single digit is obtained.<\/li>\n<li>Additive persistence is the number of times you need to sum the digits to reach a single digit.<\/li>\n<\/ul>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>Starting this week, I'm going to turn off VS Code Copilot when completing the challenge. As AI takes over the task of code completion, it's still a good exercise to do things by hand so as I don't depend on it.<\/p>\n\n<p>For this tasks, I create two variables. The first is called <code>persistence<\/code> and starts at <code>0<\/code>. The second variable is called <code>digital_root<\/code> and starts with the supplied integer. This is called <code>number<\/code> in Python, as <code>int<\/code> is a reserved word.<\/p>\n\n<p>I then have a loop that continues until <code>digital_root<\/code> is a single digit. Breaking down the line:<\/p>\n\n<ul>\n<li>\n<code>str(digital_root)<\/code> will convert the <code>digital_root<\/code> integer to a string<\/li>\n<li>\n<code>d for d in<\/code> will convert each character to a single digit<\/li>\n<li>\n<code>map(int(...<\/code> will convert the digit back to an integer<\/li>\n<li>\n<code>sum(...<\/code> will add the single digit<\/li>\n<\/ul>\n\n<p>I also increment the <code>persistence<\/code> value by one. I end by returning the two values. The <code>main<\/code> function is responsible for displaying the text as per the examples.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">get_digital_root<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">tuple<\/span><span class=\"p\">[<\/span><span class=\"nb\">int<\/span><span class=\"p\">,<\/span> <span class=\"nb\">int<\/span><span class=\"p\">]:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"n\">number<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">raise<\/span> <span class=\"nc\">ValueError<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">You must provide a positive integer<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\n\n    <span class=\"n\">persistence<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"n\">digital_root<\/span> <span class=\"o\">=<\/span> <span class=\"n\">number<\/span>\n\n    <span class=\"k\">while<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">digital_root<\/span><span class=\"p\">))<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">1<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">digital_root<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sum<\/span><span class=\"p\">(<\/span><span class=\"nf\">map<\/span><span class=\"p\">(<\/span><span class=\"nb\">int<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"n\">d<\/span> <span class=\"k\">for<\/span> <span class=\"n\">d<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">digital_root<\/span><span class=\"p\">))))<\/span>\n        <span class=\"n\">persistence<\/span> <span class=\"o\">+=<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">persistence<\/span><span class=\"p\">,<\/span> <span class=\"n\">digital_root<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution follows the same logic. Perl doesn't make a distinction between string and integers (yes, there are some exceptions to this rule), but does require the <a href=\"https:\/\/perldoc.perl.org\/functions\/split\" rel=\"noopener noreferrer\">split<\/a> function to break the <code>digital_root<\/code> value into individual digits.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">use<\/span> <span class=\"nn\">List::<\/span><span class=\"nv\">Util<\/span> <span class=\"p\">'<\/span><span class=\"s1\">sum<\/span><span class=\"p\">';<\/span>\n\n<span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($int) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$persistence<\/span>  <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">$digital_root<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$int<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"c1\"># Keep iterating until we have a single digital<\/span>\n    <span class=\"k\">while<\/span> <span class=\"p\">(<\/span> <span class=\"nb\">length<\/span><span class=\"p\">(<\/span><span class=\"nv\">$digital_root<\/span><span class=\"p\">)<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">1<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">$digital_root<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">sum<\/span><span class=\"p\">(<\/span> <span class=\"nb\">split<\/span><span class=\"p\">(<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$digital_root<\/span> <span class=\"p\">)<\/span> <span class=\"p\">);<\/span>\n        <span class=\"nv\">$persistence<\/span><span class=\"o\">++<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"nv\">say<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">Persistence  = <\/span><span class=\"si\">$persistence<\/span><span class=\"p\">\";<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">Digital Root = <\/span><span class=\"si\">$digital_root<\/span><span class=\"p\">\";<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py 38\nPersistence  <span class=\"o\">=<\/span> 2\nDigital Root <span class=\"o\">=<\/span> 2\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 7\nPersistence  <span class=\"o\">=<\/span> 0\nDigital Root <span class=\"o\">=<\/span> 7\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 999\nPersistence  <span class=\"o\">=<\/span> 2\nDigital Root <span class=\"o\">=<\/span> 9\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1999999999\nPersistence  <span class=\"o\">=<\/span> 3\nDigital Root <span class=\"o\">=<\/span> 1\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 101010\nPersistence  <span class=\"o\">=<\/span> 1\nDigital Root <span class=\"o\">=<\/span> 3\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: String Reduction\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a word containing only alphabets.<\/p>\n\n<p>Write a function that repeatedly removes adjacent duplicate characters from a string until no adjacent duplicates remain and return the final word.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This is a duplicate (albeit slightly re-worded) of the first task in <a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-340\/\" rel=\"noopener noreferrer\">week 340<\/a>. Therefore I copy and pasted that code, and renamed the function. See my <a href=\"https:\/\/dev.to\/simongreennet\/weekly-challenge-ascending-regex-to-remove-the-duplicates-2bd#task-1-duplicate-removals\">original blog post<\/a> on how this was solved.<\/p>\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py aabbccdd\n<span class=\"s2\">\"\"<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py abccba\n<span class=\"s2\">\"\"<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py abcdef\n<span class=\"s2\">\"abcdef\"<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py aabbaeaccdd\n<span class=\"s2\">\"aea\"<\/span>\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py mississippi\n<span class=\"s2\">\"m\"<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","perl","theweeklychallenge"]},{"title":"Weekly Challenge: Maximum Encryption","pubDate":"Tue, 27 Jan 2026 06:49:48 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-maximum-encryption-49a8","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-maximum-encryption-49a8","description":"<h2>\n  \n  \n  Weekly Challenge 358\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-358\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-358\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Max Str Value\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given an array of alphanumeric string, <code>@strings<\/code>.<\/p>\n\n<p>Write a script to find the max value of alphanumeric string in the given array. The numeric representation of the string, if it comprises of digits only otherwise length of the string.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This task can be achieved in a single line in both Python and Perl, while still maintaining readability. For the Python solution I use list comprehension to convert each string into an integer (if it is all digits) or the length of string (if it isn't). This is wrapped around the <a href=\"https:\/\/docs.python.org\/3\/library\/functions.html#max\" rel=\"noopener noreferrer\">max<\/a> function to return maximum (largest) of these values.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">max_string_value<\/span><span class=\"p\">(<\/span><span class=\"n\">input_strings<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"nf\">max<\/span><span class=\"p\">(<\/span><span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">s<\/span><span class=\"p\">)<\/span> <span class=\"k\">if<\/span> <span class=\"n\">s<\/span><span class=\"p\">.<\/span><span class=\"nf\">isdigit<\/span><span class=\"p\">()<\/span> <span class=\"k\">else<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">s<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">s<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">input_strings<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Not to out-shinned, Perl can achieve similar functionality by using the <a href=\"https:\/\/perldoc.perl.org\/functions\/map\" rel=\"noopener noreferrer\">map<\/a> function, converting each string into its numeric representation or its length. Perl doesn't have a built-in <code>max<\/code> function, but it is available from the <a href=\"https:\/\/metacpan.org\/pod\/List::Util\" rel=\"noopener noreferrer\">List::Util<\/a> package.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">(@input_strings) {<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nv\">max<\/span><span class=\"p\">(<\/span> <span class=\"nb\">map<\/span> <span class=\"p\">{<\/span> <span class=\"sr\">\/^\\d+$\/<\/span> <span class=\"p\">?<\/span> <span class=\"vg\">$_<\/span> <span class=\"p\">:<\/span> <span class=\"nb\">length<\/span><span class=\"p\">(<\/span><span class=\"vg\">$_<\/span><span class=\"p\">)<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@input_strings<\/span> <span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"123\"<\/span> <span class=\"s2\">\"45\"<\/span> <span class=\"s2\">\"6\"<\/span>\n123\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"abc\"<\/span> <span class=\"s2\">\"de\"<\/span> <span class=\"s2\">\"fghi\"<\/span>\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"0012\"<\/span> <span class=\"s2\">\"99\"<\/span> <span class=\"s2\">\"a1b2c\"<\/span>\n99\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"x\"<\/span> <span class=\"s2\">\"10\"<\/span> <span class=\"s2\">\"xyz\"<\/span> <span class=\"s2\">\"007\"<\/span>\n10\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py <span class=\"s2\">\"hello123\"<\/span> <span class=\"s2\">\"2026\"<\/span> <span class=\"s2\">\"perl\"<\/span>\n2026\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Encrypted String\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a string <code>$str<\/code> and an integer $int.<\/p>\n\n<p>Write a script to encrypt the string using the algorithm - for each character <code>$char<\/code> in <code>$str<\/code>, replace <code>$char<\/code> with the <code>$int th<\/code> character after <code>$char<\/code> in the alphabet, wrapping if needed and return the encrypted string.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>For this task, I start by setting <code>$int<\/code> (called <code>i<\/code> in Python as <code>int<\/code> is a reserved word) to be the modulus (remainder) of 26. If that value is <code>0<\/code>, I return the original string as no encryption is required.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">encrypted_string<\/span><span class=\"p\">(<\/span><span class=\"n\">input_string<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">i<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">i<\/span> <span class=\"o\">=<\/span> <span class=\"n\">i<\/span> <span class=\"o\">%<\/span> <span class=\"mi\">26<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"n\">i<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"n\">input_string<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The next step is creating a mapping table. I start with the variable <code>old_letters<\/code> that has all the lower case letters of the English alphabet. I create a <code>new_letters<\/code> string by slicing the <code>old_letters<\/code> string at the appropriate point. I then double the length of each string by adding the upper case equivalent string. Finally, I use <code>dict(zip())<\/code> to convert the strings to a dictionary where the key is the original letter and the value is the new letter.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"n\">old_letters<\/span> <span class=\"o\">=<\/span> <span class=\"n\">string<\/span><span class=\"p\">.<\/span><span class=\"n\">ascii_lowercase<\/span>\n    <span class=\"n\">new_letters<\/span> <span class=\"o\">=<\/span> <span class=\"n\">old_letters<\/span><span class=\"p\">[<\/span><span class=\"n\">i<\/span><span class=\"p\">:]<\/span> <span class=\"o\">+<\/span> <span class=\"n\">old_letters<\/span><span class=\"p\">[:<\/span><span class=\"n\">i<\/span><span class=\"p\">]<\/span>\n    <span class=\"n\">old_letters<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">old_letters<\/span><span class=\"p\">.<\/span><span class=\"nf\">upper<\/span><span class=\"p\">()<\/span>\n    <span class=\"n\">new_letters<\/span> <span class=\"o\">+=<\/span> <span class=\"n\">new_letters<\/span><span class=\"p\">.<\/span><span class=\"nf\">upper<\/span><span class=\"p\">()<\/span>\n    <span class=\"n\">mapping<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">dict<\/span><span class=\"p\">(<\/span><span class=\"nf\">zip<\/span><span class=\"p\">(<\/span><span class=\"n\">old_letters<\/span><span class=\"p\">,<\/span> <span class=\"n\">new_letters<\/span><span class=\"p\">))<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The final step is to loop through each character and use the <code>mapping<\/code> dictionary to replace the letter, or use the original character if it is not found (numbers, spaces, punctuation characters, etc).<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"k\">return<\/span> <span class=\"sh\">\"\"<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"n\">mapping<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">char<\/span><span class=\"p\">,<\/span> <span class=\"n\">char<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">char<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">input_string<\/span><span class=\"p\">)<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl code follows the same logic. It uses the splice method to create the <code>new_letters<\/code> variable, and both <code>old_letters<\/code> and <code>new_letters<\/code> are arrays. The <code>mesh<\/code> function also comes from the List::Util package. Perl will automatically convert a flat list to key\/value pairs in the <code>mapping<\/code> hash.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">( $input_string, $i ) {<\/span>\n    <span class=\"nv\">$i<\/span> <span class=\"o\">%=<\/span> <span class=\"mi\">26<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span> <span class=\"nv\">$i<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span> <span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">say<\/span> <span class=\"nv\">$input_string<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">@old_letters<\/span> <span class=\"o\">=<\/span> <span class=\"k\">my<\/span> <span class=\"nv\">@new_letters<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">a<\/span><span class=\"p\">\"<\/span> <span class=\"o\">..<\/span> <span class=\"p\">\"<\/span><span class=\"s2\">z<\/span><span class=\"p\">\"<\/span> <span class=\"p\">);<\/span>\n    <span class=\"nb\">push<\/span> <span class=\"nv\">@new_letters<\/span><span class=\"p\">,<\/span> <span class=\"nb\">splice<\/span><span class=\"p\">(<\/span> <span class=\"nv\">@new_letters<\/span><span class=\"p\">,<\/span> <span class=\"mi\">0<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$i<\/span> <span class=\"p\">);<\/span>\n\n    <span class=\"nb\">push<\/span> <span class=\"nv\">@old_letters<\/span><span class=\"p\">,<\/span> <span class=\"nb\">map<\/span> <span class=\"p\">{<\/span> <span class=\"nb\">uc<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@old_letters<\/span><span class=\"p\">;<\/span>\n    <span class=\"nb\">push<\/span> <span class=\"nv\">@new_letters<\/span><span class=\"p\">,<\/span> <span class=\"nb\">map<\/span> <span class=\"p\">{<\/span> <span class=\"nb\">uc<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@new_letters<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">%mapping<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">mesh<\/span> <span class=\"o\">\\<\/span><span class=\"nv\">@old_letters<\/span><span class=\"p\">,<\/span> <span class=\"o\">\\<\/span><span class=\"nv\">@new_letters<\/span><span class=\"p\">;<\/span>\n\n\n    <span class=\"nv\">say<\/span> <span class=\"nb\">join<\/span> <span class=\"p\">\"\",<\/span> <span class=\"nb\">map<\/span> <span class=\"p\">{<\/span> <span class=\"nv\">$mapping<\/span><span class=\"p\">{<\/span><span class=\"vg\">$_<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/\/<\/span> <span class=\"vg\">$_<\/span> <span class=\"p\">}<\/span> <span class=\"nb\">split<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$input_string<\/span><span class=\"p\">;<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py abc 1\nbcd\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py xyz 2\nzab\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py abc 27\nbcd\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py hello 5\nmjqqt\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py perl 26\nperl\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["perl","python","theweeklychallenge"]},{"title":"Weekly Challenge: Fractional Constant","pubDate":"Mon, 19 Jan 2026 06:54:24 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-fractional-constant-2mop","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-fractional-constant-2mop","description":"<h2>\n  \n  \n  Weekly Challenge 357\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-357\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-357\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Kaprekar Constant\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>Write a function that takes a 4-digit integer and returns how many iterations are required to reach <a href=\"https:\/\/en.wikipedia.org\/wiki\/6174\" rel=\"noopener noreferrer\">Kaprekar's constant<\/a> (6174).<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This is where GitHub Copilot really scars me somewhat. Without mentioning \"kaprekar\" at all, and after typing <code>while number != 6174:<\/code> it auto-completed the rest of the code.<\/p>\n\n<p>For this solution, I start by checking that the number is between 1 and 9999, and that it is not divisible by 1111. If any of these are false, I return <code>-1<\/code>.<\/p>\n\n<p>I create a variable called <code>count<\/code>, starting at <code>0<\/code>. If <code>number<\/code> is not 6174, I take the following steps<\/p>\n\n<ol>\n<li>Set <code>digits<\/code> to be the individual digits, left padded with zeros if needed.<\/li>\n<li>Set <code>asc_digits<\/code> to the above <code>digits<\/code> list, sorted numerically (lowest first). Set <code>desc_digits<\/code> to the same, but in reversed sorted order.<\/li>\n<li>Set <code>small_num<\/code> to the integer that concatenates <code>asc_digits<\/code>.<\/li>\n<li>Set <code>large_num<\/code> to the integer that concatenates <code>desc_digits<\/code>.<\/li>\n<li>Set number to be <code>large_num<\/code> minus <code>small_num<\/code>.<\/li>\n<li>If this is not 6174, repeat the loop again.\n<\/li>\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">kaprekar_constant<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"mi\">0<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">number<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">10000<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"n\">number<\/span> <span class=\"o\">%<\/span> <span class=\"mi\">1111<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span>\n\n    <span class=\"n\">count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span>\n    <span class=\"k\">while<\/span> <span class=\"n\">number<\/span> <span class=\"o\">!=<\/span> <span class=\"mi\">6174<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">digits<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">d<\/span><span class=\"p\">)<\/span> <span class=\"k\">for<\/span> <span class=\"n\">d<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">str<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">).<\/span><span class=\"nf\">zfill<\/span><span class=\"p\">(<\/span><span class=\"mi\">4<\/span><span class=\"p\">)]<\/span>\n        <span class=\"n\">asc_digits<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sorted<\/span><span class=\"p\">(<\/span><span class=\"n\">digits<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">desc_digits<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sorted<\/span><span class=\"p\">(<\/span><span class=\"n\">digits<\/span><span class=\"p\">,<\/span> <span class=\"n\">reverse<\/span><span class=\"o\">=<\/span><span class=\"bp\">True<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">small_num<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"sh\">''<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"nf\">map<\/span><span class=\"p\">(<\/span><span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">asc_digits<\/span><span class=\"p\">)))<\/span>\n        <span class=\"n\">large_num<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"sh\">''<\/span><span class=\"p\">.<\/span><span class=\"nf\">join<\/span><span class=\"p\">(<\/span><span class=\"nf\">map<\/span><span class=\"p\">(<\/span><span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">desc_digits<\/span><span class=\"p\">)))<\/span>\n        <span class=\"n\">number<\/span> <span class=\"o\">=<\/span> <span class=\"n\">large_num<\/span> <span class=\"o\">-<\/span> <span class=\"n\">small_num<\/span>\n        <span class=\"n\">count<\/span> <span class=\"o\">+=<\/span> <span class=\"mi\">1<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"n\">count<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution is a little shorter, as I don't need to worry about finicky things like converting integers to strings :P<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($int) {<\/span>\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$int<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">1<\/span> <span class=\"ow\">or<\/span> <span class=\"nv\">$int<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">9999<\/span> <span class=\"ow\">or<\/span> <span class=\"nv\">$int<\/span> <span class=\"o\">%<\/span> <span class=\"mi\">1111<\/span> <span class=\"o\">==<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nv\">say<\/span> <span class=\"o\">-<\/span><span class=\"mi\">1<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">$count<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">while<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$int<\/span> <span class=\"o\">!=<\/span> <span class=\"mi\">6174<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">my<\/span> <span class=\"nv\">$small_number<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">join<\/span><span class=\"p\">(\"\",<\/span> <span class=\"nb\">sort<\/span> <span class=\"p\">{<\/span> <span class=\"nv\">$a<\/span> <span class=\"o\">&lt;=&gt;<\/span> <span class=\"nv\">$b<\/span> <span class=\"p\">}<\/span> <span class=\"p\">(<\/span><span class=\"nb\">split<\/span> <span class=\"sr\">\/\/<\/span><span class=\"p\">,<\/span> <span class=\"nb\">sprintf<\/span><span class=\"p\">(\"<\/span><span class=\"s2\">%04d<\/span><span class=\"p\">\",<\/span> <span class=\"nv\">$int<\/span><span class=\"p\">)));<\/span>\n        <span class=\"k\">my<\/span> <span class=\"nv\">$big_number<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">reverse<\/span><span class=\"p\">(<\/span><span class=\"nv\">$small_number<\/span><span class=\"p\">);<\/span>\n        <span class=\"nv\">$int<\/span> <span class=\"o\">=<\/span> <span class=\"nv\">$big_number<\/span> <span class=\"o\">-<\/span> <span class=\"nv\">$small_number<\/span><span class=\"p\">;<\/span>\n        <span class=\"nv\">$count<\/span><span class=\"o\">++<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"nv\">say<\/span> <span class=\"nv\">$count<\/span><span class=\"p\">;<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py 3524\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 6174\n0\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 9998\n5\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1001\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 9000\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1111\n<span class=\"nt\">-1<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Unique Fraction Generator\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>Given a positive integer <code>n<\/code>, generate all unique fractions you can create using integers from 1 to <code>n<\/code> and follow the rules below:<\/p>\n\n<ul>\n<li>Use numbers <code>1<\/code> through <code>n<\/code> only (no zero)<\/li>\n<li>Create fractions like numerator\/denominator<\/li>\n<li>List them in ascending order (from smallest to largest)<\/li>\n<li>If two fractions have the same value (like <code>1\/2<\/code> and <code>2\/4<\/code>), only show the one with the smallest numerator<\/li>\n<\/ul>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>Python has the <a href=\"https:\/\/docs.python.org\/3\/library\/fractions.html#fractions.Fraction\" rel=\"noopener noreferrer\">fractions<\/a> module as standard, while Perl has a CPAN module called <a href=\"https:\/\/metacpan.org\/pod\/Number::Fraction\" rel=\"noopener noreferrer\">Numbers::Fraction<\/a>.<\/p>\n\n<p>Both exhibit the same behaviors:<\/p>\n\n<ul>\n<li>Takes the numerator (top part) and denominator (bottom part) as input variables<\/li>\n<li>Will automatically convert to have the lowest unique values. For example, <code>Fraction(2, 4)<\/code> automatically is <code>Fraction(1, 2)<\/code>.<\/li>\n<li>Annoyingly for this task, will print a whole number if the denominator is 1.<\/li>\n<li>Two fractions variables can be compared to be sorted correctly (by the number they represent). For example <code>\u00bc &lt; \u00bd<\/code>.<\/li>\n<\/ul>\n\n<p>With that in mind, this task involves having a double loop for <code>n<\/code> and <code>d<\/code> (both from <code>1<\/code> to <code>number<\/code>), removing the duplicates with the <code>set<\/code> function, and then sorting them numerically. Finally, I turn the <code>Fraction<\/code> object into strings, and return the list.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">unique_fraction_generator<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">list<\/span><span class=\"p\">[<\/span><span class=\"nb\">str<\/span><span class=\"p\">]:<\/span>\n    <span class=\"n\">fractions<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sorted<\/span><span class=\"p\">(<\/span><span class=\"nf\">set<\/span><span class=\"p\">(<\/span>\n        <span class=\"nc\">Fraction<\/span><span class=\"p\">(<\/span><span class=\"n\">n<\/span><span class=\"p\">,<\/span><span class=\"n\">d<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">for<\/span> <span class=\"n\">d<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">range<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">number<\/span> <span class=\"o\">+<\/span> <span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">for<\/span> <span class=\"n\">n<\/span> <span class=\"ow\">in<\/span> <span class=\"nf\">range<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">number<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n    <span class=\"p\">))<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"p\">[<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">frac<\/span><span class=\"p\">.<\/span><span class=\"n\">numerator<\/span><span class=\"si\">}<\/span><span class=\"s\">\/<\/span><span class=\"si\">{<\/span><span class=\"n\">frac<\/span><span class=\"p\">.<\/span><span class=\"n\">denominator<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">for<\/span> <span class=\"n\">frac<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">fractions<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution follows the same logic. It uses <code>grep<\/code> to check if a fraction is added previously, and pushes it to the <code>fractions<\/code> array if it is not.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">use<\/span> <span class=\"nn\">Number::<\/span><span class=\"nv\">Fraction<\/span><span class=\"p\">;<\/span>\n\n<span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($int) {<\/span>\n    <span class=\"k\">my<\/span> <span class=\"nv\">@fractions<\/span> <span class=\"o\">=<\/span> <span class=\"p\">();<\/span>\n    <span class=\"k\">foreach<\/span> <span class=\"k\">my<\/span> <span class=\"nv\">$n<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span> <span class=\"o\">..<\/span> <span class=\"nv\">$int<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">foreach<\/span> <span class=\"k\">my<\/span> <span class=\"nv\">$d<\/span> <span class=\"p\">(<\/span><span class=\"mi\">1<\/span> <span class=\"o\">..<\/span> <span class=\"nv\">$int<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n            <span class=\"k\">my<\/span> <span class=\"nv\">$fraction<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Number::<\/span><span class=\"nv\">Fraction<\/span><span class=\"o\">-&gt;<\/span><span class=\"k\">new<\/span><span class=\"p\">(<\/span><span class=\"nv\">$n<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$d<\/span><span class=\"p\">);<\/span>\n            <span class=\"nb\">push<\/span> <span class=\"nv\">@fractions<\/span><span class=\"p\">,<\/span> <span class=\"nv\">$fraction<\/span> <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"nb\">grep<\/span> <span class=\"p\">{<\/span> <span class=\"vg\">$_<\/span> <span class=\"o\">==<\/span> <span class=\"nv\">$fraction<\/span><span class=\"p\">}<\/span> <span class=\"nv\">@fractions<\/span><span class=\"p\">;<\/span>\n        <span class=\"p\">}<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">my<\/span> <span class=\"nv\">@sorted_fractions<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">sort<\/span> <span class=\"p\">{<\/span> <span class=\"nv\">$a<\/span> <span class=\"o\">&lt;=&gt;<\/span> <span class=\"nv\">$b<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@fractions<\/span><span class=\"p\">;<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nb\">join<\/span><span class=\"p\">(\"<\/span><span class=\"s2\">, <\/span><span class=\"p\">\",<\/span> <span class=\"nb\">map<\/span><span class=\"p\">({<\/span> <span class=\"p\">\"<\/span><span class=\"si\">$_<\/span><span class=\"s2\">-&gt;{num}\/<\/span><span class=\"si\">$_<\/span><span class=\"s2\">-&gt;{den}<\/span><span class=\"p\">\"<\/span> <span class=\"p\">}<\/span> <span class=\"nv\">@sorted_fractions<\/span><span class=\"p\">));<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py 3\n1\/3, 1\/2, 2\/3, 1\/1, 3\/2, 2\/1, 3\/1\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 4\n1\/4, 1\/3, 1\/2, 2\/3, 3\/4, 1\/1, 4\/3, 3\/2, 2\/1, 3\/1, 4\/1\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 1\n1\/1\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 6\n1\/6, 1\/5, 1\/4, 1\/3, 2\/5, 1\/2, 3\/5, 2\/3, 3\/4, 4\/5, 5\/6, 1\/1, 6\/5, 5\/4, 4\/3, 3\/2, 5\/3, 2\/1, 5\/2, 3\/1, 4\/1, 5\/1, 6\/1\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 5\n1\/5, 1\/4, 1\/3, 2\/5, 1\/2, 3\/5, 2\/3, 3\/4, 4\/5, 1\/1, 5\/4, 4\/3, 3\/2, 5\/3, 2\/1, 5\/2, 3\/1, 4\/1, 5\/1\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["perl","python","theweeklychallenge"]},{"title":"Weekly Challenge: Winning sequence","pubDate":"Tue, 13 Jan 2026 06:46:48 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-winning-sequence-3eic","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-winning-sequence-3eic","description":"<h2>\n  \n  \n  Weekly Challenge 356\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-356\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-356\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Kolakoski Sequence\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given an integer, <code>$int<\/code> &gt; 3.<\/p>\n\n<p>Write a script to generate the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Kolakoski_sequence\" rel=\"noopener noreferrer\">Kolakoski Sequence<\/a> of given length <code>$int<\/code> and return the count of 1 in the generated sequence.<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>The Kolakoski Sequence alternates between <code>1<\/code> and <code>2<\/code>, so the equation I really need to solve is how many odd (1-based) integers between 1 and <code>$int<\/code> are there. This can be achieved by adding <code>1<\/code> to <code>$int<\/code> and taking the integer division of 2.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">kolakoski_sequence<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">int<\/span><span class=\"p\">:<\/span>\n    <span class=\"nf\">return <\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"o\">+<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span> <span class=\"o\">\/\/<\/span> <span class=\"mi\">2<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py 4\n2\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 5\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 6\n3\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 7\n4\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 8\n4\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Who Wins\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>It's NFL playoff time. Since the 2020 season, seven teams from each of the league's two conferences (AFC and NFC) qualify for the playoffs based on regular season winning percentage, with a tie-breaking procedure if required. The top team in each conference receives a first-round bye, automatically advancing to the second round.<\/p>\n\n<p>The following games are played. Some times the games are played in a different order. To make things easier, assume the order is always as below.<\/p>\n\n<ul>\n<li>Week 1: Wild card playoffs\n\n<ul>\n<li>Team 1 gets a bye<\/li>\n<li>\n<strong>Game 1<\/strong>: Team 2 hosts Team 7.<\/li>\n<li>\n<strong>Game 2<\/strong>: Team 3 hosts Team 6.<\/li>\n<li>\n<strong>Game 3<\/strong>: Team 4 hosts Team 5.<\/li>\n<\/ul>\n\n\n<\/li>\n\n<li>Week 2: Divisional playoffs\n\n<ul>\n<li>\n<strong>Game 4<\/strong>: Team 1 hosts the third seeded winner from the previous week.<\/li>\n<li>\n<strong>Game 5<\/strong>: The highest seeded winner from the previous week hosts the second seeded winner.<\/li>\n<\/ul>\n\n\n<\/li>\n\n<li>Week 3: Conference final\n\n<ul>\n<li>\n<strong>Game 6<\/strong>: The highest seeded winner from the previous week hosts the other winner.<\/li>\n<\/ul>\n\n\n<\/li>\n\n<\/ul>\n\n<p>You are given a six character string containing only <code>H<\/code> (home) and <code>A<\/code> away which has the winner of each game. Which two teams competed in the the conference final and who won?<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>Two hundred and eighty nine weeks since I <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-068\/sgreen\" rel=\"noopener noreferrer\">first completed<\/a> a weekly challenge, I finally submitted my own one, and it was accepted.<\/p>\n\n<p>To me this is relatively straight forward, but maybe its because I watch the NFL. Go <a href=\"https:\/\/www.patriots.com\/\" rel=\"noopener noreferrer\">Patriots<\/a> :-D<\/p>\n\n<p>I start by determining the teams that are going to play in the second week (team one, plus the winners of the first round). This is sorted numerically.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">who_wins<\/span><span class=\"p\">(<\/span><span class=\"n\">results<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"n\">week_two<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sorted<\/span><span class=\"p\">([<\/span>\n        <span class=\"mi\">1<\/span><span class=\"p\">,<\/span>\n        <span class=\"mi\">2<\/span> <span class=\"k\">if<\/span> <span class=\"n\">results<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">H<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"mi\">7<\/span><span class=\"p\">,<\/span>\n        <span class=\"mi\">3<\/span> <span class=\"k\">if<\/span> <span class=\"n\">results<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">H<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"mi\">6<\/span><span class=\"p\">,<\/span>\n        <span class=\"mi\">4<\/span> <span class=\"k\">if<\/span> <span class=\"n\">results<\/span><span class=\"p\">[<\/span><span class=\"mi\">2<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">H<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"mi\">5<\/span><span class=\"p\">,<\/span>\n    <span class=\"p\">])<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The next step is to calculate the two teams playing in the conference final, based on the results in the second round. The fourth game (first in week two) will always be team 1 at home to the lowest seeded winner from week one, while the highest seeded winner from week 1 hosts the second seeded team.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"n\">week_three<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">sorted<\/span><span class=\"p\">([<\/span>\n        <span class=\"n\">week_two<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"k\">if<\/span> <span class=\"n\">results<\/span><span class=\"p\">[<\/span><span class=\"mi\">3<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">H<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"n\">week_two<\/span><span class=\"p\">[<\/span><span class=\"mi\">3<\/span><span class=\"p\">],<\/span>\n        <span class=\"n\">week_two<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"k\">if<\/span> <span class=\"n\">results<\/span><span class=\"p\">[<\/span><span class=\"mi\">4<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">H<\/span><span class=\"sh\">\"<\/span> <span class=\"k\">else<\/span> <span class=\"n\">week_two<\/span><span class=\"p\">[<\/span><span class=\"mi\">2<\/span><span class=\"p\">],<\/span>\n    <span class=\"p\">])<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>Now that I know the teams in the final (with the highest seeded team as the home team), I switch the <code>week_three<\/code> list around if the away team won. Finally I return the expected string.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code>    <span class=\"k\">if<\/span> <span class=\"n\">results<\/span><span class=\"p\">[<\/span><span class=\"mi\">5<\/span><span class=\"p\">]<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">A<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">week_three<\/span><span class=\"p\">.<\/span><span class=\"nf\">reverse<\/span><span class=\"p\">()<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Team <\/span><span class=\"si\">{<\/span><span class=\"n\">week_three<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span><span class=\"si\">}<\/span><span class=\"s\"> defeated Team <\/span><span class=\"si\">{<\/span><span class=\"n\">week_three<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py HAHAHH\nTeam 2 defeated Team 6\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py HHHHHH\nTeam 1 defeated Team 2\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py HHHAHA\nTeam 4 defeated Team 2\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py HAHAAH\nTeam 4 defeated Team 6\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py HAAHAA\nTeam 5 defeated Team 1\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["python","theweeklychallenge"]},{"title":"Weekly Challenge: Commify every mountain","pubDate":"Tue, 06 Jan 2026 02:41:06 +0000","link":"https:\/\/dev.to\/simongreennet\/weekly-challenge-commify-every-mountain-1kid","guid":"https:\/\/dev.to\/simongreennet\/weekly-challenge-commify-every-mountain-1kid","description":"<h2>\n  \n  \n  Weekly Challenge 355\n<\/h2>\n\n<p>Each week Mohammad S. Anwar sends out <a href=\"https:\/\/theweeklychallenge.org\/\" rel=\"noopener noreferrer\">The Weekly Challenge<\/a>, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.<\/p>\n\n<p><a href=\"https:\/\/theweeklychallenge.org\/blog\/perl-weekly-challenge-355\/\" rel=\"noopener noreferrer\">Challenge<\/a>, <a href=\"https:\/\/github.com\/manwar\/perlweeklychallenge-club\/tree\/master\/challenge-355\/sgreen\" rel=\"noopener noreferrer\">My solutions<\/a><\/p>\n\n<h2>\n  \n  \n  Task 1: Thousand Separator\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given a positive integer, <code>$int<\/code>.<\/p>\n\n<p>Write a script to add thousand separator, , and return as string<\/p>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>Both Perl and Python have modules do this. There is absolutely no need to reinvent a perfectly round wheel. As <code>int<\/code> is a reserved word in Python, I use the variable <code>number<\/code> instead. The Python solution is as follows.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">thousand_separator<\/span><span class=\"p\">(<\/span><span class=\"n\">number<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">str<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"si\">{<\/span><span class=\"n\">number<\/span><span class=\"si\">:<\/span><span class=\"p\">,<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution uses the <a href=\"https:\/\/metacpan.org\/pod\/Number::Format\" rel=\"noopener noreferrer\">Number::Format<\/a> module.<br>\n<\/p>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight perl\"><code><span class=\"k\">use<\/span> <span class=\"nn\">Number::<\/span><span class=\"nv\">Format<\/span> <span class=\"p\">'<\/span><span class=\"s1\">format_number<\/span><span class=\"p\">';<\/span>\n\n<span class=\"k\">sub <\/span><span class=\"nf\">main<\/span> <span class=\"p\">($int) {<\/span>\n    <span class=\"nv\">say<\/span> <span class=\"nv\">format_number<\/span><span class=\"p\">(<\/span><span class=\"nv\">$int<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>It should of course be noted that not all countries use the comma to separate <a href=\"https:\/\/en.wikipedia.org\/wiki\/Decimal_separator#Digit_grouping\" rel=\"noopener noreferrer\">grouping of digits<\/a>. Some countries use the dot character instead. India also groups numbers by the hundred after the first thousand (e.g. 12,45,67,890).<\/p>\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-1.py 123\n123\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1234\n1,234\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1000000\n1,000,000\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 1\n1\n\n<span class=\"nv\">$ <\/span>.\/ch-1.py 12345\n12,345\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<h2>\n  \n  \n  Task 2: Mountain Array\n<\/h2>\n\n<h3>\n  \n  \n  Task\n<\/h3>\n\n<p>You are given an array of integers, <code>@ints<\/code>.<\/p>\n\n<p>Write a script to return true if the given array is a valid mountain array.<\/p>\n\n<p>An array is mountain if and only if:<\/p>\n\n<ol>\n<li>\n<code>arr.length &gt;= 3<\/code>, and<\/li>\n<li>There exists some <code>i<\/code> with <code>0 &lt; i &lt; arr.length - 1<\/code> such that:\n\n<ul>\n<li><code>arr[0] &lt; arr[1]     &lt; ... &lt; arr[i - 1] &lt; arr[i]<\/code><\/li>\n<li><code>arr[i] &gt; arr[i + 1] &gt; ... &gt; arr[arr.length - 1]<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n<h3>\n  \n  \n  My solution\n<\/h3>\n\n<p>This turned out to be harder than I thought it would be. I'm not sure if this is the best solution. I advantage of this solution is I loop over the list once.<\/p>\n\n<p>These are the steps I take.<\/p>\n\n<ol>\n<li>Check that there are at least three items in the <code>ints<\/code> list (array in Perl). Return <code>False<\/code> if there are not.<\/li>\n<li>Set the variable <code>last_int<\/code> to the first item in the <code>ints<\/code> list, and the variable <code>direction<\/code> to <code>up<\/code>.<\/li>\n<li>Check that the second item is higher than the first, and return <code>False<\/code> if it is not. This ensures that descents won't return the wrong result.<\/li>\n<li>Loop through the remaining items in <code>ints<\/code> setting the value to <code>current_int<\/code>.\n\n<ol>\n<li>If <code>current_int<\/code> and <code>last_int<\/code> are the same, return <code>False<\/code>.<\/li>\n<li>If <code>direction<\/code> is <code>up<\/code> and the <code>current_int<\/code> value is less than <code>last_int<\/code>, set <code>direction<\/code> to <code>down<\/code>.<\/li>\n<li>If <code>direction<\/code> is <code>down<\/code> and the <code>current_int<\/code> value is higher than <code>last_int<\/code>, return <code>False<\/code>.<\/li>\n<li>Set <code>last_int<\/code> to the <code>current_int<\/code> value.<\/li>\n<\/ol>\n\n\n<\/li>\n\n<li>If <code>direction<\/code> is still <code>up<\/code>, return <code>False<\/code>. This ensures ascents won't return the wrong result.<\/li>\n\n<li>Return <code>True<\/code>.\n<\/li>\n\n<\/ol>\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight python\"><code><span class=\"k\">def<\/span> <span class=\"nf\">mountain_array<\/span><span class=\"p\">(<\/span><span class=\"n\">ints<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"nb\">bool<\/span><span class=\"p\">:<\/span>\n    <span class=\"k\">if<\/span> <span class=\"nf\">len<\/span><span class=\"p\">(<\/span><span class=\"n\">ints<\/span><span class=\"p\">)<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">3<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"bp\">False<\/span>\n\n    <span class=\"n\">direction<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">up<\/span><span class=\"sh\">'<\/span>\n    <span class=\"n\">last_int<\/span> <span class=\"o\">=<\/span> <span class=\"n\">ints<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"n\">ints<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"o\">&lt;=<\/span> <span class=\"n\">last_int<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"bp\">False<\/span>\n\n    <span class=\"k\">for<\/span> <span class=\"n\">current_int<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">ints<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">:]:<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">current_int<\/span> <span class=\"o\">==<\/span> <span class=\"n\">last_int<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">return<\/span> <span class=\"bp\">False<\/span>\n        <span class=\"k\">if<\/span> <span class=\"n\">direction<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">'<\/span><span class=\"s\">up<\/span><span class=\"sh\">'<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">current_int<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">last_int<\/span><span class=\"p\">:<\/span>\n                <span class=\"n\">direction<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">down<\/span><span class=\"sh\">'<\/span>\n        <span class=\"k\">else<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if<\/span> <span class=\"n\">current_int<\/span> <span class=\"o\">&gt;<\/span> <span class=\"n\">last_int<\/span><span class=\"p\">:<\/span>\n                <span class=\"k\">return<\/span> <span class=\"bp\">False<\/span>\n\n        <span class=\"n\">last_int<\/span> <span class=\"o\">=<\/span> <span class=\"n\">current_int<\/span>\n\n    <span class=\"k\">if<\/span> <span class=\"n\">direction<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">'<\/span><span class=\"s\">up<\/span><span class=\"sh\">'<\/span><span class=\"p\">:<\/span>\n        <span class=\"k\">return<\/span> <span class=\"bp\">False<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"bp\">True<\/span>\n<\/code><\/pre>\n\n<\/div>\n\n\n\n<p>The Perl solution follows the same logic.<\/p>\n\n<h3>\n  \n  \n  Examples\n<\/h3>\n\n\n\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight shell\"><code><span class=\"nv\">$ <\/span>.\/ch-2.py 1 2 3 4 5\nFalse\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 0 2 4 6 4 2 0\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 5 4 3 2 1\nFalse\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 1 3 5 5 4 2\nFalse\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 1 3 2\nTrue\n\n<span class=\"nv\">$ <\/span>.\/ch-2.py 1 3 \nFalse\n<\/code><\/pre>\n\n<\/div>\n\n\n\n","category":["perl","python","theweeklychallenge"]}]}}