Cod sursa(job #2610954)

Utilizator AlexnolifeAlexandru Ica Alexnolife Data 5 mai 2020 22:20:44
Problema Radix Sort Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.01 kb
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdlib>
#include <deque>
#include <fstream>
#include <iostream>
#include <type_traits>
#include <utility>
#include <vector>

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

    result[1] = b;

    for(std::uint64_t i = 2; i < result.size(); ++i) {
        std::uint64_t prod = a * result[i - 1] + b;
        result[i] = prod % c;
    }

    return result;
}

constexpr auto nth_byte(std::uint64_t const x, std::uint64_t const n)
    -> std::uint64_t
{
    return (x >> (n * 8)) & 0xFF;
}

auto radix_sort(std::vector<std::uint64_t>& v) -> void
{
    std::array<std::array<std::deque<std::uint64_t>, 256>, 2> bucket;
    std::uint64_t i{ 0 };
    std::uint64_t k{ 0 };

    for(i = 0; i < v.size(); ++i) {
        // bucket[0][nth_byte(v[i], 1)].push_back(v[i]);
        bucket[0][v[i] & 0x00'00'00'ff].push_back(v[i]);
    }
    for(i = 0; i < 256; ++i) {
        while(!bucket[0][i].empty()) {
            auto const e = bucket[0][i].front();
            // bucket[1][nth_byte(e, 2)].push_back(e);
            bucket[1][(e & 0x00'00'ff'00) >> 8].push_back(e);
            bucket[0][i].pop_front();
        }
    }
    for(i = 0; i < 256; ++i) {
        while(!bucket[1][i].empty()) {
            auto const e = bucket[1][i].front();
            // bucket[0][nth_byte(e, 3)].push_back(e);
            bucket[0][(e & 0x00ff0000) >> 16].push_back(e);
            bucket[1][i].pop_front();
        }
    }
    for(i = 0; i < 256; ++i) {
        while(!bucket[0][i].empty()) {
            auto const e = bucket[0][i].front();
            // bucket[1][nth_byte(e, 4)].push_back(e);
            bucket[1][(e & 0xff'00'00'00) >> 8].push_back(e);
            bucket[0][i].pop_front();
        }
    }
    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<std::uint64_t>, Base> digits;
    std::uint64_t pow{ 1 };

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

        pow *= Base;
        v.clear();

        for(std::uint64_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" };
    std::uint64_t n{ 0 };
    std::uint64_t a{ 0 };
    std::uint64_t b{ 0 };
    std::uint64_t c{ 0 };

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

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

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

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

    return EXIT_SUCCESS;
}