/// Podany kod działa niepoprawnie dla pewnych danych. Zmień go tak, żeby działał
/// zawsze. Zastosuj reguły borrow checker'a znane z Rust'a i/lub metody synchronizacji.

#include <algorithm>
#include <iostream>
#include <string>
#include <thread>
#include <unordered_map>
#include <vector>

typedef std::unordered_map<char, int> letter_counts;
typedef std::vector<std::string> strings;

letter_counts count_letters(const strings& texts) {
    letter_counts counts;
    for (const auto& text : texts) {
        for (const auto& letter : text) {
            ++counts[letter];
        }
    }
    return counts;
}

void uppercasify(strings& values) {
    for(auto& s : values){
        std::transform(s.begin(), s.end(), s.begin(),
            [](char c){ return std::toupper(c); });
    }
}

letter_counts uppercasify_and_count_letters(strings& values) {
    letter_counts l;

    std::thread t2([&l, &values]() { l = count_letters(values); });
    std::thread t1([&values]() { uppercasify(values); });
    t2.join();
    t1.join();

    return l;
}

int main() {
    strings values = {"Alice", "Crocodile", "Is water wet?"};
    auto mean_median = uppercasify_and_count_letters(values);
    for (const auto& letter : mean_median) {
        std::cout << letter.first << " " << letter.second << std::endl;
    }
    return 0;
}
