Series from For loop (is there a repository for Integer Sequences?)

I often find the need to loop through numbers in a series. For example, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, … or 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, …

I don’t think I need help with the code (see below), but what is the correct name for this so I can look up other examples. And, is there a repository of these? If not, should there be?

int j;

void setup()
{
  size(40, 40);
  for (int i = 0; i < 80; i++) {

    j = (i/4) + 1;

    println("i:",i,"j:",j);
    
  }
}
int j;

void setup()
{
  size(40, 40);
  for (int i = 0; i < 80; i++) {

    j = (i % 4) + 1;

    println("i:",i,"j:",j);
    
  }
}
1 Like

Hello @paulstgeorge,

I am aware of this:

:)

3 Likes

You can see it (or some of it) as a nested for-loop (from the code perspective),
so one inner for-loop inside the outer for-loop

That’s a term often used in this forum.

But it doesn’t really fit for your intention.

2 Likes

Excellent repository of integer sequences!!! @glv
So, I guess the word I am looking for is ‘formula’…?

We still need a Processing repository because the definition of a sequence is often not enough. See, for example, Prime numbers https://oeis.org/A000040

Here is my first attempt at the Fibonacci series (https://oeis.org/A000045 )

int[] numbers = new int[40];

void setup()
{
  size(40, 40);

  numbers[0] = 0;
  numbers[1] = 1;

  for (int i = 2; i < numbers.length; i++) {

    numbers[i] = numbers[i-1] + numbers[i-2];
  }

  println(numbers);
}
2 Likes

Maybe the word is Integer Sequences or
formula for Integer Sequences or algorithm for Integer Sequences.

1 Like

We could also create separate functions which would create the sequence array of the desired type for us.

Here’s your 1st example as a function named seqIntsRepeatedNTimesEach(n, lo, hi):

int[] seq4_1_20, seqNeg4_1_20, seq1_10_Neg10;

void setup() {
  seq4_1_20 = seqIntsRepeatedNTimesEach(4, 20);
  seqNeg4_1_20 = seqIntsRepeatedNTimesEach(4, -20);
  seq1_10_Neg10 = seqIntsRepeatedNTimesEach(-1, 10, -10);

  println(str(seq4_1_20));
  println();
  println(str(seqNeg4_1_20));
  println();
  println(str(seq1_10_Neg10));

  exit();
}

static final int[] seqIntsRepeatedNTimesEach(final int n, final int hi) {
  return seqIntsRepeatedNTimesEach(n, hi >= 0 ? 1 : -1, hi);
}

static final int[] seqIntsRepeatedNTimesEach(
  final int n, final int lo, final int hi)
{
  final int
    nn = Math.abs(n), 
    len = (Math.abs(hi - lo) + 1) * nn, 
    dir = hi >= lo ? 1 : -1, 
    seq[] = new int[len];

  for (int i = 0; i < len; ++i) seq[i] = i / nn * dir + lo;

  return seq;
}
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8 9 9 9 9 10 10 10 10 11 11 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15 15 15 16 16 16 16 17 17 17 17 18 18 18 18 19 19 19 19 20 20 20 20 -1 -1 -1 -1 -2 -2 -2 -2 -3 -3 -3 -3 -4 -4 -4 -4 -5 -5 -5 -5 -6 -6 -6 -6 -7 -7 -7 -7 -8 -8 -8 -8 -9 -9 -9 -9 -10 -10 -10 -10 -11 -11 -11 -11 -12 -12 -12 -12 -13 -13 -13 -13 -14 -14 -14 -14 -15 -15 -15 -15 -16 -16 -16 -16 -17 -17 -17 -17 -18 -18 -18 -18 -19 -19 -19 -19 -20 -20 -20 -20 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10
1 Like

Excellent, I am studying this @GoToLoop because I am not familiar with some of the code.
It looks like the way to go because the integer sequences in the OEIS are wonderful, but not the kind one would use in a project.
The two examples I gave can be used for picking locations in a two dimensional array, so row numbers 1, 1, 1, 1 and column numbers 1, 2, 3, 4; then 2, 2, 2, 2 and column numbers 1, 2, 3, 4. It’s a trivial but practical example of the kinds of integer sequences that are useful.

Yes, that’s it! And I guess the algorithm is used to write the formula.

1 Like

@GoToLoop I am getting this for the println lines:
Type String [ ] of the last argument to method println(Object…) doesn’t exactly match the vararg parameter type. Cast to Object [ ] to confirm the non-varargs invocation, or pass individual arguments of type Object for a varargs invocation.

I didn’t see that b/c I always had the option “Continuously check for errors” disabled in “Preferences”.

Anyways, the use of str() is for logging purposes only, and it can be removed:
println(str(seq4_1_20));println(seq4_1_20);

Regardless, what really matters is the code implementation inside seqIntsRepeatedNTimesEach()!

1 Like

Made some smalls changes and now it takes care of the 2nd case of “Simple periodic sequence” as function periodicIntSeqRepeatedNTimes(n, lo, hi):

int[] seq4_1_20, seqNeg4_1_20, seq1_10_Neg10;

void setup() {
  seq4_1_20 = periodicIntSeqRepeatedNTimes(4, 20);
  seqNeg4_1_20 = periodicIntSeqRepeatedNTimes(4, -20);
  seq1_10_Neg10 = periodicIntSeqRepeatedNTimes(-1, 10, -10);

  println(str(seq4_1_20));
  println();
  println(str(seqNeg4_1_20));
  println();
  println(str(seq1_10_Neg10));

  exit();
}

static final int[] periodicIntSeqRepeatedNTimes(final int n, final int hi) {
  return periodicIntSeqRepeatedNTimes(n, hi >= 0 ? 1 : -1, hi);
}

static final int[] periodicIntSeqRepeatedNTimes(
  final int n, final int lo, final int hi)
{
  final int
    qty = Math.abs(hi - lo) + 1, 
    len = Math.abs(n) * qty, 
    dir = hi >= lo ? 1 : -1, 
    seq[] = new int[len];

  for (int i = 0; i < len; ++i) seq[i] = i % qty * dir + lo;

  return seq;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10
1 Like

@GoToLoop
Would it be possible for you to give me the same workings, but without the Function Overloading and with vanilla Processing functions instead of Java’s static final???

Everything you’ve mentioned can be deleted from my code!
My both examples would work perfectly w/o keywords static and final.
Also, the overloaded function w/ 2 parameters can be removed as well.

1 Like

@GoToLoop Is this correct (below)?

int[] seq4_1_20, seqNeg4_1_20, seq1_10_Neg10;
int lo, dir;


void setup() {
  seq4_1_20 = first_function(4, 20);
  seqNeg4_1_20 = first_function(4, -20);
  seq1_10_Neg10 = second_function(-1, 10, -10);

  println(seq4_1_20);
  println();
  println(seqNeg4_1_20);
  println();
  println(seq1_10_Neg10);

  exit();
}

int[] first_function(int n, int hi) {

  if (hi >= 0) {
    lo = 1;
  } else {
    lo = -1;
  }
  return second_function(n, lo, hi);
}


int[] second_function(int n, int lo, int hi) {

  int nn = abs(n);
  int len = (abs(hi - lo) + 1) * nn;
  if (hi >= lo) {
    dir = 1;
  } else {
    dir = -1;
  }
  int seq [ ] = new int[len];


  for (int i = 0; i < len; i++) {
    seq[i] = i / nn * dir + lo;
  }

  return seq;
}

There is something wrong. Please compare the results of:
seq4_1_20 = first_function(4, 20);
with the same call from your earlier code…

int[] seq4_1_20, seqNeg4_1_20, seq1_10_Neg10;
int lo, dir;

void setup() {
  seq4_1_20 = first_function(4, 20);
  seqNeg4_1_20 = first_function(4, -20);
  seq1_10_Neg10 = second_function(-1, 10, -10);

  println(seq4_1_20);
  println();
  //println(seqNeg4_1_20);
  println();
  //println(seq1_10_Neg10);


  exit();
}

int[] first_function(int n, int hi) {

  if (hi >= 0) {
    lo = 1;
  } else {
    lo = -1;
  }
  return second_function(n, lo, hi);
}

int[] second_function(int n, int lo, int hi) {

  int qty = abs(hi - lo) + 1;
  int len = abs(n) * qty;
  if (hi >= lo) {
    dir = 1;
  } else {
    dir = -1;
  }
  int seq[] = new int[len];

  for (int i = 0; i < len; i++) {
    seq[i] = i % qty * dir + lo;
  }

  return seq;
}

Both outputs match mine! Only diff. is due to use of str(), mine is 1 line of values for the whole array w/o indices; while yours display each array’s [index] value pair at its own line.
But the actual array’s contents are the same for both versions!

Why are you declaring global variables lo & dir instead of inside the functions that exclusively depend on them?
Besides decreasing performance, it also makes those functions thread-unsafe!

if you’d add back keyword static, your function will refuse to compile w/ message:
“Cannot make a static reference to the non-static field lo/dir”

It’d reveal that your version of those functions now depend on the state of the rest of the PApplet sketch.

But a high quality & robust function should be isolated and completely independent from the rest of the code.

It doesn’t make sense for the same functionality to have different function names.

For example, does it make sense to you for Processing function random() w/ overloaded version w/ 1 parameter high & the version w/ 2 parameters low & high to have different names?

Should random(50) & random(0, 50) be renamed to something like:
randomWith1Param(50) & randomWith2Params(0, 50)?

Also notice that first_function(4, 20) is equivalent to second_function(4, 1, 20).
And first_function(4, -20) is equivalent to second_function(4, -1, -20).

And in the second_function(-1, 10, -10), the -1 is an illegal argument. It should be 1 instead!

The reason I was passing -1 was to test if my function would sanitize it to a positive value using abs(n)!

Now I understand why I should not declare global variables lo & dir as I did. Thank you. @GoToLoop

When I say there is something wrong, I mean your
seq4_1_20 = periodicIntSeqRepeatedNTimes(4, 20);
in post 11 does not give the same result as the same code in your post 6.

https://discourse.processing.org/t/series-from-for-loop-is-there-a-repository-for-integer-sequences/44970/6
https://discourse.processing.org/t/series-from-for-loop-is-there-a-repository-for-integer-sequences/44970/11

My reason for breaking everything into single lines and using first_function, second_function, and so on is to increase understanding (and to appreciate the beauty) of the code. When it is all understood and appreciated, it can all be packed up again. An analogous example, if I was trying to find the formula for determining whether a number was prime or not I would ignore a function (if was available) called something like isPrime(). It would do the job, but I wouldn’t learn much by using it.

Can we use the same function for 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, …

B/c they’re different functions w/ different names w/ diff. implementation:

  1. seqIntsRepeatedNTimesEach()
  2. periodicIntSeqRepeatedNTimes()

1st 1 repeats each number from a range (lo, hi) n times.
For example, seqIntsRepeatedNTimesEach(2, 3, 5) would output:
3 3 4 4 5 5, which is 3 twice, 4 twice and 5 twice.

2nd 1 repeats a whole range (lo, hi) n times.
For example, periodicIntSeqRepeatedNTimes(2, 3, 5) would output:
3 4 5 3 4 5, which is the sequence 3, 4, 5 repeated twice.

Notice though that when we have 1st param (n = 1), both functions output the same result.

Param (n = 0) would output an empty array for both functions.

And negative param n is sanitized to positive n via abs().

2 Likes

Got it! Thank you for your patience…
I tried to extend the code for 3, 5, 7, 9, 3, 5, 7, 9, but on the second repeat I get 4, 6, 8…

int[] testsequence;

// first parameter is number of repetitions
// second parameter is lo
// third parameter is hi
// fourth parameter is interval

void setup() {
  testsequence = series_function(2, 3, 9, 2);

  //println(testsequence);


  exit();
}


int[] series_function(int n, int lo, int hi, int skip) {

  int qty = abs(hi - lo) + 1;
  int len = abs(n) * qty;
  int dir;
  if (hi >= lo) {
    dir = 1;
  } else {
    dir = -1;
  }
  int seq[] = new int[len];

  for (int i = 0; i < len; i += skip) {
    seq[i] = i % qty * dir + lo;
    println(seq[i]);  // here during testing
  }

  return seq;
}

I don’t get what would be the desired effect of your 4th parameter.

You didn’t say what would be the expected output for those 4 arguments.

We can’t interfere w/ how the iterator i progresses!
It should be always: for (int i = 0; i < len; ++i).
Your output now is full of 0s: 3 0 5 0 7 0 9 0 4 0 6 0 8 0

1 Like