# Hex words

Hex words
You are encouraged to solve this task according to the task description, using any language you may know.
Definition

For the purposes of this task a hex word means a word which (in lower case form) consists entirely of the letters a, b, c, d, e and f.

Using unixdict.txt, find all hex words with 4 letters or more.

Convert each such word to its decimal equivalent and compute its base 10 digital root.

Display all three in increasing order of digital root and show the total count of such words.

Keeping only words which contain at least 4 distinct letters, display the same statistics but in decreasing order of decimal equivalent together with their total count.

## 11l

Translation of: Python
```F digroot(=n)
L n > 9
n = sum(String(n).map(d -> Int(d)))
R n

V words = lines.filter(w -> w.len >= 4 & all(w.map(c -> c C ‘abcdef’)))
V results = words.map(w -> (w, Int(w, radix' 16), digroot(Int(w, radix' 16))))

print("Hex words in unixdict.txt:\nRoot  Word      Base 10\n "(‘-’ * 22))
L(a) sorted(results, key' x -> x[2])
print(f:‘{a[2]}     {a[0]:<6}{a[1]:10}’)

print(‘Total count of these words: ’results.len)
print("\nHex words with > 3 distinct letters:\nRoot  Word      Base 10\n "(‘-’ * 22))
results = results.filter(a -> Set(Array(String(a[0]))).len > 3)
L(a) sorted(results, key' x -> x[2])
print(f:‘{a[2]}     {a[0]:<6}{a[1]:10}’)

print(‘Total count of those words: ’results.len)```
Output:
```Hex words in unixdict.txt:
Root  Word      Base 10
----------------------
1     ababa     703162
1     abbe       43966
1     deaf       57007
2     cede       52958
2     feed       65261
3     abed       44013
4     beebe     782014
4     decca     912586
6     deface  14613198
7     babe       47806
8     efface  15727310
9     accede  11325150
9     beef       48879
9     cafe       51966
9     dacca     896202
9     deed       57069
9     face       64206
Total count of these words: 26

Hex words with > 3 distinct letters:
Root  Word      Base 10
----------------------
1     deaf       57007
3     abed       44013
4     decca     912586
6     deface  14613198
8     efface  15727310
9     accede  11325150
9     cafe       51966
9     face       64206
Total count of those words: 13
```

## ALGOL 68

```# find words that contain only hex digits a-f #
IF  FILE input file;
STRING file name = "unixdict.txt";
open( input file, file name, stand in channel ) /= 0
THEN
# failed to open the file #
print( ( "Unable to open """ + file name + """", newline ) )
ELSE
# file opened OK #
BOOL at eof := FALSE;
# set the EOF handler for the file #
on logical file end( input file, ( REF FILE f )BOOL:
BEGIN
# note that we reached EOF on the #
at eof := TRUE;
# return TRUE so processing can continue #
TRUE
END
);
INT count := 0;
INT max words = 100; # guess at the maximum number of words #
MODE HEXWORD = STRUCT( STRING word, LONG INT value, INT root, INT len );
[ 1 : max words ]HEXWORD hw;
WHILE STRING word;
get( input file, ( word, newline ) );
NOT at eof
DO
# check the word contains only a-f and compute its decimal value #
IF  INT word len = ( UPB word + 1 ) - LWB word;
word len >= 4
THEN
# the word is at least 4 characters long #
BOOL is hex word := word /= "";
LONG INT  int word    := 0;
FOR i FROM LWB word TO UPB word
WHILE is hex word := word[ i ] >= "a" AND word[ i ] <= "f"
DO
int word *:= 16;
int word +:= ( ABS word[ i ] - ABS "a" ) + 10
OD;
IF is hex word
THEN
# have a hex word #
count +:= 1;
# compute the digital root #
LONG INT r := int word;
WHILE r > 9 DO
LONG INT dr := r MOD 10;
WHILE ( r OVERAB 10 ) > 0 DO dr +:= r MOD 10 OD;
r := dr
OD;
word  OF hw[ count ] := word;
value OF hw[ count ] := int word;
root  OF hw[ count ] := SHORTEN r;
len   OF hw[ count ] := word len
FI
FI
OD;
close( input file );
# prints the HEXWORD hw #
PROC show = ( HEXWORD hw )VOID:
BEGIN
STRING pad = IF len OF hw >= 12 THEN "" ELSE ( 12 - len OF hw ) * " " FI;
print( ( word OF hw, ": ", pad, whole( value OF hw, -10 ), " [ ", whole( root OF hw, 0 ), " ]", newline ) )
END # show # ;
# Quicksorts in-place the array of HEXWORDS a, from lb to ub on ascending value #
PROC quicksort = ( REF[]HEXWORD a, INT lb, ub )VOID:
IF ub > lb THEN
# more than one element, so must sort #
INT left   := lb;
INT right  := ub;
# choosing the middle element of the array as the pivot #
LONG INT pivot  := value OF a[ left + ( ( right + 1 ) - left ) OVER 2 ];
WHILE
WHILE IF left  <= ub THEN value OF a[ left  ] < pivot ELSE FALSE FI DO left  +:= 1 OD;
WHILE IF right >= lb THEN value OF a[ right ] > pivot ELSE FALSE FI DO right -:= 1 OD;
left <= right
DO
HEXWORD t  := a[ left  ];
a[ left  ] := a[ right ];
a[ right ] := t;
left      +:= 1;
right     -:= 1
OD;
quicksort( a, lb,   right );
quicksort( a, left, ub    )
FI # quicksort # ;
# show the hex words in ascending order of digital root #
FOR r FROM 1 TO 9 DO
FOR i FROM 1 TO count DO
IF root OF hw[ i ] = r THEN show( hw[ i ] ) FI
OD
OD;
print( ( "Found ", whole( count, 0 ), " hex words", newline, newline ) );
# show the words in descending value order excluding those with less than 4 unique letters #
quicksort( hw, 1, count );
INT count 4 := 0;
FOR i FROM count BY -1 TO 1 DO
# check the word has at least four different digits #
INT a := 0, b := 0, c := 0, d := 0, e := 0, f := 0;
FOR c pos FROM LWB word OF hw[ i ] TO UPB word OF hw[ i ] DO
IF   CHAR ch = ( word OF hw[ i ] )[ c pos ];
ch = "a"
THEN a := 1
ELIF ch = "b"
THEN b := 1
ELIF ch = "c"
THEN c := 1
ELIF ch = "d"
THEN d := 1
ELIF ch = "e"
THEN e := 1
ELSE f := 1
FI
OD;
IF a + b + c + d + e + f >= 4
THEN
# have a hex word with at least 4 different digits #
count 4 +:= 1;
show( hw[ i ] )
FI
OD;
print( ( "Found ", whole( count 4, 0 ), " hex words with 4 or more distinct digits", newline ) )
FI```
Output:
```ababa:            703162 [ 1 ]
abbe:              43966 [ 1 ]
deaf:              57007 [ 1 ]
cede:              52958 [ 2 ]
feed:              65261 [ 2 ]
abed:              44013 [ 3 ]
beebe:            782014 [ 4 ]
decca:            912586 [ 4 ]
deface:         14613198 [ 6 ]
babe:              47806 [ 7 ]
efface:         15727310 [ 8 ]
accede:         11325150 [ 9 ]
beef:              48879 [ 9 ]
cafe:              51966 [ 9 ]
dacca:            896202 [ 9 ]
deed:              57069 [ 9 ]
face:              64206 [ 9 ]
Found 26 hex words

efface:         15727310 [ 8 ]
deface:         14613198 [ 6 ]
accede:         11325150 [ 9 ]
decca:            912586 [ 4 ]
face:              64206 [ 9 ]
deaf:              57007 [ 1 ]
cafe:              51966 [ 9 ]
abed:              44013 [ 3 ]
Found 13 hex words with 4 or more distinct digits
```

