Bijektive Abbildung (Selbstabbildung) mithilfe des %-Operators in JS/ES



  • Moin, ich hätte eine Frage.

    Wie müsste der folgende Term für j umgestellt werden, damit eine bijektive Abbildung, jeweils mit einem Versatz um 4, entsteht? Bislang fehlt die 13, aber die 0 kommt zweimal vor. Ginge das nur mit einer for-Schleife?

    for (let i = 0; i < 18; i++) {
      let j = (((i * 4) % 18) + Math.floor(i / 4)) % 18;
      console.log(i, j);
    }
    

  • Mod

    (i+4) % 18?



  • @SeppJ sagte in Bijektive Abbildung mithilfe des %-Operators in JS/ES:

    (i+4) % 18?

    Theoretisch ja. Aber ich hatte an ein Raster gedacht (jeweils 4 weiter):

    0 4 8 12 16
    1 5 9 13 17
    2 6 10 14
    3 7 11 15

    Jetzt sieht man vielleicht das Problem: Es gibt "Leerplätze".

    Für beliebige n (momentan 18) und m (momentan 4) komme ich da auf keinen grünen Zweig.

    Und die KI möchte eine zusätzliche Schleife einführen.


  • Mod

    Jetzt verstehe ich erst, was du möchtest. Da braucht man keine zweite Schleife, sondern Mathematik der 3. Klasse. Tolle KI 🙄

    Ich weiß nicht, wie man in Javascript eine Integerdivision schreibt. Also eine Division, wo man nur den ganzzahligen Teil einer Integerdivision bekommt, das Gegenstück von modulo (%). Das musst du selber herausfinden, gibt es ganz sicher. Mal angenommen // wäre diese Integerdivision (Merke // ist es ganz bestimmt nicht, das weiß selbst ich, dass das ein Kommentar in JS ist), dann wäre die Formel für beliebige n und m (und i von 0 bis m):

    (i * n) % m + (i * n) // m
    

    Beispiel für dein n=4 und m=18:

    0 0
    1 4
    2 8
    3 12
    4 16
    5 3
    6 7
    7 11
    8 15
    9 2
    10 6
    11 10
    12 14
    13 18
    14 5
    15 9
    16 13
    17 17
    

    Okay, ein Drittklässler käme da wahrscheinlich nicht alleine drauf, aber er könnte es immerhin alles ausrechnen 🙂

    PS: Ich schätze dein Math.floor(i / 4) ist effektiv schon die Integerdivision von i und 4. Gibt es da nichts besseres? Aber zu Not tut es das auch, hier dann natürlich Math.floor((i * n) / m)



  • Dein Ansatz ist gut... funktioniert aber nicht für beliebige "n" und "m":

    function interleaveShiftIndex(totalSteps, offset, currentIndex) {
      return (
        ((currentIndex * offset) % totalSteps) +
        Math.floor((currentIndex * offset) / totalSteps)
      );
    }
    
    (function test(rounds) {
      a: for (let i = 0; i < rounds; i++) {
        let totalSteps = 10 + Math.round(Math.random() * 20);
        let offset = 1 + Math.round(Math.random() * (totalSteps / 2 - 1));
        let counts = {};
        for (let j = 0; j < totalSteps; j++) {
          let sIndex = interleaveShiftIndex(totalSteps, offset, j);
          // console.log(j, sIndex);
          if (!counts[sIndex]) {
            counts[sIndex] = 1;
          } else {
            counts[sIndex]++;
          }
        }
        for (let key in counts) {
          if (counts[key] !== 1) {
            console.log('Error', totalSteps, offset, i, key, counts[key]);
            continue a;
          }
        }
        console.log('Ok', totalSteps, offset, i);
      }
    })(100);
    

    ... und 3. Klasse ist bei mir schon länger her.



  • @SeppJ sagte in Bijektive Abbildung mithilfe des %-Operators in JS/ES:

    13 18

    18 darf auch nicht vorkommen, denn der Definitionsbereich ist zugleich auch der Wertebereich.

    Edit: Selbstabbildung, Endomorphismus bzw. Permutation.