DEV Community

Cover image for Achilles numbers generation
Grzegorz Kućmierz
Grzegorz Kućmierz

Posted on

Achilles numbers generation

Today I solved "Slay Achilles!" codewars task.

Achilles numbers can be found on on-line encyclopedia of integer sequences A052486

https://www.codewars.com/kata/5708c90cd531cdfecf00147c/javascript

Here is my code that is checking if number is Achilles one, and prints 10k first integers with Achilles check.

function factors(n) {
  let max = Math.floor(Math.sqrt(n));
  let res = [];
  for (let i = 2; i <= max; ++i) {
    if (n % i === 0) {
      res.push(i);
      n /= i;
      max = Math.floor(Math.sqrt(n));
      i = (Math.min(...res) || 2) - 1;
    }
  }
  res.push(n);
  return res;
}

const groupToMap = (array, cb = el => el) => {
  const map = new Map();
  array.map((el, i) => {
    const key = cb(el, i);
    if (map.has(key)) {
      map.get(key).push(el);
    } else {
      map.set(key, [el]);
    }
  });
  return map;
};

function gcd(a, b) {
  if (a < 0) a = -a;
  if (b < 0) b = -b;
  if (b > a) {
    [a, b] = [b, a];
  }
  while (1) {
    if (b == 0) return a;
    a %= b;
    if (a == 0) return b;
    b %= a;
  }
}

const isAchilles = n => {
  const f = factors(n);
  const grouped = groupToMap(f);
  const values = [...grouped.values()];
  const gcdLen = values.map(arr => arr.length).reduce(gcd);
  if (gcdLen !== 1) return false;
  return values.length > 1 && values.every(arr => arr.length > 1);
};

for (let i = 0; i < 1e4; ++i) {
  console.log(i, isAchilles(i));
}
Enter fullscreen mode Exit fullscreen mode

In this code I used few already created functions:

  • factors - breaks integer number into factors
  • groupToMap - group array elements (MDN experimental feature yet)
  • gcd - calculates Greatest Common Divisor

Here you can play with that code:

Instacode playground

Top comments (0)