#include <array>
#include <cstdio>
#include <cstdint>
#include <cassert>
#include <algorithm>
int
main()
{
    std::array<int64_t,4> sample = {0,1,2,3};
    // use binary search to find >=1 left->right ascending order
    auto i0 = std::lower_bound(sample.begin(), sample.end(), 1);
    // use binary search to find <=2 right->left descending order
    // (reversal is because there is no inverse of lower_bound)
    auto i1 = std::lower_bound(sample.rbegin(), sample.rend(), 2, std::greater<int64_t>());
    printf("1 found at location %ld\n", i0 - sample.begin());
    // output: 1 found at location 1
    // end position minus distance from end:
    printf("2 found at location %ld\n", (sample.size()-1) - (i1 - sample.rbegin()) );
    // output: 2 found at location 2
// -------
printf("-------\n");
    // problem statement:
    // Given the two parallel arrays (nuts,seq) below, search for (1,1) and (2,0) indices
    // as above.  Hopefully using std::lower_bound, and hopefully without copying or
    // pre-combining the arrays.  Also check searching for (1,2), etc, and make sure we get the index
    // of (2,0) which is the first >= for the pair. Goal is to capture the range that includes
    // the ordered tuples ((first,last),(first,last)) whether or not the given tuples exist
    // in the data.
    std::array<int64_t,8> nuts = {0,0,1,1,2,2,3,3}; // always increasing
    std::array<uint64_t,8> seq = {0,1,0,1,0,1,0,1}; // always increasing within nuts value
// attempt:
    assert(seq.size()==nuts.size());
// <queries>
    //struct {int64_t first=1; uint64_t last=1;} first;
    //struct {int64_t first=2; uint64_t last=0;} last;
    
    //struct {int64_t first=1; uint64_t last=2;} first;
    //struct {int64_t first=1; uint64_t last=2;} last;
    //struct {int64_t first=4; uint64_t last=0;} first;
    //struct {int64_t first=4; uint64_t last=0;} last;
    struct {int64_t first=0; uint64_t last=1;} first;
    struct {int64_t first=2; uint64_t last=2;} last;
// </queries>
    // nuts:
    auto i2 = std::lower_bound(nuts.begin(), nuts.end(), first.first);
    auto u2 = std::upper_bound(nuts.begin(), nuts.end(), first.first);
    auto l2 = i2 - nuts.begin();
    auto ul2 = u2 - nuts.begin();
    auto i3 = std::lower_bound(nuts.rbegin(), nuts.rend(), last.first, std::greater<int64_t>());
    auto u3 = std::upper_bound(nuts.rbegin(), nuts.rend(), last.first, std::greater<int64_t>());
    auto l3 = i3 - nuts.rbegin(); // distance from end
    auto ul3 = u3 - nuts.rbegin();
    auto a3 = (nuts.size()-1) - l3;
    if(l2 > a3)
    {
        printf("nothing in nuts range found (%ld>%ld)\n",l2,a3);
        return 0;
    }
    printf("%ld found at location %ld\n", first.first, l2);
    printf("%ld found at location %ld\n", last.first, a3);
    // now narrow it for seq:
    auto i4 = std::lower_bound(seq.begin()+l2, seq.begin()+ul2, first.last);
    auto l4 = i4 - seq.begin();
    auto i5 = std::lower_bound(seq.rbegin()+l3, seq.rbegin()+ul3, last.last, std::greater<uint64_t>());
    auto l5 = i5 - seq.rbegin();
    auto a5 = (seq.size()-1) - l5;
    if(l4 > a5)
    {
        printf("nothing in seq range found\n");
        return 0;
    }
    printf("(%ld,%lu) found at location %ld\n", first.first, first.last, l4);
    printf("(%ld,%lu) found at location %ld\n", last.first, last.last, a5);
    return 0;
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: