---
title: "Hackerrank solutions: Python 3 and Perl 6 (part 2)"
layout: language-war
tags: Hackerrank Perl6 Python3 Programming Comparison
description: >
A number of solutions to Hackerrank challenges in both the Python 3 and the
Perl 6 programming languages. This is the second part of the series, and will
work through the subdomain of Strings.
---
{% markdown %}
# Hackerrank solutions: Python 3 and Perl 6 (part 2)
{% endmarkdown %}
{% markdown %}
As a continuation of the [previous
part](/post/2018/09/13/hackerrank-solutions-python3-and-perl6-part-1/) of this
series, I will be continuing to work through some Hackerrank challenges for
Python 3, and compare the solutions to how I would solve them in a language I'm
more proficient in, Perl 6. In this post, I will work through some of the
Python 3 string challenges from Hackerrank.
Raiph [posted a comment on
Reddit](https://www.reddit.com/r/perl6/comments/9ffc2p/hackerrank_solutions_python_3_and_perl_6_part_1/e5xml3m)
suggesting a slightly different layout, which I will be using for this post.
Additional comments are always welcome as I try to improve the format.
{% endmarkdown %}
{% admonition_md Disclaimer %}
Once again I'd like to make clear I'm trying to stick to the original
Hackerrank challenges by not using any imports not specifically used in the
original challenge. If you have suggestions for Python 3 or Perl 6 modules to
make a given task easier, I still appreciate them, but I won't update my
solutions to use a module.
{% endadmonition_md %}
{% markdown %}
## Challenges
{% endmarkdown %}
{% markdown %}
### String Split and Join
This challenge involves a string containing spaces, where the spaces are to be
replaced with dashes (`-`) instead.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##K6gsycjPM/7/PyU1TaG4ICezJD4xLyU@Kz8zTyMnMy9V04pLAQiKUktKi/IUlHSV9OBSemDlGkoKSpqa/wuKMvNKNNAMyMwrKC3R0ARKp@XnKyQlFgFxFQA %}
def split_and_join(line):
return "-".join(line.split(" "))
{% endhighlight %}
{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEmhuCAns0Q3MS9FNys/M09BQyUnMy9VU6GaSwEIwBw9sBINJQUlTT2QGg0lXSVNrtr/KlqefnrFOaVFBXpqqKboFSdW/k/Lz1dISiwC4ioA %}
sub split-and-join ($line) {
$line.split(" ").join("-")
}
{% endhighlight %}
{% markdown %}
### What's Your Name?
The next challenge is a simply string formatting task. You get two inputs, a
first name and a last name, and have to put it in a string which will be
printed to `STDOUT`.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##XYzBCsIwEETv/YqxUEigePHmD@jZm6cSyRYj22ww2UK/PobqyWEOAzPz0laeEk@1epqR3iGWaVbmKbqFjBvxsOcOTXtl@isxC4bcfMBdFC/NBZ54JY@2EKQdeOwx4Pu39R8bYtJi7IhfsPWiwUu3uoib5KzLBw %}
def print_full_name(a, b):
print("Hello %s %s! You just delved into python." % (a, b))
{% endhighlight %}
{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEmhoCgzr0Q3rTQnRzcvMTdVQyVRR0ElSVOhmksBCIoTKxWUPFJzcvIVVBKB4ooKkfmlClmlxSUKKak5ZakpCkDd@QoBQPMUzPSUuGr/Y5in5emnl55aAjQVytL875NYVFTJFZ6YkwMA %}
sub print-full-name($a, $b) {
say "Hello $a $b! You just delved into Perl 6."
}
{% endhighlight %}
{% markdown %}
### Mutations
You are given a string _string_, an integer _position_ and a character
_character_. In _string_, replace the character at _position_ to the given
_character_. The position is counted from starting point 0, so I don't have to
think about differences between what a human or computer considers to be
position 1 in a string.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##VY5BC8IwDIXv/RVhpxaKIN4Ef4mIjNm5iCYlTQ/79bXrpmIuyeN975E468R0KOUWRnhl7TVckwrS3a7LQ@SEikwehqmXftAg7migzqITnOCJSTfc/YzzJ3ipyDdqGiBBsxB03e7BSLbxrsTaoPb/C6SY1ToPi7WJptbLlZHZ7I28AQ %}
def mutate_string(string, position, character):
chars = list(string)
chars[position] = character
return "".join(chars)
{% endhighlight %}
{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEkht7QksSRVt7ikKDMvXUFDBcLQUVApyC/OLMnMzwMykzMSixKTS1KLNBWquRSAILdSwSEns7hEwVYBqkEvOT83yRosCZaJhuuPBSmCm2DNhVCjl5WfmWfNVfsfxQ0aKlqefnrpqSVAizFYmnrFiZX/0/LzuQy5igA %}
sub mutate-string ($string, $position, $character) {
my @list = $string.comb;
@list[$position] = $character;
@list.join;
}
{% endhighlight %}
{% markdown %}
### Find a String
In the following challenge you are given a string _string_, and a substring
_sub\_string_. The challenge is to find how often a substring occurs in the
_string_. The substrings may overlap one another, so the string `"ABCDCDC"`
contains the substring `"CDC"` twice.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##XU67CsMwDNz9FTfaxENKt4CHPv4ilNCHkwqKbBx76Ne7bhxIqYSQdNzp5N/x6Xif88OOuLvEcZjTbY6BeJK1aRRkqLPqBEosRBi0YllHF0AgRrjyZGWr8bK8qtUq@QaNqGBPHaGprO32Bcb8eG26zbIx2FXPYGMKXOHsCz/K//eJfYpSaayDUvlwPJ1LilIf %}
def count_substring(string, sub_string):
count = 0
for i in range(0, len(string)):
if string[i:i + len(sub_string)] == sub_string:
count += 1
return count
{% endhighlight %}
{% highlight perl6
tio=https://tio.run/##K0gtyjH7/7@4NEkhOb80r0QXyCouKcrMS1fQUIEwdBRUgIK6EI6mQjUXZ2pOam6xAlRaoa5OIdcqvwxoUGKBPpJSfa7a/2hmaqhoefrppaeWAM2EsjT1ihMr/zs6ObsAIRcQAwA %}
sub count-substring ($string, $sub-string) {
elems $string ~~ m:overlap/$sub-string/
}
{% endhighlight %}
{% markdown %}
### String Validators
In the following challenge, the program is given a string _s_, and have to
validate a number of properties on this string. These are, in order, whether
they contain
- alphanumeric characters (a-z, A-Z or 0-9),
- alphabetic characters (a-z or A-Z),
- digits (0-9),
- lowercase characters (a-z),
- uppercase characters (A-Z).
If any character in the given string passes a validation, it must print
`"True"`, otherwise it must print `"False"`.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##hZLNioMwEIDvPsXQPdTAIrS9CR72sk@wt1JCVtMaqklIIqWUPrubn6p1MZib38x8zmQi76YW/ND37AwYc9JSjKEoYItxSxjHeJsnYI@GAhiXnUlR4kFZ0/Lq6MN/urMhDe/aTQ7fpNH0853Lmizwil2YWeCNuFG1wDspJ@7xMzRzFso2RJRtERqmTapRPpbZybgwr4aPryZPQHjlazKmPUrfSqYBp/wCflRHk7jWzfhPa1FcG/JXtOGKZlqPYtohf0Ubbnim9SimHfJXtGFBM61HMe2QH7QQvFd6d@/K7zEkZg6lCI3hTAs1vkS3fAvd7l1s@pNUjA@Kow2dUN9//ZbVbn/4@AM %}
if __name__ == '__main__':
s = input()
checks = {
"alnum": False,
"alpha": False,
"digit": False,
"lower": False,
"upper": False
}
for char in list(s):
if not checks["alnum"] and char.isalnum():
checks["alnum"] = True
if not checks["alpha"] and char.isalpha():
checks["alpha"] = True
if not checks["digit"] and char.isdigit():
checks["digit"] = True
if not checks["lower"] and char.islower():
checks["lower"] = True
if not checks["upper"] and char.isupper():
checks["upper"] = True
keys = list(checks.keys())
keys.sort()
for key in keys:
print(checks[key])
{% endhighlight %}
{% highlight perl6
tio=https://tio.run/##K0gtyjH7/7@4NEnB19HTT6GaSwEIcisVVIoVbBVUtDz99NJTS6y5wMLFiZUKxfkgqbo6BX2bxJy80lw7fWvscgUZiTjkUjLTM0twyOXkl6cW4ZArLSiAyNX@/@@YlJxiaGSsDAA %}
sub MAIN {
my $s = $*IN.get;
say so $s ~~ /
/;
say so $s ~~ //;
say so $s ~~ //;
say so $s ~~ //;
say so $s ~~ //;
}
{% endhighlight %}
{% markdown %}
### Text Wrap
You are given a string _s_ and a width _w_. The string should be split over
multiple lines so it is never more wide than _w_.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##K6gsycjPM/7/PzO3IL@oRKEktaKkvCixgIsrJTVNAcTSKC4pysxL11HITayIL89MKcnQtOJSAIKi1JLSojwFpZg8Jb2s/Mw8DZhePRzaNP8XAIVKNMDSmXkFpSUamjoKIBEoBwj@Ozo5u7i6uXt4enn7@Pr5BwQGBYeEhoVHREZxmQIA %}
import textwrap
def wrap(string, max_width):
return "\n".join(textwrap.wrap(string, max_width))
{% endhighlight %}
{% highlight perl6 tio=https://tio.run/##K0gtyjH7/7@4NEmhvCixQEFDpbikKDMvXUdBpTwzpSRDU6GaSwEIoMJ6yfm5SRpQKb2s/Mw8DaWYPCVNrtr/IO0aKlqefnrpqSVA7VCWnmdeiaZecWLlf0cnZxdXN3cPTy9vH18//4DAoOCQ0LDwiMgoLlMA %}
sub wrap ($string, $width) {
$string.comb($width).join("\n")
}
{% endhighlight %}
{% markdown %}
### Designer Door Mat
This challenge is more complex than previous challenges. The task at hand is to
"draw" a certain "design" as the output. For the input, you are given both a
height _y_ and a width _x_, however _x_ must always be _y_ × 3, so you can
ignore the second argument.
This one is much simpler to explain using two examples. The first example is
the output if the input were `7 21`.
{% endmarkdown %}
{% highlight text %}
---------.|.---------
------.|..|..|.------
---.|..|..|..|..|.---
-------WELCOME-------
---.|..|..|..|..|.---
------.|..|..|.------
---------.|.---------
{% endhighlight %}
{% markdown %}
In the second example, the input is `11 33`.
{% endmarkdown %}
{% highlight text %}
---------------.|.---------------
------------.|..|..|.------------
---------.|..|..|..|..|.---------
------.|..|..|..|..|..|..|.------
---.|..|..|..|..|..|..|..|..|.---
-------------WELCOME-------------
---.|..|..|..|..|..|..|..|..|.---
------.|..|..|..|..|..|..|.------
---------.|..|..|..|..|.---------
------------.|..|..|.------------
---------------.|.---------------
{% endhighlight %}
{% highlight python3 tio=https://tio.run/##zZDNS8MwGMbv@SseMwbJlrbrehCEnWS3DS@CBxGpNFsCJQ1p5xD832s@Nh2I7GpyCHmf3/u8H/ZjUJ2pxnFyg@LQu@JNm0Kad9gkEKKk3qsBK2gzMKaNPQyM571ttX/58@KFk6NuBuWJEzpDRVTd7s45p3CGkqPAkhMywWNnERiy6xxabaRH4Wqzl6wUUcHc83cE/pjOvDZ1r2TvLRmL@MwbRctIfKuxYOonA7tI9E3xc/mQYV1A6bQPl2IKRjPqqYQL0PwzD/8fCx@7IHgcY6ubppVxAPLbMRZKSSxoqa8idV5xkfSn9eb@Ybum4gpOUslNd5Tur92FsMBCIPvfuxvHWyzLLw %}
#! /usr/bin/env python3
height = int((input().split())[0])
width = height * 3
half = int((height - 1) / 2)
# Top half
for line in range(1, half + 1):
non_dashes = ((line * 2) - 1)
dashes = int((width - (non_dashes * 3)) / 2)
print("%s%s%s" % ("-" * dashes, ".|." * non_dashes, "-" * dashes))
# Middle line
print("%s%s%s" % (
"-" * (int(width / 2) - 3),
"WELCOME",
"-" * (int(width / 2) - 3)
))
# Lower half
for line in range(half, 0, -1):
non_dashes = ((line * 2) - 1)
dashes = int((width - (non_dashes * 3)) / 2)
print("%s%s%s" % ("-" * dashes, ".|." * non_dashes, "-" * dashes))
{% endhighlight %}
{% highlight perl6 tio=https://tio.run/##zZBBTsMwEEX3PsXgdpEgxVFSqSwiVqiLSi1skFiiIE@xpeBEdtpQhZyDo3CAHix0UpKGSuzxypp5/8/XL9Bm87adXEG4dTZ80SZEs4OCxoy97WGqUL@qEm5her28Fy7b2kJUuZVOKEylWJoy6bhKy1IR9iM4fMLstFFptgkGG68HAoh8OHxBnDA2gce8AALZJrcQCfFLVTM4PvIyuQlk6hS6zuqZzsQ@eSUDM9qfQgXH30hIyfzhNKlcugde84DDey9vai4@RDc4S5sLhiesofBrLWWGkGmDbOzl9QnoFqWc@c3TYnX3sF7U8DfCu0ZWeYX23Il3UYovLO7QOvzX7bTtDcTRNw %}
#! /usr/bin/env perl6
my $height = $*IN.slurp.words.head.Int;
my $width = $height × 3;
my $half-height = ($height - 1) ÷ 2;
# Top half
for 1..$half-height {
my $non-dashes = ($_ × 2) - 1;
my $dashes = ($width - ($non-dashes × 3)) ÷ 2;
say "{"-" x $dashes}{".|." x $non-dashes}{"-" x $dashes}";
}
# Middle line
say "{"-" x (($width ÷ 2) - 3)}WELCOME{ "-" x (($width ÷ 2) - 3)}";
# Lower half
for (1..$half-height).reverse {
my $non-dashes = ($_ × 2) - 1;
my $dashes = ($width - ($non-dashes × 3)) ÷ 2;
say "{"-" x $dashes}{".|." x $non-dashes}{"-" x $dashes}";
}
{% endhighlight %}
{% markdown %}
### String Formatting
In this challenge, you are to produce a table with four columns. The columns
should contain the decimal, octal, hexadecimal and binary values of the row
numbers. The function receives an int _number_. The table should contain that
many rows, starting with row number 1.
{% endmarkdown %}
{% highlight python3 tio=https://tio.run/##jZFNCoMwEIX3nmIQhIQG0XYn9CwSTawpJoYYqVJ6dht/W7uQDlll3vveTKJ7W9bqMgyMF6CNUDYtaiOptZwh1cqMG5x44ErSLn0IZku4QsUV8p9Rkr38cJavWuxNYncJAoQCQ9WNo5jA3IcTxAtvLMZzIWnliI72YQkcmnvbWLRl4s1S53Y1JPV/lpJ3dJeUdDtjqzU36ACQCUVNv3iz49DNND0m8oMG1uNDAGgZhMyLkO/hyBKE8fD7EyNKKN1ahF33HL0B %}
def print_formatted(number):
max_width = len("{0:b}".format(number))
for i in range(1, number + 1):
decimal = "{0}".format(i).rjust(max_width)
octal = "{0:o}".format(i).rjust(max_width)
hexadecimal = "{0:x}".format(i).upper().rjust(max_width)
binary = "{0:b}".format(i).rjust(max_width)
print("%s %s %s %s" % (decimal, octal, hexadecimal, binary))
{% endhighlight %}
{% highlight perl6 tio=https://tio.run/##XY9NCsIwEIX3PcUQIiRiB1tEBPEA3bhxK0iq0VZMWpIUK1KvXmNb/HurGWbeN29KaS7ztrVVCqXJtQuPhVHCOXkARnWlUmk43APwUjegStThNT@4DFYwjDEVVrKY48YZ3GfC2OV7vYeF1nn0yVsYGd0/jMYSqGuYcTwXuWYECIcHkK0my6BDeDtEiMOhIcZLv2Dskh8Z3U2A7vo8C/6po/lXE3Pe52uCpv17mdFxssaTdJhox9t4@gQ %}
sub print-formatted ($number) {
my $max-width = $number.base(2).Str.chars;
my $format-string = ("%{$max-width}s" xx 4).join(" ") ~ "\n";
for 1..$number {
$format-string.printf($_, $_.base(8), $_.base(16), $_.base(2));
}
}
{% endhighlight %}
{% markdown %}
## Wrap-up
This time I did not do all of the challenges, as the post would probably get
too long. I still did 8 of them, and might do the rest of the string challenges
in a later part anyway.
I still find Perl 6 to produce much cleaner code, which is shown best with the
first challenge. In Perl 6 (`$line.split(" ").join("-")`), I can read from left
to right to see what I'm doing: I have a `$line`, which I split, and then join.
In the Python variant (`"-".join(line.split(" "))`), it is much less clear what
the actual item I'm working on is, as it's hidden inbetween the `join` and
`split` calls.
Of course, I'm still not an expert on Python 3 code, so I'm sure that there are
many parts that could be written in a cleaner fashion. I'm still open for
feedback to improve my Python 3 skills (hence I'm publishing these posts), so
please let me know if you know better ways to solve some challenges.
{% endmarkdown %}