Camel
Peter
Peter Campbell Smith

Binary aliens

Weekly challenge 305 — 20 January 2025

Week 305: 20 Jan 2025

Task 2

Task — Alien dictionary

You are given a list of words and alien dictionary character order. Write a script to sort lexicographically the given list of words based on the alien dictionary characters.

Examples


Example 1
Input: @words = ('perl', 'python', 'raku')
       @alien = qw/h l a b y d e f g i r k m n o p q j s
	   t u v w x c z/
Output: ('raku', 'python', 'perl')

Example 2
Input: @words = ('the', 'weekly', 'challenge')
       @alien = qw/c o r l d a b t e f g h i j k m n p q 
	   s w u v x y z/
Output: ('challenge', 'the', 'weekly')

Analysis

I can see two ways to do this:

  • Create a function fn() such that

    sort { fn($a) <=> fn($b) } @words

    creates the desired ordering. I'm sure that can be done, and expect that some solutions will be submitted doing it that way.

  • Or translate the words into alienese, which sorts in the desired order, and then translate them back into English. So, in example 1 above, 'abbey' in English becomes 'cddge' because 'a' is the 3rd letter in the alienese alphabet and we substitute 'c', which is the 3rd letter in the order sort produces by default.

I chose the second option. I did that because it's easier to read, and it's faster than the first option because each word is translated each way only once.

Try it 

Try running the script with any input:



example: the quick brown fox jumps over the lazy dog
Words must use only a-z



example: acegikmoqsuwybdfhjlnprtvxz
All 26 lower case letters in any order

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-01-20
use utf8;     # Week 305 - task 2 - Alien dictionary
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

alien_dictionary(['perl', 'python', 'raku'],
       [qw/h l a b y d e f g i r k m n o p q j s t u v w x c z/]);
alien_dictionary(['the', 'weekly', 'challenge'],
       [qw/c o r l d a b t e f g h i j k m n p q s w u v x y z/]);
alien_dictionary(['aarvark', 'antelope', 'deer', 'hyrax', 'meercat',  'sloth', 'tiger', 'unicorn', 'zebra'],
       [qw/z y x w v u t s r q p o n m l k j i h g f e d c b a/]);

sub alien_dictionary {
    
    my (@words, @alien, %from_alien, %to_alien, $j, $w, @letters);
    
    @words = @{$_[0]};
    @alien = @{$_[1]};
    say qq[\nInput:  \@words = ('] . join(q[', '], @words) . q[')];
    say qq[        \@alien = qw/] . join(' ', @alien) . '/';
    
    # make translation tables
    for $j (0 .. 25) {
        $to_alien{$alien[$j]} = chr(ord('a') + $j); 
        $from_alien{chr(ord('a') + $j)} = $alien[$j];
    }
    
    # translate each word to Alienese
    for $w (0 .. $#words) {
        @letters = split('', $words[$w]);
        $letters[$_] = $to_alien{$letters[$_]} for 0 .. $#letters;
        $words[$w] = join('', @letters);
    }
    
    # sort words
    @words = sort @words;
    
    # translate each word to English
    for $w (0 .. $#words) {
        @letters = split('', $words[$w]);
        $letters[$_] = $from_alien{$letters[$_]}  for 0 .. $#letters;;
        $words[$w] = join('', @letters);
    }   

    say qq[Output: \@words = ('] . join(q[', '], @words) . q[')];
}

Output


Input:  @words = ('perl', 'python', 'raku')
        @alien = qw/h l a b y d e f g i r k m n o p q j s
        t u v w x c z/
Output: @words = ('raku', 'python', 'perl')

Input:  @words = ('the', 'weekly', 'challenge')
        @alien = qw/c o r l d a b t e f g h i j k m n p q
        s w u v x y z/
Output: @words = ('challenge', 'the', 'weekly')

Input:  @words = ('aarvark', 'antelope', 'deer', 'hyrax',
        'meercat', 'sloth', 'tiger', 'unicorn', 'zebra')
        @alien = qw/z y x w v u t s r q p o n m l k j i h
        g f e d c b a/
Output: @words = ('zebra', 'unicorn', 'tiger', 'sloth',
        'meercat', 'hyrax', 'deer', 'antelope', 'aarvark')

 

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