On 02/16/2011 09:42 PM, jam wrote:
On Wed, 16 Feb 2011 20:24:36 +0100, Andrej Mitrovic wrote:

The only thing I could come up with is exhausting the entire range to
get the length of a bidirectional range. But that's inefficient. Anyway
here's the dull thing:

import std.stdio;
import std.range;
import std.array;

R findBack(alias pred = "a == b", R, E)(R haystack, E needle)
     if (isBidirectionalRange!R)
{
     size_t index;
     bool found;
     auto saved = haystack;

     foreach (item; retro(haystack))
     {
         if (item == needle)
         {
             found = true;
             index++;
             break;
         }
         index++;
     }

     if (found)
     {
         size_t newIndex;
         while (!haystack.empty)
         {
             newIndex++;
             haystack.popBack;
         }

         newIndex -= index;
         while (!saved.empty&&  newIndex)
         {
             saved.popFront;
             newIndex--;
         }
     }

     return saved;
}

void main()
{
     auto orig = [4, 0, 4, 0];
     auto result = findBack(orig, 4);

     assert(array(result) == [4, 0]);

     result.front = 10;
     assert(orig == [4, 0, 10, 0]);
}

You'll have to forgive me but I have yet to study algorithms properly.
:)

import std.stdio,std.algorithm,std.range;

void main()
{
     auto a = [5,1,2,3,4,5,1];
     auto index = countUntil(retro(a),5);
     writeln(a[a.length-1-index .. a.length]);
}

outputs:

[5,1]

but yeah, it is a little awkward.

And you're assuming the range is slice-able (I mean at arbitrary position, witout popping it); which you cannot do in the general case.

Denis
--
_________________
vita es estrany
spir.wikidot.com

Reply via email to