## APL

Works with: Dyalog APL
```∇HexWords;todec;digroot;displayrow;words;distinct4
todec←16⊥9+'abcdef'∘⍳
digroot←(+/10⊥⍣¯1⊢)⍣(10≥⊢)
displayrow←{⍵ n (digroot⊢n←todec ⍵)}

words←((~∊)∘⎕TC⊆⊢)⊃⎕NGET'unixdict.txt'
words←(words∧.∊¨⊂⊂'abcdef')/words
words←(4≤≢¨words)/words
words←words[⍋digroot∘todec¨words]

distinct4←(4≤≢∘∪¨words)/words
distinct4←distinct4[⍒todec¨distinct4]

⎕←(⍕≢words),' hex words with at least 4 letters in unixdict.txt:'
⎕←↑displayrow¨words
⎕←''

⎕←(⍕≢distinct4),' hex words with at least 4 distinct letters:'
⎕←↑displayrow¨distinct4
∇
```
Output:
```26 hex words with at least 4 letters in unixdict.txt:
ababa     703162 1
abbe       43966 1
deaf       57007 1
cede       52958 2
feed       65261 2
abed       44013 3
beebe     782014 4
decca     912586 4
deface  14613198 6
babe       47806 7
efface  15727310 8
accede  11325150 9
beef       48879 9
cafe       51966 9
dacca     896202 9
deed       57069 9
face       64206 9

13 hex words with at least 4 distinct letters:
efface  15727310 8
deface  14613198 6
accede  11325150 9
decca     912586 4
face       64206 9
deaf       57007 1
cafe       51966 9
abed       44013 3```

## AppleScript

```use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
use sorter : script ¬
"Custom Iterative Ternary Merge Sort" -- <www.macscripter.net/t/timsort-and-nigsort/71383/3>

on hexToInt(hex)
set digits to "0123456789ABCDEF"
set n to 0
set astid to AppleScript's text item delimiters
ignoring case
repeat with thisDigit in hex
set AppleScript's text item delimiters to thisDigit
set n to n * 16 + (count digits's first text item)
end repeat
end ignoring
set AppleScript's text item delimiters to astid
return n
end hexToInt

on digitalRoot(r, base)
repeat until (r < base)
set n to r
set r to 0
repeat until (n = 0)
set r to r + n mod base
set n to n div base
end repeat
end repeat
return r as integer
end digitalRoot

on join(lst, delim)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delim
set txt to lst as text
set AppleScript's text item delimiters to astid
return txt
end join

set ca to current application
set unixdictPath to (path to desktop as text) & "unixdict.txt"
set allWords to (read (unixdictPath as «class furl») from 1 as «class utf8»)'s words
set hexwordFilter to ca's class "NSPredicate"'s ¬
predicateWithFormat:("self MATCHES '^[a-f]{4,}+\$'")
set hexwords to ((ca's class "NSArray"'s arrayWithArray:(allWords))'s ¬
filteredArrayUsingPredicate:(hexwordFilter))

set {list1, list2} to {{}, {}}
repeat with thisWord in hexwords
set thisWord to thisWord as text
set decimal to hexToInt(thisWord)
set root to digitalRoot(decimal, 10)
set thisEntry to {thisWord, decimal, root}
set end of list1 to thisEntry
set distinctChars to (ca's class "NSSet"'s setWithArray:(thisWord's characters))
if (distinctChars's |count|() > 3) then set end of list2 to thisEntry
end repeat

-- Sort list1 on its sublists' digital root values.
script
on isGreater(a, b)
return (a's end > b's end)
end isGreater
end script
tell sorter to sort(list1, 1, -1, {comparer:result})
-- Reverse sort list2 on its sublists' decimal equivalent values.
script
on isGreater(a, b)
return (a's 2nd item < b's 2nd item)
end isGreater
end script
tell sorter to sort(list2, 1, -1, {comparer:result})

-- Format for display and output.
repeat with thisList in {list1, list2}
repeat with thisEntry in thisList
tell thisEntry to set its contents to ¬
text 1 thru 9 of (its beginning & padding) & ¬
text -9 thru -1 of (padding & its 2nd item) & ¬
text -9 thru -1 of (padding & its end)
end repeat
set thisList's beginning to "
Word       Decimal      Root
----------------------------"
end repeat
set beginning of list1 to linefeed & ((count list1) - 1) & ¬
" 4+-character hexwords, sorted on their decimal equivalents' digital roots:"
set beginning of list2 to linefeed & "The " & ((count list2) - 1) & ¬
" with at least 4 /different/ characters, reverse sorted on their decimal equivalents:"

return join({list1, list2}, linefeed)

```
Output:
```"
26 4+-character hexwords, sorted on their decimal equivalents' digital roots:

Word       Decimal      Root
----------------------------
ababa       703162        1
abbe         43966        1
deaf         57007        1
cede         52958        2
feed         65261        2
abed         44013        3
beebe       782014        4
decca       912586        4
deface    14613198        6
babe         47806        7
efface    15727310        8
accede    11325150        9
beef         48879        9
cafe         51966        9
dacca       896202        9
deed         57069        9
face         64206        9

The 13 with at least 4 /different/ characters, reverse sorted on their decimal equivalents:

Word       Decimal      Root
----------------------------
efface    15727310        8
deface    14613198        6
accede    11325150        9
decca       912586        4
face         64206        9
deaf         57007        1
cafe         51966        9
abed         44013        3"
```

## Arturo

```words: map read.lines relative "unixdict.txt" => strip
hexWords: new []

digRoot: function [num][
res: num
while [1 < size digits res][
res: sum digits res
]
return res
]

printTable: function [wrds][
print repeat "-" 38
loop wrds 'wrd [
]
print repeat "-" 38
print ["   Total count:" size wrds "\n"]
]

loop words 'word [
if 4 > size word ->
continue

if not? empty? match word {/^[a-f]+\$/} [
base10: from.hex word
droot: digRoot base10
'hexWords ++ #[
root: droot
hex: word
decimal: base10
]
]
]

printTable sort.by:'root hexWords
printTable sort.descending.by:'decimal select hexWords 'h ->
4 =< size unique split h\hex
```
Output:
```   Root    Word               Base-10
--------------------------------------
1      ababa               703162
1      abbe                 43966
1      deaf                 57007
2      cede                 52958
2      feed                 65261
3      abed                 44013
4      beebe               782014
4      decca               912586
6      deface            14613198
7      babe                 47806
8      efface            15727310
9      accede            11325150
9      beef                 48879
9      cafe                 51966
9      dacca               896202
9      deed                 57069
9      face                 64206
--------------------------------------
Total count: 26

Root    Word               Base-10
--------------------------------------
8      efface            15727310
6      deface            14613198
9      accede            11325150
4      decca               912586
9      face                 64206
1      deaf                 57007
9      cafe                 51966
3      abed                 44013
--------------------------------------
Total count: 13```

## AutoHotkey

