Skip to content

Instantly share code, notes, and snippets.

@iamazeem
Created February 2, 2020 17:16
Show Gist options
  • Save iamazeem/85e8a608c9fb977caf0725d2b7641d7b to your computer and use it in GitHub Desktop.
Save iamazeem/85e8a608c9fb977caf0725d2b7641d7b to your computer and use it in GitHub Desktop.
Find nearest value to the given index
// Ref: https://stackoverflow.com/questions/60023221/finding-the-closest-true-value-for-an-index
#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>
#include <limits>
using Result = std::tuple<bool, std::size_t, std::string>; // result (T/F), index, message
Result find_nearest( const std::vector<int>& v, const std::size_t index, const int value )
{
constexpr auto max_index = std::numeric_limits<std::size_t>::max();
if ( v.empty() || index >= v.size() )
{
return { false, max_index, "Empty container or invalid index!" };
}
std::size_t ilhs { max_index };
std::size_t irhs { max_index };
for ( std::size_t i {0}; i != v.size(); ++i )
{
if ( v[i] == value )
{
if ( i < index ) { ilhs = i; }
else if ( i > index ) { irhs = i; break; }
}
}
// if element not found i.e. no index
if ( ilhs == max_index && irhs == max_index )
{
return { false, max_index, "Index not found!" };
}
// shortest distance based comparison to determine indexes
const auto dlhs = ( ilhs != max_index ? index - ilhs : ilhs );
const auto drhs = ( irhs != max_index ? irhs - index : irhs );
if ( dlhs == drhs )
{
return { true, ilhs, "Equal distance found! Left index returned!" };
}
const auto idx = ( dlhs < drhs ? ilhs : irhs );
return { true, idx, "Index found!" };
}
int main()
{
using Args = std::tuple<std::vector<int>, std::size_t, int>; // list, index, value
using Tests = std::vector<Args>;
const Tests tests
{
{ {}, 0, 1 },
{ { 1 }, 0, 1 },
{ { 1 }, 1, 1 },
{ { 1 }, 2, 1 },
{ { 0, 0, 0 }, 1, 1 },
{ { 0, 0, 0, 1, 0 }, 2, 1 },
{ { 1, 0, 0, 0, 1 }, 2, 1 },
{ { 1, 0, 0, 1, 0, 1, 0 }, 3, 1 },
{ { 1, 0, 0, 0, 1, 0, 0, 0, 1 }, 5, 1 },
};
for ( const auto& [list, index, value] : tests )
{
const auto& [found, idx, msg] = find_nearest( list, index, value );
if ( found )
std::cout << "INF: " << msg << " index: " << idx << '\n';
else
std::cerr << "ERR: " << msg << '\n';
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment