Peter
Peter Campbell Smith

D00DlE5 and directory compare

Weekly challenge 166 — 23 May 2022

Week 166 - 23 May 2022

Task 1

Task — Hexadecimal words

As an old systems programmer, whenever I needed to come up with a 32-bit number, I would reach for the tired old examples like 0xDeadBeef and 0xC0dedBad. I want more!

Write a program that will read from a dictionary and find 2- to 8-letter words that can be “spelled” in hexadecimal, with the addition of the following letter substitutions:

  • o0 (e.g., 0xf00d = “food”)
  • l1
  • i1
  • s5
  • t7

You can use your own dictionary or you can simply open this link to access the dictionary of common words from Week 161.

Examples

ABD1CA7E, BAFF1E5, 57AB1ED    

Analysis

The operations required on any word are:

  • discard if not 2-8 letters long
  • discard if contain anything not in ABCDEFOLIST
  • anything left is a solution

From the supplied dictionary there are 1464 such words.

I found that having 1 represent I or L made for some hard to read solutions such as 1111C17 (illicit), so eliminating 1 ⟶ L reduced the number to 693.

For the first optional extra I limited the number of 'special' substitutions to 3, which reduced the number to 559, losing such words as DE5I57ED (desisted).

The second optional extra, requiring us to make 8-letter phrases from these words is a little trickier. Given that the words vary from 2-8 letters long, they could be combined as follows:

2 + 6, 3 + 5, 4 + 4, 2 + 2 + 4, 2 + 3 + 3, 2 + 2 + 2 + 2

Of the 559 words from optional extra 1, 15 have 2 letters, 69 have three letters, 139 have 4 letters, 125 have 5 letters and 109 have 6 letters.

So:

  • 2 + 6 combinations total 1635
  • 3 + 5 -> 8625
  • 4 + 4 -> 19321
  • 2 + 2 + 4 -> 31275
  • 2 + 3 + 3 -> 71415
  • 2 + 2 + 2 + 2 -> 50625

So there are 182896 possible phrases, of which most are probably not 'phrases' that one would use, and while it would be easy enough to generate them all, I didn't.

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2022-05-23
# PWC 166 task 1

use v5.28;
use strict;
use warnings;
use utf8;

my ($dictionary, $word, $count, $word2, $words); 

# fetch dictionary
$dictionary = `curl -s -L https://github.com/manwar/perlweeklychallenge-club/raw/master/data/dictionary.txt`;

# as stated above
say qq[\nAs stated in challenge:];
$count = 0;
WORD: while ($dictionary =~ m|(.*)?\n|g) {
    $word = $1;
    
    # eliminate too short, too long or containing illegal lettes
    next if (length($word) < 2 or length($word) > 8) or $word =~ m|[^abcdefolist]|i;
    
    # make 'special' substitutions
    $word =~ y|oistlOISTL|0157101571|;
    
    # output
    print sprintf('%9s', uc($word));
    print qq[\n] unless ++$count %10;
}
print qq[\n] if ++$count %10;
say qq[$count words];

#----------------------------------------------------------------------------------

if ($ARGV[0] eq 'extras') {
    # not allowing l -> 1
    say qq[\nOmitting l -> 1:];
    $count = 0;
    WORD: while ($dictionary =~ m|(.*)?\n|g) {
        $word = $1;
        next if (length($word) < 2 or length($word) > 8) or $word =~ m|[^abcdefoist]|i;
        $word =~ y|oistOIST|01570157|;
        print sprintf('%9s', uc($word));
        print qq[\n] unless ++$count %10;
    }
    print qq[\n] if ++$count %10;
    say qq[$count words];

#----------------------------------------------------------------------------------

    # limiting 'specials' to 3 (optional extra 1)
    say qq[\nLimiting 'specials' to 3:];
    $count = 0;
    WORD: while ($dictionary =~ m|(.*)?\n|g) {
        $word = $1;
        next if (length($word) < 2 or length($word) > 8) or $word =~ m|[^abcdefoist]|i;
        
        # check number of specials
        $word2 = $word;
        $word2 =~ s|[^oist]||g;
        next if length($word2) > 3;
        
        $word =~ y|oistOIST|01570157|;
        print sprintf('%9s', uc($word));
        print qq[\n] unless ++$count %10;

    }
    print qq[\n] if ++$count %10;
    say qq[$count words];
}

Output


As stated in challenge:
    ABA7E   ABA7ED   ABA7E5    ABB07   ABB075 ABD1CA7E     ABE7
    ABE75  ABE77ED    AB1DE   AB1DE5     AB1E   AB1E57    AB0DE
   AB0DE5  AB5CE55   ACCEDE  ACCEDED  ACCEDE5   ACCE55 ACCE55ED
 ACCE55E5 ACC01ADE   ACC057 ACC057ED  ACC0575      ACE     ACED
     ACE5     AC1D    AC1D5      AC7    AC7ED     AC75       AD
      ADD    ADDED   ADD1C7 ADD1C7ED  ADD1C75     ADD5      AD0
    AD0BE   AD0BE5      AD5  AFFAB1E   AFFEC7 AFFEC7ED  AFFEC75
  AFF11C7 AFF11C75   AF1E1D   AF10A7    AF007      A1D     A1DE
    A1DED    A1DE5     A1D5      A11    A11ED     A115    A151E
   A151E5     A1A5   A1BE17      A1E     A1E5    A11A5  A11A5ED
  A11A5E5    A11B1  A11B1ED   A11B15      A11   A111ED   A111E5
 A110CA7E    A1107   A11075 A11077ED    A10F7    A100F     A150
     A170    A1705       A5 A5BE5705  A5CE71C A5CE71C5    A51DE
   A51DE5      A55   A55A11 A55A11ED  A55A115    A55E5   A55E55
 A55E55ED A55E55E5    A55E7   A55E75   A55157 A55157ED  A551575
       A7      A7E    A71A5  A71A5E5   A77E57 A77E57ED  A77E575
    A771C   A771C5   BABB1E  BABB1ED  BABB1E5     BABE    BABE5
   BAB1ED   BAB1E5  BAB1E57      BAD  BADDE57     BADE   BAFF1E
  BAFF1ED  BAFF1E5     BA11   BA11ED    BA115     BA17   BA17ED
    BA175     BA1D   BA1DED  BA1DE57    BA1D5     BA1E    BA1ED
    BA1E5     BA11   BA11AD  BA11AD5  BA11A57 BA11A575   BA11ED
   BA11E7  BA11E75   BA1107 BA1107ED  BA11075    BA115     BA5E
 BA5EBA11    BA5ED    BA5E5   BA5E57    BA51C   BA51C5    BA511
    BA515     BA55   BA55E5    BA57E   BA57ED   BA57E5      BA7
     BA75   BA77ED   BA771E  BA771ED  BA771E5       BE     BEAD
   BEADED BEAD1E57    BEAD5    BEA57   BEA575     BEA7    BEA75
      BED   BEDDED     BED5  BED51DE BED51DE5      BEE     BEEF
   BEEFED BEEF1E57    BEEF5     BEE5     BEE7   BEE71E  BEE71ED
  BEE71E5    BEE75   BEFA11  BEFA115   BEFE11    BEF17   BEF175
 BEF177ED  BE1A7ED    BE11E   BE11ED   BE11EF  BE11EF5   BE11E5
 BE11771E     BE11   BE11ED  BE111ED  BE111E5    BE115     BE17
   BE17ED    BE175    BE5E7   BE5E75   BE51DE  BE51DE5     BE57
   BE57ED  BE571A1    BE575      BE7     BE7A     BE75     B1A5
   B1A5ED   B1A5E5      B1B    B1B1E B1B11CA1     B1B5      B1D
     B1DE    B1DE5     B1D5 B1F0CA15     B11E     B111   B111ED
 B111F01D    B1115   B15EC7 B15EC7ED  B15EC75      B17     B17E
    B17E5     B175     B1AB  B1ABBED    B1AB5    B1ADE   B1ADE5
    B1A57  B1A57ED   B1A575    B1EA7  B1EA7ED   B1EA75     B1ED
    B1EED   B1EED5    B1E55  B1E55ED  B1E55E5    B1155     B10B
  B10BBED    B10B5     B10C    B10C5    B100D  B100DED B100D1ED
 B100D1E5   B100D5     B107    B1075  B1077ED      B0A     B0A5
    B0A57  B0A57ED   B0A575     B0A7   B0A7ED    B0A75      B0B
   B0BBED   B0BCA7  B0BCA75     B0B5  B0B51ED B0B51ED5     B0DE
    B0DED    B0DE5   B0D1CE  B0D1CE5   B0D1E5     B011   B011ED
    B0115     B01D  B01DE57     B017   B017ED    B0175      B00
    B00ED     B005    B0057  B0057ED   B00575     B007   B007ED
   B007EE  B007EE5  B0071E5    B0075     B055   B055ED   B055E5
 B0551E57   B0771E  B0771ED  B0771E5      CAB   CABBED    CAB1E

... and so on

1464 words