March 25, 2015
On Wednesday, 25 March 2015 at 20:02:20 UTC, Ivan Kazmenko wrote:
> Will file an issue soon.
Here it is:
https://issues.dlang.org/show_bug.cgi?id=14340
And another one, a 2.067 regression:
https://issues.dlang.org/show_bug.cgi?id=14341
March 25, 2015
On Wednesday, 25 March 2015 at 20:09:53 UTC, bearophile wrote:
> Dennis Ritchie:
>
>> A more effective solution for C ++:
>>
>> #include <iostream>
>> #include <vector>
>> #include <range/v3/all.hpp>
>>
>> int main() {
>>  using namespace ranges;
>>
>>  auto rng = istream<int>( std::cin )
>>           | to_vector
>>           | action::sort
>>           | view::group_by( std::equal_to<int>() )
>>           | copy
>>           | action::stable_sort( []( const auto& e1, const auto& e2 ) { return distance( e1 ) < distance( e2 ); } );
>>  std::cout << ( rng );
>> }
>
>
> This is still not very efficient (perhaps the last sorting has to be stable):
>
> void main() {
>     import std.stdio, std.algorithm, std.typecons, std.array;
>
>     [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]
>     .sort()
>     .groupBy!((a, b) => a == b)
>     .map!array
>     .array
>     .sort!q{a.length > b.length}
>     .joiner
>     .writeln;
> }
>
>
> Bye,
> bearophile

5. An efficient version would be to count the integers by using an associative array (or a redBlackTree for guaranteed upper bound) and then use these.  It is O (n) time and memory spent in precalculation phase and O (n log n) time for sorting.  Looks like there is no way to write that as a chain of transforms, but many optimizations do require manual labor.

-----
import std.algorithm, std.conv, std.range, std.stdio;
void main () {
    auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
1, 1, 2, 2, 8, 5, 8, 8];
    int [int] counts;
    foreach (e; arr) {
        counts[e]++;
    }
    arr.multiSort !((a, b) => counts[a] > counts[b], (a, b) => a < b);
    arr.map !(to !(string))
        .join (" ")
        .writeln;
    // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0
}
-----

Also, some of my previously posted codes do not compile under 2.066 or earlier unless you replace .join (' ') with .join (" ") there.
March 25, 2015
On Wednesday, 25 March 2015 at 20:17:57 UTC, bearophile wrote:
> Ivan Kazmenko:
>
>> (1) For me, the name of the function is obscure.  Something like sortBy would be a lot easier to find than schwartzSort.
>
> I've asked to change the name of that function for years. But Andrei Alexandrescu is a adamantly against changing that pet name he has chosen. This is irrational behavour:
> https://issues.dlang.org/show_bug.cgi?id=4909
>
> There's lot of way to go for Phobos. And the only want to find holes, missed opportunities, sub-optimal performance spots, missing functions and features, and bad APIs and bad names is to actually try to use Phobos, like we are doing in this thread.

On the bright side, the list under "Sorting" at the docs
http://dlang.org/phobos/std_algorithm.html
is short enough for the curious to just look at the entries and find it.
The specific page
http://dlang.org/phobos/std_algorithm_sorting.html
does even contain a link explaining what that is, but I'd propose
-"Sorts with the help of the Schwartzian transform."
+"Sorts by key predicate with the help of the Schwartzian transform."
or some similar wording.
March 25, 2015
On Wednesday, 25 March 2015 at 20:09:53 UTC, bearophile wrote:
> This is still not very efficient (perhaps the last sorting has to be stable):
>
> void main() {
>     import std.stdio, std.algorithm, std.typecons, std.array;
>
>     [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1, 1, 1, 2, 2, 8, 5, 8, 8]
>     .sort()
>     .groupBy!((a, b) => a == b)
>     .map!array
>     .array
>     .sort!q{a.length > b.length}
>     .joiner
>     .writeln;
> }

On Wednesday, 25 March 2015 at 20:53:43 UTC, Ivan Kazmenko wrote:
> 5. An efficient version would be to count the integers by using an associative array (or a redBlackTree for guaranteed upper bound) and then use these.  It is O (n) time and memory spent in precalculation phase and O (n log n) time for sorting.  Looks like there is no way to write that as a chain of transforms, but many optimizations do require manual labor.
>
> -----
> import std.algorithm, std.conv, std.range, std.stdio;
> void main () {
>     auto arr = [7, 5, 7, 3, 3, 5, 3, 3, 0, 3, 1, 1, 5, 1,
> 1, 1, 2, 2, 8, 5, 8, 8];
>     int [int] counts;
>     foreach (e; arr) {
>         counts[e]++;
>     }
>     arr.multiSort !((a, b) => counts[a] > counts[b], (a, b) => a < b);
>     arr.map !(to !(string))
>         .join (" ")
>         .writeln;
>     // prints 1 1 1 1 1 3 3 3 3 3 5 5 5 5 8 8 8 2 2 7 7 0
> }
> -----

Thank you very much, Ivan and bearophile!

On Wednesday, 25 March 2015 at 20:53:43 UTC, Ivan Kazmenko wrote:
> Also, some of my previously posted codes do not compile under 2.066 or earlier unless you replace .join (' ') with .join (" ") there.

I have long been updated :)
March 25, 2015
Ivan Kazmenko:

>     arr.map !(to !(string))
>         .join (" ")
>         .writeln;

I suggest to not put a space before the bang (!), because it's confusing for me.

Also, "arr.map !(to !(string))" is better written "arr.map!text".

But even better is to use the range formatting of writefln, avoiding the "map", "to", and "join", something like:

writefln("%(%d %)", arr);

Bye,
bearophile
1 2
Next ›   Last »