```FileRead, wList, % A_Desktop "\unixdict.txt"
hexWords := Hex_words(wList)
for dr, obj in hexWords
for word, dec in obj
result .= dec "`t" (StrLen(dec) < 8 ? "`t" : "") word "`t" dr "`n"

MsgBox, 262144, ,% result := Header . result . "`n4 distinct letter words:`n" . Header . filter(result, "abcdef", 4)
return
;-------------------------------------------
filter(result, letters, Count){
for i, line in StrSplit(result, "`n", "`r") {
counter := 0
for j, letter in StrSplit(letters)
StrReplace(line, letter, letter, cnt, 1), counter += cnt
if (counter >= Count)
filtered .= line "`n"
}
Sort, filtered, RN
return filtered
}
;-------------------------------------------
Hex_words(wList){
hexWords := []
for i, w in StrSplit(wList, "`n", "`r") {
if (StrLen(w) < 4 || w ~= "i)[^abcdef]")
continue
dec := hex2dec(w)
dr := digital_root(dec)
hexWords[dr, w] := dec
}
return hexWords
}
;-------------------------------------------
digital_root(n){
loop {
sum := 0, i := 1
while (i <= StrLen(n))
sum += SubStr(n, i++, 1)
n := sum
}
until (sum < 10)
return sum
}
```
Output:
```Base 10		Word	Root
703162		ababa	1
43966		abbe	1
57007		deaf	1
52958		cede	2
65261		feed	2
44013		abed	3
782014		beebe	4
912586		decca	4
14613198	deface	6
47806		babe	7
15727310	efface	8
11325150	accede	9
48879		beef	9
51966		cafe	9
896202		dacca	9
57069		deed	9
64206		face	9

4 distinct letter words:
Base 10		Word	Root
15727310	efface	8
14613198	deface	6
11325150	accede	9
912586		decca	4
64206		face	9
57007		deaf	1
51966		cafe	9
44013		abed	3```

## AWK

```# syntax: GAWK -f HEX_WORDS.AWK unixdict.txt
{   nf += NF
if (length(\$1) >= 4) {
if (\$0 ~ /^[a-fA-F]{4,}\$/) {
base10 = hex2dec(\$1)
dr = digital_root(base10)
arr[dr " " \$1] = base10
}
}
}
ENDFILE {
printf("%s: %d records, %d fields\n\n",FILENAME,FNR,nf)
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (i in arr) {
printf("%-8s %10d \n",i,arr[i])
count1++
}
printf("Found %d hex words\n\n",count1)
PROCINFO["sorted_in"] = "@val_num_desc"
for (i in arr) {
if (distinct(substr(i,3)) >= 4) {
printf("%-8s %10d \n",i,arr[i])
count2++
}
}
printf("Found %d hex words with 4 or more distinct\n\n",count2)
exit(0)
}
function digital_root(n,  i,sum) {
while (1) {
sum = 0
for (i=1; i<=length(n); i++) {
sum += substr(n,i,1)
}
if (sum < 10) {
break
}
n = sum
}
return(sum)
}
function distinct(str,  arr,i) {
for (i=1; i<=length(str); i++) {
arr[substr(str,i,1)]++
}
return(length(arr))
}
function hex2dec(s,  num) {
num = index("0123456789ABCDEF",toupper(substr(s,length(s)))) - 1
sub(/.\$/,"",s)
return num + (length(s) ? 16*hex2dec(s) : 0)
}
```
Output:
```unixdict.txt: 25104 records, 25104 fields

1 ababa      703162
1 abbe        43966
1 deaf        57007
2 cede        52958
2 feed        65261
3 abed        44013
4 beebe      782014
4 decca      912586
6 deface   14613198
7 babe        47806
8 efface   15727310
9 accede   11325150
9 beef        48879
9 cafe        51966
9 dacca      896202
9 deed        57069
9 face        64206
Found 26 hex words

8 efface   15727310
6 deface   14613198
9 accede   11325150
4 decca      912586
9 face        64206
1 deaf        57007
9 cafe        51966
3 abed        44013
Found 13 hex words with 4 or more distinct
```

## C++

```#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>

struct Item {
std::string word;
int32_t number;
int32_t digital_root;
};

void display(const std::vector<Item>& items) {
std::cout << "  Word      Decimal value   Digital root" << std::endl;
std::cout << "----------------------------------------" << std::endl;
for ( const Item& item : items ) {
std::cout << std::setw(7) << item.word << std::setw(15) << item.number
<< std::setw(12) << item.digital_root << std::endl;
}
std::cout << "\n" << "Total count: " << items.size() << "\n" << std::endl;
}

int32_t digital_root(int32_t number) {
int32_t result = 0;
while ( number > 0 ) {
result += number % 10;
number /= 10;
}
return ( result <= 9 ) ? result : digital_root(result);
}

bool contains_only(const std::string& word, const std::unordered_set<char>& acceptable) {
return std::all_of(word.begin(), word.end(),
[acceptable](char ch) { return acceptable.find(ch) != acceptable.end(); });
}

int main() {
const std::unordered_set<char> hex_digits{ 'a', 'b', 'c', 'd', 'e', 'f' };
std::vector<Item> items;

std::fstream file_stream;
file_stream.open("unixdict.txt");
std::string word;
while ( file_stream >> word ) {
if ( word.length() >= 4 && contains_only(word, hex_digits)) {
const int32_t value = std::stoi(word, 0, 16);
int32_t root = digital_root(value);
items.push_back(Item(word, value, root));
}
}

auto compare = [](Item a, Item b) {
return ( a.digital_root == b.digital_root ) ? a.word < b.word : a.digital_root < b.digital_root;
};
std::sort(items.begin(), items.end(), compare);
display(items);

std::vector<Item> filtered_items;
for ( const Item& item : items ) {
if ( std::unordered_set<char>(item.word.begin(), item.word.end()).size() >= 4 ) {
filtered_items.push_back(item);
}
}

auto comp = [](Item a, Item b) { return a.number > b.number; };
std::sort(filtered_items.begin(), filtered_items.end(), comp);
display(filtered_items);
}
```
Output:
```  Word      Decimal value   Digital root
----------------------------------------
ababa         703162           1
abbe          43966           1
deaf          57007           1
cede          52958           2
feed          65261           2
abed          44013           3
beebe         782014           4
decca         912586           4
deface       14613198           6
babe          47806           7
efface       15727310           8
accede       11325150           9
beef          48879           9
cafe          51966           9
dacca         896202           9
deed          57069           9
face          64206           9

Total count: 26

Word      Decimal value   Digital root
----------------------------------------
efface       15727310           8
deface       14613198           6
accede       11325150           9
decca         912586           4
face          64206           9
deaf          57007           1
cafe          51966           9
abed          44013           3

Total count: 13
```

## Factor

Works with: Factor version 0.99 2021-06-02
```USING: formatting io io.encodings.ascii io.files kernel literals
math math.parser prettyprint sequences sets sorting ;

CONSTANT: words \$[
"unixdict.txt" ascii file-lines
[ length 3 > ] filter
[ "abcdef" subset? ] filter
]

: droot ( m -- n ) 1 - 9 mod 1 + ;

: info. ( str -- ) dup hex> dup droot "%-8s-> %-10d-> %d\n" printf ;

: info-by ( quot ? -- )
[ sort-with ] [ inv-sort-with ] if [ length ] keep
[ info. ] each pprint ; inline

words [ hex> droot ] t info-by
" hex words with 4 or more letters found." print nl

