Changeable words: Difference between revisions

no edit summary
m (→‎{{header|REXX}}: changed a comment.)
No edit summary
 
(48 intermediate revisions by 26 users not shown)
Line 6:
 
The length of any word shown should have a length &nbsp; <big>'''>&nbsp; 11</big>.
 
;Note:
* A copy of the specific [https://web.archive.org/web/20180611003215/http://www.puzzlers.org/pub/wordlists/unixdict.txt unixdict.txt] linked to should be used for consistency of results.
* Words <big>'''>&nbsp; 11</big>''' are required, ie of 12 characters or more.
 
 
Line 11 ⟶ 15:
<br><br>
 
;Reference:
* [[Levenshtein distance]]
<br><br>
=={{header|11l}}==
{{trans|Nim}}
{{trans|Go}}
 
<syntaxhighlight lang="11l">V words = File(‘unixdict.txt’).read().split("\n").filter(word -> word.len > 11)
 
F hamming_dist(word1, word2)
I word1.len != word2.len
R 0
V count = 0
L(i) 0 .< word1.len
I word1[i] != word2[i]
count++
I count == 2
L.break // don't care about counts > 2
R count
 
print("List of changeable words:\n")
V count = 0
L(i) 0 .< words.len
V word1 = words[i]
L(j) i + 1 .< words.len
V word2 = words[j]
I hamming_dist(word1, word2) == 1
print(word1‘ <-> ’word2)
count += 2
 
print("\nFound "count‘ changeable words.’)</syntaxhighlight>
 
{{out}}
<pre>
List of changeable words:
 
aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen
 
Found 52 changeable words.
</pre>
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_Io;
with Ada.Strings.Fixed;
with Ada.Containers.Indefinite_Vectors;
 
procedure Changeable is
use Ada.Text_Io, Ada.Strings.Fixed;
 
package String_Vectors is
new Ada.Containers.Indefinite_Vectors (Index_Type => Positive,
Element_Type => String);
 
Filename : constant String := "unixdict.txt";
File : File_Type;
Words : String_Vectors.Vector;
begin
Open (File, In_File, Filename);
while not End_Of_File (File) loop
declare
Word : constant String := Get_Line (File);
begin
if Word'Length > 11 then
Words.Append (Word);
end if;
end;
end loop;
Close (File);
 
for Word_Index_1 in Words.First_Index .. Words.Last_Index loop
for Word_Index_2 in Word_Index_1 + 1 .. Words.Last_Index loop
declare
Image : String (1 .. 14);
Word_1 : String renames Words (Word_Index_1);
Word_2 : String renames Words (Word_Index_2);
Match : Natural := 0;
begin
if Word_1'Length = Word_2'Length then
for Index in Word_1'Range loop
if Word_1 (Index) = Word_2 (Index) then
Match := Match + 1;
end if;
end loop;
if Match = Word_1'Length - 1 then
Move (Word_1, Image);
Put (Image); Put (" <-> ");
Move (Word_2, Image);
Put_Line (Image);
end if;
end if;
end;
end loop;
end loop;
end Changeable;</syntaxhighlight>
{{out}}
<pre>
aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen
</pre>
=={{header|ALGOL 68}}==
Brute force - tries each possible changed word.
<syntaxhighlight lang="algol68">
# find words where changing one letter results in another word #
# only words of 12 or more characters are to be considered #
IF FILE input file;
STRING file name = "unixdict.txt";
open( input file, file name, stand in channel ) /= 0
THEN
# failed to open the file #
print( ( "Unable to open """ + file name + """", newline ) )
ELSE
# file opened OK #
BOOL at eof := FALSE;
# set the EOF handler for the file - notes eof has been reached and #
# returns TRUE so processing can continue #
on logical file end( input file, ( REF FILE f )BOOL: at eof := TRUE );
 
# table of possible words - there are around 1000 12+ character words #
[ 1 : 2 000 ]STRING words; # in unixdict.txt #
 
# in-place quick sort an array of strings #
PROC s quicksort = ( REF[]STRING a, INT lb, ub )VOID:
IF ub > lb
THEN
# more than one element, so must sort #
INT left := lb;
INT right := ub;
# choosing the middle element of the array as the pivot #
STRING pivot := a[ left + ( ( right + 1 ) - left ) OVER 2 ];
WHILE
WHILE IF left <= ub THEN a[ left ] < pivot ELSE FALSE FI
DO
left +:= 1
OD;
WHILE IF right >= lb THEN a[ right ] > pivot ELSE FALSE FI
DO
right -:= 1
OD;
left <= right
DO
STRING t := a[ left ];
a[ left ] := a[ right ];
a[ right ] := t;
left +:= 1;
right -:= 1
OD;
s quicksort( a, lb, right );
s quicksort( a, left, ub )
FI # s quicksort # ;
 
# returns the length of s #
OP LENGTH = ( STRING s )INT: 1 + ( UPB s - LWB s );
 
# returns TRUE if words[ low : high ] contains 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 # ;
 
INT w count := 0; # store the 12 character words #
WHILE
STRING word;
get( input file, ( word, newline ) );
NOT at eof
DO
IF LENGTH word > 11 THEN
words[ w count +:= 1 ] := word
FI
OD;
close( input file );
s quicksort( words, 1, w count ); # sort the words #
FOR i TO w count DO # find the changeable words #
STRING word = words[ i ];
STRING c word := word;
FOR i FROM LWB word TO UPB word DO
FOR c FROM ABS word[ i ] + 1 TO ABS "z" DO
c word[ i ] := REPR c;
IF is word( c word, 1, w count ) THEN
FOR p FROM LENGTH word TO 15 DO print( ( " " ) ) OD;
print( ( word, " <-> ", c word, newline ) )
FI
OD;
c word[ i ] := word[ i ]
OD
OD
FI
</syntaxhighlight>
{{out}}
<pre>
aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen
</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">wordset: map read.lines relative "unixdict.txt" => strip
 
wordset: select wordset 'word -> 12 =< size word
results: new []
loop wordset 'a [
loop select wordset 'word [equal? size a size word] 'b [
if a <> b [
if 1 = levenshtein a b [
'results ++ @[sort @[a b]]
]
]
]
]
 
loop unique results 'result ->
print join.with:" - " result</syntaxhighlight>
 
{{out}}
 
<pre>aristotelean - aristotelian
claustrophobia - claustrophobic
committeeman - committeemen
committeewoman - committeewomen
complementary - complimentary
confirmation - conformation
congresswoman - congresswomen
councilwoman - councilwomen
craftsperson - draftsperson
eavesdropped - eavesdropper
frontiersman - frontiersmen
handicraftsman - handicraftsmen
incommutable - incomputable
installation - instillation
kaleidescope - kaleidoscope
neuroanatomy - neuroanotomy
newspaperman - newspapermen
nonagenarian - nonogenarian
onomatopoeia - onomatopoeic
philanthrope - philanthropy
prescription - proscription
schizophrenia - schizophrenic
shakespearean - shakespearian
spectroscope - spectroscopy
underclassman - underclassmen
upperclassman - upperclassmen</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">FileRead, db, % A_Desktop "\unixdict.txt"
oWord := [], Found := []
for i, word in StrSplit(db, "`n", "`r")
if (StrLen(word) > 11)
oWord[word] := true
 
for word1 in oWord
for word2 in oWord
if Changeable(word1, word2) && !Found[word2]
found[word1] := true, result .= word1 . "`t<-> " word2 "`n"
 
MsgBox, 262144, , % result
return
 
Changeable(s1, s2) {
if (StrLen(s1) <> StrLen(s2))
return 0
for i, v in StrSplit(s1)
if (v = SubStr(s2, i, 1))
num++
return (StrLen(s1) - num = 1)
}</syntaxhighlight>
{{out}}
<pre>aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f CHANGEABLE_WORDS.AWK unixdict.txt
#
# sorting:
# PROCINFO["sorted_in"] is used by GAWK
# SORTTYPE is used by Thompson Automation's TAWK
#
{ arr[$0]++ }
END {
a2z = "abcdefghijklmnopqrstuvwxyz"
a2z_leng = length(a2z)
PROCINFO["sorted_in"] = "@ind_str_asc" ; SORTTYPE = 1
for (word in arr) {
leng = length(word)
if (leng < 12) {
continue
}
printed = 0
for (i=1; i<=leng; i++) {
if (printed == 1) {
break
}
if (i == 1) {
L = ""
R = substr(word,2)
}
else if (i == leng) {
L = substr(word,1,leng-1)
R = ""
}
else {
L = substr(word,1,i)
R = substr(word,i+2)
}
for (j=1; j<a2z_leng; j++) {
new_word = L substr(a2z,j,1) R
if (new_word in arr && word != new_word) {
printf("%-15s %s\n",word,new_word)
printed = 1
count++
}
}
}
}
printf("%d words\n",count)
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
aristotelean aristotelian
aristotelian aristotelean
claustrophobia claustrophobic
claustrophobic claustrophobia
committeeman committeemen
committeemen committeeman
committeewoman committeewomen
committeewomen committeewoman
complementary complimentary
complimentary complementary
confirmation conformation
conformation confirmation
congresswoman congresswomen
congresswomen congresswoman
councilwoman councilwomen
councilwomen councilwoman
craftsperson draftsperson
draftsperson craftsperson
eavesdropped eavesdropper
eavesdropper eavesdropped
frontiersman frontiersmen
frontiersmen frontiersman
handicraftsman handicraftsmen
handicraftsmen handicraftsman
incommutable incomputable
incomputable incommutable
installation instillation
instillation installation
kaleidescope kaleidoscope
kaleidoscope kaleidescope
neuroanatomy neuroanotomy
neuroanotomy neuroanatomy
newspaperman newspapermen
newspapermen newspaperman
nonagenarian nonogenarian
nonogenarian nonagenarian
onomatopoeia onomatopoeic
onomatopoeic onomatopoeia
philanthrope philanthropy
philanthropy philanthrope
prescription proscription
proscription prescription
schizophrenia schizophrenic
schizophrenic schizophrenia
shakespearean shakespearian
shakespearian shakespearean
spectroscope spectroscopy
spectroscopy spectroscope
underclassman underclassmen
underclassmen underclassman
upperclassman upperclassmen
upperclassmen upperclassman
</pre>
=={{header|C}}==
{{trans|Go}}
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define MAX_WORD_SIZE 32
 
typedef struct string_tag {
size_t length;
char str[MAX_WORD_SIZE];
} string_t;
 
void fatal(const char* message) {
fprintf(stderr, "%s\n", message);
exit(1);
}
 
void* xmalloc(size_t n) {
void* ptr = malloc(n);
if (ptr == NULL)
fatal("Out of memory");
return ptr;
}
 
void* xrealloc(void* p, size_t n) {
void* ptr = realloc(p, n);
if (ptr == NULL)
fatal("Out of memory");
return ptr;
}
 
int hamming_distance(const string_t* str1, const string_t* str2) {
size_t len1 = str1->length;
size_t len2 = str2->length;
if (len1 != len2)
return 0;
int count = 0;
const char* s1 = str1->str;
const char* s2 = str2->str;
for (size_t i = 0; i < len1; ++i) {
if (s1[i] != s2[i])
++count;
// don't care about counts > 2 in this case
if (count == 2)
break;
}
return count;
}
 
int main(int argc, char** argv) {
const char* filename = argc < 2 ? "unixdict.txt" : argv[1];
FILE* in = fopen(filename, "r");
if (!in) {
perror(filename);
return EXIT_FAILURE;
}
char line[MAX_WORD_SIZE];
size_t size = 0, capacity = 1024;
string_t* dictionary = xmalloc(sizeof(string_t) * capacity);
while (fgets(line, sizeof(line), in)) {
if (size == capacity) {
capacity *= 2;
dictionary = xrealloc(dictionary, sizeof(string_t) * capacity);
}
size_t len = strlen(line) - 1;
if (len > 11) {
string_t* str = &dictionary[size];
str->length = len;
memcpy(str->str, line, len);
str->str[len] = '\0';
++size;
}
}
fclose(in);
printf("Changeable words in %s:\n", filename);
int n = 1;
for (size_t i = 0; i < size; ++i) {
const string_t* str1 = &dictionary[i];
for (size_t j = 0; j < size; ++j) {
const string_t* str2 = &dictionary[j];
if (i != j && hamming_distance(str1, str2) == 1)
printf("%2d: %-14s -> %s\n", n++, str1->str, str2->str);
}
}
free(dictionary);
return EXIT_SUCCESS;
}</syntaxhighlight>
 
{{out}}
<pre>
Changeable words in unixdict.txt:
1: aristotelean -> aristotelian
2: aristotelian -> aristotelean
3: claustrophobia -> claustrophobic
4: claustrophobic -> claustrophobia
5: committeeman -> committeemen
6: committeemen -> committeeman
7: committeewoman -> committeewomen
8: committeewomen -> committeewoman
9: complementary -> complimentary
10: complimentary -> complementary
11: confirmation -> conformation
12: conformation -> confirmation
13: congresswoman -> congresswomen
14: congresswomen -> congresswoman
15: councilwoman -> councilwomen
16: councilwomen -> councilwoman
17: craftsperson -> draftsperson
18: draftsperson -> craftsperson
19: eavesdropped -> eavesdropper
20: eavesdropper -> eavesdropped
21: frontiersman -> frontiersmen
22: frontiersmen -> frontiersman
23: handicraftsman -> handicraftsmen
24: handicraftsmen -> handicraftsman
25: incommutable -> incomputable
26: incomputable -> incommutable
27: installation -> instillation
28: instillation -> installation
29: kaleidescope -> kaleidoscope
30: kaleidoscope -> kaleidescope
31: neuroanatomy -> neuroanotomy
32: neuroanotomy -> neuroanatomy
33: newspaperman -> newspapermen
34: newspapermen -> newspaperman
35: nonagenarian -> nonogenarian
36: nonogenarian -> nonagenarian
37: onomatopoeia -> onomatopoeic
38: onomatopoeic -> onomatopoeia
39: philanthrope -> philanthropy
40: philanthropy -> philanthrope
41: prescription -> proscription
42: proscription -> prescription
43: schizophrenia -> schizophrenic
44: schizophrenic -> schizophrenia
45: shakespearean -> shakespearian
46: shakespearian -> shakespearean
47: spectroscope -> spectroscopy
48: spectroscopy -> spectroscope
49: underclassman -> underclassmen
50: underclassmen -> underclassman
51: upperclassman -> upperclassmen
52: upperclassmen -> upperclassman
</pre>
=={{header|C++}}==
{{trans|Go}}
<syntaxhighlight lang="cpp">#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
 
int hamming_distance(const std::string& str1, const std::string& str2) {
size_t len1 = str1.size();
size_t len2 = str2.size();
if (len1 != len2)
return 0;
int count = 0;
for (size_t i = 0; i < len1; ++i) {
if (str1[i] != str2[i])
++count;
// don't care about counts > 2 in this case
if (count == 2)
break;
}
return count;
}
 
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::vector<std::string> dictionary;
while (getline(in, line)) {
if (line.size() > 11)
dictionary.push_back(line);
}
std::cout << "Changeable words in " << filename << ":\n";
int n = 1;
for (const std::string& word1 : dictionary) {
for (const std::string& word2 : dictionary) {
if (hamming_distance(word1, word2) == 1)
std::cout << std::setw(2) << std::right << n++
<< ": " << std::setw(14) << std::left << word1
<< " -> " << word2 << '\n';
}
}
return EXIT_SUCCESS;
}</syntaxhighlight>
 
{{out}}
<pre>
Changeable words in unixdict.txt:
1: aristotelean -> aristotelian
2: aristotelian -> aristotelean
3: claustrophobia -> claustrophobic
4: claustrophobic -> claustrophobia
5: committeeman -> committeemen
6: committeemen -> committeeman
7: committeewoman -> committeewomen
8: committeewomen -> committeewoman
9: complementary -> complimentary
10: complimentary -> complementary
11: confirmation -> conformation
12: conformation -> confirmation
13: congresswoman -> congresswomen
14: congresswomen -> congresswoman
15: councilwoman -> councilwomen
16: councilwomen -> councilwoman
17: craftsperson -> draftsperson
18: draftsperson -> craftsperson
19: eavesdropped -> eavesdropper
20: eavesdropper -> eavesdropped
21: frontiersman -> frontiersmen
22: frontiersmen -> frontiersman
23: handicraftsman -> handicraftsmen
24: handicraftsmen -> handicraftsman
25: incommutable -> incomputable
26: incomputable -> incommutable
27: installation -> instillation
28: instillation -> installation
29: kaleidescope -> kaleidoscope
30: kaleidoscope -> kaleidescope
31: neuroanatomy -> neuroanotomy
32: neuroanotomy -> neuroanatomy
33: newspaperman -> newspapermen
34: newspapermen -> newspaperman
35: nonagenarian -> nonogenarian
36: nonogenarian -> nonagenarian
37: onomatopoeia -> onomatopoeic
38: onomatopoeic -> onomatopoeia
39: philanthrope -> philanthropy
40: philanthropy -> philanthrope
41: prescription -> proscription
42: proscription -> prescription
43: schizophrenia -> schizophrenic
44: schizophrenic -> schizophrenia
45: shakespearean -> shakespearian
46: shakespearian -> shakespearean
47: spectroscope -> spectroscopy
48: spectroscopy -> spectroscope
49: underclassman -> underclassmen
50: underclassmen -> underclassman
51: upperclassman -> upperclassmen
52: upperclassmen -> upperclassman
</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|Classes,SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
var Dict: TStringList; {List holds dictionary}
 
 
procedure DoChangeWords(Memo: TMemo);
{Do change word problem}
var I,J,K,Inx,Cnt: integer;
var S: string;
 
procedure Display(OldStr,NewStr: string);
{Display both the original word and the modified word}
begin
Inc(Cnt);
Memo.Lines.Add(IntToStr(Cnt)+': '+OldStr+' '+NewStr);
end;
 
begin
Cnt:=0;
{Check every word in the dictionary}
for I:=0 to Dict.Count-1 do
begin
{Only check words at least 12 chars long}
if Length(Dict[I])>=12 then
begin
{Test a specific position in the word}
for J:=1 to Length(Dict[I]) do
begin
{try all combinations of alpha chars in the position}
for K:=byte('a') to byte('z') do
begin
{skip if the char is already in the position}
if Dict[I][J]=char(K) then continue;
{Get a new copy of the word to modify}
S:=Dict[I];
{Modify the position}
S[J]:=char(K);
{Is it in the dictionary? }
Inx:=Dict.IndexOf(S);
{Display it if it is}
if Inx>=0 then Display(Dict[I],S);
end;
end;
end;
end;
end;
 
 
initialization
{Create/load dictionary}
Dict:=TStringList.Create;
Dict.LoadFromFile('unixdict.txt');
Dict.Sorted:=True;
finalization
Dict.Free;
end.
</syntaxhighlight>
{{out}}
<pre>
 
1: aristotelean aristotelian
2: aristotelian aristotelean
3: claustrophobia claustrophobic
4: claustrophobic claustrophobia
5: committeeman committeemen
6: committeemen committeeman
7: committeewoman committeewomen
8: committeewomen committeewoman
9: complementary complimentary
10: complimentary complementary
11: confirmation conformation
12: conformation confirmation
13: congresswoman congresswomen
14: congresswomen congresswoman
15: councilwoman councilwomen
16: councilwomen councilwoman
17: craftsperson draftsperson
18: draftsperson craftsperson
19: eavesdropped eavesdropper
20: eavesdropper eavesdropped
21: frontiersman frontiersmen
22: frontiersmen frontiersman
23: handicraftsman handicraftsmen
24: handicraftsmen handicraftsman
25: incommutable incomputable
26: incomputable incommutable
27: installation instillation
28: instillation installation
29: kaleidescope kaleidoscope
30: kaleidoscope kaleidescope
31: neuroanatomy neuroanotomy
32: neuroanotomy neuroanatomy
33: newspaperman newspapermen
34: newspapermen newspaperman
35: nonagenarian nonogenarian
36: nonogenarian nonagenarian
37: onomatopoeia onomatopoeic
38: onomatopoeic onomatopoeia
39: philanthrope philanthropy
40: philanthropy philanthrope
41: prescription proscription
42: proscription prescription
43: schizophrenia schizophrenic
44: schizophrenic schizophrenia
45: shakespearean shakespearian
46: shakespearian shakespearean
47: spectroscope spectroscopy
48: spectroscopy spectroscope
49: underclassman underclassmen
50: underclassmen underclassman
51: upperclassman upperclassmen
52: upperclassmen upperclassman
</pre>
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// Changeable words: Nigel Galloway. June 14th., 2021
let fN g=Seq.fold2(fun z n g->z+if n=g then 0 else 1) 0 g
let rec fG n g=match g with h::t->fG(n@(t|>List.choose(fun g->match fN g h with 1->Some(h,g)|_->None))) t|_->n
seq{use n=System.IO.File.OpenText("unixdict.txt") in while not n.EndOfStream do yield n.ReadLine()}|>Seq.filter(fun n->n.Length>11)
|>List.ofSeq|>List.groupBy(fun n->n.Length)|>Seq.collect(fun(_,n)->fG [] n)|>Seq.iter(fun(n,g)->printfn "%s <=> %s" n g)
</syntaxhighlight>
{{out}}
<pre>
claustrophobia <=> claustrophobic
committeewoman <=> committeewomen
handicraftsman <=> handicraftsmen
aristotelean <=> aristotelian
committeeman <=> committeemen
confirmation <=> conformation
councilwoman <=> councilwomen
craftsperson <=> draftsperson
eavesdropped <=> eavesdropper
frontiersman <=> frontiersmen
incommutable <=> incomputable
installation <=> instillation
kaleidescope <=> kaleidoscope
neuroanatomy <=> neuroanotomy
newspaperman <=> newspapermen
nonagenarian <=> nonogenarian
onomatopoeia <=> onomatopoeic
philanthrope <=> philanthropy
prescription <=> proscription
spectroscope <=> spectroscopy
complementary <=> complimentary
congresswoman <=> congresswomen
schizophrenia <=> schizophrenic
shakespearean <=> shakespearian
underclassman <=> underclassmen
upperclassman <=> upperclassmen
</pre>
=={{header|Factor}}==
{{works with|Factor|0.99 2021-02-05}}
<syntaxhighlight lang="factor">USING: assocs combinators.short-circuit formatting
io.encodings.ascii io.files kernel math math.combinatorics
math.distances sequences ;
 
: changeable? ( str str -- ? )
{ [ [ length ] bi@ = ] [ hamming-distance 1 = ] } 2&& ;
 
"unixdict.txt" ascii file-lines
[ length 11 > ] filter
2 [ first2 changeable? ] filter-combinations
[ "%s <-> %s\n" printf ] assoc-each</syntaxhighlight>
{{out}}
<pre>
aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen
</pre>
=={{header|FreeBASIC}}==
Brute force method, reuses some code from [[Odd_words#FreeBASIC]].
<langsyntaxhighlight lang="freebasic">
#define NULL 0
 
Line 69 ⟶ 995:
next i
curr = curr->nxt
wend</langsyntaxhighlight>
{{out}}
<pre>
Line 124 ⟶ 1,050:
upperclassman ---> upperclassmen
upperclassmen ---> upperclassman</pre>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
 
#plist NSAppTransportSecurity @{NSAllowsArbitraryLoads:YES}
 
include "NSLog.incl"
 
local fn Words as CFArrayRef
CFURLRef url = fn URLWithString( @"http://wiki.puzzlers.org/pub/wordlists/unixdict.txt" )
CFStringRef string = fn StringWithContentsOfURL( url, NSUTF8StringEncoding, NULL )
CFArrayRef array = fn StringComponentsSeparatedByCharactersInSet( string, fn CharacterSetNewlineSet )
CFMutableArrayRef words = fn MutableArrayWithCapacity(0)
for string in array
if ( len(string) > 11 )
MutableArrayAddObject( words, string )
end if
next
end fn = words
 
void local fn DoIt
dispatchglobal
CFArrayRef words = fn Words
CFStringRef wd1, wd2
long length, i, j
unichar chr
for wd1 in words
length = len(wd1)
for i = 0 to length - 1
chr = fn StringCharacterAtIndex( wd1, i )
for j = 97 to 122
if ( j == chr ) then continue
wd2 = fn StringWithFormat( @"%@%c%@", left(wd1,i), j, right(wd1,length-i-1) )
if ( fn ArrayContainsObject( words, wd2 ) )
NSLog(@"%@\t%@",wd1,wd2)
end if
next
next
next
dispatchend
end fn
 
fn DoIt
 
HandleEvents
</syntaxhighlight>
 
{{out}}
<pre style="height:30ex">
aristotelean aristotelian
aristotelian aristotelean
claustrophobia claustrophobic
claustrophobic claustrophobia
committeeman committeemen
committeemen committeeman
committeewoman committeewomen
committeewomen committeewoman
complementary complimentary
complimentary complementary
confirmation conformation
conformation confirmation
congresswoman congresswomen
congresswomen congresswoman
councilwoman councilwomen
councilwomen councilwoman
craftsperson draftsperson
draftsperson craftsperson
eavesdropped eavesdropper
eavesdropper eavesdropped
frontiersman frontiersmen
frontiersmen frontiersman
handicraftsman handicraftsmen
handicraftsmen handicraftsman
incommutable incomputable
incomputable incommutable
installation instillation
instillation installation
kaleidescope kaleidoscope
kaleidoscope kaleidescope
neuroanatomy neuroanotomy
neuroanotomy neuroanatomy
newspaperman newspapermen
newspapermen newspaperman
nonagenarian nonogenarian
nonogenarian nonagenarian
onomatopoeia onomatopoeic
onomatopoeic onomatopoeia
philanthrope philanthropy
philanthropy philanthrope
prescription proscription
proscription prescription
schizophrenia schizophrenic
schizophrenic schizophrenia
shakespearean shakespearian
shakespearian shakespearean
spectroscope spectroscopy
spectroscopy spectroscope
underclassman underclassmen
underclassmen underclassman
upperclassman upperclassmen
upperclassmen upperclassman
</pre>
 
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 179 ⟶ 1,209:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 237 ⟶ 1,267:
52: upperclassmen -> upperclassman
</pre>
=={{header|J}}==
<syntaxhighlight lang="j"> ;:inv ({~ ~.@($ /:~"1@#: I.@,)@(1=+/ .~: ::0:&>/~))(#~ 11<#@>) cutLF fread'unixdict.txt'
aristotelean aristotelian
claustrophobia claustrophobic
committeeman committeemen
committeewoman committeewomen
complementary complimentary
confirmation conformation
congresswoman congresswomen
councilwoman councilwomen
craftsperson draftsperson
eavesdropped eavesdropper
frontiersman frontiersmen
handicraftsman handicraftsmen
incommutable incomputable
installation instillation
kaleidescope kaleidoscope
neuroanatomy neuroanotomy
newspaperman newspapermen
nonagenarian nonogenarian
onomatopoeia onomatopoeic
philanthrope philanthropy
prescription proscription
schizophrenia schizophrenic
shakespearean shakespearian
spectroscope spectroscopy
underclassman underclassmen
upperclassman upperclassmen</syntaxhighlight>
=={{header|Java}}==
{{trans|Go}}
<syntaxhighlight lang="java">import java.io.*;
import java.util.*;
 
public class ChangeableWords {
=={{header|Julia}}==
public static void main(String[] args) {
After finding for example "are <=> art", we do not also list the redundant "art <=> are" below.
try {
<lang julia>function changeable(wordfile, lengthover)
final String fileName = "unixdict.txt";
words, results = split(read(wordfile, String)), []
List<String> dictionary = new ArrayList<>();
worddict = Dict(w => length(w) for w in words)
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
for w in words
len = get(worddict, w, 0) String line;
while ((line = reader.readLine()) != null) {
if len <= lengthover
continue if (line.length() > 11)
dictionary.add(line);
end
}
alternatives = [w[1:p[1]-1] * p[2] * w[p[1]+1:end] for p in Iterators.product(1:len, 'a':'z')]
for a in alternatives }
ifSystem.out.printf("Changeable awords !=in w && haskey(worddict%s:\n", afileName);
int n push!(results, join(sort([w, a]), " <=> "))1;
for (String word1 : breakdictionary) {
end for (String word2 : dictionary) {
if (word1 != word2 && hammingDistance(word1, word2) == 1)
end
System.out.printf("%2d: %-14s -> %s\n", n++, word1, word2);
end
}
println(join(sort(unique(results)), "\n"))
}
end
} catch (Exception e) {
e.printStackTtexture();
}
}
 
private static int hammingDistance(String str1, String str2) {
changeable("unixdict.txt", 11)
int len1 = str1.length();
</lang>{{out}}
int len2 = str2.length();
if (len1 != len2)
return 0;
int count = 0;
for (int i = 0; i < len1; ++i) {
if (str1.charAt(i) != str2.charAt(i))
++count;
// don't care about counts > 2 in this case
if (count == 2)
break;
}
return count;
}
}</syntaxhighlight>
 
{{out}}
<pre>
Changeable words in unixdict.txt:
aristotelean <=> aristotelian
1: aristotelean -> aristotelian
2: aristotelian -> aristotelean
3: claustrophobia -> claustrophobic
4: claustrophobic -> claustrophobia
5: committeeman -> committeemen
6: committeemen -> committeeman
7: committeewoman -> committeewomen
8: committeewomen -> committeewoman
9: complementary -> complimentary
10: complimentary -> complementary
11: confirmation -> conformation
12: conformation -> confirmation
13: congresswoman -> congresswomen
14: congresswomen -> congresswoman
15: councilwoman -> councilwomen
16: councilwomen -> councilwoman
17: craftsperson -> draftsperson
18: draftsperson -> craftsperson
19: eavesdropped -> eavesdropper
20: eavesdropper -> eavesdropped
21: frontiersman -> frontiersmen
22: frontiersmen -> frontiersman
23: handicraftsman -> handicraftsmen
24: handicraftsmen -> handicraftsman
25: incommutable -> incomputable
26: incomputable -> incommutable
27: installation -> instillation
28: instillation -> installation
29: kaleidescope -> kaleidoscope
30: kaleidoscope -> kaleidescope
31: neuroanatomy -> neuroanotomy
32: neuroanotomy -> neuroanatomy
33: newspaperman -> newspapermen
34: newspapermen -> newspaperman
35: nonagenarian -> nonogenarian
36: nonogenarian -> nonagenarian
37: onomatopoeia -> onomatopoeic
38: onomatopoeic -> onomatopoeia
39: philanthrope -> philanthropy
40: philanthropy -> philanthrope
41: prescription -> proscription
42: proscription -> prescription
43: schizophrenia -> schizophrenic
44: schizophrenic -> schizophrenia
45: shakespearean -> shakespearian
46: shakespearian -> shakespearean
47: spectroscope -> spectroscopy
48: spectroscopy -> spectroscope
49: underclassman -> underclassmen
50: underclassmen -> underclassman
51: upperclassman -> upperclassmen
52: upperclassmen -> upperclassman
</pre>
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="jq"># Emit a stream of words "greater than" the input word that differ by just one character.
def changeable_to($dict):
. as $w
| range(0;length) as $i
| (.[$i:$i+1]|explode[]) as $j
| [range($j+1;123) | [.] | implode] as $alphas # 122 is "z"
| .[:$i] + $alphas[] + .[$i+1:]
| select($dict[.]);
INDEX( inputs; . )
| . as $dict
| keys_unsorted[] # or keys[] for gojq
| select(length>11)
| . as $w
| [changeable_to($dict)] | unique[]
| "\($w) <=> \(.)"</syntaxhighlight>
Invocation: jq -n -rR -f changeable-words.jq unixdict.txt
{{out}}
<pre>
aristotelean <=> aristotelian
claustrophobia <=> claustrophobic
committeeman <=> committeemen
committeewoman <=> committeewomen
complementary <=> complimentary
confirmation <=> conformation
congresswoman <=> congresswomen
councilwoman <=> councilwomen
craftsperson <=> draftsperson
eavesdropped <=> eavesdropper
frontiersman <=> frontiersmen
handicraftsman <=> handicraftsmen
incommutable <=> incomputable
Line 288 ⟶ 1,446:
underclassman <=> underclassmen
upperclassman <=> upperclassmen
</pre>
=={{header|Julia}}==
See [[Alternade_words#Julia]] for the foreachword function.
<syntaxhighlight lang="julia">const alts = Set{String}()
function ischangeable(w, d)
alternatives = [w[1:p[1]-1] * p[2] * w[p[1]+1:end] for p in Iterators.product(1:length(w), 'a':'z')]
for a in alternatives
if a != w && haskey(d, a)
result = join(sort([w, a]), " <=> ")
if !(result in alts)
push!(alts, result)
return result
end
end
end
return ""
end
 
foreachword("unixdict.txt", ischangeable, minlen = 12, colwidth=40, numcols=2)
</syntaxhighlight>{{out}}
<pre>
Word source: unixdict.txt
 
aristotelean <=> aristotelian claustrophobia <=> claustrophobic
committeeman <=> committeemen committeewoman <=> committeewomen
complementary <=> complimentary confirmation <=> conformation
congresswoman <=> congresswomen councilwoman <=> councilwomen
craftsperson <=> draftsperson eavesdropped <=> eavesdropper
frontiersman <=> frontiersmen handicraftsman <=> handicraftsmen
incommutable <=> incomputable installation <=> instillation
kaleidescope <=> kaleidoscope neuroanatomy <=> neuroanotomy
newspaperman <=> newspapermen nonagenarian <=> nonogenarian
onomatopoeia <=> onomatopoeic philanthrope <=> philanthropy
prescription <=> proscription schizophrenia <=> schizophrenic
shakespearean <=> shakespearian spectroscope <=> spectroscopy
underclassman <=> underclassmen upperclassman <=> upperclassmen
</pre>
=={{header|Nim}}==
Using the standard module <code>std/editdistance</code> to get the distance between two words.
<syntaxhighlight lang="nim">import std/editdistance, sugar
 
# Build list of words with length >= 12.
let words = collect(newSeq):
for word in "unixdict.txt".lines:
if word.len >= 12:
word
 
echo "List of changeable words:\n"
var count = 0
for i in 0..<words.high:
let word1 = words[i]
for j in i+1..words.high:
let word2 = words[j]
if word1.len == word2.len and editDistance(word1, word2) == 1:
echo word1, " <-> ", word2
inc count, 2
 
echo "\nFound ", count, " changeable words."</syntaxhighlight>
 
{{out}}
<pre>List of changeable words:
 
aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen
 
Found 52 changeable words.</pre>
 
=={{header|Pascal}}==
==={{header|Free Pascal}}===
<syntaxhighlight lang="pascal">
{$mode ObjFPC}{$H+}
uses
Classes, SysUtils;
 
const
FNAME = 'unixdict.txt';
 
function OneCharDifference(s1, s2: string): boolean;
var
i, diffCount: integer;
begin
diffCount := 0;
if Length(s1) <> Length(s2) then
Exit(false);
for i := 1 to Length(s1) do
begin
if s1[i] <> s2[i] then
Inc(diffCount);
if diffCount > 1 then
Exit(false);
end;
Result := diffCount = 1;
end;
 
procedure PurgeList(var list: TStringList);
{ Remove every word that doesn't have at least 12 characters }
var
i: Integer;
begin
for i := Pred(list.Count) downto 0 do
if Length(list[i]) < 12 then
list.Delete(i);
end;
 
var
list: TStringList;
i, j: Integer;
 
begin
list := TStringList.Create;
try
list.LoadFromFile(FNAME);
PurgeList(list);
for i := 0 to list.Count - 2 do
for j := i + 1 to list.Count - 1 do
if OneCharDifference(list[i], list[j]) then
writeln(list[i]:15, ' <-> ', list[j]);
finally
list.Free;
end;
end.
</syntaxhighlight>
{{out}}
<pre>
aristotelean <-> aristotelian
claustrophobia <-> claustrophobic
committeeman <-> committeemen
committeewoman <-> committeewomen
complementary <-> complimentary
confirmation <-> conformation
congresswoman <-> congresswomen
councilwoman <-> councilwomen
craftsperson <-> draftsperson
eavesdropped <-> eavesdropper
frontiersman <-> frontiersmen
handicraftsman <-> handicraftsmen
incommutable <-> incomputable
installation <-> instillation
kaleidescope <-> kaleidoscope
neuroanatomy <-> neuroanotomy
newspaperman <-> newspapermen
nonagenarian <-> nonogenarian
onomatopoeia <-> onomatopoeic
philanthrope <-> philanthropy
prescription <-> proscription
schizophrenia <-> schizophrenic
shakespearean <-> shakespearian
spectroscope <-> spectroscopy
underclassman <-> underclassmen
upperclassman <-> upperclassmen
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict;
Line 307 ⟶ 1,639:
}
push @{ $words[length] }, $_;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 336 ⟶ 1,668:
underclassman <-> underclassmen
upperclassman <-> upperclassmen
</pre> Alternatively:
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Changeable_words
=={{header|Phix}}==
use warnings;
<lang Phix>function changeable(string a, b)
return length(a)=length(b) and sum(sq_ne(a,b))=1
end function
 
local $_ = do {local(@ARGV, $/) = 'unixdict.txt'; <> =~ s/^.{0,11}\n//gmr };
function over11(string word) return length(word)>11 end function
my $count = 0;
sequence words = filter(get_text("demo/unixdict.txt",GT_LF_STRIPPED),over11),
printf "%3d: %15s <-> %s\n", ++$count, $1, $4
res = {}
while /^ ((\N*)\N(\N*)) \n(?=.*^ (\2\N\3) \n)/gmsx;</syntaxhighlight>
for i=1 to length(words) do
{{out}}
for j=i+1 to length(words) do
<pre>
if changeable(words[i],words[j]) then
1: aristotelean <-> aristotelian
res = append(res,words[i]&" <=> "&words[j])
2: claustrophobia <-> claustrophobic
end if
3: committeeman <-> committeemen
end for
4: committeewoman <-> committeewomen
end for
5: complementary <-> complimentary
printf(1,"%d changeable words found:\n%s\n",{length(res),join(shorten(res,"",3),"\n")})</lang>
6: confirmation <-> conformation
7: congresswoman <-> congresswomen
8: councilwoman <-> councilwomen
9: craftsperson <-> draftsperson
10: eavesdropped <-> eavesdropper
11: frontiersman <-> frontiersmen
12: handicraftsman <-> handicraftsmen
13: incommutable <-> incomputable
14: installation <-> instillation
15: kaleidescope <-> kaleidoscope
16: neuroanatomy <-> neuroanotomy
17: newspaperman <-> newspapermen
18: nonagenarian <-> nonogenarian
19: onomatopoeia <-> onomatopoeic
20: philanthrope <-> philanthropy
21: prescription <-> proscription
22: schizophrenia <-> schizophrenic
23: shakespearean <-> shakespearian
24: spectroscope <-> spectroscopy
25: underclassman <-> underclassmen
26: upperclassman <-> upperclassmen
</pre>
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">changeable</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_ne</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">))=</span><span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">over11</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">word</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">return</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">word</span><span style="color: #0000FF;">)></span><span style="color: #000000;">11</span> <span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">words</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">filter</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">unix_dict</span><span style="color: #0000FF;">(),</span><span style="color: #000000;">over11</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">changeable</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]&</span><span style="color: #008000;">" &lt;=&gt; "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d changeable words found:\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">shorten</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 365 ⟶ 1,737:
upperclassman <=> upperclassmen
</pre>
=={{header|Prolog}}==
{{works with|SWI Prolog}}
{{trans|Go}}
<syntaxhighlight lang="prolog">:- dynamic dictionary_word/1.
 
main:-
=={{header|Python}}==
File_name = 'unixdict.txt',
load_dictionary_from_file(File_name, 12),
print_changeable_words(File_name).
 
load_dictionary_from_file(File, Min_length):-
{{incorrect|Python| <br><br> This program uses MINLENGTH of '''11''' instead of '''12'''). <br><br>}}
open(File, read, Stream),
retractall(dictionary_word(_)),
load_dictionary_from_stream(Stream, Min_length),
close(Stream).
 
load_dictionary_from_stream(Stream, Min_length):-
read_line_to_string(Stream, String),
String \= end_of_file,
!,
string_length(String, Length),
(Length >= Min_length ->
assertz(dictionary_word(String))
;
true),
load_dictionary_from_stream(Stream, Min_length).
load_dictionary_from_stream(_, _).
 
print_changeable_words(File_name):-
writef('Changeable words in %w:\n', [File_name]),
findall([Word1, Word2],
(dictionary_word(Word1),
dictionary_word(Word2),
Word1 \= Word2,
hamming_distance(Word1, Word2, 1)),
Words),
nth1(N, Words, [Word1, Word2]),
writef('%3r: %15l-> %w\n', [N, Word1, Word2]),
fail.
print_changeable_words(_).
 
hamming_distance(String1, String2, Dist):-
string_chars(String1, Chars1),
string_chars(String2, Chars2),
hamming_distance(Chars1, Chars2, Dist, 0).
 
hamming_distance([], [], Dist, Dist):-!.
hamming_distance([Ch|Chars1], [Ch|Chars2], Dist, Count):-
!,
hamming_distance(Chars1, Chars2, Dist, Count).
hamming_distance([_|Chars1], [_|Chars2], Dist, Count):-
Count1 is Count + 1,
Count1 < 2,
hamming_distance(Chars1, Chars2, Dist, Count1).</syntaxhighlight>
 
{{out}}
<pre>
Changeable words in unixdict.txt:
1: aristotelean -> aristotelian
2: aristotelian -> aristotelean
3: claustrophobia -> claustrophobic
4: claustrophobic -> claustrophobia
5: committeeman -> committeemen
6: committeemen -> committeeman
7: committeewoman -> committeewomen
8: committeewomen -> committeewoman
9: complementary -> complimentary
10: complimentary -> complementary
11: confirmation -> conformation
12: conformation -> confirmation
13: congresswoman -> congresswomen
14: congresswomen -> congresswoman
15: councilwoman -> councilwomen
16: councilwomen -> councilwoman
17: craftsperson -> draftsperson
18: draftsperson -> craftsperson
19: eavesdropped -> eavesdropper
20: eavesdropper -> eavesdropped
21: frontiersman -> frontiersmen
22: frontiersmen -> frontiersman
23: handicraftsman -> handicraftsmen
24: handicraftsmen -> handicraftsman
25: incommutable -> incomputable
26: incomputable -> incommutable
27: installation -> instillation
28: instillation -> installation
29: kaleidescope -> kaleidoscope
30: kaleidoscope -> kaleidescope
31: neuroanatomy -> neuroanotomy
32: neuroanotomy -> neuroanatomy
33: newspaperman -> newspapermen
34: newspapermen -> newspaperman
35: nonagenarian -> nonogenarian
36: nonogenarian -> nonagenarian
37: onomatopoeia -> onomatopoeic
38: onomatopoeic -> onomatopoeia
39: philanthrope -> philanthropy
40: philanthropy -> philanthrope
41: prescription -> proscription
42: proscription -> prescription
43: schizophrenia -> schizophrenic
44: schizophrenic -> schizophrenia
45: shakespearean -> shakespearian
46: shakespearian -> shakespearean
47: spectroscope -> spectroscopy
48: spectroscopy -> spectroscope
49: underclassman -> underclassmen
50: underclassmen -> underclassman
51: upperclassman -> upperclassmen
52: upperclassmen -> upperclassman
</pre>
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">from collections import defaultdict, Counter
 
 
def getwords(minlength=11, fname='unixdict.txt'):
"Return set of lowercased words of >= given number of characters"
with open(fname) as f:
words = f.read().strip().lower().split()
return {w for w in words if len(w) >= minlength}
 
words11 = getwords()
Line 408 ⟶ 1,888:
print(f"\n{len(cwords)} words that are from changing a char from other words:")
for v in sorted(cwords):
print(f" {v[0]:12} From {', '.join(v[1:])}")</langsyntaxhighlight>
 
{{out}}
<pre>276 words that are from deleting a char from other words:
choreograph From choreography
chromatograph From chromatography
chronograph From chronography
conservator From conservatory
contributor From contributory
dodecahedra From dodecahedral
econometric From econometrica
electroencephalograph From electroencephalography
evolutionary From revolutionary
headquarter From headquarters
homomorphic From homeomorphic
internecine From internescine
megalomania From megalomaniac
michelangelo From michaelangelo
nymphomania From nymphomaniac
polarograph From polarography
referential From preferential
reservation From preservation
residential From presidential
sarsparilla From sarsaparilla
seismograph From seismography
spectrograph From spectrography
sportswrite From sportswriter
straightway From straightaway
synchronous From asynchronous
tetrafluoride From tetrafluouride
trifluoride From trifluouride
 
5426 words that are from changing a char from other words:
aristotelean From aristotelian
businessman From businessmen
calorimeter From colorimeter
christensen From christenson
churchwoman From churchwomen
claustrophobia From claustrophobic
committeeman From committeemen
committeewoman From committeewomen
complainant From complaisant
complementary From complimentary
confirmation From conformation
congressman From congressmen
congresswoman From congresswomen
constrictor From constructor
councilwoman From councilwomen
countersink From countersunk
countryside From countrywide
craftsperson From draftsperson
crystalline From crystallite
declamation From declaration
declamation From reclamation
declamatory From declaratory
demonstrate From remonstrate
eavesdropped From eavesdropper
exhortation From exportation
frontiersman From frontiersmen
handicapped From handicapper
handicraftsman From handicraftsmen
hydrophobia From hydrophobic
impartation From importation
implementer From implementor
incommutable From incomputable
infantryman From infantrymen
installation From instillation
irredentism From irredentist
kaleidescope From kaleidoscope
matriarchal From patriarchal
matrimonial From patrimonial
neuroanatomy From neuroanotomy
newspaperman From newspapermen
nonagenarian From nonogenarian
onomatopoeia From onomatopoeic
parentheses From parenthesis
philanthrope From philanthropy
preposition From proposition
prescription From proscription
schizophrenia From schizophrenic
secretarial From secretariat
shakespearean From shakespearian
spectroscope From spectroscopy
transmitted From transmitter
trencherman From trenchermen
underclassman From underclassmen
upperclassman From upperclassmen</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery"> [ over size
over size != iff
[ 2drop false ]
done
0 unrot
witheach
[ over i^ peek
!= rot + swap
over 2 = if
conclude ]
drop 1 = ] is 1diff ( $ $ --> b )
 
$ "rosetta/unixdict.txt"
sharefile drop nest$
[] swap witheach
[ dup size 11 > iff
[ nested join ]
else drop ]
[ behead over witheach
[ 2dup
1diff iff
[ over echo$
sp echo$ cr ]
else drop ]
drop
dup size 1 = until ]
drop</syntaxhighlight>
 
{{out}}
 
<pre>aristotelean aristotelian
claustrophobia claustrophobic
committeeman committeemen
committeewoman committeewomen
complementary complimentary
confirmation conformation
congresswoman congresswomen
councilwoman councilwomen
craftsperson draftsperson
eavesdropped eavesdropper
frontiersman frontiersmen
handicraftsman handicraftsmen
incommutable incomputable
installation instillation
kaleidescope kaleidoscope
neuroanatomy neuroanotomy
newspaperman newspapermen
nonagenarian nonogenarian
onomatopoeia onomatopoeic
philanthrope philanthropy
prescription proscription
schizophrenia schizophrenic
shakespearean shakespearian
spectroscope spectroscopy
underclassman underclassmen
upperclassman upperclassmen</pre>
 
=={{header|Raku}}==
Line 500 ⟶ 1,990:
 
Get the best of both worlds by doing an initial filter with Sorensen, then get exact results with Levenshtein.
<syntaxhighlight lang="raku" perl6line>use Text::Levenshtein;
use Text::Sorensen :sorensen;
 
Line 518 ⟶ 2,008:
%skip{$_}++ for @sorensens[@levenshtein];
": {$this.fmt('%14s')} <-> ", @sorensens[@levenshtein].join: ', ';
}</langsyntaxhighlight>
{{out}}
<pre> 1: aristotelean <-> aristotelian
Line 546 ⟶ 2,036:
25: underclassman <-> underclassmen
26: upperclassman <-> upperclassmen</pre>
 
=={{header|REXX}}==
This REXX version doesn't care what order the words in the dictionary are in, &nbsp; nor does it care what
Line 552 ⟶ 2,041:
 
It also allows the minimum length to be specified on the command line (CL) as well as the dictionary file identifier.
<langsyntaxhighlight lang="rexx">/*REXX program finds changeable words (within an identified dict.), changing any letter.*/
parse arg minL iFID . /*obtain optional arguments from the CL*/
if minL=='' | minL=="," then minL= 12 /*Not specified? Then use the default.*/
if iFID=='' | iFID=="," then iFID='unixdict.txt' /* " " " " " " */
@.= call readDict /*defaultread value& ofprocess/filter anythe 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. */
end /*#*/ /* [↑] semaphore name is uppercased. */
 
say copies('─', 30) # "words in the dictionary file: " iFID
finds= 0 /*count of the changeable words found.*/
abc= 'abcdefghijklmnopqrstuvwxyz'; upper abc /*alphabet ordered by frequency of use.*/
Labc= length(abc) /*the length of the alphabet to be used*/
finds= 0 /*count of the changeable words found.*/
 
do j=1 for #-1n; L= length($.j) /*process all the words that were found*/
if L<minL then iterate /*Is the word long enough? No, skip it*/
if \datatype($.j, 'M') then iterate /*verify that the word is all letters. */
x= $.j; upper x /*get an uppercased version of the word*/
 
pad= left('', 9) /*PAD: used for indenting the output.*/
do k=1 for L; y= substr(x, k, 1) /*Y: the current letter being changed.*/
do c=1 for Labc /* [↓] change the Y letter to another.*/
?= substr(abc, c, 1) /*get a new char to replace one in word*/
if ?==y then iterate /*Is this the same char? Then use next*/
new= overlay(?, x, k); upper new /*create a spanking new (changed) word.*/
if @.new=='' then iterate /*ifNew theword newnot wordin isn'tdictionary? a word, skipSkip it.*/
finds= finds + 1 /*bump count of changeable words found.*/
say pad right(left($.j, 30), 40) @.new /*indent original word for readability.*/
end /*c*/
end /*k*/
end /*j*/
 
say copies('─', 30) finds ' changeable words found with a minimum length of ' minL</lang>
say copies('─', 30) finds ' changeable words found with a minimum length of ' minL
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
readDict: n=0; @.= /*N: the word count of usable words. */
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. */
if length(x)<minL then iterate /*Is the word too short? Then skip it.*/
if \datatype(x, 'M') then iterate /* " " " not alphabetic? Skip it.*/
n= n + 1; $.n= x; /*bump the word counter; assign to $. */
upper x; @.x= $.n /*assign uppercased word ───► array. */
end /*#*/ /* [↑] semaphore name is uppercased. */
#= # - 1 /*adjust word count because of DO loop.*/
say copies('─', 30) # "words ("n 'usable words) in the dictionary file: ' iFID
return</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
────────────────────────────── 2510525104 words (1064 usable words) in the dictionary file: unixdict.txt
aristotelean aristotelian
aristotelian aristotelean
Line 641 ⟶ 2,135:
────────────────────────────── 52 changeable words found with a minimum length of 12
</pre>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
cStr = read("unixdict.txt")
wordList = str2list(cStr)
Line 679 ⟶ 2,172:
 
see "done..." + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 738 ⟶ 2,231:
done...
</pre>
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">words = File.open("unixdict.txt").readlines.map(&:chomp).select{|w| w.size > 11 }
 
size_groups = words.group_by(&:size).sort.map(&:last)
res = size_groups.flat_map do |group|
group.combination(2).select{|word1, word2| word1.chars.zip(word2.chars).one?{|c1, c2| c1 != c2} }
end
 
puts "Found #{res.size} changeable word pairs:"
res.each{|w1, w2|puts "#{w1} - #{w2}" }
</syntaxhighlight>
{{out}}
<pre>Found 26 changeable word pairs:
aristotelean - aristotelian
committeeman - committeemen
confirmation - conformation
councilwoman - councilwomen
craftsperson - draftsperson
eavesdropped - eavesdropper
frontiersman - frontiersmen
incommutable - incomputable
installation - instillation
kaleidescope - kaleidoscope
neuroanatomy - neuroanotomy
newspaperman - newspapermen
nonagenarian - nonogenarian
onomatopoeia - onomatopoeic
philanthrope - philanthropy
prescription - proscription
spectroscope - spectroscopy
complementary - complimentary
congresswoman - congresswomen
schizophrenia - schizophrenic
shakespearean - shakespearian
underclassman - underclassmen
upperclassman - upperclassmen
claustrophobia - claustrophobic
committeewoman - committeewomen
handicraftsman - handicraftsmen
</pre>
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">var file = File("unixdict.txt")
 
if (!file.exists) {
require('LWP::Simple')
say ":: Retrieving #{file} from internet..."
%S<LWP::Simple>.mirror(
'https://web.archive.org/web/20180611003215if_/' +
'http://www.puzzlers.org:80/pub/wordlists/unixdict.txt',
'unixdict.txt')
}
 
var words = file.read.words
var bucket = Hash()
var count = 0
 
words.each {|word|
 
var len = word.len
 
len > 11 || next
bucket{len} := []
 
bucket{len}.each{|prev|
if (prev ^ word -> count("\0") == len-1) {
printf("%2d: %20s <-> %s\n", ++count, prev, word)
}
}
bucket{len} << word
}</syntaxhighlight>
{{out}}
<pre>
1: aristotelean <-> aristotelian
2: claustrophobia <-> claustrophobic
3: committeeman <-> committeemen
4: committeewoman <-> committeewomen
5: complementary <-> complimentary
6: confirmation <-> conformation
7: congresswoman <-> congresswomen
8: councilwoman <-> councilwomen
9: craftsperson <-> draftsperson
10: eavesdropped <-> eavesdropper
11: frontiersman <-> frontiersmen
12: handicraftsman <-> handicraftsmen
13: incommutable <-> incomputable
14: installation <-> instillation
15: kaleidescope <-> kaleidoscope
16: neuroanatomy <-> neuroanotomy
17: newspaperman <-> newspapermen
18: nonagenarian <-> nonogenarian
19: onomatopoeia <-> onomatopoeic
20: philanthrope <-> philanthropy
21: prescription <-> proscription
22: schizophrenia <-> schizophrenic
23: shakespearean <-> shakespearian
24: spectroscope <-> spectroscopy
25: underclassman <-> underclassmen
26: upperclassman <-> upperclassmen
</pre>
=={{header|Wren}}==
{{libheader|Wren-fmt}}
Using the Hamming Distance between two equal length strings which needs to be 1 here:
<langsyntaxhighlight ecmascriptlang="wren">import "io" for File
import "./fmt" for Fmt
 
var hammingDist = Fn.new { |s1, s2|
Line 773 ⟶ 2,365:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 833 ⟶ 2,425:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="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
Line 906 ⟶ 2,498:
DI:= DI+1;
until DI >= DictSize;
]</langsyntaxhighlight>
 
{{out}}
45

edits