Skip to content

Commit

Permalink
Add div_pos_int_ceil and split_evenly (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dobiasd authored Apr 15, 2024
1 parent 0b5d720 commit b50cb3c
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/fplus/curry_instances.autogenerated_defines
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ fplus_curry_define_fn_2(insert_at_idx)
fplus_curry_define_fn_1(partition)
fplus_curry_define_fn_1(split_at_idxs)
fplus_curry_define_fn_1(split_every)
fplus_curry_define_fn_1(split_evenly)
fplus_curry_define_fn_2(split_by_token)
fplus_curry_define_fn_1(run_length_encode_by)
fplus_curry_define_fn_0(run_length_encode)
Expand Down
2 changes: 2 additions & 0 deletions include/fplus/fwd_instances.autogenerated_defines
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ fplus_fwd_define_fn_2(insert_at_idx)
fplus_fwd_define_fn_1(partition)
fplus_fwd_define_fn_1(split_at_idxs)
fplus_fwd_define_fn_1(split_every)
fplus_fwd_define_fn_1(split_evenly)
fplus_fwd_define_fn_2(split_by_token)
fplus_fwd_define_fn_1(run_length_encode_by)
fplus_fwd_define_fn_0(run_length_encode)
Expand Down Expand Up @@ -693,6 +694,7 @@ fplus_fwd_flip_define_fn_1(split_at_idx)
fplus_fwd_flip_define_fn_1(partition)
fplus_fwd_flip_define_fn_1(split_at_idxs)
fplus_fwd_flip_define_fn_1(split_every)
fplus_fwd_flip_define_fn_1(split_evenly)
fplus_fwd_flip_define_fn_1(run_length_encode_by)
fplus_fwd_flip_define_fn_1(span)
fplus_fwd_flip_define_fn_1(aperture)
Expand Down
11 changes: 11 additions & 0 deletions include/fplus/numeric.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,17 @@ std::function<X(X)> divide_by(const X& x)
};
}

// API search type: div_pos_int_ceil : (a, a) -> a
// Positive integer division, but rounding up instead of down.
// div_pos_int_ceil(5, 3) == 2
template <typename X>
static auto div_pos_int_ceil(X numerator, X denominator)
{
static_assert(std::is_integral<X>::value, "type must be integral");
static_assert(!std::is_signed<X>::value, "type must be unsigned");
return numerator / denominator + (numerator % denominator != 0);
}

// API search type: histogram_using_intervals : ([(a, a)], [a]) -> [((a, a), Int)]
// fwd bind count: 1
// Generate a histogram of a sequence with given bins.
Expand Down
18 changes: 18 additions & 0 deletions include/fplus/split.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,24 @@ ContainerOut split_every(std::size_t n, const ContainerIn& xs)
xs);
}

// API search type: split_evenly : (Int, [a]) -> [[a]]
// fwd bind count: 1
// Split a sequence into n similarly-sized chunks.
// split_evenly(2, [0,1,2,3,4]) == [[0,1,2],[3,4]]
template <typename ContainerIn,
typename ContainerOut = std::vector<ContainerIn>>
ContainerOut split_evenly(std::size_t n, const ContainerIn& xs)
{
const std::size_t every_n = div_pos_int_ceil(size_of_cont(xs), n);
return split_at_idxs<
std::vector<std::size_t>,
ContainerIn,
ContainerOut>(
numbers_step<std::size_t>(
every_n, size_of_cont(xs), every_n),
xs);
}

// API search type: split_by_token : ([a], Bool, [a]) -> [[a]]
// fwd bind count: 2
// Split a sequence at every segment matching a token.
Expand Down
32 changes: 32 additions & 0 deletions include_all_in_one/include/fplus/fplus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8351,6 +8351,17 @@ std::function<X(X)> divide_by(const X& x)
};
}

// API search type: div_pos_int_ceil : (a, a) -> a
// Positive integer division, but rounding up instead of down.
// div_pos_int_ceil(5, 3) == 2
template <typename X>
static auto div_pos_int_ceil(X numerator, X denominator)
{
static_assert(std::is_integral<X>::value, "type must be integral");
static_assert(!std::is_signed<X>::value, "type must be unsigned");
return numerator / denominator + (numerator % denominator != 0);
}

// API search type: histogram_using_intervals : ([(a, a)], [a]) -> [((a, a), Int)]
// fwd bind count: 1
// Generate a histogram of a sequence with given bins.
Expand Down Expand Up @@ -10762,6 +10773,24 @@ ContainerOut split_every(std::size_t n, const ContainerIn& xs)
xs);
}

