even sum을 간단히 es로 줄여서 표현하겠습니다.


0. for loop


const es0 = (n) => {

  let sum = 0;

  for (let i = 0; i <= n; i += 2) sum += i;

  return sum;

};



1. filter-reduce


const es1 = (n) =>

  [...Array(n + 1).keys()].filter((i) => i % 2 == 0).reduce((a, b) => a + b);



2. 수학


2 + 4 + ... + n = 2 * (1 + 2 + ... + floor(n)) = floor(n) * (floor(n) + 1)을 이용합니다.


const es2 = (n) => {

  n = Math.floor(n / 2);

  return n * n + n;

};



3. Math.floor 없는 수학


2로 나눈 다음 문자열로 바꾸고 소수점 뒤를 없애버리면 floor가 됩니다.


const es3 = (n) => {

  n = n / 2 + ".";

  n = +n.slice(0, n.indexOf("."));

  return n * n + n;

};


"."을 뒤에 붙인건 indexOf(".")가 항상 음수가 안되도록 하기 위함입니다.



4. 3의 변형


const es4 = (_) => {

  _ = +(_ / 2 + ".")["slice"](0, (_ / 2 + ".")["indexOf"]("."));

  return _ * _ + _;

};



5. "." 안쓰기


js에서 +(11e100 + []) + []는 문자열 "1.1e+101"과 같다. 따라서 (+(11e100 + []) + [])[1] === '.' 이다.


const es5 = (_) => {

  _ = +(_ / 2 + (+"11e100" + [])[1])["slice"](

    0,

    (_ / 2 + (+"11e100" + [])[1])["indexOf"]((+"11e100" + [])[1])

  );

  return _ * _ + _;

};



6. 숫자, "slice", "indexOf" 안쓰기


0 -> +[]

1 -> +!![] 또는 +!+[]

2, 3, ... -> +!+[]+!+[]+...

n, d, e, f, i, O, c -> "undefined"[N] -> ([][[]] + [])[N] 또는 "[object Object]"[N] -> ([] + {})[N]

l -> "false"[2] -> (![] + [])[2]


위를 적용하면


const es6 = (_) => {

  _ = +(_ / (!+[] + !+[]) + // _ / 2

    (+(

      (

        +!![] + //1

        [] +

        +!![] + //1

        ([] + {})[+!![] + !![] + !![] + !![] + !![]] + //e

        +!![] + //1

        +[] + //0

        +[]

      ) //0

    ) + [])[+!+[]]) // _ / 2 + '.'

    [

      (![] + [])[+!![] + !![] + !![]] + //s

      (![] + [])[+!+[] + !+[]] + //l

      ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] + //i

      ([] + {})[+!+[] + !+[] + !+[] + !+[] + !+[]] + //c

        ([][[]] + [])[++[++[++[+[]][+[]]][+[]]][+[]]] //e

    ](

      // slice(0, (_ / 2 + '.').indexOf("."))

      +[], //0

      (_ / (!+[] + !+[]) + // (_/2+

        (+(

          (

            +!![] + //1

            [] +

            +!![] + //1

            ([] + {})[+!![] + !![] + !![] + !![] + !![]] + //e

            +!![] + //1

            +[] + //0

            +[]

          ) //0

        ) + [])[+!+[]])[

        ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] + //i

        ([][[]] + [])[+!+[]] + //n

        ([][[]] + [])[+!+[] + !+[]] + //d

        ([][[]] + [])[+!+[] + !+[] + !+[]] + //e

        "x" +

        ([] + {})[(+!![] + !![]) * (+!![] + !![]) * (+!![] + !![])] + //O

          (![] + [])[+[]] //f

      ](

        // indexOf "."

        (+(

          +!![] +

          [] +

          +!![] +

          ([][[]] + [])[(!+[] + !+[]) * (!+[] + !+[]) - +!+[]] +

          +!![] +

          +[] +

          +[]

        ) + [])[++[[]][+[]]]

      )

    );

  return _ * _ + _;

};


x도 안쓰도록 할 수는 있는데 귀찮습니다



7. return 안쓰기


주석 다 치우고 리팩토링합니다.


