Jump to page: 1 2
Thread overview
Range golf challenge: apply predicate to a subrange, returning the original range modified.
Oct 07, 2022
FeepingCreature
Oct 07, 2022
Andrey Zherikov
Oct 07, 2022
FeepingCreature
Oct 07, 2022
FeepingCreature
Oct 07, 2022
Andrey Zherikov
Oct 07, 2022
Andrey Zherikov
Oct 07, 2022
Ali Çehreli
Oct 07, 2022
rassoc
Oct 07, 2022
FeepingCreature
Oct 07, 2022
Ali Çehreli
Oct 08, 2022
FeepingCreature
Oct 08, 2022
H. S. Teoh
Oct 08, 2022
H. S. Teoh
Oct 07, 2022
H. S. Teoh
October 07, 2022

AKA "Do My Job For Me Challenge"

You have a range. You have an expression that's a chain of std.algorithm functions, ie. filter, find, until, drop, etc. that select a subset of the range. Let's abbreviate it with .select.

The subset has the same order of elements as the original range. The only change is that some elements of the original range will be missing.

The elements of the range are not mutable, so you cannot mutate the range via foreach (ref). Instead, you have a predicate, let's say .modify, that takes a value of the range and returns a new value.

Task: Given a range range, return a new range that consists of the elements of range, except modified with the modify predicate at all elements that are part of the subrange selected by .select.

While @nogc.

Note: You are allowed to redefine the types of range elements, as long as select can see the original value, for instance with value.

Sketch of a solution: I've been thinking something like "enumerate the range, apply selector, "left join zip" (zip where the enumeration matches, to be written) with the original range, apply predicate where left join zip has a match. I'm thinking a syntax like range.selectSubrange!select.modifySubrange!modify.

Thoughts?

October 07, 2022

On Friday, 7 October 2022 at 14:00:57 UTC, FeepingCreature wrote:

>

Task: Given a range range, return a new range that consists of the elements of range, except modified with the modify predicate at all elements that are part of the subrange selected by .select.

May be I misunderstood but why doesn't .select.map work here?

October 07, 2022

On Friday, 7 October 2022 at 14:16:19 UTC, Andrey Zherikov wrote:

>

On Friday, 7 October 2022 at 14:00:57 UTC, FeepingCreature wrote:

>

Task: Given a range range, return a new range that consists of the elements of range, except modified with the modify predicate at all elements that are part of the subrange selected by .select.

May be I misunderstood but why doesn't .select.map work here?

range.select returns a subrange of range. What's desired is "range, but with the subrange only mapped to modify."

October 07, 2022

On Friday, 7 October 2022 at 15:18:08 UTC, FeepingCreature wrote:

>

range.select returns a subrange of range. What's desired is "range, but with the subrange only mapped to modify."

For example!

auto result = 10.iota.selectSubrange!isEven.mapSubrange!"a * 2";

assert(result.equal([0, 1, 4, 3, 8, 5, 12, 7, 16, 9]));
October 07, 2022

On Friday, 7 October 2022 at 15:20:50 UTC, FeepingCreature wrote:

>

On Friday, 7 October 2022 at 15:18:08 UTC, FeepingCreature wrote:

>

range.select returns a subrange of range. What's desired is "range, but with the subrange only mapped to modify."

For example!

auto result = 10.iota.selectSubrange!isEven.mapSubrange!"a * 2";

assert(result.equal([0, 1, 4, 3, 8, 5, 12, 7, 16, 9]));
10.iota.map!(_ => _.isEven ? _*2 : _); // => [0, 1, 4, 3, 8, 5, 12, 7, 16, 9]
October 07, 2022

On Friday, 7 October 2022 at 16:32:07 UTC, Andrey Zherikov wrote:

>
10.iota.map!(_ => _.isEven ? _*2 : _); // => [0, 1, 4, 3, 8, 5, 12, 7, 16, 9]

You can even generalize this:

alias mapSubrange(alias filter, alias transform) = map!(_ => filter(_) ? transform(_) : _);
10.iota.mapSubrange!(isEven, _ => _*2);
October 07, 2022
On 10/7/22 09:35, Andrey Zherikov wrote:
> On Friday, 7 October 2022 at 16:32:07 UTC, Andrey Zherikov wrote:
>> ```d
>> 10.iota.map!(_ => _.isEven ? _*2 : _); // => [0, 1, 4, 3, 8, 5, 12, 7,
>> 16, 9]
>> ```
>
> You can even generalize this:
> ```d
> alias mapSubrange(alias filter, alias transform) = map!(_ => filter(_) ?
> transform(_) : _);
> 10.iota.mapSubrange!(isEven, _ => _*2);
> ```

I was trying something similar where I left .map to the user code:

import std;

bool isEven(T)(T value) {
    return !(value % 2);
}

alias applyIf(alias pred, alias func) = value => (pred(value) ? func(value) : value);

void main() {
    auto result = 10.iota.map!(applyIf!(isEven, a => a * 2));
    assert(result.equal([0, 1, 4, 3, 8, 5, 12, 7, 16, 9]));
}

Ali


October 07, 2022
On 10/7/22 16:00, FeepingCreature via Digitalmars-d wrote:
> Thoughts?

How about your selector func wraps the elements, similar to Nullable or via SumType, and your modifier func operates on the marked ones during iteration while returning the others as is? Poor man's monads?
October 07, 2022
On Fri, Oct 07, 2022 at 04:49:33PM +0000, rassoc via Digitalmars-d wrote:
> On 10/7/22 16:00, FeepingCreature via Digitalmars-d wrote:
> > Thoughts?
> 
> How about your selector func wraps the elements, similar to Nullable or via SumType, and your modifier func operates on the marked ones during iteration while returning the others as is? Poor man's monads?

Another way is if you convert .select into a predicate, then:

	auto r = myrange.map!(e => pred(e) ? modify(e) : e);

But that depends on how easy it is to convert .select into a predicate.


T

-- 
If lightning were to ever strike an orchestra, it'd always hit the conductor first.
October 07, 2022
On Friday, 7 October 2022 at 16:49:33 UTC, rassoc wrote:
> On 10/7/22 16:00, FeepingCreature via Digitalmars-d wrote:
>> Thoughts?
>
> How about your selector func wraps the elements, similar to Nullable or via SumType, and your modifier func operates on the marked ones during iteration while returning the others as is? Poor man's monads?

Y'all are missing the point a bit. :)

The type spec of the selector is "takes a range, returns a subrange." A subrange here being "a range like the original but with some amount of elements missing." Not, specifically, a predicate! That's what makes it interesting! :)
« First   ‹ Prev
1 2