Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to write simple code that will list all numbers from $1$ to $n$ that are not multiples of $4$.

And in this case I consider that

n=100

For[i = 1, i <= n, i++, If[Mod[i, 4] != 0, Print[i]]]

And got the answer

1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31 33 34 35 37 38 39 41 42 43 45 46 47 49 50 51 53 54 55 57 58 59 61 62 63 65 66 67 69 70 71 73 74 75 77 78 79 81 82 83 85 86 87 89 90 91 93 94 95 97 98 99

Now I would like to return an expression without using Print. Are there any other functions I can use?

Also I would like to know whether I can write the same code and get the same answer using Table.

share|improve this question
    
You could do this: range1[n_] := Floor[Range[1, n + 3/4, 4/3]] – Coolwater Feb 27 at 19:00
2  
My answer below was written with a more general application in mind. For this specific task, this does a nice job: Flatten@Outer[Plus, 4 Range[0, 24], Range[3]]. (It produces a packed array.) – Michael E2 Feb 27 at 19:32
    
Mariam, Don't forget you can accept the answer, if any, that solves your problem, by clicking the checkmark sign! (I noticed you haven't accepted any answers to any of your questions. Perhaps you did not know about this aspect of Stackexchange sites.) – Michael E2 Mar 1 at 2:20
1  
Hey Michael , Hope you are doing great :) thanks for note , as to be honest I haven't know about it before . Thanks – Narine Mar 1 at 17:15

16 Answers 16

up vote 14 down vote accepted

A couple general approaches:

Table[If[Mod[i, 4] != 0, i, Unevaluated@Sequence[]], {i, 100}]

Reap[Do[If[Mod[i, 4] != 0, Sow[i]], {i, 100}]][[2, 1]]

Note that the Unevaluated@Sequence[] thing is not a beginner's trick...Table always creates an entry for each iteration, so skipping some of them turns out to be tricky. Reap and Sow are one standard way to create table entries conditionally.


Update 1: @garej's answer reminded me that in V10 Nothing is an alternative to Unevaluated@Sequence[]:

Table[If[Mod[i, 4] != 0, i, Nothing], {i, 100}]

Update 2: In the comments that it is pointed out that Divisible[i, 4] is faster than Mod[i, 4] != 4. So if speed is an issue, one might consider using it for this specific type of problem. However, Divisible[], Nothing, Reap[], Sow[], and Sequence[] are not compilable, so the whole approach is a poor one if speed on long lists, for which Table[] will try to compile its body, is an issue. One could either develop a compilable code for Table or use another approach even better adapted to the special case of skipping multiples of an given integer.

n = 10^6;
d = 4;
Table[If[Divisible[i, d], Nothing, i], {i, n}]; //             (* not compilable *)
  RepeatedTiming // First
DeleteCases[Table[If[Mod[i, d] != 0, -1, i], {i, n}], -1]; //  (* compilable Table[] *)
  RepeatedTiming // First
Flatten@Outer[Plus, d * Range[0, n/d - 1], Range[d - 1]]; //   (* faster still *)
  RepeatedTiming // First
(*
  0.93
  0.26
  0.017
*)

If n is not divisible by d, then for the last method, one could generate a list that is slightly longer and trim it to the desired length with Part, Take or Drop; the extra processing would take a negligible amount of time.

Since the focus of the question seemed to be about how to translate C-like code that conditionally skips entries in a table, I thought a general answer would be most helpful. There may be faster approaches than Outer[Plus,..], the search for which I will leave to others. The timings were given merely to illustrate my claims about compilability.

If you are interested in speed, I would point out Mr.Wizard's Drop method which is faster than Outer, or the Floor method in my other answer, which is a little faster still.

share|improve this answer
2  
Divisible[] can of course be used instead of Mod[]. – J. M. Feb 28 at 7:55
1  
@garej For speed I'd use Flatten@Outer[Plus, 4 Range[0, 10^6/4 - 1], Range[4 - 1]], which is 50 times faster than Table...maybe trim the table to length if the end point weren't a even multiple of the divisor. – Michael E2 Feb 28 at 12:50
1  
@MichaelE2 You can replace Unevaluated@Sequence[] with Nothing starting with version 10.2. Makes it a little less daunting for beginners. – Edmund Feb 28 at 13:43
1  
@MichaelE2, I would upvote twice if I could for your update 2. Could you clearify on thing. Is there a difference (connection) between ability of function to keep arrays packed and its compilability? – garej Feb 28 at 15:27
1  
@garej Yes, WVM (the Wolfram Virtual Machine, the runtime environment for compiled functions) deals only with packed arrays (as well as single values, of course). Some functions have limited implementations in the WVM that allow them to be compiled (e.g. Position, the compiled version of which cannot accept a pattern as an argument). – Michael E2 Feb 28 at 15:53

Why not:

Drop[Range @ 100, {4, -1, 4}]

Or:

Range[Range@3, 100, 4] ~Flatten~ {2, 1}
share|improve this answer
    
you may always find a couple of faster and concise solutions :)) +1. – garej Feb 28 at 10:40
2  
I think this one also deserves attantion: Union @@ Range[Range@3, 100, 4] – garej Feb 28 at 10:54
    
@garej Thanks, and I like your Union variant. – Mr.Wizard Feb 28 at 10:56
    
@garej If going for speed I think Flatten[Range[Range@3, 100, 4]\[Transpose], 1] is faster than Union and also gives a packed array, but Drop is probably faster than anything non-C-compiled. – Mr.Wizard Feb 28 at 11:03
1  
That is for sure. Drop is fastest - 0.011 for 10^6 range, Flatten is 0.014, and Union is two times slower - 0.026. – garej Feb 28 at 11:15

If you see Select, you may try Cases.

DeleteCases[Range[100], x_ /; Mod[x, 4] == 0]

If you see Table, you may try Array:

Array[If[Mod[#, 4] == 0, Nothing, #] &, 100]

One more method with Table:

Complement[Range[100], Table[i, {i, 0, 100, 4}]]

To make PackedArray, one may also use:

Partition[Range[100], 4][[;; , ;; 3]]//Flatten
share|improve this answer
1  
thanks lot @garej – Narine Feb 27 at 19:54
1  
Much like your complement answer would be: Complement[Range[100], Range[0, 99, 4]] – bill s Feb 28 at 16:56
    
@bills, I was just trying to comply with original OP's question about Table, but then the discussion moved away from the original post... – garej Feb 28 at 17:01

Many ways to skin a cat:

    n = 100;
    m = 4;

    Select[Range[n], Mod[#, m] != 0 &]

    Flatten@Table[i + Range[0, m - 2], {i, 1, n, m}]
share|improve this answer
    
Hi ,Thanks lot your answer helps me . – Narine Feb 27 at 18:20
    
Also I would like to know can I write the same code and got the same answer using table ? – Narine Feb 27 at 18:20
    
Not entirely sure why you want to use Table, kinda superfluous: Table[i, {i, Select[Range[100], Mod[#, 4] != 0 &]}] – Quantum_Oli Feb 27 at 18:24
    
Actually I am trying to learn Wolfram Language now , and from wolfram.com/language/elementary-introduction/… I learnd that I also can use table to do this kind of simple codes , but didn't got the mind how , – Narine Feb 27 at 18:27
    
really thank you – Narine Feb 27 at 18:28

I think one can use Partition this way:

Flatten @ Partition[Range @ 100, 3, 4]
share|improve this answer

A joke solution:

CoefficientList[Series[(1 - x^4)/((1 - x)^2 (1 - x^3)), {x, 0, 20}], x]
share|improve this answer

Another trick for the specific case (edit notice: I changed Range from type Integer to type Real, for a 35% or so speed-up):

Floor[
 (4./3*(1 - $MachineEpsilon)) * Range[3. * 10^2 / 4]
 ]

It's pretty fast:

foo = Floor[
    (4./3*(1 - $MachineEpsilon)) * Range[3. * 10^6 / 4]
    ]; // RepeatedTiming
(*  {0.0033, Null}  *)

It competes in speed with Mr.Wizard's Drop method, although not in elegance**:

foo2 = Drop[Range[10^6], {4, -1, 4}]; // RepeatedTiming
(*  {0.0043, Null}  *)

foo2 == foo
(*  True  *)

By the time the dodge 1 - $MachineEpsilon causes inaccuracies, you'll be out of memory (or at least I will).

foo = Floor[
    (4./3*(1 - $MachineEpsilon)) * Range[3. * 10^8 / 4]
    ]; // RepeatedTiming
foo2 = Drop[Range[10^8], {4, -1, 4}]; // RepeatedTiming
foo2 == foo
(*
  {0.77, Null}
  {1.1, Null}
  True
*)

**My method may appear to be memory-competitive as well since it does not generate extra entries and drop them, but that's an illusion. The multiplication causes the array essentially to be copied, doubling the memory usage. Since the array is 75% of the full range, we actually use 1.5 times the memory. This is observable on my machine when I push the limit to n = 10^9, when the extra swapping in my method slows it down (17.7 sec. vs. 15 sec.); however the result is still accurate.


Appendix

Two more ways to handle the particular problem, first posted in my comments below, remarkable only for adding to the seemingly endless string of methods in this Q&A:

Nearest[Unitize@Mod[Range[10^2], 4] -> Automatic, 1]            (* 0.12s for n = 10^6 *)
Flatten@SparseArray[Mod[Range[10^2], 4]]["NonzeroPositions"]    (* 0.030s for n = 10^6 *)
share|improve this answer
    
Gestalt? :)) +1 – garej Feb 28 at 16:50
1  
@garej I wonder how long this can go on. Not fast, but not slow: Nearest[Unitize@Mod[Range[10^2], 4] -> Automatic, 1]. – Michael E2 Feb 28 at 18:17
1  
There's also Flatten@SparseArray[Mod[Range[10^6], 4]]["NonzeroPositions"], which is not too bad, about 4 times faster than Nearest. – Michael E2 Feb 28 at 19:03
    
Version of Outer: Flatten@(4 Range[0, (10^6/4) - 1] + ConstantArray[Range@3, (10^6)/4]) – garej Feb 28 at 20:14
    
+1 for Floor! – Mr.Wizard Feb 29 at 2:31

Also

n = 100;
Pick[Range@n, Range@n/4, _Rational]

{1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 43, 45, 46, 47, 49, 50, 51, 53, 54, 55, 57, 58, 59, 61, 62, 63, 65, 66, 67, 69, 70, 71, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 99}

i.e.

Take the first $n$ integers, divide each element in this first list by 4, and pick the elements in the first list such that the corresponding element in the second list is an Rational

or, with Mod,

Pick[Range@n, Mod[Range@n, 4], 1|2|3]

or, avoiding "computing" the 1...n list two times

With[{l = Range@n}, Pick[l, Mod[l, 4], Except[0, _Integer]]]

or even

With[{l = Range@n}, Pick[l, UnitStep[Mod[l, 4] - 1], 1]]
share|improve this answer

There is this way of doing it:

range[n_] := 
  Catenate[
    NestList[# + 4 &, {1, 2, 3}, Floor[(n - 1)/4]]][[;; Min[-1, Mod[n, 4, 1] - 4]]]
share|improve this answer

Edit

With some help from Coolwater (see comments)

Pick[#, Sign@Mod[#, 4], 1] & @ Range[100]

{1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 43, 45, 46, 47, 49, 50, 51, 53, 54, 55, 57, 58, 59, 61, 62, 63, 65, 66, 67, 69, 70, 71, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 90, 91, 93, 94, 95, 97, 98, 99}

Original Post

Pick[#, Sign@Mod[#, 4] & @ #, 1] & @ Range[100]
share|improve this answer
    
Thanks lot @TomD – Narine Feb 27 at 20:06
1  
Why & @ # in the end of the 2nd argument?! – Coolwater Feb 27 at 20:18
    
@Coolwater. Nice once. Thanks. Have modified as you suggested. – TomD Feb 27 at 20:33

Another approach

not4k[n_] := (4 # + {1, 2, 3}) & /@ (Range[Quotient[n, 4]] - 1) // Flatten
share|improve this answer

LibraryLink function

My intuition was off for Compile, so I had to see if things worked like I expected in C using LibraryLink. Here is the C code.

#include <stdio.h>
#include "WolframLibrary.h"
#include <stdbool.h>
#include <limits.h>

DLLEXPORT mint WolframLibrary_getVersion( ) {
    return WolframLibraryVersion;}
DLLEXPORT int WolframLibrary_initialize( WolframLibraryData libData){
    return LIBRARY_NO_ERROR;}
DLLEXPORT void WolframLibrary_uninitialize( WolframLibraryData
                                           libData) {
    return;}

DLLEXPORT int nonMultsCondManMod(WolframLibraryData libData,
                                 mint Argc, MArgument *Args, MArgument Res)
{
    int err = LIBRARY_NO_ERROR;
    mint nn = MArgument_getInteger(Args[0]);
    mint mm = MArgument_getInteger(Args[1]);
    mint quot = nn/mm;
    mint rem = nn - quot*mm;
    mint resLen = (mm-1)*quot + rem;
    MTensor result;
    err = libData->MTensor_new(MType_Integer, 1, &resLen, &result);
    mint* dataPtr = libData->MTensor_getIntegerData(result);

    int ii;
    int jj = 1;
    int kk = 1;
    for (ii = 1; ii <= resLen; ii++) {
        *(dataPtr++) = jj++;
        if(kk == mm-1){
            jj++;
            kk = 1;
        } else{kk++;}
    }
    MArgument_setMTensor(Res, result);
    return LIBRARY_NO_ERROR;
}

To let Mathematica use the C code, we will make a string of the code and store it in the variable cCodeString. To do this, copy the code above, paste it between quotes "" and click "Yes" in the dialog (to escape the characters).

cCodeString = (*Insert C code here*);

Now we process the code/string and make a function out of it.

<< CCompilerDriver`;
CreateLibrary[cCodeString, "nonMults"];
Quiet@LibraryUnload["nonMults"];
nonMultsCondManMod = 
  LibraryFunctionLoad["nonMults", 
   "nonMultsCondManMod", {Integer, Integer}, {Integer, 1}];

Timing comparison

mm = 4;
nn = 10^7;

(rJ = nonMultsCondManMod[nn, mm]) // RepeatedTiming // First
(rW1 = Drop[Range@nn, {mm, -1, mm}]) // RepeatedTiming // First
rJ === rW1
0.018
0.056
True



Sillyness

It seems my intuition was a bit off and the kind of strategy shown below only works (kind of) nicely in C, see for example the code above, or here or here. The simple code by Mr.Wizard is faster. I'll refrain from deleting the code below despite this.

This solution uses Compile. It also uses meta-programming to avoid any conditionals (If) or restructuring (Select, Pick), while still being quite general. Evaluate all the code again if you want to try e.g. mm=2 (make a list of odd numbers). Of course all this overkill in a sense.

mm = 4;

hCompileBodyTemplate =
  # /. OwnValues[mm] &@
   Hold[
    quot = Quotient[nn, mm];
    rem = nn - quot*mm;
    res = ConstantArray[0, quot*(mm - 1) + rem];
    ii = 1;
    jj = 1;
    Do[
     token;
     jj++;
     ,
     quot
     ];
    Do[
     res[[ii++]] = jj++
     ,
     rem
     ];
    res
    ];

hInstructions =
  CompoundExpression @@@
   Hold @@
    Join @@@
     List@
      Table[
       Hold[res[[ii++]] = jj++]
       ,
       mm - 1
       ];

hTokenRule =
  Delete[Hold @@ {HoldPattern[token] -> hInstructions}, {1, 2, 0}];

hCompileBody =
  ReplaceAll @@ {
    hCompileBodyTemplate,
    Unevaluated @@ hTokenRule
    };

hToken2Rule =
  Delete[Hold @@ {HoldPattern[token2] -> hCompileBody}, {1, 2, 0}];

hCompileTemplate =
  Hold@
   Compile[
    {{nn, _Integer}},
    Block[{quot, rem, ii, jj, res},
     token2
     ]
    ];
heldCompile =
  ReplaceAll @@ {
    hCompileTemplate,
    Unevaluated @@ hToken2Rule
    };

cfu = Identity @@ heldCompile;

Example

cfu[22]
{1,2,3,5,6,7,9,10,11,13,14,15,17,18,19,21,22}

Message to OP (Mariam)

I really directed my answer to other experienced users of this site. Perhaps I should have been more clear. Thank you for your message, now that I know that you intend to study all the answers I will try to make my answer more readable and educational.

There are at least two things that can be learned from this answer

  1. There is a function Compile that can make certain code faster
  2. In the Wolfram Language (Mathematica) you can use code to generate and/or manipulate code

With regards to point 1., that is, the fact that Compile exists, I would like to say that it can be tricky to get started with Compile, because it requires some specific knowledge of what code can be compiled.

Concerning point 2, this manipulation and generation of code can be called meta-programming. This arguably an even more advanced (and useless) topic than Compile.

For example C++ also has some abilities to do meta-programming, mostly because of its flexible preprocessor, which is really a language all by itself. One (kind of) special thing about meta-programming in Mathematica is that you can use (many of) the same functions that would normally use to manipulate data to instead manipulate code.

In my answer I first generate some instructions and then insert them into my code. You can see that the token in the code above was replaced by three identical instructions res[[ii++]] = jj++;. The code that is generated looks as follows.

quot = Quotient[nn, 4];
rem = nn - quot 4;
res = ConstantArray[0, quot (4 - 1) + rem];
ii = 1;
jj = 1;
Do[
  (res[[ii++]] = jj++;
   res[[ii++]] = jj++;
   res[[ii++]] = jj++); jj++;,
  quot
  ];
Do[
 res[[ii++]] = jj++,
 rem]; 
res

Instead of bothering with how meta-programming or Compile works, perhaps you can first try to see why the generated code works for your question. A simpler version of the code above is this

nn = 22;
mm = 4;
quot = Quotient[nn, mm];
rem = nn - quot * mm;
resultLength = quot (mm - 1) + rem;
res = ConstantArray[0, resultLength];
jj = 1;
Do[
  res[[ii++]] = jj++;
  If[
   Divisible[jj , mm],
   jj++
   ]
  ,
  {ii, 1, resultLength}
  ];
res

And making it "more normal", we get this

nn = 22;
mm = 4;
quot = Quotient[nn, mm];
rem = nn - quot * mm;
resultLength = quot (mm - 1) + rem;
jj = 0;
res =
 Table[
  jj++;
  If[Divisible[jj , mm], jj++];
  jj
  ,
  {ii, 1, resultLength}
  ]

If we do not try to be so clever to predict the length of the result beforehand, we can end up with something that was already mentioned in other answers

nn = 22;
mm = 4;
res =
 Table[
  If[Divisible[jj , mm], Nothing, jj]
  ,
  {jj, 1, nn}
  ]

I recommend starting with this last piece of code and trying to see why the piece of code above it does the same thing.

share|improve this answer
    
thanks lot @Jacob – Narine Feb 28 at 17:31
    
@Mariam you are welcome. Please study the other answers first (and don't feel obliged to study my answer)! – Jacob Akkerboom Feb 28 at 21:01
    
to be honest I am trying to study all answers. ) – Narine Feb 28 at 21:03
    
@Mariam ok, I have updated my answer to help you with your study. I have added the section Message to OP (Mariam), other than that nothing is new. – Jacob Akkerboom Feb 28 at 22:24
    
Perhaps I should say that Michael`s second answer and J.M's joke answer are also hard to understand (and not very serious), I recommend looking at the other answer first. – Jacob Akkerboom Feb 28 at 22:28

I grabbed the sequence from jacob akkerboom's post:

FindSequenceFunction[{1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22}, n] // FullSimplify

to get:

Table[1/9 (-6 + 12 n - 3 Cos[(2 n Pi)/3] + Sqrt[3] Sin[(2 n Pi)/3]),{n,1,17}]

edited to show as table

share|improve this answer
    
Yeah :) Thanks @Fred – Narine Mar 2 at 8:48
1  
Aha, so Table[4 n + Mod[-n, 3] - 3, {n, 1, 22}]/3 also works! – Jacob Akkerboom Mar 2 at 8:48
1  
And also: Table[4 n + Sin[-2 (n + 1) Pi /3]*2/Sqrt[3] - 2, {n, 1, 22}]/3. Haha you have opened a new door to new possibilities :P. – Jacob Akkerboom Mar 2 at 9:13
1  
You could also use SeriesCoefficient[] on the function featured in my answer to obtain this result. – J. M. Mar 2 at 15:26
1  
@J.M. and conversely, GeneratingFunction[(4 n + Sin[-2 (n + 1) Pi/3]*2/Sqrt[3] - 2)/3, n, x] == jmExpr. Also works with the Mod and mr Kline's expression. – Jacob Akkerboom Mar 2 at 16:37

I've arrived late at this party. A complementary approach:

 Complement[Range[100], Range[4, 100, 4]]

... seems quite fast too.

share|improve this answer
    
thanks @wolfies – Narine Feb 28 at 17:30

Do it with image processing!

PixelValuePositions[Image[{
  Flatten[ConstantArray[{0, 0, 0, 1}, {1, 100/4}]]
}], 0][[All, 1]]

A generalized function:

fun[len_, drop_] := PixelValuePositions[Image[{Flatten[ConstantArray[
      Append[ConstantArray[0, drop - 1], 1], {1, len/drop}]
    ]}], 0][[All, 1]]

It's not too slow either:

fun[10^7, 4]; // RepeatedTiming // First
1.31
share|improve this answer
    
Hey :) thanks @shrx – Narine Mar 3 at 9:41
Complement[Range@100, FindDivisions[{1, 100, 4}, 50]]

Will get what you want.


As the documentation this code could do this thing,but unfortunately there is a bug persisted long time in this function havenot been fixed.

Complement[Range@100, FindDivisions[{1, 100, 4}]]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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