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 

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