Cod sursa(job #2610943)

Utilizator AlexnolifeAlexandru Ica Alexnolife Data 5 mai 2020 21:57:04
Problema Radix Sort Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.61 kb
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <queue>
#include <type_traits>
#include <utility>
#include <vector>

int max{ 0 };

auto generate_input(int const n, int const a, int const b, int const c)
    -> std::vector<int>
{
    std::vector<int> result(static_cast<std::size_t>(n + 1), 0);

    max = result[1] = b;

    for(std::size_t i = 2; i < result.size(); ++i) {
        std::int64_t prod = static_cast<std::int64_t>(a) * result[i - 1] + b;
        result[i] = static_cast<int>(prod % c);
        max = std::max(max, result[i]);
    }

    return result;
}

template<int Base>
auto radix_sort(std::vector<int>& v) -> void
{
    std::array<std::array<std::deque<int>, 256>, 2> bucket;
    std::size_t i;
    // std::size_t j;
    std::size_t k;

    for(i = 0; i < v.size(); ++i) {
        bucket[0][v[i] & 0x000000ff].push_back(v[i]);
    }
    for(i = 0; i < 256; ++i) {
        while(!bucket[0][i].empty()) {
            int& e = bucket[0][i].front();
            bucket[1][(e & 0x0000ff00) >> 8].push_back(e);
            bucket[0][i].pop_front();
        }
    }
    for(i = 0; i < 256; ++i) {
        while(!bucket[1][i].empty()) {
            int& e = bucket[1][i].front();
            bucket[0][(e & 0x00ff0000) >> 16].push_back(e);
            bucket[1][i].pop_front();
        }
    }
    for(i = 0; i < 256; ++i) {
        while(!bucket[0][i].empty()) {
            int& e = bucket[0][i].front();
            bucket[1][(static_cast<unsigned int>(e) & 0xff000000) >> 8]
                .push_back(e);
            bucket[0][i].pop_front();
        }
    }
    k = 0;
    for(i = 0; i < 256; ++i) {
        while(!bucket[1][i].empty()) {
            v[k++] = bucket[1][i].front();
            bucket[1][i].pop_front();
        }
    }
    /*
    std::array<std::queue<int>, Base> digits;
    int pow{ 1 };

    while(max / pow > 0) {
        for(int const num : v) {
            digits[(num / pow) % Base].push(num);
        }

        pow *= Base;
        v.clear();

        for(std::size_t i = 0; i < Base; ++i) {
            while(!digits[i].empty()) {
                v.push_back(digits[i].front());
                digits[i].pop();
            }
        }
    }*/
}

auto main(int, char*[]) noexcept -> int
{
    std::ifstream f{ "radixsort.in" };
    int n{ 0 };
    int a{ 0 };
    int b{ 0 };
    int c{ 0 };

    f >> n >> a >> b >> c;

    auto input = generate_input(n, a, b, c);
    radix_sort<10>(input);

    std::ofstream g{ "radixsort.out" };

    for(std::size_t i = 1; i < input.size(); i += 10) {
        g << input[i] << ' ';
    }

    return EXIT_SUCCESS;
}