---
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 %}
Due to some comments I had on the previous article, I want to make some
additional constraints I adhere to personally clear.
I don't want to make use of `import` (or `use` for Perl 6) statements if these
were not provided in the challenge template themselves. I do this because I
want to stick to the challenges as closely as possible. Another reason is
because it would invite all sorts of discussion that I could've used any module
for it, and then discuss which module would've solved it best.
{% 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@4NEkhOb80r0QXyCouKcrMS1fQUIEwdBRUgIK6EI6mQjWXAhDkViqogDUo2CoYWHOBxdLyixTioJr0kjMSi4qhikEAolpbWyEzTQGmBmKXhko8ihUQrZoKqYXIotZgk2ohNkEMs@aq/Y/maA0VLU8/vfTUEqCJUJamXnFi5X9HJ2cXIOQCYgA %}
sub count-substring ($string, $sub-string) {
my $count = 0;
for ^$string.chars {
$count++ if $string.substr($_, $sub-string.chars) eq $sub-string;
}
$count;
}
{% 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 %}