# Make a k-skip-j range

On the Mathematica Stack Exchange, 100xln2 asks:

I need a list of integers […] The list contains integers and is characterized by [three] parameters, lets call them k and j [and listmax], which should be variable.

If k=1 and j=1 then the list would look like this: {1,3,5,7,9,11,....until listmax}

If k=2 and j=3 then the list would look like this: {1,2,6,7,11,12,16,17,.....until listmax}

Generally speaking, the List contains the first k integers, then doesn't contain the next j integers, then contains the next k integers, then doesn't contain the next j integers and so on and so on.

Let's help them out! (I hope they're okay with Jelly, Vyxal, or Befunge code instead of Mathematica…)

Given three positive integers $$\(k, j, \text{listmax})\$$, make a list of integers as described above, sorted in increasing order.

For $$\(3,2,6)\$$ you should return [1,2,3,6] rather than [1,2,3] or [1,2,3,6,7,8]. You can imagine you're generating an infinite “include 3, skip 2” list, and taking elements from it as long as they're ≤ 6.

# Rules

This is . Write the shortest possible answer, measured in bytes.

Standard I/O methods apply, which means valid submissions include:

• a three-parameter function that returns a list of numbers,
• a three-parameter function that prints each number in the list,
• a full program that reads inputs and prints each number in the list,
• and so on.

# Tests

In the format k j listmax --> output:

1 1 11 --> [1, 3, 5, 7, 9, 11]
2 13 19 --> [1, 2, 16, 17]
2 13 16 --> [1, 2, 16]
1 4 49 --> [1, 6, 11, 16, 21, 26, 31, 36, 41, 46]
2 4 22 --> [1, 2, 7, 8, 13, 14, 19, 20]
2 10 13 --> [1, 2, 13]
5 15 10 --> [1, 2, 3, 4, 5]
1 13 27 --> [1, 15]
7 4 31 --> [1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 18, 23, 24, 25, 26, 27, 28, 29]
99 99 1 --> [1]

• Can the output be unsorted? i.e.: Is [1, 16, 2, 17] an acceptable output? Commented Jul 26, 2023 at 4:01
• No, the output has to be sorted.
– lynn
Commented Jul 26, 2023 at 13:08
• Can the output be 0-based? Commented Aug 3, 2023 at 15:34
– lynn
Commented Aug 3, 2023 at 18:38

# Zsh--extendedglob, 52 bytes

for i ({1..$3})<<<${$(((i-1)%($1+$2)<$1?i:0))/(#s)0}


Try it online!

Using the modulo technique, but still not understanding how it works!

# Perl 5 (-p), 43 bytes

/ \d+/;$_=join$",grep{$i++%($+$&)<$}1..\$'


Try it online!

# Japt, 9 bytes

0-based output. Add 1 byte for 1-based output.

o kgVcÈÇY


Try it

# C++, 125 bytes

It's never going to be a code-golf winner, but with C++23 nearing standardisation, it's interesting to showcase what the new std::views classes offer us:

#include<ranges>
auto f(int a,int b,int n){using namespace std::views;return
iota(1,n+1)|chunk(a+b)|transform(take(a))|join;}


This simply divides the input range into chunks of size a+b, taking the first a elements from each chunk, and then reassembles the chunks back into a single range.

Self-test of the question's examples:

#include <algorithm>
#include <iterator>
#include <vector>
auto k_skip_j(int a,int b,int n)
{
#ifdef __cpp_lib_ranges_to_container
return f(a,b,n) | std::ranges::to<std::vector>();
#else
auto r = f(a,b,n);
auto result = std::vector<int>();
std::ranges::copy(r, std::back_inserter(result));
return result;
#endif
}

#include <gtest/gtest.h>

TEST(k_skip_j, three_two_six) {
auto result = k_skip_j(3, 2, 6);
auto expected = std::vector{1,2,3,6};
EXPECT_EQ(result, expected);
}

TEST(k_skip_j, one_one_twelve) {
auto result = k_skip_j(1, 1, 12);
auto expected = std::vector{1,3,5,7,9,11};
EXPECT_EQ(result, expected);
}

TEST(k_skip_j, two_three_twenty) {
auto result = k_skip_j(2, 3, 20);
auto expected = std::vector{1,2,6,7,11,12,16,17};
EXPECT_EQ(result, expected);
}


For comparison, the C++20 version weighs 140 bytes:

#include<ranges>
auto f(int a,int b,int n){return
std::views::iota(1,n+1)|std::views::filter([n=-1,a,b](auto)mutable{return(++n%=a+b)<a;});}


# Rust, 88 bytes

|k:usize,j:usize,l:usize|->Vec<usize>{(0..l).filter(|x|x%(k+j)<k).map(|x|x+1).collect()}


Attempt This Online!

# Wolfram Language (Mathematica), 67 bytes

Try it online!

f[k_,j_,l_]:=Table[If[Mod[x,k+j]<k,x+1],{x,0,l-1}]~DeleteCases~Null