Алгоритм для «перемешивания» массива случайным образом

Этот рецепт продемонстрирует вам алгоритм, работающий с любым диапазоном ввода и генерирующий новый диапазон, в котором элементы переставлены («перемешаны») случайным образом. Алгоритм, в контексте данного рецепта, обозначает нечто такое, что манипулирует диапазонами (т.е практически то же понимание термина «алгоритм», которое и используется в D) и ни в коем случае не намекает на традиционный смысл понятия «алгоритм»).

Итак, алгоритм randomize перемешивающий входной диапазон:

// randomize algorithm
auto randomize(Range)(Range range)
{
    import std.algorithm : remove;
    import std.random : Random, uniform, unpredictableSeed;
    import std.range : array;
 
    auto _range = range.array;
    auto _rng = Random(unpredictableSeed);
 
    struct Result
    {
        private
        {
            size_t _index;
        }
 
        bool empty()
        {
            return (_range.length == 0);
        }
 
        auto front()
        {
            return _range[_index];
        }
 
        void popFront()
        {
           _range = _range.remove(_index);
           _index = (_range.length > 1) ? uniform(0, _range.length, _rng) : 0;
        }      
    }
 
    return Result();
}

В функции randomize используется классический для D подход в определении диапазонов, а сам код несложен для понимания и реализации.

Связанные по теме рецепты:

Добавить комментарий