Alternade words
An alternade is a word whose alternating letters themselves form two words.
- Example
The word lounge contains the word lug (lounge) and the word one (lounge).
For a word to be an alternade, all its letters must be used.
The two words that form an alternade don't need to be the same length; for example, the word board is an alternade made up of the words bad (board) and or (board).
- Task
Print out every alternade in unixdict.txt whose length is 6 or greater, also showing both the words that make up the alternade.
- See also
-
- Wikipedia entry: Alternade
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contain the most consonants
- Find words which contains more than 3 vowels
- Find words whose first and last three letters are equal
- Find words with alternating vowels and consonants
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 bottles of beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
11l
F alternating_words(word)
V r = [‘’, ‘’]
L(c) word
r[L.index [&] 1] ‘’= c
R r
V words = Set(File(‘unixdict.txt’).read().split("\n"))
[String] result
L(word) words
I word.len >= 6
V alt_words = alternating_words(word)
I alt_words[0] C words & alt_words[1] C words
result.append(word.rjust(8)‘ → ’alt_words[0]‘ ’alt_words[1])
result.sort()
L(line) result
V i = L.index
print((‘#2:’.format(i + 1))‘ ’line)
- Output:
1: accost → acs cot 2: accuse → acs cue 3: afield → ail fed 4: agleam → ala gem 5: alcott → act lot 6: allele → all lee 7: allied → ale lid 8: alpert → apr let 9: apport → apr pot 10: assist → ass sit 11: battle → btl ate 12: blaine → ban lie 13: brenda → bed rna 14: choose → cos hoe 15: choosy → cos hoy 16: claire → car lie 17: effete → eft fee 18: fabric → fbi arc 19: fealty → fat ely 20: fluent → fun let 21: friend → fin red 22: george → gog ere 23: inroad → ira nod 24: israel → ire sal 25: jaunty → jut any 26: joanne → jan one 27: lounge → lug one 28: oriole → oil roe 29: oswald → owl sad 30: parrot → pro art 31: peoria → poi era 32: pierre → per ire 33: poodle → pol ode 34: pounce → puc one 35: racial → rca ail 36: realty → rat ely 37: sordid → sri odd 38: sprain → sri pan 39: strain → sri tan 40: strait → sri tat 41: sturdy → sud try 42: sweaty → set way 43: tattle → ttl ate 44: though → tog huh 45: triode → tid roe 46: triune → tin rue 47: troupe → top rue 48: truant → tun rat 49: twirly → til wry 50: ambient → abet min 51: annette → ante net 52: ariadne → aide ran 53: collude → clue old 54: forwent → fret own 55: spatial → sail pta 56: theorem → term hoe 57: throaty → tray hot 58: calliope → clip aloe
Ada
with Ada.Text_Io;
with Ada.Containers.Indefinite_Ordered_Maps;
procedure Alternade_Words is
use Ada.Text_Io;
package String_Maps is
new Ada.Containers.Indefinite_Ordered_Maps (Key_Type => String,
Element_Type => String);
function Get_Odd (Word : String) return String is
Odd : String (1 .. (Word'Length + 1) / 2);
begin
for Index in Odd'Range loop
Odd (Index) := Word (1 + 2 * (Index - 1));
end loop;
return Odd;
end Get_Odd;
function Get_Even (Word : String) return String is
Even : String (1 .. Word'Length / 2);
begin
for Index in Even'Range loop
Even (Index) := Word (1 + 1 + 2 * (Index - 1));
end loop;
return Even;
end Get_Even;
Filename : constant String := "unixdict.txt";
Words : String_Maps.Map;
File : File_Type;
begin
Open (File, In_File, Filename);
while not End_Of_File (File) loop
declare
Word : constant String := Get_Line (File);
begin
Words.Insert (Word, Word);
end;
end loop;
Close (File);
for Word of Words loop
declare
Odd : constant String := Get_Odd (Word);
Even : constant String := Get_Even (Word);
begin
if
Word'Length >= 6 and then
Words.Contains (Odd) and then
Words.Contains (Even)
then
Put (Word);
Set_Col (15); Put (Odd);
Set_Col (25); Put (Even);
New_Line;
end if;
end;
end loop;
end Alternade_Words;
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
ALGOL 68
Note, the sources of files.incl.a68 and sort.incl.a68 are on separate pages on Rosetta Code - see the above links.
BEGIN # find alternade words (words whose alternate letters also form words) #
PR read "files.incl.a68" PR # include file utilities #
PR read "sort.incl.a68" PR # include sort utilities #
# returns w split into n parts by taking alternate characters #
PRIO SPLIT = 1;
OP SPLIT = ( STRING w, INT n )[]STRING:
BEGIN
[ n ]STRING result;
FOR init pos FROM LWB result TO UPB result DO result[ init pos ] := "" OD;
INT r pos := 1;
FOR w pos FROM LWB w TO UPB w DO
result[ r pos ] +:= w[ w pos ];
r pos +:= 1;
IF r pos > n THEN r pos := 1 FI
OD;
result
END # SPLIT # ;
[ 1 : 30 000 ]STRING words;
# stores word in words #
# count so far will contain the number of words stored so far #
# returns TRUE #
PROC store words = ( STRING word, INT count so far )BOOL:
BEGIN
words[ count so far + 1 ] := word;
TRUE
END # store words # ;
# returns TRUE if words[ low : high ] comntains s, FALSE otherwise #
PROC is word = ( STRING s, INT low, high )BOOL:
IF high < low THEN FALSE
ELSE INT mid = ( low + high ) OVER 2;
IF words[ mid ] > s THEN is word( s, low, mid - 1 )
ELIF words[ mid ] = s THEN TRUE
ELSE is word( s, mid + 1, high )
FI
FI # is word # ;
IF INT w count = "unixdict.txt" EACHLINE store words;
w count < 0
THEN print( ( "Unable to open unixdict.txt", newline ) )
ELSE words QUICKSORT ELEMENTS( 1, w count ); # sort the words #
FOR i TO w count DO # find the alternades #
STRING word = words[ i ];
IF INT w len = ( UPB word - LWB word ) + 1;
w len > 5
THEN # word is at least 6 characters long #
[]STRING sub word = word SPLIT 2;
IF is word( sub word[ 1 ], 1, w count )
AND is word( sub word[ 2 ], 1, w count )
THEN print( ( word, ": " ) );
TO 18 - w len DO print( ( " " ) ) OD;
print( ( sub word[ 1 ], ", ", sub word[ 2 ], newline ) )
FI
FI
OD
FI
END
- Output:
accost: acs, cot accuse: acs, cue afield: ail, fed agleam: ala, gem alcott: act, lot allele: all, lee allied: ale, lid alpert: apr, let ambient: abet, min annette: ante, net apport: apr, pot ariadne: aide, ran assist: ass, sit battle: btl, ate blaine: ban, lie brenda: bed, rna calliope: clip, aloe choose: cos, hoe choosy: cos, hoy claire: car, lie collude: clue, old effete: eft, fee fabric: fbi, arc fealty: fat, ely fluent: fun, let forwent: fret, own friend: fin, red george: gog, ere inroad: ira, nod israel: ire, sal jaunty: jut, any joanne: jan, one lounge: lug, one oriole: oil, roe oswald: owl, sad parrot: pro, art peoria: poi, era pierre: per, ire poodle: pol, ode pounce: puc, one racial: rca, ail realty: rat, ely sordid: sri, odd spatial: sail, pta sprain: sri, pan strain: sri, tan strait: sri, tat sturdy: sud, try sweaty: set, way tattle: ttl, ate theorem: term, hoe though: tog, huh throaty: tray, hot triode: tid, roe triune: tin, rue troupe: top, rue truant: tun, rat twirly: til, wry
APL
alternade←{
⍺←6
parts←{(⊂k/⍵),⊂(~k←2|⍳≢⍵)/⍵}
check←∊∘(words←(~words∊⎕TC)⊆words←⊃⎕NGET⍵)
long←(⍺≤≢¨words)/words
↑(⊂,parts)¨(∧/∘check∘parts¨long)/long
}
- Output:
alternade'p:\test\unixdict.txt' accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
AppleScript
use AppleScript version "2.3.1" -- OS X 10.9 (Mavericks) or later
use sorter : script ¬
"Custom Iterative Ternary Merge Sort" --<www.macscripter.net/t/timsort-and-nigsort/71383/3>
use scripting additions
on binarySearch(v, theList, l, r)
script o
property lst : theList
end script
repeat until (l = r)
set m to (l + r) div 2
if (o's lst's item m < v) then
set l to m + 1
else
set r to m
end if
end repeat
if (o's lst's item l = v) then return l
return 0
end binarySearch
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
on alternades(inputList, subsPerAlternade, minAlternadeLen, outputType)
script o
property wordList : inputList's items
property searchRanges : {}
property output : {}
-- Custom comparison handler for the sort.
on isGreater(a, b)
set lenA to a's length
set lenB to b's length
if (lenA = lenB) then return (a > b)
return (lenA > lenB)
end isGreater
on finish()
if (outputType is text) then set output to join(output, linefeed)
return output
end finish
end script
set wordCount to (count o's wordList)
if (wordCount ≤ subsPerAlternade) then return o's finish()
-- Sort the word list ascending by length, lexically within lengths.
tell sorter to sort(o's wordList, 1, wordCount, {comparer:o})
-- Deduce the maximum possible "subword" length from the length of the longest word.
set maxWordLen to o's wordList's end's length
if (maxWordLen < minAlternadeLen) then return o's finish()
set maxSubLen to (maxWordLen + subsPerAlternade - 1) div subsPerAlternade
-- Give the searchRanges list that many slots.
repeat maxSubLen times
set end of o's searchRanges to missing value
end repeat
-- For each word length in wordlist that's suitable for a subword, set the same-numbered slot in
-- searchRanges to the range indices of the wordList range covering the words of that length.
-- Also find the index in wordList of the first word whose length ≥ minAlternadeLen.
set minSubLen to minAlternadeLen div subsPerAlternade
set minAltLenStart to 1
set i to 1
set currentLength to o's wordList's beginning's length
repeat with j from 2 to wordCount
set wordLen to o's wordList's item j's length
if (wordLen > currentLength) then
if ((currentLength ≥ minSubLen) and (currentLength ≤ maxSubLen)) then
set o's searchRanges's item currentLength to {i, j - 1}
if (wordLen ≥ minAlternadeLen) then
if (minAltLenStart = 1) then
set minAltLenStart to j
else if (wordLen > maxSubLen) then
exit repeat
end if
end if
end if
set i to j
set currentLength to wordLen
end if
end repeat
-- Extract subtexts from words having minAlternadeLen or more characters and see if they match
-- words from the same-length ranges in wordList. Append any hits to the output.
if (outputType is text) then set end of o's output to ""
repeat with w from minAltLenStart to wordCount -- Per long-enough word.
set thisWord to o's wordList's item w
set wordLen to thisWord's length
set foundSubs to {}
repeat with s from 1 to subsPerAlternade -- Per subword.
set sub to thisWord's character s
repeat with c from (s + subsPerAlternade) to wordLen by subsPerAlternade -- Per chr.
set sub to sub & thisWord's character c
end repeat
set range to o's searchRanges's item (sub's length)
if ((range = missing value) or ¬
(binarySearch(sub, o's wordList, range's beginning, range's end) = 0)) then ¬
exit repeat
set end of foundSubs to sub
end repeat
if ((count foundSubs) = subsPerAlternade) then
if (outputType is text) then
set beginning of foundSubs to thisWord & ":"
set end of o's output to join(foundSubs, tab & tab)
else
set end of o's output to {alternade:thisWord, subs:foundSubs}
end if
end if
end repeat
return o's finish()
end alternades
-- Task code:
local wordFile, wordList
set wordFile to ((path to desktop as text) & "www.rosettacode.org:unixdict.txt") as «class furl»
set wordList to words of (read wordFile as «class utf8»)
-- Return two-word alternades of 6 or more characters. Result as text (as opposed to list).
return alternades(wordList, 2, 6, text)
- Output:
"
accost: acs cot
accuse: acs cue
afield: ail fed
agleam: ala gem
alcott: act lot
allele: all lee
allied: ale lid
alpert: apr let
apport: apr pot
assist: ass sit
battle: btl ate
blaine: ban lie
brenda: bed rna
choose: cos hoe
choosy: cos hoy
claire: car lie
effete: eft fee
fabric: fbi arc
fealty: fat ely
fluent: fun let
friend: fin red
george: gog ere
inroad: ira nod
israel: ire sal
jaunty: jut any
joanne: jan one
lounge: lug one
oriole: oil roe
oswald: owl sad
parrot: pro art
peoria: poi era
pierre: per ire
poodle: pol ode
pounce: puc one
racial: rca ail
realty: rat ely
sordid: sri odd
sprain: sri pan
strain: sri tan
strait: sri tat
sturdy: sud try
sweaty: set way
tattle: ttl ate
though: tog huh
triode: tid roe
triune: tin rue
troupe: top rue
truant: tun rat
twirly: til wry
ambient: abet min
annette: ante net
ariadne: aide ran
collude: clue old
forwent: fret own
spatial: sail pta
theorem: term hoe
throaty: tray hot
calliope: clip aloe"
Arturo
words: map read.lines relative "unixdict.txt" => strip
loop words 'word [
sw: new size word
if 6 > sw ->
continue
dec 'sw
alt1: join map select 0..sw => odd? 'x -> word\[x]
alt2: join map select 0..sw => even? 'x -> word\[x]
if and? [contains? words alt1][contains? words alt2] ->
print [word "=>" alt1 alt2]
]
- Output:
accost => cot acs accuse => cue acs afield => fed ail agleam => gem ala alcott => lot act allele => lee all allied => lid ale alpert => let apr ambient => min abet annette => net ante apport => pot apr ariadne => ran aide assist => sit ass battle => ate btl blaine => lie ban brenda => rna bed calliope => aloe clip choose => hoe cos choosy => hoy cos claire => lie car collude => old clue effete => fee eft fabric => arc fbi fealty => ely fat fluent => let fun forwent => own fret friend => red fin george => ere gog inroad => nod ira israel => sal ire jaunty => any jut joanne => one jan lounge => one lug oriole => roe oil oswald => sad owl parrot => art pro peoria => era poi pierre => ire per poodle => ode pol pounce => one puc racial => ail rca realty => ely rat sordid => odd sri spatial => pta sail sprain => pan sri strain => tan sri strait => tat sri sturdy => try sud sweaty => way set tattle => ate ttl theorem => hoe term though => huh tog throaty => hot tray triode => roe tid triune => rue tin troupe => rue top truant => rat tun twirly => wry til
AutoHotkey
FileRead, db, % A_Desktop "\unixdict.txt"
words := [], sixWords := []
for i, w in StrSplit(db, "`n", "`r")
if (StrLen(w) >= 6)
sixWords[w] := true
else
Words[w] := true
for w in sixWords
{
w1 := w2 := ""
for j, letter in StrSplit(w)
if Mod(j, 2)
w1 .= letter
else
w2 .= letter
if words[w1] && words[w2]
result .= w "`t-> " w1 " " w2 "`n"
}
MsgBox % result
- Output:
accost -> acs cot accuse -> acs cue afield -> ail fed agleam -> ala gem alcott -> act lot allele -> all lee allied -> ale lid alpert -> apr let ambient -> abet min annette -> ante net apport -> apr pot ariadne -> aide ran assist -> ass sit battle -> btl ate blaine -> ban lie brenda -> bed rna calliope -> clip aloe choose -> cos hoe choosy -> cos hoy claire -> car lie collude -> clue old effete -> eft fee fabric -> fbi arc fealty -> fat ely fluent -> fun let forwent -> fret own friend -> fin red george -> gog ere inroad -> ira nod israel -> ire sal jaunty -> jut any joanne -> jan one lounge -> lug one oriole -> oil roe oswald -> owl sad parrot -> pro art peoria -> poi era pierre -> per ire poodle -> pol ode pounce -> puc one racial -> rca ail realty -> rat ely sordid -> sri odd spatial -> sail pta sprain -> sri pan strain -> sri tan strait -> sri tat sturdy -> sud try sweaty -> set way tattle -> ttl ate theorem -> term hoe though -> tog huh throaty -> tray hot triode -> tid roe triune -> tin rue troupe -> top rue truant -> tun rat twirly -> til wry
AWK
# syntax: GAWK -f ALTERNADE_WORDS.AWK unixdict.txt
#
# sorting:
# PROCINFO["sorted_in"] is used by GAWK
# SORTTYPE is used by Thompson Automation's TAWK
#
{ arr[$0]++ }
END {
PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1
for (word in arr) {
leng = length(word)
if (leng < 6) {
continue
}
odd_word = even_word = ""
for (i=1; i<=leng; i++) {
if (i ~ /[13579]$/) {
odd_word = odd_word substr(word,i,1)
}
else {
even_word = even_word substr(word,i,1)
}
}
if (odd_word in arr && even_word in arr) {
printf("%-9s %-5s %-5s\n",word,odd_word,even_word)
}
}
exit(0)
}
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
BQN
Unmix ← (=`0¨)⊸⊔
•Show Unmix∘>˘⊸(∧´˘∘∊/∾˘˜) (2<≠¨)⊸/ •Flines "unixdict.txt"
- Output:
┌─ ╵ "accost" "acs" "cot" "accuse" "acs" "cue" "afield" "ail" "fed" "agleam" "ala" "gem" "alcott" "act" "lot" "allele" "all" "lee" "allied" "ale" "lid" "alpert" "apr" "let" "ambient" "abet" "min" "annette" "ante" "net" "apport" "apr" "pot" "ariadne" "aide" "ran" "assist" "ass" "sit" "battle" "btl" "ate" "blaine" "ban" "lie" "brenda" "bed" "rna" "calliope" "clip" "aloe" "choose" "cos" "hoe" "choosy" "cos" "hoy" "claire" "car" "lie" "collude" "clue" "old" "effete" "eft" "fee" "fabric" "fbi" "arc" "fealty" "fat" "ely" "fluent" "fun" "let" "forwent" "fret" "own" "friend" "fin" "red" "george" "gog" "ere" "inroad" "ira" "nod" "israel" "ire" "sal" "jaunty" "jut" "any" "joanne" "jan" "one" "lounge" "lug" "one" "oriole" "oil" "roe" "oswald" "owl" "sad" "parrot" "pro" "art" "peoria" "poi" "era" "pierre" "per" "ire" "poodle" "pol" "ode" "pounce" "puc" "one" "racial" "rca" "ail" "realty" "rat" "ely" "sordid" "sri" "odd" "spatial" "sail" "pta" "sprain" "sri" "pan" "strain" "sri" "tan" "strait" "sri" "tat" "sturdy" "sud" "try" "sweaty" "set" "way" "tattle" "ttl" "ate" "theorem" "term" "hoe" "though" "tog" "huh" "throaty" "tray" "hot" "triode" "tid" "roe" "triune" "tin" "rue" "troupe" "top" "rue" "truant" "tun" "rat" "twirly" "til" "wry" ┘
C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define WORD_BUF_SIZE 30
#define MIN_WORD_SIZE 6
/* Print last error and exit */
void fail(void) {
fprintf(stderr, "%s\n", strerror(errno));
exit(42);
}
/* Define a trie data structure to store the words */
struct trie_node {
char ch, final;
struct trie_node *parent, *sibling, *root, *child;
};
struct trie_node *alloc_node() {
struct trie_node *t = calloc(1, sizeof(struct trie_node));
if (t == NULL) fail();
return t;
}
struct trie_node *make_sibling(struct trie_node *node) {
struct trie_node *t = alloc_node();
node->sibling = t;
t->ch = node->ch;
t->parent = node->parent;
t->root = node->root;
return t;
}
struct trie_node *make_child(struct trie_node *node, char ch) {
struct trie_node *t = alloc_node();
t->parent = node;
t->ch = ch;
t->root = node->root;
node->child = t;
return t;
}
/* Add a word to the trie */
struct trie_node *add_word(struct trie_node *root, const char *word) {
struct trie_node *cur = root;
for (; *word; word++) {
while (cur->child == NULL || cur->child->ch != *word) {
if (cur->child == NULL) {
/* Node does not exist yet; insert it */
make_child(cur, *word);
} else {
/* Check next sibling, if it exists */
if (cur->sibling == NULL) make_sibling(cur);
cur = cur->sibling;
}
}
/* We have either made or found the right node, descend */
cur = cur->child;
}
cur->final = 1; /* This node marks the end of a word */
return cur;
}
/* Check if a word is in the trie; returns the word or NULL if not there */
struct trie_node *find_word(struct trie_node *root, const char *word) {
struct trie_node *cur = root;
for (; *word && cur; word++) {
while (cur != NULL && cur->child != NULL && cur->child->ch != *word) {
cur = cur->sibling;
}
if (cur == NULL) return NULL; /* node doesn't exist */
cur = cur->child;
}
if (cur && cur->final) return cur;
else return NULL;
}
/* Call function for every word in the trie */
void scan_trie(struct trie_node *node, void callback(struct trie_node *)) {
if (node == NULL) return;
if (node->final) callback(node);
scan_trie(node->child, callback);
scan_trie(node->sibling, callback);
}
/* Retrieve word from trie given pointer to end node */
char *get_word(struct trie_node *node, char *buffer) {
char t, *ch = buffer, *s = buffer;
for (; node != NULL; node=node->parent) *ch++ = node->ch;
for (ch-=2; ch >= s; ch--, s++) *ch ^= *s ^= *ch ^= *s;
return buffer;
}
/* See if a word is an alternade, and print it if it is */
void check_alternade(struct trie_node *node) {
static char word[WORD_BUF_SIZE], even[WORD_BUF_SIZE], odd[WORD_BUF_SIZE];
char *p_even = even, *p_odd = odd;
int i;
/* Ignore words that are shorter than the minimum length */
if (strlen(get_word(node, word)) < MIN_WORD_SIZE) return;
/* Make even and odd words */
for (i=0; word[i]; i++) {
if (i & 1) *p_odd++ = word[i];
else *p_even++ = word[i];
}
*p_odd = *p_even = '\0';
/* If both words exist, this is an alternade */
if (find_word(node->root, even) && find_word(node->root, odd)) {
printf("%-20s%-10s%-10s\n", word, even, odd);
}
}
int main(void) {
struct trie_node *root = alloc_node();
root->root = root;
char word[WORD_BUF_SIZE], *nl;
/* Read all words from stdin */
while (!feof(stdin)) {
fgets(word, WORD_BUF_SIZE, stdin);
if (nl = strchr(word, '\n')) *nl = '\0'; /* remove newline */
add_word(root, word);
}
/* Print all alternades */
scan_trie(root, check_alternade);
return 0;
}
- Output:
$ ./alternade < unixdict.txt accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
C++
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
int main(int argc, char** argv) {
const char* filename(argc < 2 ? "unixdict.txt" : argv[1]);
std::ifstream in(filename);
if (!in) {
std::cerr << "Cannot open file '" << filename << "'.\n";
return EXIT_FAILURE;
}
std::string line;
std::set<std::string> dictionary;
while (getline(in, line))
dictionary.insert(line);
std::cout << std::left;
for (const std::string& word : dictionary) {
size_t len = word.size();
if (len < 6)
continue;
std::string word1, word2;
for (size_t i = 0; i < len; i += 2) {
word1 += word[i];
if (i + 1 < len)
word2 += word[i + 1];
}
if (dictionary.find(word1) != dictionary.end()
&& dictionary.find(word2) != dictionary.end()) {
std::cout << std::setw(10) << word
<< std::setw(6) << word1 << word2 << '\n';
}
}
return EXIT_SUCCESS;
}
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
Delphi
Delphi-style problem solving, using standard Delphi controls like the TStringList, which greatly simplifies the solution.
unit Alternade;
interface
uses Classes,StdCtrls,SysUtils;
procedure FindAlternadeWords(Memo: TMemo);
implementation
var Dict: TStringList; {List holds dictionary}
function GetAlts(S: string; var Alt1,Alt2: string): boolean;
{Grab Alternades from string and test if they are valid }
var I: integer;
begin
Alt1:='';
Alt2:='';
{Copy every other letter into different string}
for I:=1 to Length(S) do
if (I mod 2)=0 then Alt2:=Alt2+S[I]
else Alt1:=Alt1+S[I];
{Check if the two strings are in the dictionary}
Result:=(Dict.IndexOf(Alt1)>=0) and (Dict.IndexOf(Alt2)>=0);
end;
procedure FindAlternadeWords(Memo: TMemo);
{test all words in the dictionary}
{And diplays the Alternade words in the Memo}
var I,Cnt: integer;
var Alt1,Alt2: string;
begin
Cnt:=0;
for I:=0 to Dict.Count-1 do
if (Length(Dict[I])>=6) and GetAlts(Dict[I], Alt1, Alt2) then
begin
Inc(Cnt);
Memo.Lines.Add(IntToStr(Cnt)+': '+Dict[I]+' '+Alt1+' '+Alt2);
end
end;
initialization
{Create/load dictionary}
Dict:=TStringList.Create;
Dict.LoadFromFile('unixdict.txt');
Dict.Sorted:=True;
finalization
Dict.Free;
end.
- Output:
1: accost acs cot 2: accuse acs cue 3: afield ail fed 4: agleam ala gem 5: alcott act lot 6: allele all lee 7: allied ale lid 8: alpert apr let 9: ambient abet min 10: annette ante net 11: apport apr pot 12: ariadne aide ran 13: assist ass sit 14: battle btl ate 15: blaine ban lie 16: brenda bed rna 17: calliope clip aloe 18: choose cos hoe 19: choosy cos hoy 20: claire car lie 21: collude clue old 22: effete eft fee 23: fabric fbi arc 24: fealty fat ely 25: fluent fun let 26: forwent fret own 27: friend fin red 28: george gog ere 29: inroad ira nod 30: israel ire sal 31: jaunty jut any 32: joanne jan one 33: lounge lug one 34: oriole oil roe 35: oswald owl sad 36: parrot pro art 37: peoria poi era 38: pierre per ire 39: poodle pol ode 40: pounce puc one 41: racial rca ail 42: realty rat ely 43: sordid sri odd 44: spatial sail pta 45: sprain sri pan 46: strain sri tan 47: strait sri tat 48: sturdy sud try 49: sweaty set way 50: tattle ttl ate 51: theorem term hoe 52: though tog huh 53: throaty tray hot 54: triode tid roe 55: triune tin rue 56: troupe top rue 57: truant tun rat 58: twirly til wry
EasyLang
repeat
s$ = input
until s$ = ""
if len s$ >= 3
w$[] &= s$
.
.
func binsearch s$ .
max = len w$[] + 1
while min + 1 < max
mid = min + (max - min) div 2
h = strcmp w$[mid] s$
if h = 0
return 1
elif h < 0
min = mid
else
max = mid
.
.
return 0
.
for w$ in w$[]
if len w$ >= 6
a$ = ""
b$ = ""
for i to len w$
if i mod 2 = 1
a$ &= substr w$ i 1
else
b$ &= substr w$ i 1
.
.
if binsearch a$ = 1 and binsearch b$ = 1
print w$ & " -> " & a$ & " " & b$
.
.
.
# the content of unixdict.txt
input_data
10th
.
fin
friend
red
F#
// Alternade words: Nigel Galloway. June 10th., 2021
let dict=seq{use n=System.IO.File.OpenText("unixdict.txt") in while not n.EndOfStream do yield n.ReadLine()}|>Seq.filter(fun n->n.Length>2)|>List.ofSeq
let fN g=let n=Seq.foldBack2(fun n g (z:char list [])->z.[g]<-n::z.[g]; z) g (let rec fN()=seq{yield![0;1]; yield! fN()} in fN())([|[];[]|]) in (n.[0],n.[1])
let fG(n,g)=let fN g=(Array.ofList>>System.String) g in let n,g=fN n,fN g in if List.contains n dict && List.contains g dict then Some(n,g) else None
dict|>Seq.filter(fun n->n.Length>5)|>Seq.iter(fun n->match (fN>>fG) n with Some(g,l)->printfn "%s -> %s * %s" n g l |_->())
- Output:
accost -> acs * cot accuse -> acs * cue afield -> ail * fed agleam -> ala * gem alcott -> act * lot allele -> all * lee allied -> ale * lid alpert -> apr * let ambient -> abet * min annette -> ante * net apport -> apr * pot ariadne -> aide * ran assist -> ass * sit battle -> btl * ate blaine -> ban * lie brenda -> bed * rna calliope -> clip * aloe choose -> cos * hoe choosy -> cos * hoy claire -> car * lie collude -> clue * old effete -> eft * fee fabric -> fbi * arc fealty -> fat * ely fluent -> fun * let forwent -> fret * own friend -> fin * red george -> gog * ere inroad -> ira * nod israel -> ire * sal jaunty -> jut * any joanne -> jan * one lounge -> lug * one oriole -> oil * roe oswald -> owl * sad parrot -> pro * art peoria -> poi * era pierre -> per * ire poodle -> pol * ode pounce -> puc * one racial -> rca * ail realty -> rat * ely sordid -> sri * odd spatial -> sail * pta sprain -> sri * pan strain -> sri * tan strait -> sri * tat sturdy -> sud * try sweaty -> set * way tattle -> ttl * ate theorem -> term * hoe though -> tog * huh throaty -> tray * hot triode -> tid * roe triune -> tin * rue troupe -> top * rue truant -> tun * rat twirly -> til * wry
Factor
USING: formatting io.encodings.ascii io.files kernel literals
math sequences sequences.extras sets strings ;
<< CONSTANT: words $[ "unixdict.txt" ascii file-lines ] >>
CONSTANT: wordset $[ words HS{ } set-like ]
: word? ( str -- ? ) wordset in? ;
: subwords ( str -- str str )
dup <evens> >string swap <odds> >string ;
: alternade? ( str -- ? ) subwords [ word? ] both? ;
words
[ alternade? ] filter
[ length 5 > ] filter
[ dup subwords "%-8s %-4s %-4s\n" printf ] each
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
FreeBASIC
#define DLEN 25104
function is_in(word() as string, s as string) as boolean
for i as uinteger = 1 to DLEN
if word(i)=s then return true
next i
return false
end function
dim as string word(1 to DLEN), alt(0 to 1)
dim as integer i, j
open "unixdict.txt" for input as #1
while not eof(1)
i+=1
line input #1, word(i)
wend
close #1
for i = 1 to DLEN
if len(word(i))<6 then continue for
alt(0) = ""
alt(1) = ""
for j = 1 to len(word(i))
alt(j mod 2) += mid(word(i),j, 1)
next j
if is_in(word(), alt(0)) and is_in(word(), alt(1)) then print word(i), alt(1), alt(0)
next i
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
FutureBasic
#plist NSAppTransportSecurity @{NSAllowsArbitraryLoads:YES}
local fn Words as CFArrayRef
CFURLRef url = fn URLWithString( @"https://web.archive.org/web/20180611003215/http://www.puzzlers.org/pub/wordlists/unixdict.txt" )
CFStringRef string = fn StringWithContentsOfURL( url, NSUTF8StringEncoding, NULL )
end fn = fn StringComponentsSeparatedByCharactersInSet( string, fn CharacterSetNewlineSet )
void local fn DoIt
text,,,,, 80
dispatchglobal
CFArrayRef words = fn Words
CFStringRef wd, wd1, wd2
long length, i
for wd in words
length = len(wd)
if ( length >= 6 )
wd1 = @"" : wd2 = @""
for i = 0 to length-1
if ( i mod 2 == 0 )
wd1 = fn StringByAppendingString( wd1, mid(wd,i,1) )
else
wd2 = fn StringByAppendingString( wd2, mid(wd,i,1) )
end if
next
if ( fn ArrayContainsObject( words, wd1 ) and fn ArrayContainsObject( words, wd2 ) )
dispatchmain
print wd,wd1,wd2
dispatchend
end if
end if
next
dispatchend
end fn
fn DoIt
HandleEvents
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
Go
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"unicode/utf8"
)
func main() {
b, err := ioutil.ReadFile("unixdict.txt")
if err != nil {
log.Fatal("Error reading file")
}
bwords := bytes.Fields(b)
dict := make(map[string]bool, len(bwords))
words := make([]string, len(bwords))
for i, bword := range bwords {
word := string(bword)
dict[word] = true
words[i] = word
}
fmt.Println("'unixdict.txt' contains the following alternades of length 6 or more:\n")
count := 0
for _, word := range words {
if utf8.RuneCountInString(word) < 6 {
continue
}
var w1 = ""
var w2 = ""
for i, c := range word {
if i%2 == 0 {
w1 += string(c)
} else {
w2 += string(c)
}
}
_, ok1 := dict[w1]
_, ok2 := dict[w2]
if ok1 && ok2 {
count++
fmt.Printf("%2d: %-8s -> %-4s %-4s\n", count, word, w1, w2)
}
}
}
- Output:
'unixdict.txt' contains the following alternades of length 6 or more: 1: accost -> acs cot 2: accuse -> acs cue 3: afield -> ail fed 4: agleam -> ala gem 5: alcott -> act lot 6: allele -> all lee 7: allied -> ale lid 8: alpert -> apr let 9: ambient -> abet min 10: annette -> ante net 11: apport -> apr pot 12: ariadne -> aide ran 13: assist -> ass sit 14: battle -> btl ate 15: blaine -> ban lie 16: brenda -> bed rna 17: calliope -> clip aloe 18: choose -> cos hoe 19: choosy -> cos hoy 20: claire -> car lie 21: collude -> clue old 22: effete -> eft fee 23: fabric -> fbi arc 24: fealty -> fat ely 25: fluent -> fun let 26: forwent -> fret own 27: friend -> fin red 28: george -> gog ere 29: inroad -> ira nod 30: israel -> ire sal 31: jaunty -> jut any 32: joanne -> jan one 33: lounge -> lug one 34: oriole -> oil roe 35: oswald -> owl sad 36: parrot -> pro art 37: peoria -> poi era 38: pierre -> per ire 39: poodle -> pol ode 40: pounce -> puc one 41: racial -> rca ail 42: realty -> rat ely 43: sordid -> sri odd 44: spatial -> sail pta 45: sprain -> sri pan 46: strain -> sri tan 47: strait -> sri tat 48: sturdy -> sud try 49: sweaty -> set way 50: tattle -> ttl ate 51: theorem -> term hoe 52: though -> tog huh 53: throaty -> tray hot 54: triode -> tid roe 55: triune -> tin rue 56: troupe -> top rue 57: truant -> tun rat 58: twirly -> til wry
Haskell
import qualified Data.Set as S
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
-- Two words constructed from the alternating characters of a single word.
alt :: T.Text -> (T.Text, T.Text)
alt = T.foldl' (\(l, r) c -> (r `T.snoc` c, l)) (T.empty, T.empty)
-- The alternades of a list of words.
alternades :: S.Set T.Text -> [T.Text] -> [(T.Text, (T.Text, T.Text))]
alternades dict ws = filter (areMembers . snd) $ zip ws $ map alt ws
where areMembers (x, y) = S.member x dict && S.member y dict
main :: IO ()
main = TIO.interact $ \txt ->
let words' = map T.toLower $ T.lines txt
dict = S.fromList words'
in T.unlines $ map alterShow $ alternades dict $ filter longEnough words'
where longEnough = (>= 6) . T.length
alterShow (w, (x, y)) = T.unwords [w, x, y]
- Output:
$ alternade < unixdict.txt accost cot acs accuse cue acs afield fed ail agleam gem ala alcott lot act allele lee all allied lid ale alpert let apr ambient abet min annette ante net apport pot apr ariadne aide ran assist sit ass battle ate btl blaine lie ban brenda rna bed calliope aloe clip choose hoe cos choosy hoy cos claire lie car collude clue old effete fee eft fabric arc fbi fealty ely fat fluent let fun forwent fret own friend red fin george ere gog inroad nod ira israel sal ire jaunty any jut joanne one jan lounge one lug oriole roe oil oswald sad owl parrot art pro peoria era poi pierre ire per poodle ode pol pounce one puc racial ail rca realty ely rat sordid odd sri spatial sail pta sprain pan sri strain tan sri strait tat sri sturdy try sud sweaty way set tattle ate ttl theorem term hoe though huh tog throaty tray hot triode roe tid triune rue tin troupe rue top truant rat tun twirly wry til
J
words=: cutLF fread 'unixdict.txt'
alts=: <@deb"1@|:@(_2]\])@> ref=: (#~ 5<#@>) words
;:inv (ref,.alts) #~ alts */@e."1 words
accost acs cot
accuse acs cue
afield ail fed
agleam ala gem
alcott act lot
allele all lee
allied ale lid
alpert apr let
ambient abet min
annette ante net
apport apr pot
ariadne aide ran
assist ass sit
battle btl ate
blaine ban lie
brenda bed rna
calliope clip aloe
choose cos hoe
choosy cos hoy
claire car lie
collude clue old
effete eft fee
fabric fbi arc
fealty fat ely
fluent fun let
forwent fret own
friend fin red
george gog ere
inroad ira nod
israel ire sal
jaunty jut any
joanne jan one
lounge lug one
oriole oil roe
oswald owl sad
parrot pro art
peoria poi era
pierre per ire
poodle pol ode
pounce puc one
racial rca ail
realty rat ely
sordid sri odd
spatial sail pta
sprain sri pan
strain sri tan
strait sri tat
sturdy sud try
sweaty set way
tattle ttl ate
theorem term hoe
though tog huh
throaty tray hot
triode tid roe
triune tin rue
troupe top rue
truant tun rat
twirly til wry
Java
The 'userdict.txt' file is great, except it contains entries like 'mrs' and '1st'.
Testing a word for at least one vowel, and 'a-z' is necessary for this task.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;
class AlternadeWords {
static char[] vowels = "aeiouy".toCharArray();
static String alphabet;
static {
alphabet = "";
for (int index = 0; index < 26; index++)
alphabet += (char) (index + 'a');
}
boolean alphabetic(String string) {
for (char character : string.toCharArray()) {
if (!alphabet.contains(String.valueOf(character)))
return false;
}
return true;
}
boolean containsVowel(String string) {
for (char vowel : vowels) {
if (string.contains(String.valueOf(vowel)))
return true;
}
return false;
}
void alternateWords() throws IOException {
Set<String> dictionary = new TreeSet<>();
try (BufferedReader reader = new BufferedReader(new FileReader("unixdict.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
if (!alphabetic(line) || !containsVowel(line))
continue;
dictionary.add(line);
}
}
StringBuilder wordA = new StringBuilder();
StringBuilder wordB = new StringBuilder();
for (String word : dictionary) {
int length = word.length();
if (length < 6)
continue;
wordA.setLength(0);
wordB.setLength(0);
for (int index = 0; index < length; index += 2) {
wordA.append(word.charAt(index));
if (index + 1 < length)
wordB.append(word.charAt(index + 1));
}
if (dictionary.contains(wordA.toString()))
if (dictionary.contains(wordB.toString()))
System.out.printf("%-15s%5s %s%n", word, wordA, wordB);
}
}
}
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
jq
Works with gojq, the Go implementation of jq
Note: For gojq, change `keys_unsorted` to `keys`. The results are unaffected.
# if the input is an alternade word relative to the keys of $dict,
# then emit [$even, $odd], else false.
def is_alternade($dict):
def seconds($start): [.[range($start;length;2)]];
explode
| [seconds(0,1)] | map(implode)
| if $dict[.[0]] and $dict[.[1]] then . else false end;
INDEX( inputs; . )
| . as $dict
| keys_unsorted[]
| select(length>5)
| . as $w
| is_alternade($dict)
| (select(.) // empty)
| "\($w) → \(.[0]) \(.[1])"
Invocation: jq -n -rR -f alternade-words.jq unixdict.txt
- Output:
accost → acs cot accuse → acs cue afield → ail fed agleam → ala gem alcott → act lot allele → all lee allied → ale lid alpert → apr let ambient → abet min annette → ante net apport → apr pot ariadne → aide ran assist → ass sit battle → btl ate blaine → ban lie brenda → bed rna calliope → clip aloe choose → cos hoe choosy → cos hoy claire → car lie collude → clue old effete → eft fee fabric → fbi arc fealty → fat ely fluent → fun let forwent → fret own friend → fin red george → gog ere inroad → ira nod israel → ire sal jaunty → jut any joanne → jan one lounge → lug one oriole → oil roe oswald → owl sad parrot → pro art peoria → poi era pierre → per ire poodle → pol ode pounce → puc one racial → rca ail realty → rat ely sordid → sri odd spatial → sail pta sprain → sri pan strain → sri tan strait → sri tat sturdy → sud try sweaty → set way tattle → ttl ate theorem → term hoe though → tog huh throaty → tray hot triode → tid roe triune → tin rue troupe → top rue truant → tun rat twirly → til wry
Julia
function foreachword(wordfile::String, condition::Function; minlen = 0, colwidth = 15, numcols = 6, toshow = 0)
println("Word source: $wordfile\n")
words = split(read(wordfile, String), r"\s+")
dict, shown = Dict(w => 1 for w in words), 0
for word in words
if (minlen < 1 || length(word) >= minlen) && (output = condition(word, dict)) != ""
shown += 1
print(rpad(output, colwidth), shown % numcols == 0 ? "\n" : "")
toshow > 0 && toshow < shown && break
end
end
end
function isalternade(w, d)
wodd, weven = (mapreduce(i -> w[i], *, j:2:length(w)) for j in [1,2])
return haskey(d, wodd) && haskey(d, weven) ? rpad(w, 8) * ": $wodd, $weven" : ""
end
foreachword("unixdict.txt", isalternade, minlen = 6, numcols=1)
- Output:
Word source: unixdict.txt accost : acs, cot accuse : acs, cue afield : ail, fed agleam : ala, gem alcott : act, lot allele : all, lee allied : ale, lid alpert : apr, let ambient : abet, min annette : ante, net apport : apr, pot ariadne : aide, ran assist : ass, sit battle : btl, ate blaine : ban, lie brenda : bed, rna calliope: clip, aloe choose : cos, hoe choosy : cos, hoy claire : car, lie collude : clue, old effete : eft, fee fabric : fbi, arc fealty : fat, ely fluent : fun, let forwent : fret, own friend : fin, red george : gog, ere inroad : ira, nod israel : ire, sal jaunty : jut, any joanne : jan, one lounge : lug, one oriole : oil, roe oswald : owl, sad parrot : pro, art peoria : poi, era pierre : per, ire poodle : pol, ode pounce : puc, one racial : rca, ail realty : rat, ely sordid : sri, odd spatial : sail, pta sprain : sri, pan strain : sri, tan strait : sri, tat sturdy : sud, try sweaty : set, way tattle : ttl, ate theorem : term, hoe though : tog, huh throaty : tray, hot triode : tid, roe triune : tin, rue troupe : top, rue truant : tun, rat twirly : til, wry
Mathematica /Wolfram Language
dic = Once[Import["https://web.archive.org/web/20180611003215/http://www.puzzlers.org/pub/wordlists/unixdict.txt"]];
dic = StringSplit[dic, "\n"];
largerthansix = Select[dic, StringLength /* GreaterEqualThan[6]];
smallerthansix = Select[dic, StringLength /* LessEqualThan[5]];
ClearAll[AlternadeQ]
AlternadeQ[w_String, words_List] := Module[{chars, ws, c1, c2},
chars = Characters[w];
c1 = StringJoin@chars[[1 ;; ;; 2]];
c2 = StringJoin@chars[[2 ;; ;; 2]];
If[MemberQ[words, c1] \[And] MemberQ[words, c2], w -> {c1, c2}, {}]
]
all = DeleteCases[Table[AlternadeQ[w, smallerthansix], {w, largerthansix}], {}];
all // Column
- Output:
accost->{acs,cot} accuse->{acs,cue} afield->{ail,fed} agleam->{ala,gem} alcott->{act,lot} allele->{all,lee} allied->{ale,lid} alpert->{apr,let} ambient->{abet,min} annette->{ante,net} apport->{apr,pot} ariadne->{aide,ran} assist->{ass,sit} battle->{btl,ate} blaine->{ban,lie} brenda->{bed,rna} calliope->{clip,aloe} choose->{cos,hoe} choosy->{cos,hoy} claire->{car,lie} collude->{clue,old} effete->{eft,fee} fabric->{fbi,arc} fealty->{fat,ely} fluent->{fun,let} forwent->{fret,own} friend->{fin,red} george->{gog,ere} inroad->{ira,nod} israel->{ire,sal} jaunty->{jut,any} joanne->{jan,one} lounge->{lug,one} oriole->{oil,roe} oswald->{owl,sad} parrot->{pro,art} peoria->{poi,era} pierre->{per,ire} poodle->{pol,ode} pounce->{puc,one} racial->{rca,ail} realty->{rat,ely} sordid->{sri,odd} spatial->{sail,pta} sprain->{sri,pan} strain->{sri,tan} strait->{sri,tat} sturdy->{sud,try} sweaty->{set,way} tattle->{ttl,ate} theorem->{term,hoe} though->{tog,huh} throaty->{tray,hot} triode->{tid,roe} triune->{tin,rue} troupe->{top,rue} truant->{tun,rat} twirly->{til,wry}
MiniScript
This implementation is for use with the Mini Micro version of MiniScript. The command-line version does not include a HTTP library. Modify the declaration of wordList object to use the file class to read a local copy of the word list file.
alternateLetters = function(word, ix)
if ix != 0 then ix = 1
altWord = ""
for i in range(ix, word.len - 1, 2)
altWord += word[i]
end for
return altWord
end function
wordList = http.get("http://wiki.puzzlers.org/pub/wordlists/unixdict.txt").split(char(10))
ctr = 0
for word in wordList
if word.len > 5 then
word1 = alternateLetters(word, 0)
word2 = alternateLetters(word, 1)
if wordList.indexOf(word1) != null and wordList.indexOf(word2) != null then
ctr += 1
print [ctr, word, char(18), word1, word2].join(" ")
end if
end if
end for
- Output:
1 accost : acs cot 2 accuse : acs cue 3 afield : ail fed 4 agleam : ala gem 5 alcott : act lot 6 allele : all lee 7 allied : ale lid 8 alpert : apr let 9 ambient : abet min 10 annette : ante net 11 apport : apr pot 12 ariadne : aide ran 13 assist : ass sit 14 battle : btl ate 15 blaine : ban lie 16 brenda : bed rna 17 calliope : clip aloe 18 choose : cos hoe 19 choosy : cos hoy 20 claire : car lie 21 collude : clue old 22 effete : eft fee 23 fabric : fbi arc 24 fealty : fat ely 25 fluent : fun let 26 forwent : fret own 27 friend : fin red 28 george : gog ere 29 inroad : ira nod 30 israel : ire sal 31 jaunty : jut any 32 joanne : jan one 33 lounge : lug one 34 oriole : oil roe 35 oswald : owl sad 36 parrot : pro art 37 peoria : poi era 38 pierre : per ire 39 poodle : pol ode 40 pounce : puc one 41 racial : rca ail 42 realty : rat ely 43 sordid : sri odd 44 spatial : sail pta 45 sprain : sri pan 46 strain : sri tan 47 strait : sri tat 48 sturdy : sud try 49 sweaty : set way 50 tattle : ttl ate 51 theorem : term hoe 52 though : tog huh 53 throaty : tray hot 54 triode : tid roe 55 triune : tin rue 56 troupe : top rue 57 truant : tun rat 58 twirly : til wry
Miranda
main :: [sys_message]
main = [Stdout (lay (map showitem (find_alternades dict longwords)))]
where longwords = [w | w <- words; #w >= 6]
showitem (w, (a1, a2)) = w ++ ": " ++ a1 ++ ", " ++ a2
btree * ::= Leaf | Node * (btree *) (btree *)
has :: (btree *) -> * -> bool
has Leaf x = False
has (Node x l r) x = True
has (Node x l r) y = l $has y, if y<x
has (Node x l r) y = r $has y, if y>x
buildtree :: [*] -> (btree *)
buildtree [] = Leaf
buildtree xs = Node (xs ! half) l r
where half = #xs div 2
l = buildtree (take half xs)
r = buildtree (drop (half+1) xs)
words :: [[char]]
words = lines (read "unixdict.txt")
dict :: btree [char]
dict = buildtree words
alternades :: [*]->([*],[*])
alternades = f [] []
where f l r [] = (l,r)
f l r [x] = (l++[x],r)
f l r (x:y:xs) = f (l++[x]) (r++[y]) xs
is_alternade :: btree [*]->[*]->bool
is_alternade dict word = dict $has a1 & dict $has a2
where (a1, a2) = alternades word
find_alternades :: btree [*]->[[*]]->[([*],([*],[*]))]
find_alternades dict words = [(w, alternades w) | w <- words; is_alternade dict w]
- Output:
accost: acs, cot accuse: acs, cue afield: ail, fed agleam: ala, gem alcott: act, lot allele: all, lee allied: ale, lid alpert: apr, let ambient: abet, min annette: ante, net apport: apr, pot ariadne: aide, ran assist: ass, sit battle: btl, ate blaine: ban, lie brenda: bed, rna calliope: clip, aloe choose: cos, hoe choosy: cos, hoy claire: car, lie collude: clue, old effete: eft, fee fabric: fbi, arc fealty: fat, ely fluent: fun, let forwent: fret, own friend: fin, red george: gog, ere inroad: ira, nod israel: ire, sal jaunty: jut, any joanne: jan, one lounge: lug, one oriole: oil, roe oswald: owl, sad parrot: pro, art peoria: poi, era pierre: per, ire poodle: pol, ode pounce: puc, one racial: rca, ail realty: rat, ely sordid: sri, odd spatial: sail, pta sprain: sri, pan strain: sri, tan strait: sri, tat sturdy: sud, try sweaty: set, way tattle: ttl, ate theorem: term, hoe though: tog, huh throaty: tray, hot triode: tid, roe triune: tin, rue troupe: top, rue truant: tun, rat twirly: til, wry
newLISP
The file of words that it was convenient to use was named "words". The list of alternade words of length 6 or more was too long, so I printed those that were at least 7 characters long.
(let (handle (open "words" "read"))
(setq word-list (collect (read-line handle)))
(close handle))
(define (in-dict? word) (find word word-list))
(define (alternates word , pair)
(and
(> (length word) 6)
(setq pair
(map (fn(s) (apply string (map first (explode s 2))))
(list word (1 word))))
(for-all in-dict? pair)
pair))
(dolist (w word-list)
(if (alternates w) (println w " " $it)))
- Output:
abramis ("arms" "bai") airless ("ares" "ils") alberta ("abra" "let") algiers ("ages" "lir") ambient ("abet" "min") amniota ("anoa" "mit") barbarea ("brae" "abra") barbarian ("brain" "abra") breasts ("bess" "rat") breathe ("bete" "rah") calliope ("clip" "aloe") cellule ("clue" "ell") celtuce ("clue" "etc") cereals ("cras" "eel") collude ("clue" "old") couplet ("cult" "ope") courses ("cuss" "ore") curtain ("cran" "uti") drayman ("damn" "rya") enlarge ("elre" "nag") estonia ("etna" "soi") fleuron ("fern" "luo") galliass ("glis" "alas") goodwin ("gown" "odi") gouttes ("guts" "ote") grounded ("gone" "rudd") hairnet ("hint" "are") impasto ("ipso" "mat") learned ("land" "ere") neoprene ("norn" "epee") oriolus ("oils" "rou") osmanli ("omni" "sal") rounded ("rudd" "one") sallust ("slut" "als") saltation ("slain" "atto") sapless ("spes" "als") sciollo ("silo" "col") sciolto ("silo" "cot") sentiat ("snit" "eta") spoiled ("sold" "pie") spurred ("surd" "pre") stained ("sand" "tie") terrene ("tree" "ern") theorem ("term" "hoe") throaty ("tray" "hot") unteach ("utah" "nec") whitney ("winy" "hte")
Nim
import algorithm, sets, strutils, sugar
proc alternatingWords(word: string): array[2, string] =
## Return the candidate alternating words of a word.
for i, c in word:
result[i and 1].add c
let words = collect(HashSet, for word in "unixdict.txt".lines: {word})
var result: seq[string]
for word in words:
if word.len >= 6:
let altWords = alternatingWords(word)
if altWords[0] in words and altWords[1] in words:
result.add word.align(8) & " → $1 $2" % altWords
result.sort()
for i, line in result: echo ($(i+1)).align(2), ": ", line
- Output:
1: accost → acs cot 2: accuse → acs cue 3: afield → ail fed 4: agleam → ala gem 5: alcott → act lot 6: allele → all lee 7: allied → ale lid 8: alpert → apr let 9: apport → apr pot 10: assist → ass sit 11: battle → btl ate 12: blaine → ban lie 13: brenda → bed rna 14: choose → cos hoe 15: choosy → cos hoy 16: claire → car lie 17: effete → eft fee 18: fabric → fbi arc 19: fealty → fat ely 20: fluent → fun let 21: friend → fin red 22: george → gog ere 23: inroad → ira nod 24: israel → ire sal 25: jaunty → jut any 26: joanne → jan one 27: lounge → lug one 28: oriole → oil roe 29: oswald → owl sad 30: parrot → pro art 31: peoria → poi era 32: pierre → per ire 33: poodle → pol ode 34: pounce → puc one 35: racial → rca ail 36: realty → rat ely 37: sordid → sri odd 38: sprain → sri pan 39: strain → sri tan 40: strait → sri tat 41: sturdy → sud try 42: sweaty → set way 43: tattle → ttl ate 44: though → tog huh 45: triode → tid roe 46: triune → tin rue 47: troupe → top rue 48: truant → tun rat 49: twirly → til wry 50: ambient → abet min 51: annette → ante net 52: ariadne → aide ran 53: collude → clue old 54: forwent → fret own 55: spatial → sail pta 56: theorem → term hoe 57: throaty → tray hot 58: calliope → clip aloe
OCaml
module StrSet = Set.Make(String)
let seq_lines ch =
let rec repeat () =
match input_line ch with
| s -> Seq.Cons (s, repeat)
| exception End_of_file -> Nil
in repeat
let min_len l s =
l <= String.length s
let get_alternade set s =
let s0 = String.init (succ (String.length s) lsr 1) (fun i -> s.[i + i])
and s1 = String.init (String.length s lsr 1) (fun i -> s.[i + succ i]) in
if StrSet.mem s0 set && StrSet.mem s1 set
then Some (Printf.sprintf "%s | %s %s" s s0 s1) else None
let () =
let set = seq_lines stdin |> Seq.filter (min_len 3) |> StrSet.of_seq in
StrSet.to_seq set |> Seq.filter (min_len 6)
|> Seq.filter_map (get_alternade set) |> Seq.iter print_endline
- Output:
accost | acs cot accuse | acs cue afield | ail fed agleam | ala gem alcott | act lot allele | all lee allied | ale lid alpert | apr let ambient | abet min annette | ante net apport | apr pot ariadne | aide ran assist | ass sit battle | btl ate blaine | ban lie brenda | bed rna calliope | clip aloe choose | cos hoe choosy | cos hoy claire | car lie collude | clue old effete | eft fee fabric | fbi arc fealty | fat ely fluent | fun let forwent | fret own friend | fin red george | gog ere inroad | ira nod israel | ire sal jaunty | jut any joanne | jan one lounge | lug one oriole | oil roe oswald | owl sad parrot | pro art peoria | poi era pierre | per ire poodle | pol ode pounce | puc one racial | rca ail realty | rat ely sordid | sri odd spatial | sail pta sprain | sri pan strain | sri tan strait | sri tat sturdy | sud try sweaty | set way tattle | ttl ate theorem | term hoe though | tog huh throaty | tray hot triode | tid roe triune | tin rue troupe | top rue truant | tun rat twirly | til wry
Perl
#!/usr/bin/perl
use strict;
use warnings;
my $words = do { local (@ARGV, $/) = 'unixdict.txt'; <> };
my %words = map { $_, 1 } $words =~ /^.{3,}$/gm;
for ( $words =~ /^.{6,}$/gm )
{
my $even = s/(.).?/$1/gr;
my $odd = s/.(.?)/$1/gr;
$words{$even} && $words{$odd} and print "$_ => [ $even $odd ]\n";
}
Phix
with javascript_semantics sequence words = unix_dict() constant minlens = {0,6,10,11,12,12} for n=2 to 6 do sequence res = {} for i=1 to length(words) do string word = words[i] if length(word)>=minlens[n] then sequence sn = repeat("",n) for j=1 to length(word) do integer ndx = mod(j-1,n)+1 sn[ndx] &= word[j] end for for j=1 to n do if binary_search(sn[j],words)<0 then exit end if if j=n then sn = prepend(sn,word) res = append(res,sn) end if end for end if end for printf(1,"\nEvery %s letter of length>=%d:\n",{ordinal(n),minlens[n]}) pp(shorten(res,"alternade words found",5),{pp_Nest,1}) end for
- Output:
Every second letter of length>=6: {{`accost`, `acs`, `cot`}, {`accuse`, `acs`, `cue`}, {`afield`, `ail`, `fed`}, {`agleam`, `ala`, `gem`}, {`alcott`, `act`, `lot`}, `...`, {`triode`, `tid`, `roe`}, {`triune`, `tin`, `rue`}, {`troupe`, `top`, `rue`}, {`truant`, `tun`, `rat`}, {`twirly`, `til`, `wry`}, ` (58 alternade words found)`} Every third letter of length>=10: {{`benevolent`, `belt`, `eve`, `non`}, {`rejuvenate`, `rune`, `eva`, `jet`}} Every fourth letter of length>=11: {{`meteorology`, `moo`, `erg`, `toy`, `el`}, {`protectorate`, `per`, `rca`, `ott`, `toe`}} Every fifth letter of length>=12: {{`inappropriate`, `ira`, `not`, `ape`, `pr`, `pi`}} Every sixth letter of length>=12: {{`aristotelean`, `at`, `re`, `il`, `se`, `ta`, `on`}, {`warehouseman`, `wu`, `as`, `re`, `em`, `ha`, `on`}}
Picat
split_word(Word) = Words =>
N = len(Word),
W1 = [Word[I]: I in 1..N, I mod 2 == 1],
W2 = [Word[I]: I in 1..N, I mod 2 == 0],
Words = {W1, W2}.
main(Args) =>
File = Args[1],
Reader = open(File),
Dict = new_set(25104, []),
while (not at_end_of_stream(Reader))
Word = read_line(Reader),
put(Dict, Word),
end,
DictWords = keys(Dict),
LongWords = [Long: Long in DictWords, len(Long) >= 6],
LongSorted = sort(LongWords),
foreach (Word in LongSorted)
Words = split_word(Word),
if (has_key(Dict, Words[1]), has_key(Dict, Words[2])) then
printf("%w = %w + %w\n", Word, Words[1], Words[2])
end
end,
close(Reader).
- Output:
accost = acs + cot accuse = acs + cue afield = ail + fed agleam = ala + gem alcott = act + lot allele = all + lee allied = ale + lid alpert = apr + let ambient = abet + min annette = ante + net apport = apr + pot ariadne = aide + ran assist = ass + sit battle = btl + ate blaine = ban + lie brenda = bed + rna calliope = clip + aloe choose = cos + hoe choosy = cos + hoy claire = car + lie collude = clue + old effete = eft + fee fabric = fbi + arc fealty = fat + ely fluent = fun + let forwent = fret + own friend = fin + red george = gog + ere inroad = ira + nod israel = ire + sal jaunty = jut + any joanne = jan + one lounge = lug + one oriole = oil + roe oswald = owl + sad parrot = pro + art peoria = poi + era pierre = per + ire poodle = pol + ode pounce = puc + one racial = rca + ail realty = rat + ely sordid = sri + odd spatial = sail + pta sprain = sri + pan strain = sri + tan strait = sri + tat sturdy = sud + try sweaty = set + way tattle = ttl + ate theorem = term + hoe though = tog + huh throaty = tray + hot triode = tid + roe triune = tin + rue troupe = top + rue truant = tun + rat twirly = til + wry
Prolog
:- dynamic dictionary_word/1.
main:-
load_dictionary_from_file("unixdict.txt"),
print_alternade_words(6).
load_dictionary_from_file(File):-
open(File, read, Stream),
retractall(dictionary_word(_)),
load_dictionary_from_stream(Stream),
close(Stream).
load_dictionary_from_stream(Stream):-
read_line_to_string(Stream, String),
String \= end_of_file,
!,
assertz(dictionary_word(String)),
load_dictionary_from_stream(Stream).
load_dictionary_from_stream(_).
print_alternade_words(Min_length):-
dictionary_word(Word),
string_length(Word, Length),
Length >= Min_length,
odd_even_words(Word, Word1, Word2),
dictionary_word(Word1),
dictionary_word(Word2),
writef('%10l%6l%w\n', [Word, Word1, Word2]),
fail.
print_alternade_words(_).
odd_even_words(Word, Word1, Word2):-
string_chars(Word, Chars),
odd_even_chars(Chars, Chars1, Chars2),
string_chars(Word1, Chars1),
string_chars(Word2, Chars2).
odd_even_chars([], [], []):-!.
odd_even_chars([Ch], [Ch], []):-!.
odd_even_chars([Ch1, Ch2|Chars], [Ch1|Chars1], [Ch2|Chars2]):-
odd_even_chars(Chars, Chars1, Chars2).
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
Python
WORDFILE = 'unixdict.txt'
MINLEN = 6
class Trie(object):
"""Trie data structure"""
class Node(object):
"""A node in the trie"""
def __init__(self, char='\0', parent=None):
self.children = {}
self.char = char
self.final = False
self.parent = parent
def descend(self, char, extend=False):
"""Descend into the trie"""
if not char in self.children:
if not extend: return None
self.children[char] = Trie.Node(char,self)
return self.children[char]
def __init__(self):
self.root = Trie.Node()
def insert(self, word):
"""Insert a word in the trie"""
node = self.root
for char in word: node = node.descend(char, extend=True)
node.final = True
return node
def __contains__(self, word):
"""See if the trie contains a word"""
node = self.root
for char in word:
node = node.descend(char)
if not node: return False
return node.final
def words(self):
"""Yield every word in the trie"""
nodes = [self.root]
while nodes:
node = nodes.pop()
nodes += node.children.values()
if node.final:
word = []
while node:
if node.char != '\0': word.append(node.char)
node = node.parent
yield "".join(reversed(word))
def __iter__(self):
return self.words()
words = Trie()
with open(WORDFILE, "rt") as f:
for word in f.readlines():
words.insert(word.strip())
for word in words:
if len(word) < MINLEN: continue
even = word[::2]
odd = word[1::2]
if even in words and odd in words:
print(word, even, odd)
- Output:
twirly til wry truant tun rat troupe top rue triune tin rue triode tid roe throaty tray hot though tog huh theorem term hoe tattle ttl ate sweaty set way sturdy sud try strait sri tat strain sri tan sprain sri pan spatial sail pta sordid sri odd realty rat ely racial rca ail pounce puc one poodle pol ode pierre per ire peoria poi era parrot pro art oswald owl sad oriole oil roe lounge lug one joanne jan one jaunty jut any israel ire sal inroad ira nod george gog ere friend fin red forwent fret own fluent fun let fealty fat ely fabric fbi arc effete eft fee collude clue old claire car lie choosy cos hoy choose cos hoe calliope clip aloe brenda bed rna blaine ban lie battle btl ate assist ass sit ariadne aide ran apport apr pot annette ante net ambient abet min alpert apr let allied ale lid allele all lee alcott act lot agleam ala gem afield ail fed accuse acs cue accost acs cot
QB64
Const DLEN = 25104
Dim word$(1 To DLEN), alt$(0 To 1)
Dim i As Integer
Open "i:\unixdict.txt" For Input As #1
Do While Not EOF(1)
i = i + 1
Line Input #1, word$(i)
Loop
Close #1
For i = 1 To DLEN
If Not Len(word$(i)) < 6 Then 'Continue For
alt$(0) = ""
alt$(1) = ""
For j = 1 To Len(word$(i))
alt$(j Mod 2) = alt$(j Mod 2) + Mid$(word$(i), j, 1)
Next j
If isIn(word$(), alt$(0)) And isIn(word$(), alt$(1)) Then Print word$(i), alt$(1), alt$(0)
End If
Next i
End
Function isIn (word$(), s$)
For i = 1 To DLEN
If word$(i) = s$ Then isIn = 1: Exit Function
Next i
isIn = 0
End Function
- Output:
Same as FreeBASIC entry.
Quackery
[ stack ] is sift.test ( --> s )
protect sift.test
[ ]'[ sift.test put
[] [] rot
witheach
[ sift.test share do iff
[ nested join ]
else
[ swap dip
[ nested join ] ] ]
sift.test release ] is siftwith ( [ --> [ [ )
[ 1 & ] is odd ( n --> b )
[ stack ] is dict ( --> s )
[ dict share
dup dip find found ] is indict ( $ --> b )
$ "unixdict.txt" sharefile drop
nest$ dict put
dict share
siftwith [ dup size 6 < ]
drop witheach
[ dup siftwith [ i^ odd ]
dup indict iff
[ over indict iff
[ rot echo$
swap sp echo$
sp echo$ cr ]
else [ drop 2drop ] ]
else [ drop 2drop ] ]
dict release
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
A more straightforward approach:
[ [] [] rot witheach [ join swap ] ] is unzip ( [ --> [ [ )
[ $ "rosetta/unixdict.txt" sharefile
drop nest$
[] swap witheach
[ [ nested join ]
else drop ] ] constant is unixdict ( --> [ )
unixdict witheach
[ dup size 6 < iff
drop done
dup unzip
unixdict find
unixdict found iff
[ unixdict find
unixdict found iff
[ dup echo$ sp
unzip echo$ sp
echo$ cr ]
else drop ]
else 2drop ]
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient min abet annette net ante apport apr pot ariadne ran aide assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude old clue effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent own fret friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial pta sail sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem hoe term though tog huh throaty hot tray triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
Raku
unit sub MAIN ($file = 'unixdict.txt', :$min = 6);
my %words = $file.IO.slurp.words.map: * => 1;
my @alternades;
for %words {
next if .key.chars < $min;
my @letters = .key.comb;
my @alts = @letters[0,2 … *].join, @letters[1,3 … *].join;
@alternades.push(.key => @alts) if %words{@alts[0]} && %words{@alts[1]};
}
@alternades.=sort;
say "{+@alternades} alternades longer than {$min-1} characters found in $file:";
.say for @alternades > 10
?? (flat @alternades.head(5), '...', @alternades.tail(5))
!! @alternades;
- Output:
58 alternades longer than 5 characters found in unixdict.txt: accost => [acs cot] accuse => [acs cue] afield => [ail fed] agleam => [ala gem] alcott => [act lot] ... triode => [tid roe] triune => [tin rue] troupe => [top rue] truant => [tun rat] twirly => [til wry]
Refal
$ENTRY Go {
, <ReadFile 1 'unixdict.txt'>: e.Dict
= <FindAlternades (e.Dict) <Length6 e.Dict>>;
};
ReadFile {
s.Chan e.File =
<Open 'r' s.Chan e.File>
<ReadFile (s.Chan)>;
(s.Chan), <Get s.Chan>: {
0 = <Close s.Chan>;
e.Line = (e.Line) <ReadFile (s.Chan)>;
};
};
Length6 {
= ;
(e.Word) e.Dict,
<Lenw e.Word>: s.Len e.Word,
<Compare s.Len 5>: {
'+' = (e.Word) <Length6 e.Dict>;
s.X = <Length6 e.Dict>;
};
};
FindAlternades {
(e.Dict) = ;
(e.Dict) (e.Word) e.Words, <IsAlternadeWord (e.Dict) e.Word>: {
NoMatch = <FindAlternades (e.Dict) e.Words>;
Match (e.Word) (e.A1) (e.A2) =
<Prout e.Word ': ' e.A1 ', ' e.A2>
<FindAlternades (e.Dict) e.Words>;
};
};
Alternades {
(e.X) (e.Y) = (e.X) (e.Y);
(e.X) (e.Y) s.1 = (e.X s.1) (e.Y);
(e.X) (e.Y) s.1 s.2 e.W = <Alternades (e.X s.1) (e.Y s.2) e.W>;
e.W = <Alternades () () e.W>;
};
IsAlternadeWord {
(e.Dict) e.Word,
<Alternades e.Word>: (e.A1) (e.A2),
e.Dict: {
e.X (e.A1) e.Y (e.A2) e.Z = Match (e.Word) (e.A1) (e.A2);
e.X (e.A2) e.Y (e.A1) e.Z = Match (e.Word) (e.A1) (e.A2);
e.X = NoMatch;
};
};
- Output:
accost: acs, cot accuse: acs, cue afield: ail, fed agleam: ala, gem alcott: act, lot allele: all, lee allied: ale, lid alpert: apr, let ambient: abet, min annette: ante, net apport: apr, pot ariadne: aide, ran assist: ass, sit battle: btl, ate blaine: ban, lie brenda: bed, rna calliope: clip, aloe choose: cos, hoe choosy: cos, hoy claire: car, lie collude: clue, old effete: eft, fee fabric: fbi, arc fealty: fat, ely fluent: fun, let forwent: fret, own friend: fin, red george: gog, ere inroad: ira, nod israel: ire, sal jaunty: jut, any joanne: jan, one lounge: lug, one oriole: oil, roe oswald: owl, sad parrot: pro, art peoria: poi, era pierre: per, ire poodle: pol, ode pounce: puc, one racial: rca, ail realty: rat, ely sordid: sri, odd spatial: sail, pta sprain: sri, pan strain: sri, tan strait: sri, tat sturdy: sud, try sweaty: set, way tattle: ttl, ate theorem: term, hoe though: tog, huh throaty: tray, hot triode: tid, roe triune: tin, rue troupe: top, rue truant: tun, rat twirly: til, wry
REXX
version 1, caseless
This REXX version doesn't care what order the words in the dictionary are in, nor does it care what
case (lower/upper/mixed) the words are in, the search for alternades is caseless.
It also allows the minimum length to be specified on the command line (CL) as well as the dictionary file identifier.
/*REXX program finds all the caseless alternade words (within an identified dictionary).*/
parse arg minL iFID . /*obtain optional arguments from the CL*/
if minL=='' | minL=="," then minL= 6 /*Not specified? Then use the default.*/
if iFID=='' | iFID=="," then iFID='unixdict.txt' /* " " " " " " */
@.= /*default value of any dictionary word.*/
do #=1 while lines(iFID)\==0 /*read each word in the file (word=X).*/
x= strip( linein( iFID) ) /*pick off a word from the input line. */
$.#= x; upper x; @.x= . /*save: original case and the semaphore*/
end /*#*/ /* [↑] semaphore name is uppercased. */
#= # - 1 /*adjust word count because of DO loop.*/
finds= 0 /*count of the alternade words found. */
say copies('─', 30) # "words in the dictionary file: " iFID
say
do j=1 for #; L= length($.j) /*process all the words that were found*/
if L<minL then iterate /*Is word too short? Then ignore it. */
p.= /*initialize 2 parts of alternade word.*/
do k=1 for L; _= k // 2 /*build the " " " " " */
p._= p._ || substr($.j, k, 1) /*append to one part of alternade word.*/
end /*k*/
parse upper value p.0 p.1 with p0 p1 /*obtain the uppercase alternade parts.*/
if @.p0=='' | @.p1=='' then iterate /*either parts of alternade not extant?*/
finds= finds + 1 /*bump the count of alternades found.*/
say right(left($.j, 20), 25) left(p.1, 10) left(p.0, 10) /*indent a bit.*/
end /*j*/
/*stick a fork in it, we're all done. */
say copies('─',30) finds ' alternade words found with a minimum length of ' minL
- output when using the default inputs:
────────────────────────────── 25104 words in the dictionary file: unixdict.txt accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry ────────────────────────────── 58 alternade words found with a minimum length of 6
version 2
This REXX version only handles the case (lowercase) of the dictionary being used, in this case, only lowercase words.
Independently developed at the same time as version 1 :-)
/* REXX */
fid='d:\unix.txt'
cnt.=0 /* cnt.n -> words of length n */
ww.=0 /* ww.* the words to be analyzed */
w.=0 /* w.word = 1 if word is in unix.txt */
Do While lines(fid)>0
l=linein(fid) /* a word */
ll=length(l) /* its length */
cnt.ll=cnt.ll+1 /* count it */
w.l=1 /* word is in unix.txt */
If ll>=6 Then Do /* worth to be analyzed */
z=ww.0+1 /* add it to the list */
ww.z=l
ww.0=z
End
End
Say cnt.3 'three letter words'
Say cnt.4 'four letter words'
Say cnt.5 'five letter words'
Say cnt.6 'six letter words'
Say cnt.7 'seven letter words'
Say cnt.8 'eight letter words'
n=0
Do i=1 To ww.0
Parse Value split(ww.i) With u v
If w.u & w.v Then Do
n=n+1
Say format(n,2) left(ww.i,8) left(u,4) v
End
End
Exit
split: Procedure
/* split the word into components */
Parse Arg w
s.=''
Do While w<>''
Parse Var w uu +1 vv +1 w
s.u=s.u||uu
s.v=s.v||vv
End
Return s.u s.v
Output:
D:\>rexx alternade 796 three letter words 2187 four letter words 3161 five letter words 3873 six letter words 4060 seven letter words 3618 eight letter words 1 accost acs cot 2 accuse acs cue 3 afield ail fed 4 agleam ala gem 5 alcott act lot 6 allele all lee 7 allied ale lid 8 alpert apr let 9 ambient abet min 10 annette ante net 11 apport apr pot 12 ariadne aide ran 13 assist ass sit 14 battle btl ate 15 blaine ban lie 16 brenda bed rna 17 calliope clip aloe 18 choose cos hoe 19 choosy cos hoy 20 claire car lie 21 collude clue old 22 effete eft fee 23 fabric fbi arc 24 fealty fat ely 25 fluent fun let 26 forwent fret own 27 friend fin red 28 george gog ere 29 inroad ira nod 30 israel ire sal 31 jaunty jut any 32 joanne jan one 33 lounge lug one 34 oriole oil roe 35 oswald owl sad 36 parrot pro art 37 peoria poi era 38 pierre per ire 39 poodle pol ode 40 pounce puc one 41 racial rca ail 42 realty rat ely 43 sordid sri odd 44 spatial sail pta 45 sprain sri pan 46 strain sri tan 47 strait sri tat 48 sturdy sud try 49 sweaty set way 50 tattle ttl ate 51 theorem term hoe 52 though tog huh 53 throaty tray hot 54 triode tid roe 55 triune tin rue 56 troupe top rue 57 truant tun rat 58 twirly til wry
Ring
load "stdlib.ring"
cStr = read("unixdict.txt")
wordList = str2list(cStr)
sum = 0
see "working..." + nl + nl
for n = 1 to len(wordList)
wordOdd = ""
wordEven = ""
for m = 1 to len(wordList[n]) step 2
wordOdd = wordOdd + wordList[n][m]
next
for m = 2 to len(wordList[n]) step 2
wordEven = wordEven + wordList[n][m]
next
indOdd = find(wordList,wordOdd)
indEven = find(wordList,wordEven)
if indOdd > 0 and indEven > 0 and len(wordList[indOdd]) > 2 and len(wordList[indEven]) > 2
sum = sum + 1
see "" + sum + ". "
see "word = " + wordList[n] + nl
see "wordOdd = " + wordList[indOdd] + nl
see "wordEven = " + wordList[indEven] + nl + nl
ok
next
see "done..." + nl
Output:
working... 1. word = accost wordOdd = acs wordEven = cot 2. word = accuse wordOdd = acs wordEven = cue 3. word = afield wordOdd = ail wordEven = fed 4. word = agleam wordOdd = ala wordEven = gem 5. word = alcott wordOdd = act wordEven = lot 6. word = allele wordOdd = all wordEven = lee 7. word = allied wordOdd = ale wordEven = lid 8. word = alpert wordOdd = apr wordEven = let 9. word = ambient wordOdd = abet wordEven = min 10. word = annette wordOdd = ante wordEven = net 11. word = apport wordOdd = apr wordEven = pot 12. word = ariadne wordOdd = aide wordEven = ran 13. word = assist wordOdd = ass wordEven = sit 14. word = battle wordOdd = btl wordEven = ate 15. word = blaine wordOdd = ban wordEven = lie 16. word = brenda wordOdd = bed wordEven = rna 17. word = calliope wordOdd = clip wordEven = aloe 18. word = choose wordOdd = cos wordEven = hoe 19. word = choosy wordOdd = cos wordEven = hoy 20. word = claire wordOdd = car wordEven = lie 21. word = collude wordOdd = clue wordEven = old 22. word = effete wordOdd = eft wordEven = fee 23. word = fabric wordOdd = fbi wordEven = arc 24. word = fealty wordOdd = fat wordEven = ely 25. word = fluent wordOdd = fun wordEven = let 26. word = forwent wordOdd = fret wordEven = own 27. word = friend wordOdd = fin wordEven = red 28. word = george wordOdd = gog wordEven = ere 29. word = inroad wordOdd = ira wordEven = nod 30. word = israel wordOdd = ire wordEven = sal 31. word = jaunty wordOdd = jut wordEven = any 32. word = joanne wordOdd = jan wordEven = one 33. word = lounge wordOdd = lug wordEven = one 34. word = oriole wordOdd = oil wordEven = roe 35. word = oswald wordOdd = owl wordEven = sad 36. word = parrot wordOdd = pro wordEven = art 37. word = peoria wordOdd = poi wordEven = era 38. word = pierre wordOdd = per wordEven = ire 39. word = poodle wordOdd = pol wordEven = ode 40. word = pounce wordOdd = puc wordEven = one 41. word = racial wordOdd = rca wordEven = ail 42. word = realty wordOdd = rat wordEven = ely 43. word = sordid wordOdd = sri wordEven = odd 44. word = spatial wordOdd = sail wordEven = pta 45. word = sprain wordOdd = sri wordEven = pan 46. word = strain wordOdd = sri wordEven = tan 47. word = strait wordOdd = sri wordEven = tat 48. word = sturdy wordOdd = sud wordEven = try 49. word = sweaty wordOdd = set wordEven = way 50. word = tattle wordOdd = ttl wordEven = ate 51. word = theorem wordOdd = term wordEven = hoe 52. word = though wordOdd = tog wordEven = huh 53. word = throaty wordOdd = tray wordEven = hot 54. word = triode wordOdd = tid wordEven = roe 55. word = triune wordOdd = tin wordEven = rue 56. word = troupe wordOdd = top wordEven = rue 57. word = truant wordOdd = tun wordEven = rat 58. word = twirly wordOdd = til wordEven = wry done...
Ruby
words = File.open("unixdict.txt").map(&:chomp)
res = words.filter_map do |word|
next if word.size < 6
splitted = word.each_char.partition.with_index{|_,i| i.even? }.map(&:join)
next unless splitted.all?{|split| words.bsearch{|w| split <=> w} }
"#{word}: #{splitted.join(", ")}"
end
puts res
- Output:
accost: acs, cot accuse: acs, cue afield: ail, fed agleam: ala, gem alcott: act, lot allele: all, lee allied: ale, lid alpert: apr, let ambient: abet, min annette: ante, net apport: apr, pot ariadne: aide, ran assist: ass, sit battle: btl, ate blaine: ban, lie brenda: bed, rna calliope: clip, aloe choose: cos, hoe choosy: cos, hoy claire: car, lie collude: clue, old effete: eft, fee fabric: fbi, arc fealty: fat, ely fluent: fun, let forwent: fret, own friend: fin, red george: gog, ere inroad: ira, nod israel: ire, sal jaunty: jut, any joanne: jan, one lounge: lug, one oriole: oil, roe oswald: owl, sad parrot: pro, art peoria: poi, era pierre: per, ire poodle: pol, ode pounce: puc, one racial: rca, ail realty: rat, ely sordid: sri, odd spatial: sail, pta sprain: sri, pan strain: sri, tan strait: sri, tat sturdy: sud, try sweaty: set, way tattle: ttl, ate theorem: term, hoe though: tog, huh throaty: tray, hot triode: tid, roe triune: tin, rue troupe: top, rue truant: tun, rat twirly: til, wry
Rust
use std::collections::BTreeSet;
use std::fs::File;
use std::io::{self, BufRead};
fn load_dictionary(filename: &str) -> std::io::Result<BTreeSet<String>> {
let file = File::open(filename)?;
let mut dict = BTreeSet::new();
for line in io::BufReader::new(file).lines() {
dict.insert(line?);
}
Ok(dict)
}
fn main() {
match load_dictionary("unixdict.txt") {
Ok(dictionary) => {
for word in &dictionary {
if word.len() < 6 {
continue;
}
let mut odd_word = String::new();
let mut even_word = String::new();
for (i, c) in word.chars().enumerate() {
if (i & 1) == 0 {
odd_word.push(c);
} else {
even_word.push(c);
}
}
if dictionary.contains(&odd_word) && dictionary.contains(&even_word) {
println!("{:<10}{:<6}{}", word, odd_word, even_word);
}
}
}
Err(error) => eprintln!("{}", error),
}
}
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
SETL
program alternade;
dict := read_dict("unixdict.txt");
loop for word in dict | #word >= 6 do
if forall w in alt := alternades(word) | w in dict then
print(word + ": " + str alt);
end if;
end loop;
proc read_dict(fname);
dictfile := open(fname, "r");
dict := {getline(dictfile) : until eof(dictfile)};
close(dictfile);
return dict;
end proc;
proc alternades(word);
words := ["", ""];
loop for i in [1..#word] do
words((i+1) mod 2 + 1) +:= word(i);
end loop;
return words;
end proc;
end program;
- Output:
accost: [acs cot] accuse: [acs cue] afield: [ail fed] agleam: [ala gem] alcott: [act lot] allele: [all lee] allied: [ale lid] alpert: [apr let] ambient: [abet min] annette: [ante net] apport: [apr pot] ariadne: [aide ran] assist: [ass sit] battle: [btl ate] blaine: [ban lie] brenda: [bed rna] calliope: [clip aloe] choose: [cos hoe] choosy: [cos hoy] claire: [car lie] collude: [clue old] effete: [eft fee] fabric: [fbi arc] fealty: [fat ely] fluent: [fun let] forwent: [fret own] friend: [fin red] george: [gog ere] inroad: [ira nod] israel: [ire sal] jaunty: [jut any] joanne: [jan one] lounge: [lug one] oriole: [oil roe] oswald: [owl sad] parrot: [pro art] peoria: [poi era] pierre: [per ire] poodle: [pol ode] pounce: [puc one] racial: [rca ail] realty: [rat ely] sordid: [sri odd] spatial: [sail pta] sprain: [sri pan] strain: [sri tan] strait: [sri tat] sturdy: [sud try] sweaty: [set way] tattle: [ttl ate] theorem: [term hoe] though: [tog huh] throaty: [tray hot] triode: [tid roe] triune: [tin rue] troupe: [top rue] truant: [tun rat] twirly: [til wry]
Swift
import Foundation
func loadDictionary(_ path: String) throws -> Set<String> {
let contents = try String(contentsOfFile: path, encoding: String.Encoding.ascii)
return Set<String>(contents.components(separatedBy: "\n").filter{!$0.isEmpty})
}
func lpad(string: String, width: Int) -> String {
return string.count >= width ? string
: string + String(repeating: " ", count: width - string.count)
}
do {
let dictionary = try loadDictionary("unixdict.txt")
var alternades: [(String,String,String)] = []
for word in dictionary {
if word.count < 6 {
continue
}
var word1 = ""
var word2 = ""
for (i, c) in word.enumerated() {
if (i & 1) == 0 {
word1.append(c)
} else {
word2.append(c)
}
}
if dictionary.contains(word1) && dictionary.contains(word2) {
alternades.append((word, word1, word2))
}
}
alternades.sort(by: {$0.0 < $1.0})
for (word, word1, word2) in alternades {
print("\(lpad(string: word, width: 10))\(lpad(string: word1, width: 6))\(word2)")
}
} catch {
print(error.localizedDescription)
}
- Output:
accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
Tcl
set unixdict [dict create]
foreach word [read [open unixdict.txt]] {
dict set unixdict $word {}
}
proc is_alt_word word {
global unixdict
for {set i 0} {$i < [string length $word]} {incr i} {
append [expr {$i % 2 ? "odd" : "even"}] [string index $word $i]
}
if {[dict exists $unixdict $even] && [dict exists $unixdict $odd]} {
return [list $even $odd]
}
}
foreach word [dict keys $unixdict] {
if {[string length $word] >= 6 && [set oddeven [is_alt_word $word]] ne ""} {
puts "$word $oddeven"
}
}
- Output:
$ tclsh alternate_words.tcl | column -t accost acs cot accuse acs cue afield ail fed agleam ala gem alcott act lot allele all lee allied ale lid alpert apr let ambient abet min annette ante net apport apr pot ariadne aide ran assist ass sit battle btl ate blaine ban lie brenda bed rna calliope clip aloe choose cos hoe choosy cos hoy claire car lie collude clue old effete eft fee fabric fbi arc fealty fat ely fluent fun let forwent fret own friend fin red george gog ere inroad ira nod israel ire sal jaunty jut any joanne jan one lounge lug one oriole oil roe oswald owl sad parrot pro art peoria poi era pierre per ire poodle pol ode pounce puc one racial rca ail realty rat ely sordid sri odd spatial sail pta sprain sri pan strain sri tan strait sri tat sturdy sud try sweaty set way tattle ttl ate theorem term hoe though tog huh throaty tray hot triode tid roe triune tin rue troupe top rue truant tun rat twirly til wry
V (Vlang)
import os
fn main() {
bwords := os.read_lines('unixdict.txt')?//bytes.Fields(b)
mut dict := map[string]bool{}
mut words := bwords.clone()
for bword in bwords {
dict[bword] = true
}
println("'unixdict.txt' contains the following alternades of length 6 or more:\n")
mut count := 0
for word in words {
if word.len < 6 {
continue
}
mut w1 := ""
mut w2 := ""
for i, c in word {
if i%2 == 0 {
w1 += c.ascii_str()
} else {
w2 += c.ascii_str()
}
}
ok1 := w1 in dict
ok2 := w2 in dict
if ok1 && ok2 {
count++
println("${count:2}: ${word:-8} -> ${w1:-4} ${w2:-4}")
}
}
}
- Output:
Same as Go entry
Wren
import "io" for File
import "./set" for Set
import "./fmt" for Fmt
var wordList = "unixdict.txt" // local copy
var set = Set.new()
var words = File.read(wordList).trimEnd().split("\n")
for (word in words) set.add(word)
System.print("'unixdict.txt' contains the following alternades of length 6 or more:\n")
var count = 0
for (word in words) {
if (word.count >= 6) {
var w1 = ""
var w2 = ""
var i = 0
for (c in word) {
if (i%2 == 0) {
w1 = w1 + c
} else {
w2 = w2 + c
}
i = i + 1
}
if (set.contains(w1) && set.contains(w2)) {
count = count + 1
Fmt.print("$2d: $-8s -> $-4s $-4s", count, word, w1, w2)
}
}
}
- Output:
'unixdict.txt' contains the following alternades of length 6 or more: 1: accost -> acs cot 2: accuse -> acs cue 3: afield -> ail fed 4: agleam -> ala gem 5: alcott -> act lot 6: allele -> all lee 7: allied -> ale lid 8: alpert -> apr let 9: ambient -> abet min 10: annette -> ante net 11: apport -> apr pot 12: ariadne -> aide ran 13: assist -> ass sit 14: battle -> btl ate 15: blaine -> ban lie 16: brenda -> bed rna 17: calliope -> clip aloe 18: choose -> cos hoe 19: choosy -> cos hoy 20: claire -> car lie 21: collude -> clue old 22: effete -> eft fee 23: fabric -> fbi arc 24: fealty -> fat ely 25: fluent -> fun let 26: forwent -> fret own 27: friend -> fin red 28: george -> gog ere 29: inroad -> ira nod 30: israel -> ire sal 31: jaunty -> jut any 32: joanne -> jan one 33: lounge -> lug one 34: oriole -> oil roe 35: oswald -> owl sad 36: parrot -> pro art 37: peoria -> poi era 38: pierre -> per ire 39: poodle -> pol ode 40: pounce -> puc one 41: racial -> rca ail 42: realty -> rat ely 43: sordid -> sri odd 44: spatial -> sail pta 45: sprain -> sri pan 46: strain -> sri tan 47: strait -> sri tat 48: sturdy -> sud try 49: sweaty -> set way 50: tattle -> ttl ate 51: theorem -> term hoe 52: though -> tog huh 53: throaty -> tray hot 54: triode -> tid roe 55: triune -> tin rue 56: troupe -> top rue 57: truant -> tun rat 58: twirly -> til wry
XPL0
string 0; \use zero-terminated strings
int Dict(26000); \pointers to words (enough for unixdict.txt)
int DictSize; \actual number of pointers in Dict
func StrCmp(A, B); \Compare string A to B
char A, B; \Returns: >0 if A>B, =0 if A=B, and <0 if A<B
int I;
[for I:= 0 to -1>>1 do
[if A(I) # B(I) then return A(I) - B(I);
if A(I) = 0 then return 0;
];
]; \StrCmp
func LookUp(Word); \Return 'true' if Word is in Dict
char Word;
int Lo, Hi, I, Cmp;
[Lo:= 0; Hi:= DictSize-1;
loop [I:= (Lo+Hi) / 2; \binary search
Cmp:= StrCmp(Word, Dict(I));
if Cmp < 0 then Hi:= I-1 else Lo:= I+1;
if Cmp = 0 then return true;
if Lo > Hi then return false;
];
]; \LookUp
int I, I0, I1, DI, Ch, Count;
char Word, Alt0(25), Alt1(25);
def Tab=$09, LF=$0A, CR=$0D, EOF=$1A;
[FSet(FOpen("unixdict.txt", 0), ^I); \load dictionary
OpenI(3); \assume alphabetical order and all lowercase
DI:= 0; \ignore non-alpha characters: 0..9, ' and &
repeat Dict(DI):= Reserve(0); \get pointer to memory used to store Word
Word:= Dict(DI);
I:= 0;
loop [repeat Ch:= ChIn(3) until Ch # CR; \remove possible CR
if Ch=LF or Ch=EOF then quit;
Word(I):= Ch;
I:= I+1;
];
Word(I):= 0; \terminate Word string
I:= Reserve(I+1); \reserve memory used for Word
DI:= DI+1; \next dictionary entry
until Ch = EOF;
DictSize:= DI;
DI:= 0; Count:= 0;
repeat Word:= Dict(DI); \print out all alternade words
I:= 0; I0:= 0; I1:= 0;
loop [Ch:= Word(I); \get even and odd alternades
if Ch = 0 then quit;
if I&1 then [Alt1(I1):= Ch; I1:= I1+1]
else [Alt0(I0):= Ch; I0:= I0+1];
I:= I+1;
];
if I >= 6 then \Word must have at least 6 chars
[Alt0(I0):= 0; Alt1(I1):= 0;
if LookUp(Alt0) & LookUp(Alt1) then
[Count:= Count+1;
IntOut(0, Count); ChOut(0, Tab);
Text(0, Word); ChOut(0, Tab);
Text(0, Alt0); ChOut(0, Tab);
Text(0, Alt1); CrLf(0);
];
];
DI:= DI+1;
until DI >= DictSize;
]
- Output:
1 accost acs cot 2 accuse acs cue 3 afield ail fed 4 agleam ala gem 5 alcott act lot 6 allele all lee 7 allied ale lid 8 alpert apr let 9 ambient abet min 10 annette ante net 11 apport apr pot 12 ariadne aide ran 13 assist ass sit 14 battle btl ate 15 blaine ban lie 16 brenda bed rna 17 calliope clip aloe 18 choose cos hoe 19 choosy cos hoy 20 claire car lie 21 collude clue old 22 effete eft fee 23 fabric fbi arc 24 fealty fat ely 25 fluent fun let 26 forwent fret own 27 friend fin red 28 george gog ere 29 inroad ira nod 30 israel ire sal 31 jaunty jut any 32 joanne jan one 33 lounge lug one 34 oriole oil roe 35 oswald owl sad 36 parrot pro art 37 peoria poi era 38 pierre per ire 39 poodle pol ode 40 pounce puc one 41 racial rca ail 42 realty rat ely 43 sordid sri odd 44 spatial sail pta 45 sprain sri pan 46 strain sri tan 47 strait sri tat 48 sturdy sud try 49 sweaty set way 50 tattle ttl ate 51 theorem term hoe 52 though tog huh 53 throaty tray hot 54 triode tid roe 55 triune tin rue 56 troupe top rue 57 truant tun rat 58 twirly til wry