I’ve been doing the Weekly
Challenges. The
latest
involved daisywheels and a list breakdown. (Note that this ends today.)
Task 1: Minimum Time
You are given a typewriter with lowercase English letters a
to z
arranged in a circle.
Typing a character takes 1 sec
. You can move pointer one character
clockwise
or anti-clockwise
.
The pointer initially points at a
.
Write a script to return minimum time it takes to print the given
string.
This seems to fall into two main ideas, getting the inter-character
transfer time and getting the total. So I'll break that into two
functions. in Perl:
sub transfer($a, $b) {
Take the numerical code of each character (doesn't have to be ASCII as
long as the letters are in order)
my $ac = ord($a);
my $bc = ord($b);
Work out the minimum difference between them, going in either
direction.
min(($ac - $bc + 26) % 26, ($bc - $ac + 26) % 26);
}
(One could cache that, but at this scale it doesn't seem important.)
sub minimumtime($a) {
The total starts off as the number of characters.
my $tot = length($a);
and the wheel is initially at 'a'.
my $prev = 'a';
foreach my $c (split '', $a) {
Then for each character add the transfer time, and set the wheel
position for the next character.
$tot += transfer($prev, $c);
$prev = $c;
}
$tot;
}
Task 2: Balls and Boxes
There are $n
balls of mixed colors: red
, blue
or green
. They
are all distributed in 10 boxes
labelled 0-9
.
You are given a string describing the location of balls.
Write a script to find the number of boxes containing all three
colors. Return 0
if none found.
This smelt to me like a problem for sets, so that's what I did. In
Crystal (and almost identically in Ruby):
def ballsandboxes(a)
Set up the hash of sets.
boxes = Hash(Int32, Set(Char)).new
Initialise with a dummy colour which won't get used. (We're not
checking for correctness of input. If we were, I'd do it in Rust and
use winnow
.)
colour = '@'
Loop over the input characters.
a.chars.each_with_index do |c, i|
Even-numbered characters specify the colour.
if i % 2 == 0
colour = c
else
Odd-numbered characters specify where the colour goes. (In a new set,
or extending an existing set.)
boxid = c.to_i
if boxes.has_key?(boxid)
boxes[boxid].add(colour)
else
boxes[boxid] = Set.new([colour])
end
end
end
Then, having made somewhat heavy weather of rearranging the input, all
I have to do is filter the sets for ones that are big enough, and
return the count of them.
boxes.values.select{|x| x.size >= 3}.size
Full code on
github.