9
$\begingroup$

I need a list of integers to check if a variable has one of the values of the list. If[ MemberQ[List,x], Green, Red] The list contains integers and is characterized by two parameters, lets call them k and j, 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}

Whereas listmax should be kept variable.

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

In the end I need the List to decide whether x has one of the values of the List, so if there is a way to skip the part where one has to define the list and can directly check if x has one of those values, that would also do the job.

$\endgroup$

6 Answers 6

11
$\begingroup$
BlockMap[Splice, Range@listmax, k, k + j]

Since you haven't defined the edge case behavior, this might not actually give you what you want. For example:

k = 2;
j = 3;
listmax = 5;
BlockMap[Splice, Range@listmax, k, k + j]
(* {1, 2} *)

listmax = 6;
BlockMap[Splice, Range@listmax, k, k + j]
(* {1, 2} *)
(* you might have wanted {1, 2, 6 *)

listmax = 7;
BlockMap[Splice, Range@listmax, k, k + j]
(* {1, 2, 6, 7} *)

Update

If you want different behavior at the upper end of the range, then something like this might be better:

Flatten[Partition[Range@listmax, k, k + j, {1, 1}, Nothing]]

(Unlike @Alan's solution, this one will take elements at the end even if there isn't a full k+j "block".)

$\endgroup$
11
$\begingroup$
Flatten@Partition[Range[listmax], k + j][[All, ;; k]]

Edit: Or, using the 3rd argument to Partition,

Flatten@Partition[Range@listmax, UpTo@k, k + j]
$\endgroup$
6
$\begingroup$

In the end I need the List to decide whether x has one of the values of the List, so if there is a way to skip the part where one has to define the list and can directly check if x has one of those values, that would also do the job.

To skip creating the list, you can check if $1 \le x \le \text{listmax}$ and $1 \le \text{Mod}[x, k+j] \le k$.

You can check the correctness using Solve:

k = 2;
j = 3;
listmax = 30;
Solve[1 <= x <= listmax && 1 <= Mod[x, k+j] <= k, x, Integers]
{{x -> 1}, {x -> 2}, {x -> 6}, {x -> 7}, {x -> 11}, {x -> 12},
 {x -> 16}, {x -> 17}, {x -> 21}, {x -> 22}, {x -> 26}, {x -> 27}}
$\endgroup$
1
  • $\begingroup$ This is the best answer, why bother creating the list if we can check directly $\endgroup$
    – Jean-Abdel
    Jul 26, 2023 at 8:35
5
$\begingroup$
ClearAll[f]

f[k_,j_,listmax_]:=Flatten@NestWhileList[#+k+j&,Range[k],Last@#<listmax-Max[k,j]&]
f[1,1,20]

(* {1, 3, 5, 7, 9, 11, 13, 15, 17, 19} *)

f[2,3,20]

(* {1, 2, 6, 7, 11, 12, 16, 17} *)
f[5,3,20]

(* {1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 17, 18, 19, 20, 21} *)
$\endgroup$
5
$\begingroup$
Clear[k, j, listmax, sieve];
sieve[k_Integer, j_Integer, listmax_Integer] := 
 If[Mod[#, k + j, 1] > k, False, True] & /@ Range[listmax]

Usage:

sieve[3, 1, 22]

{True, True, True, False, True, True, True, False, True, True, True,
False, True, True, True, False, True, True, True, False, True, True}

which can be used with in conjunction with Pick:

listmax = 20;
Pick[Range@listmax, sieve[1, 1, listmax]]

{1, 3, 5, 7, 9, 11, 13, 15, 17, 19}

listmax = 23; 
Pick[Range@listmax, sieve[5, 3, listmax]]

{1, 2, 3, 4, 5, 9, 10, 11, 12, 13, 17, 18, 19, 20, 21}

listmax = 19
Pick[Range@listmax, sieve[2, 3, listmax]]

{1, 2, 6, 7, 11, 12, 16, 17}

$\endgroup$
2
$\begingroup$

Per your update:

directly check if x has one of those values

You could do this:

TheCheck[k_, j_][n_] := Mod[n, k + j, 1] <= k

We can test it with your example:

TheCheck[2, 3] /@ Range[17]
(* {True, True, False, False, False, True, True, False, False, False, True, True, False, False, False, True, True} *)

Select[Range[17], TheCheck[2, 3]]
(* {1, 2, 6, 7, 11, 12, 16, 17} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.