Task: Teacup rim text


C++: #include <algorithm>
#include <fstream>
#include <iostream>
#include <set>
#include <string>
#include <vector>


std::set<std::string> load_dictionary(const std::string& filename) {
    std::ifstream in(filename);
    if (!in)
        throw std::runtime_error("Cannot open file " + filename);
    std::set<std::string> words;
    std::string word;
    while (getline(in, word))
        words.insert(word);
    return words;
}

void find_teacup_words(const std::set<std::string>& words) {
    std::vector<std::string> teacup_words;
    std::set<std::string> found;
    for (auto w = words.begin(); w != words.end(); ++w) {
        std::string word = *w;
        size_t len = word.size();
        if (len < 3 || found.find(word) != found.end())
            continue;
        teacup_words.clear();
        teacup_words.push_back(word);
        for (size_t i = 0; i + 1 < len; ++i) {
            std::rotate(word.begin(), word.begin() + 1, word.end());
            if (word == *w || words.find(word) == words.end())
                break;
            teacup_words.push_back(word);
        }
        if (teacup_words.size() == len) {
            found.insert(teacup_words.begin(), teacup_words.end());
            std::cout << teacup_words[0];
            for (size_t i = 1; i < len; ++i)
                std::cout << ' ' << teacup_words[i];
            std::cout << '\n';
        }
    }
}

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "usage: " << argv[0] << " dictionary\n";
        return EXIT_FAILURE;
    }
    try {
        find_teacup_words(load_dictionary(argv[1]));
    } catch (const std::exception& ex) {
        std::cerr << ex.what() << '\n';
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}



Go: package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "sort"
    "strings"
)

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func readWords(fileName string) []string {
    file, err := os.Open(fileName)
    check(err)
    defer file.Close()
    var words []string
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        word := strings.ToLower(strings.TrimSpace(scanner.Text()))
        if len(word) >= 3 {
            words = append(words, word)
        }
    }
    check(scanner.Err())
    return words
}

func rotate(runes []rune) {
    first := runes[0]
    copy(runes, runes[1:])
    runes[len(runes)-1] = first
}

func main() {
    dicts := []string{"mit_10000.txt", "unixdict.txt"} 
    for _, dict := range dicts {
        fmt.Printf("Using %s:\n\n", dict)
        words := readWords(dict)
        n := len(words)
        used := make(map[string]bool)
    outer:
        for _, word := range words {
            runes := []rune(word)
            variants := []string{word}
            for i := 0; i < len(runes)-1; i++ {
                rotate(runes)
                word2 := string(runes)
                if word == word2 || used[word2] {
                    continue outer
                }
                ix := sort.SearchStrings(words, word2)
                if ix == n || words[ix] != word2 {
                    continue outer
                }
                variants = append(variants, word2)
            }
            for _, variant := range variants {
                used[variant] = true
            }
            fmt.Println(variants)
        }
        fmt.Println()
    }
}