Words from neighbour ones: Difference between revisions
(→{{header|Phix}}: (yawn)) |
(Added C and C++ solutions) |
||
Line 14: | Line 14: | ||
<br>If ''newword'' in dictionary then show on this page. |
<br>If ''newword'' in dictionary then show on this page. |
||
<br> lenght of ''newword'' = 9 |
<br> lenght of ''newword'' = 9 |
||
=={{header|C}}== |
|||
<lang c>#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#define MAX_WORD_SIZE 80 |
|||
#define MIN_LENGTH 9 |
|||
#define WORD_SIZE (MIN_LENGTH + 1) |
|||
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 word_compare(const void* p1, const void* p2) { |
|||
return memcmp(p1, p2, WORD_SIZE); |
|||
} |
|||
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; |
|||
char* words = xmalloc(WORD_SIZE * capacity); |
|||
while (fgets(line, sizeof(line), in)) { |
|||
size_t len = strlen(line) - 1; // last character is newline |
|||
if (len < MIN_LENGTH) |
|||
continue; |
|||
line[len] = '\0'; |
|||
if (size == capacity) { |
|||
capacity *= 2; |
|||
words = xrealloc(words, WORD_SIZE * capacity); |
|||
} |
|||
memcpy(&words[size * WORD_SIZE], line, WORD_SIZE); |
|||
++size; |
|||
} |
|||
fclose(in); |
|||
qsort(words, size, WORD_SIZE, word_compare); |
|||
int count = 0; |
|||
char prev_word[WORD_SIZE] = { 0 }; |
|||
for (size_t i = 0; i + MIN_LENGTH <= size; ++i) { |
|||
char word[WORD_SIZE] = { 0 }; |
|||
for (size_t j = 0; j < MIN_LENGTH; ++j) |
|||
word[j] = words[(i + j) * WORD_SIZE + j]; |
|||
if (word_compare(word, prev_word) == 0) |
|||
continue; |
|||
if (bsearch(word, words, size, WORD_SIZE, word_compare)) |
|||
printf("%2d. %s\n", ++count, word); |
|||
memcpy(prev_word, word, WORD_SIZE); |
|||
} |
|||
free(words); |
|||
return EXIT_SUCCESS; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
1. applicate |
|||
2. architect |
|||
3. astronomy |
|||
4. christine |
|||
5. christoph |
|||
6. committee |
|||
7. composite |
|||
8. constrict |
|||
9. construct |
|||
10. different |
|||
11. extensive |
|||
12. greenwood |
|||
13. implement |
|||
14. improvise |
|||
15. intercept |
|||
16. interpret |
|||
17. interrupt |
|||
18. philosoph |
|||
19. prescript |
|||
20. receptive |
|||
21. telephone |
|||
22. transcend |
|||
23. transport |
|||
24. transpose |
|||
</pre> |
|||
=={{header|C++}}== |
|||
<lang cpp>#include <algorithm> |
|||
#include <cstdlib> |
|||
#include <fstream> |
|||
#include <iomanip> |
|||
#include <iostream> |
|||
#include <string> |
|||
#include <vector> |
|||
int main(int argc, char** argv) { |
|||
const int min_length = 9; |
|||
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> words; |
|||
while (getline(in, line)) { |
|||
if (line.size() >= min_length) |
|||
words.push_back(line); |
|||
} |
|||
std::sort(words.begin(), words.end()); |
|||
std::string previous_word; |
|||
int count = 0; |
|||
for (size_t i = 0, n = words.size(); i + min_length <= n; ++i) { |
|||
std::string word; |
|||
word.reserve(min_length); |
|||
for (size_t j = 0; j < min_length; ++j) |
|||
word += words[i + j][j]; |
|||
if (previous_word == word) |
|||
continue; |
|||
auto w = std::lower_bound(words.begin(), words.end(), word); |
|||
if (w != words.end() && *w == word) |
|||
std::cout << std::setw(2) << ++count << ". " << word << '\n'; |
|||
previous_word = word; |
|||
} |
|||
return EXIT_SUCCESS; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> |
|||
1. applicate |
|||
2. architect |
|||
3. astronomy |
|||
4. christine |
|||
5. christoph |
|||
6. committee |
|||
7. composite |
|||
8. constrict |
|||
9. construct |
|||
10. different |
|||
11. extensive |
|||
12. greenwood |
|||
13. implement |
|||
14. improvise |
|||
15. intercept |
|||
16. interpret |
|||
17. interrupt |
|||
18. philosoph |
|||
19. prescript |
|||
20. receptive |
|||
21. telephone |
|||
22. transcend |
|||
23. transport |
|||
24. transpose |
|||
</pre> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
Revision as of 18:30, 6 February 2021
- Task
Use the dictionary unixdict.txt
Delete from directory words which lenghts are smaller then 9
Let's take the words from next characters:
1 <= n < (dictionary lenght) - 9
char1 = 1st character of nth word.
char2 = 2st character of (n+1)th word.
char3 = 3st character of (n+2)th word.
...
char9 = 9st character of (n+8)th word.
newword = char1+char2+char3+...+char9
If newword in dictionary then show on this page.
lenght of newword = 9
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
- define MAX_WORD_SIZE 80
- define MIN_LENGTH 9
- define WORD_SIZE (MIN_LENGTH + 1)
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 word_compare(const void* p1, const void* p2) {
return memcmp(p1, p2, WORD_SIZE);
}
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; char* words = xmalloc(WORD_SIZE * capacity); while (fgets(line, sizeof(line), in)) { size_t len = strlen(line) - 1; // last character is newline if (len < MIN_LENGTH) continue; line[len] = '\0'; if (size == capacity) { capacity *= 2; words = xrealloc(words, WORD_SIZE * capacity); } memcpy(&words[size * WORD_SIZE], line, WORD_SIZE); ++size; } fclose(in); qsort(words, size, WORD_SIZE, word_compare); int count = 0; char prev_word[WORD_SIZE] = { 0 }; for (size_t i = 0; i + MIN_LENGTH <= size; ++i) { char word[WORD_SIZE] = { 0 }; for (size_t j = 0; j < MIN_LENGTH; ++j) word[j] = words[(i + j) * WORD_SIZE + j]; if (word_compare(word, prev_word) == 0) continue; if (bsearch(word, words, size, WORD_SIZE, word_compare)) printf("%2d. %s\n", ++count, word); memcpy(prev_word, word, WORD_SIZE); } free(words); return EXIT_SUCCESS;
}</lang>
- Output:
1. applicate 2. architect 3. astronomy 4. christine 5. christoph 6. committee 7. composite 8. constrict 9. construct 10. different 11. extensive 12. greenwood 13. implement 14. improvise 15. intercept 16. interpret 17. interrupt 18. philosoph 19. prescript 20. receptive 21. telephone 22. transcend 23. transport 24. transpose
C++
<lang cpp>#include <algorithm>
- include <cstdlib>
- include <fstream>
- include <iomanip>
- include <iostream>
- include <string>
- include <vector>
int main(int argc, char** argv) {
const int min_length = 9; 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> words; while (getline(in, line)) { if (line.size() >= min_length) words.push_back(line); } std::sort(words.begin(), words.end()); std::string previous_word; int count = 0; for (size_t i = 0, n = words.size(); i + min_length <= n; ++i) { std::string word; word.reserve(min_length); for (size_t j = 0; j < min_length; ++j) word += words[i + j][j]; if (previous_word == word) continue; auto w = std::lower_bound(words.begin(), words.end(), word); if (w != words.end() && *w == word) std::cout << std::setw(2) << ++count << ". " << word << '\n'; previous_word = word; } return EXIT_SUCCESS;
}</lang>
- Output:
1. applicate 2. architect 3. astronomy 4. christine 5. christoph 6. committee 7. composite 8. constrict 9. construct 10. different 11. extensive 12. greenwood 13. implement 14. improvise 15. intercept 16. interpret 17. interrupt 18. philosoph 19. prescript 20. receptive 21. telephone 22. transcend 23. transport 24. transpose
Phix
Oh gosh, this is all rather new and exciting.... <lang Phix>function over9(string word) return length(word)>=9 end function sequence dictionary = filter(split_any(get_text("demo/unixdict.txt")," \r\n"),over9) function slicen(integer n) return vslice(dictionary,n)[n..-10+n] end function sequence neighwords = unique(filter(columnize(apply(tagset(9),slicen)),"in",dictionary)) printf(1,"%d words: %s\n",{length(neighwords),join(shorten(neighwords,"",3))})</lang>
- Output:
24 words: applicate architect astronomy ... transcend transport transpose
Raku
<lang perl6>my @words_ge_9 = 'unixdict.txt'.IO.lines.grep( *.chars >= 9 ); my %words_eq_9 = @words_ge_9 .grep( *.chars == 9 ).Set;
my @new_words = gather for @words_ge_9.rotor( 9 => -8 ) -> @nine_words {
my $new_word = [~] map { @nine_words[$_].substr($_, 1) }, ^9;
take $new_word if %words_eq_9{$new_word};
}
.say for unique @new_words;</lang>
- Output:
applicate architect astronomy christine christoph committee composite constrict construct different extensive greenwood implement improvise intercept interpret interrupt philosoph prescript receptive telephone transcend transport transpose
Ring
<lang ring> cStr = read("unixdict.txt") wordList = str2list(cStr) nextwords = [] num = 0
see "working..." + nl
ln = len(wordList) for n = ln to 1 step -1
if len(wordList[n]) < 9 del(wordList,n) ok
next
see "New words are:" + nl
for n = 1 to len(wordList)-9
c1 = substr(wordList[n],1,1) c2 = substr(wordList[n+1],2,1) c3 = substr(wordList[n+2],3,1) c4 = substr(wordList[n+3],4,1) c5 = substr(wordList[n+4],5,1) c6 = substr(wordList[n+5],6,1) c7 = substr(wordList[n+6],7,1) c8 = substr(wordList[n+7],8,1) c9 = substr(wordList[n+8],9,1) str = c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 ind = find(wordList,str) if ind > 0 add(nextwords,wordList[ind]) ok
next
nextwords = sort(nextwords) for n = len(nextwords) to 2 step -1
if nextwords[n] = nextwords[n-1] del(nextwords,n) ok
next
for n = 1 to len(nextwords)
see "" + n + ". " + nextwords[n] + nl
next
see "done..." + nl </lang> Output:
working... New words are: 1. applicate 2. architect 3. astronomy 4. christine 5. christoph 6. committee 7. composite 8. constrict 9. construct 10. different 11. extensive 12. greenwood 13. implement 14. improvise 15. intercept 16. interpret 17. interrupt 18. philosoph 19. prescript 20. receptive 21. telephone 22. transcend 23. transport 24. transpose done...