Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   НОД более чем 2-х чисел (https://javascript.ru/forum/misc/34469-nod-bolee-chem-2-kh-chisel.html)

Demath 06.01.2013 00:39

НОД более чем 2-х чисел
 
Помогите с функцией для получения НОД более чем 2-х чисел.

Для 2-х чисел функций полно. Например, для отыскания НОД 3-х чисел (a,b,c), использую эту функцию

function NOD(x,y){ while ((x!=0) && (y!=0)) {if (x>y) {x%=y} else {y%=x}} return (x+y) }
рекурсивно NOD(NOD(a,b),c). Но проблема в том, что в полевых условиях количество чисел переменно.

Дзен-трансгуманист 06.01.2013 01:33

Цитата:

Сообщение от Demath
рекурсивно NOD(NOD(a,b),c)

Это хвостовая рекурсия, ее легко упразднить.
function NOD ( /* arguments */ ) {
  return Array.prototype.reduce.call( arguments, function ( x, y ) {
    while ( x && y ) {
      x > y ? x %= y : y %= x;
    }
    return x + y;
  });
}

alert([
  NOD( 10, 15 ),
  NOD( 111, 555, 407 ),
  NOD( 100, 200, 300, 400, 2225, 175, 19873625 ),
  NOD( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 )
].join( '\n' ));


Или более обратно совместимо
function NOD ( /* arguments */ ) {
  for ( var x = arguments[ 0 ], i = 1; i < arguments.length; i++ ) {
    var y = arguments[ i ];
    while ( x && y ) {
      x > y ? x %= y : y %= x;
    }
    x += y;
  }
  return x;
}

alert([
  NOD( 10, 15 ),
  NOD( 111, 555, 407 ),
  NOD( 100, 200, 300, 400, 2225, 175, 19873625 ),
  NOD( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 )
].join( '\n' ));

Второй вариант, по идее, должен работать быстрее.

monolithed 06.01.2013 03:01

Или так:

function NOD ( /* arguments */ ) {
  return Array.prototype.reduce.call( arguments, function ( x, y ) {
    while (1) {
		if (!(x %= y))
			return y;

        if (!(y %= x))
			return x;
    }
  });
}

alert([
  NOD( 10, 15 ),
  NOD( 111, 555, 407 ),
  NOD( 100, 200, 300, 400, 2225, 175, 19873625 ),
  NOD( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 )
].join( '\n' ));

Demath 06.01.2013 03:18

monolithed,

В Вашем варианте, если последнее число 0, то НОД=0, что не желательно.
А вообще, спасибо Вам и Дзен-трансгуманист!

monolithed 06.01.2013 05:27

Цитата:

Сообщение от Demath
В Вашем варианте, если последнее число 0, то НОД=0, что не желательно.

Ага, забыл)

function NOD ( /* arguments */ ) {
	return Array.prototype.reduce.call( arguments, function ( x, y ) {
		while (true) {
			if (y === 0)
				return x;

			if (!(x %= y))
				return y;

			if (!(y %= x))
				return x;
		}
	});
}


PS: все-равно мое решение некрасивое получилось)


Часовой пояс GMT +3, время: 01:38.