Я думаю, что это хорошее решение:
Needs["Combinatorica`"]
pigeon[list_, func_, x_] :=
Join[{Null}, list, {Null}]
[[ {# - 1/2, # + 1/2}& @
BinarySearch[list, 0.5,
Piecewise[{{0, func[#, x]}, {1, True}}] &] + 1 ]]
, дающее:
> pigeon[{1, 3, 5, 7}, LessEqual, 0]
{Null, 1}
> pigeon[{1, 3, 5, 7}, LessEqual, 3]
{3, 5}
> pigeon[{1, 3, 5, 7}, LessEqual, 4]
{3, 5}
> pigeon[{1, 3, 5, 7}, LessEqual, 9]
{7, Null}
Объяснение : функция Biecewise применяется внутри BinarySearch к списку{1, 3, 5, 7}, чтобы проверить, какие элементы являются LessEqual, BinarySearch находит позицию конца этой метки, и соответствующие элементы возвращаются.В этой реализации используется только BinarySearch, поэтому предполагается, что он достаточно эффективен.
Эту функцию можно легко изменить, чтобы она возвращалась во втором случае {1, 3} вместо этого.
В качестве альтернативы, если 'x' может бытьэлемент списка, что-то вроде этого:
Needs["Combinatorica`"]
pigeon[list_, func_,
x_] := (Join[{Null},
list, {Null}])[[Select[{# - 1/2, #, # + 1/2} &@
BinarySearch[list, 0,
Piecewise[{{0, # == x}, {-1, func[#, x]}, {1, True}}] &],
IntegerQ] + 1]]
даст:
> pigeon[{1, 3, 5, 7}, LessEqual, 3]
{3}