words [ cardinality 3 > ] filter [ hex> ] f info-by
" such words found which contain 4 or more different digits." print
```
Output:
```ababa   -> 703162    -> 1
abbe    -> 43966     -> 1
deaf    -> 57007     -> 1
cede    -> 52958     -> 2
feed    -> 65261     -> 2
abed    -> 44013     -> 3
beebe   -> 782014    -> 4
decca   -> 912586    -> 4
deface  -> 14613198  -> 6
babe    -> 47806     -> 7
efface  -> 15727310  -> 8
accede  -> 11325150  -> 9
beef    -> 48879     -> 9
cafe    -> 51966     -> 9
dacca   -> 896202    -> 9
deed    -> 57069     -> 9
face    -> 64206     -> 9
26 hex words with 4 or more letters found.

efface  -> 15727310  -> 8
deface  -> 14613198  -> 6
accede  -> 11325150  -> 9
decca   -> 912586    -> 4
face    -> 64206     -> 9
deaf    -> 57007     -> 1
cafe    -> 51966     -> 9
abed    -> 44013     -> 3
13 such words found which contain 4 or more different digits.
```

## FutureBasic

```#plist NSAppTransportSecurity @{NSAllowsArbitraryLoads:YES}

include "NSLog.incl"

local fn ConvertHexToInt( hexNumberStr as CFStringRef ) as NSUInteger
NSUInteger  outVal = 0
ScannerRef scanner = fn ScannerWithString( hexNumberStr )
fn ScannerScanHexInt( scanner, @outVal )
end fn = outVal

local fn DigitalRoot( n as NSUInteger ) as NSUInteger
while ( n > 9 )
NSUInteger tot = 0
while ( n > 0 )
tot += n mod 10
n = fn floor( n / 10 )
wend
n = tot
wend
end fn = n

local fn HasDistinctLetters( hexNumberStr as CFStringRef ) as BOOL
NSUInteger A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, length = len( hexNumberStr )

while ( length > 0 )
length--
unichar aChar = fn StringCharacterAtIndex( hexNumberStr, length )
select ( aChar )
case _"a" : if A = 0 then A = 1
case _"b" : if B = 0 then B = 1
case _"c" : if C = 0 then C = 1
case _"d" : if D = 0 then D = 1
case _"e" : if E = 0 then E = 1
case _"f" : if F = 0 then F = 1
end select
wend
if ( A + B + C + D + E + F ) > 3 then exit fn = YES
end fn = NO

local fn ParseDictionaryHexWords as CFArrayRef
CFURLRef              url = fn URLWithString( @"http://wiki.puzzlers.org/pub/wordlists/unixdict.txt" )
CFStringRef        string = lcase( fn StringWithContentsOfURL( url, NSUTF8StringEncoding, NULL ) )
CFArrayRef        tempArr = fn StringComponentsSeparatedByCharactersInSet( string, fn CharacterSetNewlineSet )
CFMutableArrayRef dictArr = fn MutableArrayNew
CFStringRef       tempStr

for tempStr in tempArr
if ( fn StringLength( tempStr ) > 3 )  // Keep four letter words and longer
CFRange range = fn StringRangeOfStringWithOptions( tempStr, @"^[a-f]+\$", NSRegularExpressionSearch ) // Keep wordss with letters a to f
if range.location != NSNotFound then MutableArrayAddObject( dictArr, tempStr )
end if
next
end fn = fn ArrayWithArray( dictArr )

local fn ConvertWordsToHexValues as CFStringRef
CFArrayRef  hexWordArray = fn ParseDictionaryHexWords
CFStringRef wordStr
CFMutableArrayRef mutArr = fn MutableArrayNew //fn MutableStringWithString( @"Root   Word      Base 10\n ---------------------------\n" )
CFMutableArrayRef lngArr = fn MutableArrayNew

for wordStr in hexWordArray
NSUInteger uintFromHex = fn ConvertHexToInt( wordStr )
NSUInteger digitalRoot = fn DigitalRoot( uintFromHex )
CFStringREf formatStr = fn StringWithFormat( @"%2lu     %-8s  %lu", digitalRoot, fn StringUTF8String( wordStr ), uintFromHex )
if ( fn HasDistinctLetters( wordStr ) == YES )
end if
next
CFStringRef headerStr = @"\nRoot   Word      Base 10\n ---------------------------\n"
CFArrayRef  resultArr = fn ArraySortedArrayUsingSelector( mutArr, @"localizedCompare:" )
CFStringRef resultStr = fn ArrayComponentsJoinedByString( resultArr, @"\n" )
CFArrayRef uniquetArr = fn ArraySortedArrayUsingSelector( lngArr, @"localizedCompare:" )
CFStringRef uniqueStr = fn ArrayComponentsJoinedByString( uniquetArr, @"\n" )
CFStringRef  finalStr = fn StringWithFormat( @"%@%@\n\nHex words with 3 > distinct letters:%@%@", headerStr, resultStr, headerStr, uniqueStr )
end fn = finalStr

NSLog( @"%@", fn ConvertWordsToHexValues )

HandleEvents```
Output:
```
Root   Word      Base 10
---------------------------
1     ababa     703162
1     abbe      43966
1     deaf      57007
2     cede      52958
2     feed      65261
3     abed      44013
4     beebe     782014
4     decca     912586
6     deface    14613198
7     babe      47806
8     efface    15727310
9     accede    11325150
9     beef      48879
9     cafe      51966
9     dacca     896202
9     deed      57069
9     face      64206

Hex words with 3 > distinct letters:
Root   Word      Base 10
---------------------------
1     deaf      57007
3     abed      44013
4     decca     912586
6     deface    14613198
8     efface    15727310
9     accede    11325150
9     cafe      51966
9     face      64206

```

## J

```   (#~\$&1 0@#)(#,&":])/:~((+/@(".&>@":)^:_@]; ;~) dfh)@> (#~ (*/@e.&'abcdef' * 3<#)@>) cutLF fread'unixdict.txt'
26
│1│43966   │abbe  │
│1│57007   │deaf  │
│1│703162  │ababa │
│2│52958   │cede  │
│2│65261   │feed  │
│3│44013   │abed  │
│4│782014  │beebe │
│4│912586  │decca │
│6│14613198│deface│
│7│47806   │babe  │
│8│15727310│efface│
│9│48879   │beef  │
│9│51966   │cafe  │
│9│57069   │deed  │
│9│64206   │face  │
│9│896202  │dacca │
│9│11325150│accede│
(#~ \$&1 0@#)(#,&":])\:~((+/@(".&>@":)^:_@]; ;~) dfh)@> (#~ (*/@e.&'abcdef' * 3 < #@~.)@>) cutLF fread'unixdict.txt'
13
│9│11325150│accede│
│9│64206   │face  │
│9│51966   │cafe  │
│8│15727310│efface│
│6│14613198│deface│
│4│912586  │decca │
│3│44013   │abed  │
│1│57007   │deaf  │
```

## Java

```import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public final class HexWords {

public static void main(String[] aArgs) throws IOException {
Set<Character> hexDigits = Set.of( 'a', 'b', 'c', 'd', 'e', 'f' );

List<Item> items = Files.lines(Path.of("unixdict.txt"))
.filter( word -> word.length() >= 4 )
.filter( word -> word.chars().allMatch( ch -> hexDigits.contains((char) ch) ) )
.map( word -> { final int value = Integer.parseInt(word, 16);
return new Item(word, value, digitalRoot(value));
} )
.collect(Collectors.toList());

Collections.sort(items, Comparator.comparing(Item::getDigitalRoot).thenComparing(Item::getWord));
display(items);

List<Item> filteredItems = items.stream()
.filter( item -> item.aWord.chars().mapToObj( ch -> (char) ch ).collect(Collectors.toSet()).size() >= 4 )
.collect(Collectors.toList());

Collections.sort(filteredItems, Comparator.comparing(Item::getNumber).reversed());
display(filteredItems);
}

private static int digitalRoot(int aNumber) {
int result = 0;
while ( aNumber > 0 ) {
result += aNumber % 10;
aNumber /= 10;
}
return ( result <= 9 ) ? result : digitalRoot(result);
}

private static void display(List<Item> aItems) {
System.out.println("  Word      Decimal value   Digital root");
System.out.println("----------------------------------------");
for ( Item item : aItems ) {
}
System.out.println(System.lineSeparator() + "Total count: " + aItems.size() + System.lineSeparator());
}

private static record Item(String aWord, int aNumber, int aDigitalRoot) {

public String getWord() { return aWord; }

public int getNumber() { return aNumber; }

public int getDigitalRoot() { return aDigitalRoot; }

}

}
```
Output:
```  Word      Decimal value   Digital root
----------------------------------------
ababa         703162           1
abbe          43966           1
deaf          57007           1
cede          52958           2
feed          65261           2
abed          44013           3
beebe         782014           4
decca         912586           4
deface       14613198           6
babe          47806           7
efface       15727310           8
accede       11325150           9
beef          48879           9
cafe          51966           9
dacca         896202           9
deed          57069           9
face          64206           9

Total count: 26

Word      Decimal value   Digital root
----------------------------------------
efface       15727310           8
deface       14613198           6
accede       11325150           9
decca         912586           4
face          64206           9
deaf          57007           1
cafe          51966           9
abed          44013           3

Total count: 13
```

## jq

Works with: jq

Works with gojq, the Go implementation of jq

Preliminaries

```def lpad(\$len): tostring | (\$len - length) as \$l | (" " * \$l)[:\$l] + .;

# . may be a decimal number or a string representing a decimal number
def digital_root:
# string-only version
def dr:
# state: [mdr, persist]
until( .[0] | length == 1;
[ (.[0] | explode | map(.-48) | add | tostring), .[1] + 1 ]
);
[tostring, 0] | dr | .[0] | tonumber;

# lowercase a-f
def isHexWord:
all(explode[]; 97 <= . and . <= 102);

# Input: a valid hex number (all lowercase)
def hex2i:
def toi: if . >= 87 then .-87 else . - 48 end;
reduce (explode | map(toi) | reverse[]) as \$i ([1, 0]; # [power, sum]
.[1] += \$i * .[0]
| .[0] *= 16 )
| .[1];```

```def task:

INDEX(inputs | select(length>=4 and isHexWord); .)
| reduce keys_unsorted[] as \$word ([];
(\$word | hex2i) as \$num
| (\$num | digital_root) as \$dr
| . + [[ \$word, \$num, \$dr]])
| sort_by( .[-1] )
| . as \$details

| (reduce .[] as \$line ([];
if \$line[0] | explode | unique | length >= 4
then . + [\$line] else . end)) as \$digits4

| "\(\$details|length) hex words with 4 or more letters were found:",
(\$details[] | format),
"",
"\(\$digits4|length) such words contain 4 or more different letters:",
((\$digits4|sort_by(.[1])|reverse[] ) | format) ;

Output:

Invocation

```< unixdict.txt jq -Rrn -f rc-hex-words.jq
```
```26 hex words with 4 or more letters were found:
ababa ->    703162 -> 1
abbe ->     43966 -> 1
deaf ->     57007 -> 1
cede ->     52958 -> 2
feed ->     65261 -> 2
abed ->     44013 -> 3
beebe ->    782014 -> 4
decca ->    912586 -> 4
deface ->  14613198 -> 6
babe ->     47806 -> 7
efface ->  15727310 -> 8
accede ->  11325150 -> 9
beef ->     48879 -> 9
cafe ->     51966 -> 9
dacca ->    896202 -> 9
deed ->     57069 -> 9
face ->     64206 -> 9

13 such words contain 4 or more different letters:
efface ->  15727310 -> 8
deface ->  14613198 -> 6
accede ->  11325150 -> 9
decca ->    912586 -> 4
face ->     64206 -> 9
deaf ->     57007 -> 1
cafe ->     51966 -> 9
abed ->     44013 -> 3
```

## Julia

```digroot(n) = (while n > 9 n = sum(digits(n)) end; n)

function hexwords(wordfile = "unixdict.txt")
filter!(w -> length(w) >= 4 && all(c -> c in "abcdef", w), words)
results = [[w, parse(Int, w, base = 16)] for w in words]
for a in results
pushfirst!(a, digroot(a[2]))
end
println("Hex words in \$wordfile:\nRoot  Word      Base 10\n", "-"^30)
for a in sort!(results)
end
println("Total count of these words: \$(length(results)).")
println("\nHex words with > 3 distinct letters:\nRoot  Word      Base 10\n", "-"^30)
filter!(a -> length(unique(a[2])) > 3, results)
for a in results
end
println("Total count of those words: \$(length(results)).")
end

hexwords()
```
Output:
```Hex words in unixdict.txt:
Root  Word      Base 10
------------------------------
1     ababa     703162
1     abbe      43966
1     deaf      57007
2     cede      52958
2     feed      65261
3     abed      44013
4     beebe     782014
4     decca     912586
6     deface    14613198
7     babe      47806
8     efface    15727310
9     accede    11325150
9     beef      48879
9     cafe      51966
9     dacca     896202
9     deed      57069
9     face      64206
Total count of these words: 26.

Hex words with > 3 distinct letters:
Root  Word      Base 10
------------------------------
1     deaf      57007
3     abed      44013
4     decca     912586
6     deface    14613198
8     efface    15727310
9     accede    11325150
9     cafe      51966
9     face      64206
Total count of those words: 13.
```

## Lua

```-- Import http namespace from socket library
http = require("socket.http")

function getFromWeb (url)
local body, statusCode, headers, statusText = http.request(url)
if statusCode == 200 then
return body
else
error(statusText)
end
end

-- Return a boolean to show whether word is a hexword
function isHexWord (word)
local hexLetters, ch = "abcdef"
for pos = 1, #word do
ch = word:sub(pos, pos)
if not string.find(hexLetters, ch) then return false end
end
return true
end

-- Return the sum of the digits in num
function sumDigits (num)
local sum, nStr, digit = 0, tostring(num)
for pos = 1, #nStr do
digit = tonumber(nStr:sub(pos, pos))
sum = sum + digit
end
return sum
end

-- Return the digital root of x
function digitalRoot (x)
while x > 9 do
x = sumDigits(x)
end
return x
end

-- Return a table from built from the lines of the string dct
-- Each table entry contains the digital root, word and base 10 conversion
function buildTable (dct)
local t, base10 = {}
for line in dct:gmatch("[^\n]+") do
if # line > 3 and isHexWord(line) then
base10 = (tonumber(line, 16))
table.insert(t, {digitalRoot(base10), line, base10})
end
end
table.sort(t, function (a,b) return a[1] < b[1] end)
return t
end

-- Return a boolean to show whether str has at least 4 distinct characters
function fourDistinct (str)
local distinct, ch = ""
for pos = 1, #str do
ch = str:sub(pos, pos)
if not string.match(distinct, ch) then
distinct = distinct .. ch
end
end
return #distinct > 3
end

-- Unpack each entry in t and print to the screen
function showTable (t)
print("\n\nRoot\tWord\tBase 10")
print("====\t====\t=======")
for i, v in ipairs(t) do
print(unpack(v))
end
print("\nTable length: " .. #t)
end

-- Main procedure
local dict = getFromWeb("http://wiki.puzzlers.org/pub/wordlists/unixdict.txt")
local hexWords = buildTable(dict)
showTable(hexWords)
local hexWords2 = {}
for k, v in pairs(hexWords) do
if fourDistinct(v[2]) then
table.insert(hexWords2, v)
end
end
table.sort(hexWords2, function (a, b) return a[3] > b[3] end)
showTable(hexWords2)
```
Output:
```
Root    Word    Base 10
====    ====    =======
1       ababa   703162
1       deaf    57007
1       abbe    43966
2       cede    52958
2       feed    65261
3       abed    44013
4       decca   912586
4       beebe   782014
6       deface  14613198
7       babe    47806
8       efface  15727310
9       face    64206
9       accede  11325150
9       cafe    51966
9       deed    57069
9       beef    48879
9       dacca   896202

Table length: 26

Root    Word    Base 10
====    ====    =======
8       efface  15727310
6       deface  14613198
9       accede  11325150
4       decca   912586
9       face    64206
1       deaf    57007
9       cafe    51966
3       abed    44013

Table length: 13```

## Nim

```import std/[algorithm, setutils, strformat, strutils]

const LowerHexDigits = {'a'..'f'}

type Item = tuple[word: string; value, droot: int]

iterator digits(n: Natural): Natural =
## Yield the digits of a natural.
var n = n
while true:
yield n mod 10
n = n div 10
if n == 0:
break

func digitalRoot(n: Natural): Natural =
## Return the digital root of a natural.
var n = n
while true:
result = 0
for d in n.digits:
result += d
if result <= 9:
break
n = result

proc display(items: seq[Item]) =
## Display the items.
echo "Word     Decimal value   Digital root"
echo repeat("─", 39)
for item in items:
echo &"{item.word:<8}{item.value:>12}{item.droot:12}"
echo "\nTotal count: ", items.len

# Build the list of items.
var items: seq[Item]
for word in lines("unixdict.txt"):
if word.len >= 4 and card(word.toSet - LowerHexDigits) == 0:
let val = word.parseHexInt()

# Sort the items by increasing digital root and display the result.
echo "Hex words in “unixdict.txt”:\n"
items = items.sortedByIt(it.droot)
items.display()

# Remove the items with less than 4 distinct letters.
for i in countdown(items.high, 0):
if card(items[i].word.toSet) < 4:
items.delete i

# Sort the items by decreasing value and display the result.
echo "\n\nHex words with more than three distinct letters:\n"
items = items.sortedByIt(-it.value)
items.display()
```
Output:
```Hex words in “unixdict.txt”:

Word     Decimal value   Digital root
───────────────────────────────────────
ababa         703162           1
abbe           43966           1
deaf           57007           1
cede           52958           2
feed           65261           2
abed           44013           3
beebe         782014           4
decca         912586           4
deface      14613198           6
babe           47806           7
efface      15727310           8
accede      11325150           9
beef           48879           9
cafe           51966           9
dacca         896202           9
deed           57069           9
face           64206           9

Total count: 26

Hex words with more than three distinct letters:

Word     Decimal value   Digital root
───────────────────────────────────────
efface      15727310           8
deface      14613198           6
accede      11325150           9
decca         912586           4
face           64206           9
deaf           57007           1
cafe           51966           9
abed           44013           3

Total count: 13
```

## Perl

```#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Hex_words
use warnings;
use List::AllUtils qw( nsort_by uniq );

sub root
{
local \$_ = shift;
\$_ = eval while s/\B/+/g;
return \$_;
}

my @bydecimal = grep +(uniq /[a-f]/g)[3],
my @byroot = map { sprintf "%10s %10d %3d\n", \$_, hex \$_, root hex \$_
} do { local(@ARGV, \$/) = 'unixdict.txt'; <> =~ /^[a-f]{4,}\$/gm };

print +(nsort_by { (split ' ')[2] } @byroot),
"total count = @{[ scalar @byroot ]} and @{[ scalar @bydecimal
]} have at least 4 distinct digits\n",
reverse nsort_by { (split ' ')[1] } @bydecimal;
```
Output:
```     ababa     703162   1
abbe      43966   1
deaf      57007   1
cede      52958   2
feed      65261   2
abed      44013   3
beebe     782014   4
decca     912586   4
deface   14613198   6
babe      47806   7
efface   15727310   8
accede   11325150   9
beef      48879   9
cafe      51966   9
dacca     896202   9
deed      57069   9
face      64206   9
total count = 26 and 13 have at least 4 distinct digits
efface   15727310   8
deface   14613198   6
accede   11325150   9
decca     912586   4
face      64206   9
deaf      57007   1
cafe      51966   9
abed      44013   3
```

## Phix

```with javascript_semantics
function af(string s) return max(s)<='f' and min(s)>='a' end function
function digital_root(integer n)
assert(n>=0)
while n>9 do
integer tot = 0
while n>0 do
tot += remainder(n,10)
n = floor(n/10)
end while
n = tot
end while
return n
end function
sequence words = filter(unix_dict(4),af),
decml = apply(true,to_integer,{words,0,16}),
roots = apply(decml,digital_root),
tags = custom_sort(roots,tagset(length(roots)))

function caejasp() -- columnize/apply/extract/join/apply/sprint(...)
sequence s = columnize(apply(true,extract,{{words,decml,roots},{tags}}))
return join(apply(true,sprintf,{{"%6s -> %8d -> %d\n"},s}))
end function
printf(1," %s\n %d hex words with 4 or more letters found,\n",{caejasp(),length(tags)})
function ge4(integer t) return length(unique(words[t]))>=4 end function
tags = filter(tags,ge4)
tags = extract(tags,reverse(custom_sort(extract(decml,tags),tagset(length(tags)))))
printf(1," %d with 4 or more distinct characters:\n\n %s\n",{length(tags),caejasp()})
```
Output:
```  ababa ->   703162 -> 1
abbe ->    43966 -> 1
deaf ->    57007 -> 1
cede ->    52958 -> 2
feed ->    65261 -> 2
abed ->    44013 -> 3
beebe ->   782014 -> 4
decca ->   912586 -> 4
deface -> 14613198 -> 6
babe ->    47806 -> 7
efface -> 15727310 -> 8
accede -> 11325150 -> 9
beef ->    48879 -> 9
cafe ->    51966 -> 9
dacca ->   896202 -> 9
deed ->    57069 -> 9
face ->    64206 -> 9

26 hex words with 4 or more letters found,
13 with 4 or more distinct characters:

efface -> 15727310 -> 8
deface -> 14613198 -> 6
accede -> 11325150 -> 9
decca ->   912586 -> 4
face ->    64206 -> 9
deaf ->    57007 -> 1
cafe ->    51966 -> 9
abed ->    44013 -> 3
```

## Python

```def digroot(n):
while n > 9:
n = sum([int(d) for d in str(n)])
return n

with open('unixdict.txt') as f:
lines = [w.strip() for w in f.readlines()]
words = [w for w in lines if len(w) >= 4 and all(c in 'abcdef' for c in w)]
results = [[w, int(w, 16)] for w in words]
for a in results:
a.append(digroot(a[1]))

print(f"Hex words in unixdict.txt:\nRoot  Word      Base 10\n", "-"*22)
for a in sorted(results, key=lambda x:x[2]):
print(f"{a[2]}     {a[0]:6}{a[1]:10}")

print("Total count of these words:", len(results))
print("\nHex words with > 3 distinct letters:\nRoot  Word      Base 10\n", "-"*22)
results = [a for a in results if len(set(str(a[0]))) > 3]
for a in sorted(results, key=lambda x:x[2]):
print(f"{a[2]}     {a[0]:6}{a[1]:10}")

print("Total count of those words:", len(results))
```
Output:
```Hex words in unixdict.txt:
Root  Word      Base 10
----------------------
1     ababa     703162
1     abbe       43966
1     deaf       57007
2     cede       52958
2     feed       65261
3     abed       44013
4     beebe     782014
4     decca     912586
6     deface  14613198
7     babe       47806
8     efface  15727310
9     accede  11325150
9     beef       48879
9     cafe       51966
9     dacca     896202
9     deed       57069
9     face       64206
Total count of these words: 26

Hex words with > 3 distinct letters:
Root  Word      Base 10
----------------------
1     deaf       57007
3     abed       44013
4     decca     912586
6     deface  14613198
8     efface  15727310
9     accede  11325150
9     cafe       51966
9     face       64206
Total count of those words: 13
```

## Quackery

```  [ 1 - 9 mod 1+ ]          is digitalroot (   n --> n )

[ 0 swap witheach
[ bit | ]
0 swap
[ dup while
tuck 1 & +
swap 1 >>
again ]
drop ]                  is uniques     (   \$ --> n )

[ tuck space swap of
join
swap split drop echo\$ ] is lecho\$      ( \$ n -->   )

\$ 'rosetta/unixdict.txt' sharefile drop
nest\$
[] swap witheach
[ dup size 4 < iff drop done
true over witheach
[ char a char g within
not if [ conclude not ] ]
iff [ nested join ]
else drop ]
16 base put
[] swap witheach
[ dup dip nested
\$->n drop join
nested join ]
base release
[] swap witheach
[ dup 1 peek
digitalroot
join nested join ]
dup
sortwith [ 2 peek swap 2 peek < ]
witheach
[ unpack echo sp
swap 6 lecho\$
sp echo cr ]
dup size echo say " words"
cr cr
[] swap witheach
[ dup 0 peek
uniques 4 < iff
drop
else [ nested join ] ]
sortwith [ 1 peek swap 1 peek > ]
dup
witheach
[ unpack echo sp
swap 6 lecho\$
sp echo cr ]
size echo say " words"```
Output:
```1 ababa  703162
1 abbe   43966
1 deaf   57007
2 cede   52958
2 feed   65261
3 abed   44013
4 beebe  782014
4 decca  912586
6 deface 14613198
7 babe   47806
8 efface 15727310
9 accede 11325150
9 beef   48879
9 cafe   51966
9 dacca  896202
9 deed   57069
9 face   64206
26 words

8 efface 15727310
6 deface 14613198
9 accede 11325150
4 decca  912586
9 face   64206
1 deaf   57007
9 cafe   51966
3 abed   44013
13 words```

## Raku

Sorted by digital root with a secondary alphabetical sort.

```sub dr (Int \$_ is copy) { \$_ = dr(.comb.sum) while .chars > 1; \$_ }

my %hex = './unixdict.txt'.IO.slurp.words.grep( *.chars > 3 )\
.grep({ not / <-[abcdef]> / }).map: { \$_ => dr :16(\$_).comb.sum }

say "{+%hex} hex words longer than 3 characters found in unixdict.txt:";
printf "%6s ➡ %8d ➡ %d\n", .key, :16(.key), .value for %hex.sort: { .value, .key }

my %many = %hex.grep: +*.key.comb.Set > 3;

say "\nOf which {+%many} contain at least four distinct characters:";
printf "%6s ➡ %8d ➡ %d\n", .key, :16(.key), .value for %many.sort: { -:16(.key) }
```
Output:
```26 hex words longer than 3 characters found in unixdict.txt:
ababa ➡   703162 ➡ 1
abbe ➡    43966 ➡ 1
deaf ➡    57007 ➡ 1
cede ➡    52958 ➡ 2
feed ➡    65261 ➡ 2
abed ➡    44013 ➡ 3
beebe ➡   782014 ➡ 4
decca ➡   912586 ➡ 4
deface ➡ 14613198 ➡ 6
babe ➡    47806 ➡ 7
efface ➡ 15727310 ➡ 8
accede ➡ 11325150 ➡ 9
beef ➡    48879 ➡ 9
cafe ➡    51966 ➡ 9
dacca ➡   896202 ➡ 9
deed ➡    57069 ➡ 9
face ➡    64206 ➡ 9

Of which 13 contain at least four distinct characters:
efface ➡ 15727310 ➡ 8
deface ➡ 14613198 ➡ 6
accede ➡ 11325150 ➡ 9
decca ➡   912586 ➡ 4
face ➡    64206 ➡ 9
deaf ➡    57007 ➡ 1
cafe ➡    51966 ➡ 9
abed ➡    44013 ➡ 3```

## Ring

```Author = "Gál Zsolt (CalmoSoft)"

Words = []
HexWords = ["a","b","c","d","e","f"]
Unix = str2list(cstr)
Unix2 = []
for n = 1 to len(Unix)
uStr = Unix[n]
for m = 1 to len(uStr)
flag =1
ind = find(HexWords,uStr[m])
if ind = 0
flag = 0
exit
ok
next
if flag = 1 and len(Unix[n]) > 3
ok
next

Unix1 = newlist(len(Words),2)
for n = 1 to len(Words)
num = dec(Words[n])
dr = digRoot(num)
Unix1[n][1] = dr
Unix1[n][2] = Words[n]
next

Unix1 = sortFirstSecondStr(Unix1,1)

see "Root" + space(2) + "Word" + space(5) + "Base 10" + nl
see "====" + space(2) + "====" + space(5) + "=======" + nl
for n = 1 to len(Unix1)
decnr = dec(Unix1[n][2])
see string(Unix1[n][1]) + space(5) + Unix1[n][2] + space(9-len(Unix1[n][2])) + decnr + nl
next

see nl + "Table length: " + len(Unix1) + nl + nl + nl

see "Root" + space(2) + "Word" + space(5) + "Base 10" + nl
see "====" + space(2) + "====" + space(5) + "=======" + nl

for n = 1 to len(Unix2)
str = Unix2[n]
str2 = sortStr(str)
flag = 0
for p = 1 to len(str2)-1
st1 = substr(str2,p,1)
st2 = substr(str2,p+1,1)
if dec(st1) < dec(st2)
flag += 1
ok
next
if flag < 4
del(Unix2,n)
ok
next

DecSort = []
for n = 1 to len(Unix2)
ds = dec(Unix2[n])
next
DecSort = sort(DecSort)
DecSort = reverse(DecSort)

for n = 1 to len(DecSort)
root = digRoot(DecSort[n])
word = hex(DecSort[n])
decnum = DecSort[n]
see "" + root + space(5) + word + space(9-len(word)) + decnum + nl
next

see nl + "Table length: " + len(DecSort) + nl

func digRoot(num2)
while true
strnr = string(num2)
sum = 0
for n = 1 to len(strnr)
sum += number(strnr[n])
next
if sum < 10
exit
else
num2 = sum
ok
end
return sum

func sortStr(str2)
for p = 1 to len(str2)
for q = p+1 to len(str2)
if strcmp(str2[q],str2[p]) < 0
temp = str2[p]
str2[p] = str2[q]
str2[q] = temp
ok
next
next
return str2

func sortFirstSecondStr(aList,ind)
aList = sort(aList,ind)
if (ind = 1)
nr = 2
else
nr = 1
ok
for n=1 to len(alist)-1
for m=n+1 to len(aList)
if (alist[n][ind] = alist[m][ind]) and
(strcmp(alist[m][nr],alist[n][nr]) < 0)
temp = alist[m]
alist[m] = alist[n]
alist[n] = temp
ok
next
next
return aList```
Output:
```
Root     Word       Base 10
====  ====     ======
1         ababa          703162
1         abbe             43966
1         deaf              57007
2         cede             52958
2         feed              65261
3         abed             44013
4         beebe         782014
4         decca         912586
6         deface    14613198
7         babe            47806
8         efface     15727310
9         accede   11325150
9         beef            48879
9         cafe            51966
9         dacca        896202
9         deed           57069
9         face            64206

Table length: 26

Root     Word       Base 10
====  ====     ======
6         deface     14613198
9         accede    11325150
9         deed            57069
2         cede            52958
9         beef            48879
7         babe           47806
1         abbe           43966

Table length: 13
```

## RPL

```≪ → words
≪ { }
1 words SIZE FOR w
words w GET
IF DUP SIZE 4 ≥ THEN
"abcdef" 1 SF
1 3 PICK SIZE FOR c
DUP2 SWAP c DUP SUB
IF POS NOT THEN 1 CF 99 'c' STO END
NEXT DROP
IF 1 FS? THEN + ELSE DROP END
ELSE DROP END
NEXT
≫ ≫ 'HXWORDS' STO

≪ 4 UnixDict HXWORDS 0 0
→ diff hexwords value maxroot
≪ { }
1 hexwords SIZE FOR h
hexwords h GET
"" 0 'value' STO
1 3 PICK SIZE FOR c
OVER c DUP SUB
IF DUP2 POS NOT THEN SWAP OVER + SWAP END
NUM 87 - value 16 * + 'value' STO
NEXT
IF SIZE diff < THEN DROP
ELSE
value 1 - 9 MOD 1 +
DUP maxroot MAX 'maxroot' STO
SWAP value
3 →LIST 1 →LIST +
END
NEXT
'hexwords' STO { }
1 maxroot FOR r
1 hexwords SIZE FOR h
hexwords h GET
IF DUP 1 GET r == THEN 1 →LIST + ELSE DROP END
NEXT NEXT
```
Output:
```1: { { 1 "deaf" 57007 } { 1 "decade" 14600926 } { 3 "abed" 44013 } { 3 "bade" 47838 } { 4 "decca" 912586 } { 6 "bead" 48813 } { 6 "deface" 14613198 } { 7 "fade" 64222 } { 8 "efface" 15727310 } { 8 "facade" 16435934 } { 9 "accede" 11325150 } { 9 "cafe" 51966 } { 9 "face" 64206 } }
```

## Ruby

```def report(a)
puts
a.each {|hexword| puts "%6s  %8d  %d" % hexword}
puts "Total count of these words: #{a.size}"
end

hexwords = File.readlines("unixdict.txt", chomp: true).reject{|w| w.size < 4 || w.match?(/[^abcdef]/) }
res = hexwords.map{|hw| [hw, hw.to_i(16), 1 + (hw.to_i(16) - 1) % 9]}.sort_by(&:last)
report( res )
report( res.reject{|hw| hw[0].chars.uniq.size < 4}.sort_by{|w| -w[1]} )
```
Output:
``` ababa    703162  1
abbe     43966  1
deaf     57007  1
cede     52958  2
feed     65261  2
abed     44013  3
beebe    782014  4
decca    912586  4
deface  14613198  6
babe     47806  7
efface  15727310  8
accede  11325150  9
beef     48879  9
cafe     51966  9
dacca    896202  9
deed     57069  9
face     64206  9
Total count of these words: 26

efface  15727310  8
deface  14613198  6
accede  11325150  9
decca    912586  4
face     64206  9
deaf     57007  1
cafe     51966  9
abed     44013  3
Total count of these words: 13
```

## V (Vlang)

Translation of: wren
```import os
import strconv
import math

fn digital_root(nn i64) i64 {
mut n := nn
for n>9 {
mut tot := i64(0)
for n>0 {
tot += n%10
n = int(math.floor(n/10))
}
n = tot
}
return n
}

fn main() {
hex_digits := 'abcdef'
mut lines := [][]string{}
//println(words)
for word in words {
if word.len < 4 {
continue
}
if word.split('').all(hex_digits.index(it) or {-1} >= 0) {
num := strconv.parse_int(word, 16, 32) or {-1}
lines << [word, num.str(), digital_root(num).str()]
}
}
lines.sort_with_compare(fn(mut a []string, mut b []string) int {
if a[2].int()<b[2].int(){
return -1
}else if a[2].int()>b[2].int(){
return 1
}
return 0
})
for line in lines {
println('\${line[0]:8} -> \${line[1]:9} -> \${line[2]}')
}
println('\$lines.len hex words with 4 or more letters found')
lines = lines.filter(fn (a []string) bool {
mut s := map[string]bool{}
for t in a[0].split('') {
if t !in s {
s[t] = true
}
}
return s.len > 3
})
for line in lines {
println('\${line[0]:8} -> \${line[1]:9} -> \${line[2]}')
}
println('\$lines.len hex words with 4 or more distinct letters found')
}```
Output:
`Same as wren entry`

## Wren

Library: Wren-ioutil
Library: Wren-fmt
Library: Wren-math
Library: Wren-seq
```import "./ioutil" for FileUtil
import "./fmt" for Conv, Fmt
import "./math" for Int
import "./seq" for Lst

var words = FileUtil.readLines("unixdict.txt").where { |w| w.count > 0 && w[0].bytes[0] < 103 }
var hexDigits = "abcdef"
var lines = []
for (word in words) {
if (word.count < 4) continue
if (word.all { |c| hexDigits.contains(c) }) {
var num = Conv.atoi(word, 16)
var dr = Int.digitalRoot(num)[0]
lines.add(Fmt.swrite("\$-7s -> \$-9s -> \$d", word, num, dr))
}
}
lines.sort { |a, b| a[-1].bytes[0] < b[-1].bytes[0] }
System.print(lines.join("\n"))
System.print("\n%(lines.count) hex words with 4 or more letters found.\n")
var digits4 = []
for (line in lines) {
var word = line.split("->")[0].trimEnd()
}
digits4.sort { |a, b| Num.fromString(a.split("->")[1]) > Num.fromString(b.split("->")[1]) }
System.print(digits4.join("\n"))
System.print("\n%(digits4.count) such words found which contain 4 or more different digits.")
```
Output:
```decade  -> 14600926  -> 1
ababa   -> 703162    -> 1
abbe    -> 43966     -> 1
deaf    -> 57007     -> 1
feed    -> 65261     -> 2
cede    -> 52958     -> 2
abed    -> 44013     -> 3
decca   -> 912586    -> 4
beebe   -> 782014    -> 4
deface  -> 14613198  -> 6
babe    -> 47806     -> 7
efface  -> 15727310  -> 8
dacca   -> 896202    -> 9
beef    -> 48879     -> 9
cafe    -> 51966     -> 9
deed    -> 57069     -> 9
face    -> 64206     -> 9
accede  -> 11325150  -> 9

26 hex words with 4 or more letters found.

efface  -> 15727310  -> 8
deface  -> 14613198  -> 6