const es7 = (_) =>

  +(_ / (!+[] + !+[]) +

    (+(

      +!![] +

      [] +

      +!![] +

      ([] + {})[+!![] + !![] + !![] + !![] + !![]] +

      +!![] +

      +[] +

      +[]

    ) + [])[+!+[]])[

    (![] + [])[+!![] + !![] + !![]] +

      (![] + [])[+!+[] + !+[]] +

      ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] +

      ([] + {})[+!+[] + !+[] + !+[] + !+[] + !+[]] +

      ([][[]] + [])[++[++[++[+[]][+[]]][+[]]][+[]]]

  ](

    +[],

    (_ / (!+[] + !+[]) +

      (+(

        +!![] +

        [] +

        +!![] +

        ([] + {})[+!![] + !![] + !![] + !![] + !![]] +

        +!![] +

        +[] +

        +[]

      ) + [])[+!+[]])[

      ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] +

        ([][[]] + [])[+!+[]] +

        ([][[]] + [])[+!+[] + !+[]] +

        ([][[]] + [])[+!+[] + !+[] + !+[]] +

        "x" +

        ([] + {})[(+!![] + !![]) * (+!![] + !![]) * (+!![] + !![])] +

        (![] + [])[+[]]

    ](

      (+(

        +!![] +

        [] +

        +!![] +

        ([][[]] + [])[(!+[] + !+[]) * (!+[] + !+[]) - +!+[]] +

        +!![] +

        +[] +

        +[]

      ) + [])[++[[]][+[]]]

    )

  ) *

    +(_ / (!+[] + !+[]) +

      (+(

        +!![] +

        [] +

        +!![] +

        ([] + {})[+!![] + !![] + !![] + !![] + !![]] +

        +!![] +

        +[] +

        +[]

      ) + [])[+!+[]])[

      (![] + [])[+!![] + !![] + !![]] +

        (![] + [])[+!+[] + !+[]] +

        ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] +

        ([] + {})[+!+[] + !+[] + !+[] + !+[] + !+[]] +

        ([][[]] + [])[++[++[++[+[]][+[]]][+[]]][+[]]]

    ](

      +[],

      (_ / (!+[] + !+[]) +

        (+(

          +!![] +

          [] +

          +!![] +

          ([] + {})[+!![] + !![] + !![] + !![] + !![]] +

          +!![] +

          +[] +

          +[]

        ) + [])[+!+[]])[

        ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] +

          ([][[]] + [])[+!+[]] +

          ([][[]] + [])[+!+[] + !+[]] +

          ([][[]] + [])[+!+[] + !+[] + !+[]] +

          "x" +

          ([] + {})[(+!![] + !![]) * (+!![] + !![]) * (+!![] + !![])] +

          (![] + [])[+[]]

      ](

        (+(

          +!![] +

          [] +

          +!![] +

          ([][[]] + [])[(!+[] + !+[]) * (!+[] + !+[]) - +!+[]] +

          +!![] +

          +[] +

          +[]

        ) + [])[++[[]][+[]]]

      )

    ) +

  +(_ / (!+[] + !+[]) +

    (+(

      +!![] +

      [] +

      +!![] +

      ([] + {})[+!![] + !![] + !![] + !![] + !![]] +

      +!![] +

      +[] +

      +[]

    ) + [])[+!+[]])[

    (![] + [])[+!![] + !![] + !![]] +

      (![] + [])[+!+[] + !+[]] +

      ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] +

      ([] + {})[+!+[] + !+[] + !+[] + !+[] + !+[]] +

      ([][[]] + [])[++[++[++[+[]][+[]]][+[]]][+[]]]

  ](

    +[],

    (_ / (!+[] + !+[]) +

      (+(

        +!![] +

        [] +

        +!![] +

        ([] + {})[+!![] + !![] + !![] + !![] + !![]] +

        +!![] +

        +[] +

        +[]

      ) + [])[+!+[]])[

      ([][[]] + [])[+!![] + !![] + !![] + !![] + !![]] +

        ([][[]] + [])[+!+[]] +

        ([][[]] + [])[+!+[] + !+[]] +

        ([][[]] + [])[+!+[] + !+[] + !+[]] +

        "x" +

        ([] + {})[(+!![] + !![]) * (+!![] + !![]) * (+!![] + !![])] +

        (![] + [])[+[]]

    ](

      (+(

        +!![] +

        [] +

        +!![] +

        ([][[]] + [])[(!+[] + !+[]) * (!+[] + !+[]) - +!+[]] +

        +!![] +

        +[] +

        +[]

      ) + [])[++[[]][+[]]]

    )

  );


n = 10000까지 돌려봅시다.


const fs = [es0, es1, es2, es3, es4, es5, es6, es7];

for (let i = 1; i <= 10000; ++i) {

  const v = fs.map((f) => f(i));


  console.log("checking", i, v);

  if (!v.every((i) => i === v[0])) {

    console.log("wrong");

    break;

  }

}


결과



viewimage.php?id=3dafdf21f7d335ab67b1d1&no=24b0d769e1d32ca73ded8efa11d02831ee99512b64ee64d67099c224c4024eaa45af7197442dfd249c8d64f19cad662937d6d7b9ecd065076228792b695cef3ec19281497009aa

break 안되고 끝까지 잘 출력됩니다.



이제 까지 알기 쉬운 1~n 짝수합 구현하기였습니다.

감사합니다.


Reference ) https://github.com/aemkei/jsfuck