range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 25.07.20 04:11
Оценка: 2 (1)
В последние годы комитет пытается угодить всем, вот и за функциональный стиль плотно взялись, на что нам range-v3 как бы и намекает. Я тут решил попробовать написать с использованием этой библиотеки простой тестик, пока что по ощущениям выходит что нахер это надо, утомительно ребусы компилятора разгадывать пытаясь угодать что же пошло не так. Но может кто знает как заставить эту штуку работать?

Хочу совсем простого, есть массив массивов, его надо объеденит в один, выкинуть дубликаты, отсортировать, и взять 3 минимамльных элемента. Само собой всё надо сделать максимально приближено к функциональному стилю.

Хочу простого, для иллюстрации пример на Clojure, где такое можно сделать красиво и элегантно:

(def v1 (list (list 3 4 5 1 7)
              (list 1 3 6 3 8)))

(-> v1
    flatten
    distinct
    sort
    (#(take 3 %)))


Пока что у меня на C++ вышла вот такая хреновина, которая, почему-то, отказывается убирать дубликаты

std::vector<std::vector<size_t>> v1 = { { 3, 4, 5, 1, 7 }, { 1, 3, 6, 3, 8 } };

std::vector<size_t> joined = v1 | ranges::views::join | ranges::views::unique |
                                 ranges::to<std::vector<size_t>> | ranges::actions::sort;
std::vector<size_t> res( joined.begin(), joined.begin() + 3 );


Но хочется без разбиения на 2 этапа и, конечно же, без дубликатов
Отредактировано 25.07.2020 4:13 kaa.python . Предыдущая версия .
Re: range-v3 и модный C++
От: foxafox  
Дата: 25.07.20 04:37
Оценка: 18 (1) +1
Здравствуйте, kaa.python, Вы писали:

KP>Пока что у меня на C++ вышла вот такая хреновина, которая, почему-то, отказывается убирать дубликаты


Очерёдность sort и unique перепутана.


  std::vector<size_t> res = v1 | ranges::views::join
                               | ranges::to_vector
                               | ranges::actions::sort
                               | ranges::actions::unique
                               | ranges::actions::take (3);
Re[2]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 25.07.20 04:45
Оценка:
Здравствуйте, foxafox, Вы писали:

F>Очерёдность sort и unique перепутана.


F>

F>  std::vector<size_t> res = v1 | ranges::views::join
F>                               | ranges::to_vector
F>                               | ranges::actions::sort
F>                               | ranges::actions::unique
F>                               | ranges::actions::take (3);

F>


А почему нел6взять unique из views?

А, понял, документацию надо читать:

views::unique
Given a range, return a new range where all consecutive elements that compare equal save the first have been filtered out.

Отредактировано 25.07.2020 4:50 kaa.python . Предыдущая версия .
Re: range-v3 и модный C++
От: Reset  
Дата: 25.07.20 04:49
Оценка: 18 (1)
Эрик Ниблер (вот тут) говорит, что views::unique работает только с последовательными элементами.

views::unique
Given a range, return a new range where all consecutive elements that compare equal save the first have been filtered out.

Re[2]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 25.07.20 04:53
Оценка:
Здравствуйте, Reset, Вы писали:

R>Эрик Ниблер (вот тут) говорит, что views::unique работает только с последовательными элементами.

R>

R>views::unique
R>Given a range, return a new range where all consecutive elements that compare equal save the first have been filtered out.


Ага, нашел уже. Не очень удобно получается, из за того что часть функционала в actions, часть во views, но т.к. мы в мире C++, то надо терпеть и запоминать
Re[3]: range-v3 и модный C++
От: foxafox  
Дата: 25.07.20 09:42
Оценка: 20 (2)
Здравствуйте, kaa.python, Вы писали:

KP>А почему нел6взять unique из views?


Все, что во views, создает обертку, содержащую ссылку на переданный аргумент, а все что в actions, меняет контейнер и передает его дальше. Так как to_vector возвращает новый объект, то views::unique к нему не применить, иначе получим висящую ссылку.
Re: range-v3 и модный C++
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 25.07.20 09:49
Оценка: +1
Здравствуйте, kaa.python, Вы писали:

KP>Но хочется без разбиения на 2 этапа и, конечно же, без дубликатов


Меня пугают все эти штуки в том плане, что непонятно, с какой сложностью окажется решение. В итоге ты получаешь 3 минимальных элемента, это можно сделать императивно за N log3, то есть тупо за один проход. У тебя же там много всяких действий только для развлечения или без них не получится найти 3 минимума? Как вычислить сложность полученного решения в таком функиональном стиле?
Re[2]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 25.07.20 10:15
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Меня пугают все эти штуки в том плане, что непонятно, с какой сложностью окажется решение. В итоге ты получаешь 3 минимальных элемента, это можно сделать императивно за N log3, то есть тупо за один проход. У тебя же там много всяких действий только для развлечения или без них не получится найти 3 минимума? Как вычислить сложность полученного решения в таком функиональном стиле?


Это довольно интересный и в чем-то философский вопрос. Начнем с того, что у меня нет цели сделать быстрое решение. У меня есть цель попробовать разные новые фичи C++, который я, мало того что уже изрядно подзабыл, так еще новых вещей и не трогал вообще. Так же хочтеся написать красиво и читабельно, в функциональном стиле. Что проще читать — функциональный или императивный код, это отдельный вопрос, конечно, но C++ как ни крути читабельностью похвастаться сам по себе не может, но функциональный налет может эту ситуацию немного скрасить.

Сложность у решения на range будет, я полагаю что n log n за счет сортировки, ну и в целом будут еще какие-то немаленькие коэффиценты, да и банальные пенальти за память из за перетасовки данных.

Только вот в мире за пределами C++ такие вопросы как ты задаешь вообще никого не парят, по вполне себе очевидным причинам — будет тормозить так поправим, главное явной квадратичной и выше сложности не городить. К примеру я сейчас написал себе transpose для C++ который у меня вышел как-то так:

template <typename T>
std::vector<std::vector<T>> transpose( const std::vector<std::vector<T>> &inputs )
{
    assert( !inputs.empty() );
    size_t                      line_len  = inputs[0].size();
    size_t                      input_len = inputs.size();
    std::vector<std::vector<T>> res( line_len );
    for( size_t n = 0; n < input_len; n++ )
    {
        const auto &in_line = inputs[n];
        assert( line_len == in_line.size() );
        for( size_t m = 0; m < line_len; m++ )
        {
            res[m].emplace_back( in_line[m] );
        }
    }

    return res;
}


Но если бы этот самый transpose был бы реализован в range-v3, то можно было бы написать красиво и читаемо, пусть и менее элегантно чем, к примеру, на Clojure:
(defn transpose [v]
  (apply mapv vector v))


Тут сложность решения, я полагаю, будет линейная, единственный вопрос — это коэффициент, но так ли он важен в подавляющем большинстве задач?

А вообще я решаю задачки отсюда
Отредактировано 25.07.2020 10:37 kaa.python . Предыдущая версия . Еще …
Отредактировано 25.07.2020 10:36 kaa.python . Предыдущая версия .
Отредактировано 25.07.2020 10:34 kaa.python . Предыдущая версия .
Отредактировано 25.07.2020 10:31 kaa.python . Предыдущая версия .
Re[3]: range-v3 и модный C++
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 25.07.20 10:58
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Сложность у решения на range будет, я полагаю что n log n за счет сортировки, ну и в целом будут еще какие-то немаленькие коэффиценты, да и банальные пенальти за память из за перетасовки данных.


Сложность будет выше, т.к. надо будет удалять дубликаты, в std::vector это ооочень не бесплатно.

KP>Только вот в мире за пределами C++ такие вопросы как ты задаешь вообще никого не парят, по вполне себе очевидным причинам — будет тормозить так поправим, главное явной квадратичной и выше сложности не городить.


Да, как-то не хочется получить код на С++, который тормозит на пустом месте. Мы, типа, не привыкли платить за то, что не используем, а тип контейнера и алгоритмы выбираем, исходя из алгоритмической сложности. Неужели этому приходит конец?

KP>Тут сложность решения, я полагаю, будет линейная, единственный вопрос — это коэффициент, но так ли он важен в подавляющем большинстве задач?


Ну, это и правда больше упражнение, благо для матриц сейчас библиотек достаточно и вряд ли кто-то решит писать сам. А необходимость поиска нескольких минимальных/максимальных элементов иногда встречается, реализации из коробки нет, вот и приходится самому думать. Что предлагают делать разработчики на Питоне? Сортировать! На втором месте уже np.argpartition, про который говорят, что он сработает за линейное время, что неверно в общем случае. И только где-то там самый быстрый алгоритм — heapq.nlargest. Хотя именно с кучей можно быстрее всего найти k-top элементов. Не хочется, чтобы С++ уходил в эту же сторону, краткость не решает.
Re[4]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 25.07.20 11:24
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Сложность будет выше, т.к. надо будет удалять дубликаты, в std::vector это ооочень не бесплатно.


А если задуматься не о сложности алгоритма, а с сложности поддержки и читабельности кода?

N>Да, как-то не хочется получить код на С++, который тормозит на пустом месте. Мы, типа, не привыкли платить за то, что не используем, а тип контейнера и алгоритмы выбираем, исходя из алгоритмической сложности. Неужели этому приходит конец?


Думаю что нет, те же range достаточно тяжело использовать, т.к. чудовищно выглядящие ошибки компилятора посвященные шаблонам задолбают даже самых больших поклонников функционального программирования. Я пока из принципа держусь

N>Ну, это и правда больше упражнение, благо для матриц сейчас библиотек достаточно и вряд ли кто-то решит писать сам. А необходимость поиска нескольких минимальных/максимальных элементов иногда встречается, реализации из коробки нет, вот и приходится самому думать. Что предлагают делать разработчики на Питоне? Сортировать! На втором месте уже np.argpartition, про который говорят, что он сработает за линейное время, что неверно в общем случае. И только где-то там самый быстрый алгоритм — heapq.nlargest.


На первом месте, по оценкам, как раз ответ с argpartition, это просто особенность работы SO.

N>Хотя именно с кучей можно быстрее всего найти k-top элементов. Не хочется, чтобы С++ уходил в эту же сторону, краткость не решает.


Думаю что не уйдет, на C++ пишут фанаты оптимизации всего и вся, при этом часто забывающие о том, что:

Преждевременная оптимизация — корень всех (или большинства) проблем в программировании.

Дональд Кнут


Твоя реакция тоже показательна, кстати: "а не будет ли оно тормозить?". Ну, как минимум с точки зрения алгоритмической сложности нет, т.к. там явно худший случай n log n, но с точки зрения программиста на C++ этого обычно недостаточно. Когда-то мне казалось что именно так и надо, сейчас я уже не уверен и больше склоняюсь к к тому, что пока сложность ниже квадратичной и прогоны приложения показывают что оно не откланяется по скорости от желаемого, его лучше не трогать и акцентироваться на читабельности
Re[5]: range-v3 и модный C++
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 25.07.20 12:32
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Твоя реакция тоже показательна, кстати: "а не будет ли оно тормозить?". Ну, как минимум с точки зрения алгоритмической сложности нет, т.к. там явно худший случай n log n, но с точки зрения программиста на C++ этого обычно недостаточно. Когда-то мне казалось что именно так и надо, сейчас я уже не уверен и больше склоняюсь к к тому, что пока сложность ниже квадратичной и прогоны приложения показывают что оно не откланяется по скорости от желаемого, его лучше не трогать и акцентироваться на читабельности


Да, у меня есть проф деформация и я не очень люблю Питон из-за этого. Иногда кажется, что программирование на нём сродни программированию на Делфи: "А какой компонет может сделать ххх?" Только в Питоне слово "компонет" заменяется на "пакет". (Это конечно снобизм, я на нём сам такой же и с удовольствием пишу говноутилиты для парсинга и перекладывания разных штук, не выходя за рамки стантартных пакетов.)
Но глобально, я не понимаю, что стоит за вывеской питоновских import xxx, ни тут, за вывеской ranges. И если что-то будет тормозить, то придётся не разбираться, а тупо переписывать. Мне стрёмно, когда я не могу посмотреть в отладчике какой-то код или вставить в него логи.
Re: range-v3 и модный C++
От: Шахтер Интернет  
Дата: 25.07.20 15:48
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>В последние годы комитет пытается угодить всем,


Это называется проститутки.

KP>Хочу простого, для иллюстрации пример на Clojure, где такое можно сделать красиво и элегантно:


А вот не надо на С++ писать как на Clojure! Товарищ Страуструп сколько раз это повторял!
Не для этого С+ создан!

Да, и кстати, я конечно немного выпил, но как ты собираешься выделять уникальные элементы до сортировки?
Поделись рецептиком!

(-> v1
flatten
distinct
sort
(#(take 3 %)))
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: range-v3 и модный C++
От: ononim  
Дата: 25.07.20 20:12
Оценка: +2
KP>Только вот в мире за пределами C++ такие вопросы как ты задаешь вообще никого не парят, по вполне себе очевидным причинам — будет тормозить так поправим, главное явной квадратичной и выше сложности не городить.
В мире за пределами С++ есть например юниксовые команды sort и uniq которые должны рабать именно так: sort|uniq и еще comm которая тоже после sort применяется. Так что это как бы немного очевидно.
Как много веселых ребят, и все делают велосипед...
Re[2]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.07.20 02:23
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>А вот не надо на С++ писать как на Clojure! Товарищ Страуструп сколько раз это повторял!


Хотелось бы избавиться от ощущения "а мне Рабинович напел", поможешь с цитатой или ссылкой на источник?

Ш>Не для этого С+ создан!


Ну как не создан, если в C++20 появились ranges?

Ш>Да, и кстати, я конечно немного выпил, но как ты собираешься выделять уникальные элементы до сортировки?

Ш>Поделись рецептиком!

Вот так, а что?

(distinct [2 2 1 5 4 4 4 ])
=>; (2 1 5 4)


В функциональных языках ты можешь работать с ленивыми последовательностями, что, кстати и для ranges::views справедливо как минимум по утверждению автора библиотеки. Как ты иначе предлагаешь лениво получать уникальные значения из бесконечного списка или вывод какого-либо генератора фильтровать? На мой взгляд текущая реализация ranges::views::unique не корректна, так как она вводит в заблуждение тем, что находится в views которые как бы ленивые. Судя по реализации этого вида просто не должно быть, а должно быть только действие ranges::actions::sort.
Re[4]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.07.20 02:33
Оценка: +1
Здравствуйте, ononim, Вы писали:

KP>>Только вот в мире за пределами C++ такие вопросы как ты задаешь вообще никого не парят, по вполне себе очевидным причинам — будет тормозить так поправим, главное явной квадратичной и выше сложности не городить.

O>В мире за пределами С++ есть например юниксовые команды sort и uniq которые должны рабать именно так: sort|uniq и еще comm которая тоже после sort применяется. Так что это как бы немного очевидно.

А почему реализация функционального концепта в языке программирования должна равняться на Юникс-утилиты, а не, к примеру, на коммерческие функциональные языки?

Clojure:

(distinct [2 2 1 5 4 4 4 ])
=> (2 1 5 4)

(-> [2 2 1 5 4 4 4 ]
    distinct
    sort)
=> (1 2 4 5)


Elixir:

iex(5)> [2, 2, 1, 5, 4, 4, 4] |> Enum.uniq
[2, 1, 5, 4]
iex(6)> [2, 2, 1, 5, 4, 4, 4] |> Enum.uniq |> Enum.sort
[1, 2, 4, 5]


Функциональные концепции в языке должны базироваться на подходах принятых в функциональных языках, по причинам, которые я вот тут объяснял
Автор: kaa.python
Дата: 26.07.20
.
Отредактировано 26.07.2020 2:38 kaa.python . Предыдущая версия . Еще …
Отредактировано 26.07.2020 2:37 kaa.python . Предыдущая версия .
Re[3]: range-v3 и модный C++
От: Voivoid Россия  
Дата: 26.07.20 08:18
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>На мой взгляд текущая реализация ranges::views::unique не корректна, так как она вводит в заблуждение тем, что находится в views которые как бы ленивые. Судя по реализации этого вида просто не должно быть, а должно быть только действие ranges::actions::sort.


Так она и ленивая, просто ranges::views::unique обертка вокруг O(n) std::unique ( https://en.cppreference.com/w/cpp/algorithm/unique ) со всеми вытекающими отсюда последствиями.

Тем более в c++ какая идеология? Не платить за то, что не используешь, а в clojure я практически уверен будет оверхед на выполнение distinct для УЖЕ отсортированное последовательности.
Re[4]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.07.20 08:58
Оценка: +1
Здравствуйте, Voivoid, Вы писали:

V>Так она и ленивая, просто ranges::views::unique обертка вокруг O(n) std::unique ( https://en.cppreference.com/w/cpp/algorithm/unique ) со всеми вытекающими отсюда последствиями.


Ага, поэтому я и говорю: для действий это нормальный подход, но вот для видов мне уже кажется что это не так. Вводит в заблуждение

V>Тем более в c++ какая идеология? Не платить за то, что не используешь, а в clojure я практически уверен будет оверхед на выполнение distinct для УЖЕ отсортированное последовательности.


Основная идеология C++ — максимально задолбаться заучивая 100500 правил и изобрести 100500+1 велосипед для своего "уникального случая"
Re: range-v3 и модный C++
От: Evgeny.Panasyuk Россия  
Дата: 26.07.20 09:26
Оценка: -1
Здравствуйте, kaa.python, Вы писали:

KP>В последние годы комитет пытается угодить всем, вот и за функциональный стиль плотно взялись, на что нам range-v3 как бы и намекает.


Это не попытка "угодить всем", а вполне логичный шаг по стандартизации давно существующей и успешно применяемой практики Boost.Range
Range'и как концепция отлично дополняют итераторы, и существуют в других языках типа D.
Re[3]: range-v3 и модный C++
От: Evgeny.Panasyuk Россия  
Дата: 26.07.20 09:37
Оценка: -1
Здравствуйте, kaa.python, Вы писали:

R>>Эрик Ниблер (вот тут) говорит, что views::unique работает только с последовательными элементами.

R>>

R>>views::unique
R>>Given a range, return a new range where all consecutive elements that compare equal save the first have been filtered out.

KP>Ага, нашел уже.

В этом нет ничего удивительного, учитывая поведение std::unique из ISO C++ прошлого века.
Такой вариант вполне логичный и оправданный — во-первых это более общо, во-вторых позволяет не делать лишнюю работу. Например таким же образом работает uniq(1) (тоже из прошлого века).
Re[4]: range-v3 и модный C++
От: Evgeny.Panasyuk Россия  
Дата: 26.07.20 09:55
Оценка: 1 (1) +1
Здравствуйте, Nuzhny, Вы писали:

KP>>Сложность у решения на range будет, я полагаю что n log n за счет сортировки, ну и в целом будут еще какие-то немаленькие коэффиценты, да и банальные пенальти за память из за перетасовки данных.

N>Сложность будет выше, т.к. надо будет удалять дубликаты,

std::unique делает один линейный проход с тривиальными перемещениями.

N>в std::vector это ооочень не бесплатно.


Это только если в лоб и по-одному за раз.
Re[2]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.07.20 10:22
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Это не попытка "угодить всем", а вполне логичный шаг по стандартизации давно существующей и успешно применяемой практики Boost.Range

EP>Range'и как концепция отлично дополняют итераторы, и существуют в других языках типа D.

Надеюсь, то что попало в стандарт будет всё же более успешной практикой
Автор: ArtDenis
Дата: 23.07.20
Re[4]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.07.20 10:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>В этом нет ничего удивительного, учитывая поведение std::unique из ISO C++ прошлого века.

EP>Такой вариант вполне логичный и оправданный — во-первых это более общо, во-вторых позволяет не делать лишнюю работу. Например таким же образом работает uniq(1) (тоже из прошлого века).

Извини, я сориентироваться хочу. Ты принципиально не читаешь ответы в теме, а пишешь свой для начала?

http://rsdn.org/forum/cpp.applied/7785596.1
Автор: kaa.python
Дата: 26.07.20

http://rsdn.org/forum/cpp.applied/7785724.1
Автор: kaa.python
Дата: 26.07.20
Отредактировано 26.07.2020 10:33 kaa.python . Предыдущая версия .
Re[5]: range-v3 и модный C++
От: Evgeny.Panasyuk Россия  
Дата: 26.07.20 10:35
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>А почему реализация функционального концепта в языке программирования должна равняться на Юникс-утилиты


Ну она базируется на std::unique из C++1998. Но, даже если не знать про std::unique, а только про uniq — то существование такого интерфейса (отличного от distinct) должно натолкнуть на мысль таки заглянуть в документацию, и прочитать что именно делает используемая команда, а не строить догадки. В то что ты не знал ни про uniq, ни про std::unique — верится с трудом

KP>, а не, к примеру, на коммерческие функциональные языки?


Что ты называешь "коммерческими", какие преимущества аргументации эта "коммерческость" даёт по сравнению со стандартизированной uniq?

KP>(distinct [2 2 1 5 4 4 4 ])

KP>=> (2 1 5 4)

Это странный пример в обсуждаемом контексте, так как unique/uniq выдаст такой же результат

KP>Функциональные концепции в языке должны базироваться на подходах принятых в функциональных языках, по причинам, которые я вот тут объяснял
Автор: kaa.python
Дата: 26.07.20
.


Ну вот если бы стоял выбор между интерфейсами uniq и distinct для Range'ей, то я бы выбрал uniq.
Во-первых, это более общо — например нужно удалить именно последовательные дубликаты, а не все.
Во-вторых, быстрее если данные уже в нужном порядке.
Тем не менее, и у интерфейса distinct тоже есть преемущества, так что в идеале нужны оба.
Re[6]: range-v3 и модный C++
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 26.07.20 10:54
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ну она базируется на std::unique из C++1998.


Это прекрасно, как сочетается std::unique и заявленная ленивость?

EP> Но, даже если не знать про std::unique, а только про uniq — то существование такого интерфейса (отличного от distinct) должно натолкнуть на мысль таки заглянуть в документацию, и прочитать что именно делает используемая команда, а не строить догадки. В то что ты не знал ни про uniq, ни про std::unique — верится с трудом


Везде разные имена, где-то distinct, где-то uniq, как в моем примере с Clojure и Elixir

EP>Что ты называешь "коммерческими", какие преимущества аргументации эта "коммерческость" даёт по сравнению со стандартизированной uniq?


Довольно очевидное — это некий устаявшийся паттерн поведения, который могу ожидать люди имевшие опыт с инструментом. Но, знаю-знаю, это не C++-путь, у нас надо изобрести свой правильный велосипед с квадратными колесами.

KP>>(distinct [2 2 1 5 4 4 4 ])

KP>>=> (2 1 5 4)

EP>Это странный пример в обсуждаемом контексте, так как unique/uniq выдаст такой же результат


Да премешай их как хочешь, ничего не изменится.

(distinct [2 4 1 2 5 4 4 ])
=> (2 4 1 5)
Re[4]: range-v3 и модный C++
От: Ватакуси Россия  
Дата: 26.07.20 11:57
Оценка:
N>Ну, это и правда больше упражнение, благо для матриц сейчас библиотек достаточно и вряд ли кто-то решит писать сам. А необходимость поиска нескольких минимальных/максимальных элементов иногда встречается, реализации из коробки нет, вот и приходится самому думать. Что предлагают делать разработчики на Питоне? Сортировать! На втором месте уже np.argpartition, про который говорят, что он сработает за линейное время, что неверно в общем случае. И только где-то там самый быстрый алгоритм — heapq.nlargest. Хотя именно с кучей можно быстрее всего найти k-top элементов. Не хочется, чтобы С++ уходил в эту же сторону, краткость не решает.

Не читай советских газет перед обедом (с)

def kth(a, n):
    m = a.shape[0]
    perc = (np.arange(m-n,m)+1.0)/m*100
    return np.percentile(a, perc)
Все будет Украина!
Отредактировано 26.07.2020 15:18 Ватакуси . Предыдущая версия .
Re[6]: range-v3 и модный C++
От: Ватакуси Россия  
Дата: 26.07.20 12:01
Оценка:
N>Да, у меня есть проф деформация и я не очень люблю Питон из-за этого. Иногда кажется, что программирование на нём сродни программированию на Делфи: "А какой компонет может сделать ххх?" Только в Питоне слово "компонет" заменяется на "пакет". (Это конечно снобизм, я на нём сам такой же и с удовольствием пишу говноутилиты для парсинга и перекладывания разных штук, не выходя за рамки стантартных пакетов.)
N>Но глобально, я не понимаю, что стоит за вывеской питоновских import xxx, ни тут, за вывеской ranges. И если что-то будет тормозить, то придётся не разбираться, а тупо переписывать. Мне стрёмно, когда я не могу посмотреть в отладчике какой-то код или вставить в него логи.

monkey patching?
Все будет Украина!
Re[7]: range-v3 и модный C++
От: Evgeny.Panasyuk Россия  
Дата: 26.07.20 12:27
Оценка:
Здравствуйте, kaa.python, Вы писали:

EP>>Ну она базируется на std::unique из C++1998.

KP>Это прекрасно, как сочетается std::unique и заявленная ленивость?

А что смущает? Например имя/интерфейс views::transform базируется на std::transform — одно ленивое, другое энергичное

KP>Везде разные имена, где-то distinct, где-то uniq, как в моем примере с Clojure и Elixir


Суть не в именах, а в том что в природе встречается и тот и другой интерфейс.

EP>>Что ты называешь "коммерческими", какие преимущества аргументации эта "коммерческость" даёт по сравнению со стандартизированной uniq?

KP>Довольно очевидное — это некий устаявшийся паттерн поведения, который могу ожидать люди имевшие опыт с инструментом. Но, знаю-знаю, это не C++-путь, у нас надо изобрести свой правильный велосипед с квадратными колесами.

Аллё гараж, какой ещё C++-путь, интерфейсу uniq(1) много десятков лет, он к тому же стандартизирован в POSIX.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.