// API search type: split_evenly : (Int, [a]) -> [[a]]
// fwd bind count: 1
// Split a sequence into n similarly-sized chunks.
// split_evenly(2, [0,1,2,3,4]) == [[0,1,2],[3,4]]
template <typename ContainerIn,
typename ContainerOut = std::vector<ContainerIn>>
ContainerOut split_evenly(std::size_t n, const ContainerIn& xs)
{
const std::size_t every_n = div_pos_int_ceil(size_of_cont(xs), n);
return split_at_idxs<
std::vector<std::size_t>,
ContainerIn,
ContainerOut>(
numbers_step<std::size_t>(
every_n, size_of_cont(xs), every_n),
xs);
}

// API search type: split_by_token : ([a], Bool, [a]) -> [[a]]
// fwd bind count: 2
// Split a sequence at every segment matching a token.
Expand Down Expand Up @@ -15094,6 +15123,7 @@ fplus_curry_define_fn_2(insert_at_idx)
fplus_curry_define_fn_1(partition)
fplus_curry_define_fn_1(split_at_idxs)
fplus_curry_define_fn_1(split_every)
fplus_curry_define_fn_1(split_evenly)
fplus_curry_define_fn_2(split_by_token)
fplus_curry_define_fn_1(run_length_encode_by)
fplus_curry_define_fn_0(run_length_encode)
Expand Down Expand Up @@ -15702,6 +15732,7 @@ fplus_fwd_define_fn_2(insert_at_idx)
fplus_fwd_define_fn_1(partition)
fplus_fwd_define_fn_1(split_at_idxs)
fplus_fwd_define_fn_1(split_every)
fplus_fwd_define_fn_1(split_evenly)
fplus_fwd_define_fn_2(split_by_token)
fplus_fwd_define_fn_1(run_length_encode_by)
fplus_fwd_define_fn_0(run_length_encode)
Expand Down Expand Up @@ -16001,6 +16032,7 @@ fplus_fwd_flip_define_fn_1(split_at_idx)
fplus_fwd_flip_define_fn_1(partition)
fplus_fwd_flip_define_fn_1(split_at_idxs)
fplus_fwd_flip_define_fn_1(split_every)
fplus_fwd_flip_define_fn_1(split_evenly)
fplus_fwd_flip_define_fn_1(run_length_encode_by)
fplus_fwd_flip_define_fn_1(span)
fplus_fwd_flip_define_fn_1(aperture)
Expand Down
8 changes: 8 additions & 0 deletions test/numeric_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,14 @@ TEST_CASE("numeric_test - ceil_to_int_mult")
REQUIRE_EQ(ceil_to_int_mult(1, 1), 1);
}

TEST_CASE("numeric_test - div_pos_int_ceil")
{
using namespace fplus;
const std::uint64_t numerator = 5;
const std::uint64_t denominator = 3;
REQUIRE_EQ(div_pos_int_ceil(numerator, denominator), 2);
}

TEST_CASE("numeric_test - reference_interval")
{
using namespace fplus;
Expand Down
3 changes: 3 additions & 0 deletions test/split_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ TEST_CASE("split_test - split functions")
REQUIRE_EQ(split_at_idx(2, xs), std::make_pair(IntVector({ 1, 2 }), IntVector({ 2, 3, 2 })));
REQUIRE_EQ(partition(is_even_int, xs), std::make_pair(IntVector({ 2, 2, 2 }), IntVector({ 1, 3 })));
REQUIRE_EQ(split_every(2, xs), IntVectors({ { 1, 2 }, { 2, 3 }, { 2 } }));
REQUIRE_EQ(split_evenly(1, xs), IntVectors({ { 1, 2, 2, 3, 2 } }));
REQUIRE_EQ(split_evenly(2, xs), IntVectors({ { 1, 2, 2 }, { 3, 2 } }));
REQUIRE_EQ(split_evenly(3, xs), IntVectors({ { 1, 2 }, { 2, 3 }, { 2 } }));
auto splittedAt1And3 = split_at_idxs(IdxVector({ 1, 3 }), xs);
IntVectors splittedAt1And3Dest = { IntVector({ 1 }), IntVector({ 2, 2 }), IntVector({ 3, 2 }) };
REQUIRE_EQ(splittedAt1And3, splittedAt1And3Dest);
Expand Down

0 comments on commit b50cb3c

Please sign in to comment.