Changeable words: Difference between revisions
Content added Content deleted
m (Minor edit to C++ code) |
(Added C solution) |
||
Line 10: | Line 10: | ||
{{Template:Strings}} |
{{Template:Strings}} |
||
<br><br> |
<br><br> |
||
=={{header|C}}== |
|||
{{trans|Go}} |
|||
<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; |
|||
}</lang> |
|||
{{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++}}== |
=={{header|C++}}== |