from machine import Pin
import time
import random


def random_shuffle(seq):
  for k in range(10):
    l = len(seq)
    for i in range(l):
      j = random.randrange(l)
      seq[i], seq[j] = seq[j], seq[i]


class Combinatorics:
  def __init__(self):
    self.generate_new_combination()

  def generate_new_combination(self):
    num_on = random.randrange(3, 6)
    self.combination = ["ON"] *  num_on + ["OFF"] * (6 - num_on)
    random_shuffle(self.combination)
    self.instructions = [[] if self.combination[i] == "ON" else [random.randrange(16) for a in range(4)] for i in range(6)]
    current_switches = list(range(16))
    random_shuffle(current_switches)
    for i in range(len(self.instructions)):
        if self.instructions[i] == []:
            for b in range(16 // num_on):
                value = current_switches.pop()
                self.instructions[i].append(value)
    while current_switches != []:
        self.instructions[-1].append(current_switches.pop())
        
    random_shuffle(self.instructions)


if __name__ == "__main__":
  c = Combinatorics()
  pins = [Pin(i, Pin.OUT) for i in range(16)]
  switches = [Pin(i, Pin.IN, Pin.PULL_DOWN) for i in range(16, 22)]
  button = Pin(22, Pin.IN, Pin.PULL_DOWN)
  switch_states = [i() for i in switches]
  reset_all = lambda: [i(0) for i in pins]
  while not all(not i for i in switch_states):
    for i in range(6):
      if switches[i]() != switch_states[i]:
        switch_states[i] = not switch_states[i]
    [i(1) for i in pins]
    time.sleep(0.25)
    reset_all()
    time.sleep(0.25)
  while True:
    while button():
      reset_all()
      c.generate_new_combination()
      time.sleep(0.25)
      while not all(not i for i in switch_states):
        for i in range(6):
          if switches[i]() != switch_states[i]:
            switch_states[i] = not switch_states[i]
        [i(1) for i in pins]
        time.sleep(0.25)
        reset_all()
        time.sleep(0.25)
    for i in range(6):
      if switches[i]() != switch_states[i]:
        switch_states[i] = not switch_states[i]
        for j in c.instructions[i]:
          pins[j].toggle()
    if all(i() for i in pins):
      reset_all()
      c.generate_new_combination()
      time.sleep(0.25)
      while not all(not i for i in switch_states):
        for i in range(6):
          if switches[i]() != switch_states[i]:
            switch_states[i] = not switch_states[i]
        [i(1) for i in pins]
        time.sleep(0.25)
        reset_all()
        time.sleep(0.25)

BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT