Thread overview
How to sort byCodeUnit.permutations.filter(...)
Jun 11, 2018
Uknown
Jun 11, 2018
Adam D. Ruppe
Jun 11, 2018
Uknown
Jun 12, 2018
Adam D. Ruppe
Jun 12, 2018
Uknown
Jun 12, 2018
Adam D. Ruppe
June 11, 2018
I wrote a small program for Project Euler problem 41 ( https://projecteuler.net/problem=41 ).

--- project_euler_41.d
void main()
{
	import math_common : primesLessThan;
	import std.stdio : writeln;
	import std.conv : parse;
	import std.algorithm : permutations, canFind, filter, each, sort;
	import std.utf : byCodeUnit;
	import std.range : assumeSorted;
	import std.array : array;

	auto primes = primesLessThan(9_999_999UL).assumeSorted;

	"1234567".byCodeUnit
		.permutations
		.filter!(a => primes.canFind(a.parse!uint))
		.each!(a => a.writeln);
}
---

The problem is this prints a list of numbers. The task requires only the largest, so the intuitive fix is to add `.array.sort[$ - 1].writeln` in place of the `each`, but this prints an array of `1234567`s instead of the permutations. Does anyone know how to sort the filter result without modifying the individual results?
June 11, 2018
On Monday, 11 June 2018 at 04:06:44 UTC, Uknown wrote:
> The problem is this prints a list of numbers. The task requires only the largest, so the intuitive fix

I would just pull the max out of it.

http://dpldocs.info/experimental-docs/std.algorithm.searching.maxElement.2.html
June 11, 2018
On Monday, 11 June 2018 at 04:12:57 UTC, Adam D. Ruppe wrote:
> On Monday, 11 June 2018 at 04:06:44 UTC, Uknown wrote:
>> The problem is this prints a list of numbers. The task requires only the largest, so the intuitive fix
>
> I would just pull the max out of it.
>
> http://dpldocs.info/experimental-docs/std.algorithm.searching.maxElement.2.html

Thanks for your reply. I completely forgot about maxElement. I used it, but it prints 1234567, not the permutations. The same happens when using array. Why are the strings getting modified? The same happens with this:

"123".byCodeUnit.permutations.writeln;//[123, 213, 312, 132, 231, 321]
"123".byCodeUnit.permutations.array.writeln;//[123, 123, 123, 123, 123, 123]
Seems odd. Is this a bug or expected behaviour?
June 12, 2018
On Monday, 11 June 2018 at 04:39:54 UTC, Uknown wrote:
> Why are the strings getting modified?

I'm guessing it reuses a buffer as it iterates.

> "123".byCodeUnit.permutations.writeln;//[123, 213, 312, 132, 231, 321]

so here, it switches them, prints, switches, prints, switches, prints,e tc

> "123".byCodeUnit.permutations.array.writeln;//[123, 123, 123, 123, 123, 123]

but here it adds the same pointer to the array over and over so it all points to the same buffer.

I'm guessing. I don't actually know.


But hmmm... maybe throwing in a .dup would help. Really though, I personally would forget all the range pipeline stuff and write a simple loop.


        int largest = 0;
	foreach(part; "1234567".byCodeUnit.permutations) {
             auto asNumber = to!int(part);
             if(primes.canFind(asNumber)) {
                if(asNumber > largest)
                   largest = asNumber;
             }
        }

        writeln(largest);


But, writing the simple loop did give me a solution to the pipeline too: map it to to!int before doing the rest, so you work with ints instead of with strings and char buffers:


	"1234567".byCodeUnit
		.permutations
                .map!(to!int)
		.filter!(a => primes.canFind(a))
                .maxElement


that should do it too.
June 12, 2018
On Tuesday, 12 June 2018 at 14:21:48 UTC, Adam D. Ruppe wrote:
> On Monday, 11 June 2018 at 04:39:54 UTC, Uknown wrote:
>> Why are the strings getting modified?
>
> I'm guessing it reuses a buffer as it iterates.
>
>> "123".byCodeUnit.permutations.writeln;//[123, 213, 312, 132, 231, 321]
>
> [...]
>
> 	"1234567".byCodeUnit
> 		.permutations
>                 .map!(to!int)
> 		.filter!(a => primes.canFind(a))
>                 .maxElement
>
>
> that should do it too.

I solved the problem by piping the output to `sort`, but your workaround is useful. I'll submit a bug report on this ASAP. Thanks for your help!
June 12, 2018
On Tuesday, 12 June 2018 at 15:16:25 UTC, Uknown wrote:
> I solved the problem by piping the output to `sort`

that works but is probably less efficient since sorting the whole thing just to get the one element is more work but eh.

> I'll submit a bug report on this ASAP.

I really don't think it is a bug, but perhaps the documentation could call it out.