Camel
Peter
Peter Campbell Smith

Time box

Weekly challenge 312 — 10 March 2025

Week 312: 10 Mar 2025

Task 1

Task — Minimum time

You are given a typewriter with lowercase English letters a to z arranged in a circle. Typing a character takes 1 second. You can move pointer one character clockwise or anti-clockwise, each of which takes 1 second. The pointer initially points at 'a'. Write a script to return the minimum time it takes to print a given $string.

Examples


Example 1
Input: $str = "abc"
Output: 5
The pointer is at 'a' initially.
1 sec - type the letter 'a'
1 sec - move pointer clockwise to 'b'
1 sec - type the letter 'b'
1 sec - move pointer clockwise to 'c'
1 sec - type the letter 'c'

Example 2
Input: $str = "bza"
Output: 7
The pointer is at 'a' initially.
1 sec - move pointer clockwise to 'b'
1 sec - type the letter 'b'
1 sec - move pointer anti-clockwise to 'a'
1 sec - move pointer anti-clockwise to 'z'
1 sec - type the letter 'z'
1 sec - move pointer clockwise to 'a'
1 sec - type the letter 'a'

Example 3
Input: $str = "zjpc"
Output: 34

Analysis

I'm glad I'm not writing this page using that typewriter!

Suppose we rotate the typewriter dial 28 clicks clockwise. Clearly we will arive at the same letter as we would have if we'd rotated it by 2 clicks. In general, therefore, we can reduce any clockwise move from$at_char to $to_char to a minimum by moving
ord(($to_char) - ord($at_char) % 26 clicks.

Similarly we could move anticlockwise by
(ord($at_char) - ord($to_char)) % 26 clicks.

One of these differences is going to be negative, but Perl correctly handles that: for example -2 % 26 == 24.

So in summary the time is the lesser of the resulting clockwise and anticlockwise moves, and add 1 for typing the letter.

Of course we could do it faster if the typewriter had a space key and a backspace key, but that's a different challenge.

Try it 

Try running the script with any input:



example: sausages

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-03-10
use utf8;     # Week 312 - task 1 - Minimum time
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

minimum_time('abc');
minimum_time('bza');
minimum_time('zjpc');
minimum_time('theweeklychallenge');
minimum_time('bbb');
minimum_time('aaaaa');

sub minimum_time {
    
    my ($string, $time, $at_char, $next_char, $left, $right);
    
    #initialise
    $string = shift;
    $time = 0;
    $at_char = 'a';
    
    # loop over chars
    for $next_char (split('', $string)) {
        
        # calc left and right move
        $left = (ord($next_char) - ord($at_char)) % 26;
        $right = (ord($at_char) - ord($next_char)) % 26;
        $time += ($left < $right ? $left : $right) + 1;
        $at_char = $next_char;
    }
    
    say qq[\nInput:  \$string = '$string'];
    say qq[Output: $time secs];
}

Output


Input:  $string = 'abc'
Output: 5 secs

Input:  $string = 'bza'
Output: 7 secs

Input:  $string = 'zjpc'
Output: 34 secs

Input:  $string = 'theweeklychallenge'
Output: 128 secs

Input:  $string = 'bbb'
Output: 4 secs

Input:  $string = 'aaaaa'
Output: 5 secs

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain