leds are repeating top and bottom in pattern

hi So I have 12 leds in a line, and I am using binary notation to turn them on and off. I have patterns stored in an enumerator, and I pass the fnction Display that goes through the binary string to look for a 1 in the pattern and if it exists, it blinks the corresponding led on for a given length of time. and then moves to the next one in the sequence.
It works nicely, however i want it to go up and down the pattern, and it does that but it repeats the top and bottom led. I can see why it does that in the code, but I cant work out how to stop it. I tried moving the mask along, but then it shifts the entire pattern in the line of leds. I tried stopping the for loop early, but that doesnt seem to have an affect - and I know why… I cant just cut the top or bottom off the for loop, because it may not be that led that is meant to be lit i.e if you have 5 leds in a line, and the pattern is to light leds 2 and 4, then cutting one or 5 out of the loop wouldn’t stop it lighting, so you still get 2 twice, and then 4 twice. It seems somehow the loop needs to know whether this is the last led in the pattern to be lit???
Any ideas? Function below:

enum Pattern{ 
  P1 = 0b100010010000, 
  P2 = 0b001000100100, 
  P3 = 0b000010001001, 

};

  void Display(unsigned int Pattern, int time){
  int mask = 0b100000000000;
  for(int i=0; i<12; i++){

      if((mask & Pattern) == 0){
      }
      else {
        Ledpattern(i, time);
      }
    mask = mask >> 1;
  }
  mask = 0b000000000001;
  for(int i=11; i>=0; i--){

      if((mask & Pattern) == 0){
      }
      else {
        
        Ledpattern(i, time);
      }

    mask = mask << 1;

  }

}

Not sure what you mean by "repeats the bottom/last".

So if the pattern is LED 3 and 5 of 5 LEDs would you expect it to blink 3, 5, (going forward) and then 5, 3 (going backward) which is what the code does very well. but you want 3, 5, 3 because the 5 is at the end, you do not want it twice?

As you write, reducing your loops would not work if the numbers are 2,3 4 in the 5 Lights as it would do 2, 3, 4, 4, 3, 2 and you want to avoid doing the 4 double?.

It requires more code: you have to remember the last LED number you blinked, and then ignore it if the same number comes up again. You can code that test & skip inside your Ledpattern function.

Lastly I am worried about your construct

if ( test ) { /* empty */ } else { /*actual code*/ }

If it is temporary construct due to some debugging code now left out, OK, but change it to

if ( opposite-test ) { /*actual code*/ }

Let’s take your first pattern: 0b100010010000

That’s lights 0,4, and 7. As your code is written that will blink the pattern 0, 4, 7, 7, 4, 0 and it you repeat three times:

0, 4, 7, 7, 4, 0, 0, 4, 7, 7, 4, 0, 0, 4, 7, 7, 4, 0

Are you saying you want that to be: 0, 4, 7, 4, 0, 4, 7, 4, 0, 4, 7, 4, 0?

void Display(unsigned int Pattern, int time){
static int lastLED = -1;
  for(int i=0; i<12; i++) {
    if((((1<<(11-i)) & Pattern) && i != lastLED) {
      Ledpattern(i, time);
      lastLED = i;
    }
  }

  for(int i=11; i>=0; i--) {
    if((((1<<(11-i)) & Pattern) && i != lastLED) {
      Ledpattern(i, time);
      lastLED = i;
    }
  }
}

Yeah, that was quite hard to write, but you guys did both understand. I dont need the mask then??

johnwassers expression(1<<(11-i))is the mask - it is computed on the fly.

On a side note: It would be a long and heated debate to determine what is “more efficient” (in terms of code, memory and CPU use); shifting your mask or computing it on the fly. It does not matter. One writes the code that most clearly states what the purpose is (unless one is in a very time critical section when one possibly has to write things in a “confusing” way to get it faster).