Comment calculez-vous le plus petit multiple commun de plusieurs nombres?
Jusqu'à présent, je n'ai pu le calculer qu'entre deux nombres. Mais vous ne savez pas comment l'élargir pour calculer 3 nombres ou plus.
Jusqu'ici c'est comme ça que je l'ai fait
LCM = num1 * num2 / gcd ( num1 , num2 )
Avec gcd, la fonction permet de calculer le plus grand commun diviseur pour les nombres. Utiliser l'algorithme euclidien
Mais je ne peux pas comprendre comment le calculer pour 3 nombres ou plus.
Vous pouvez calculer le LCM de plus de deux nombres en calculant de manière itérative le LCM de deux nombres, c.-à-d.
lcm(a,b,c) = lcm(a,lcm(b,c))
En Python (modifié primes.py ):
def gcd(a, b):
"""Return greatest common divisor using Euclid's Algorithm."""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""Return lowest common multiple."""
return a * b // gcd(a, b)
def lcmm(*args):
"""Return lcm of args."""
return reduce(lcm, args)
Usage:
>>> lcmm(100, 23, 98)
112700
>>> lcmm(*range(1, 20))
232792560
reduce()
fonctionne quelque chose comme que :
>>> f = lambda a,b: "f(%s,%s)" % (a,b)
>>> print reduce(f, "abcd")
f(f(f(a,b),c),d)
Voici une implémentation de style ECMA:
function gcd(a, b){
// Euclidean algorithm
var t;
while (b != 0){
t = b;
b = a % b;
a = t;
}
return a;
}
function lcm(a, b){
return (a * b / gcd(a, b));
}
function lcmm(args){
// Recursively iterate through pairs of arguments
// i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))
if(args.length == 2){
return lcm(args[0], args[1]);
} else {
var arg0 = args[0];
args.shift();
return lcm(arg0, lcmm(args));
}
}
Je voudrais aller avec celui-ci (C #):
static long LCM(long[] numbers)
{
return numbers.Aggregate(lcm);
}
static long lcm(long a, long b)
{
return Math.Abs(a * b) / GCD(a, b);
}
static long GCD(long a, long b)
{
return b == 0 ? a : GCD(b, a % b);
}
Juste quelques clarifications, car à première vue, cela ne donne pas une idée aussi claire de ce que fait ce code:
L'agrégat est une méthode d'extension Linq. Vous ne pouvez donc pas oublier d'ajouter System.Linq à vos références.
L'agrégat obtient une fonction d'accumulation afin que nous puissions utiliser la propriété lcm (a, b, c) = lcm (a, lcm (b, c)) sur un IEnumerable. Plus sur Aggregate
Le calcul GCD utilise l'algorithme Euclidien .
le calcul en lcm utilise Abs (a * b)/gcd (a, b), se référer à Réduction par le plus grand commun diviseur .
J'espère que cela t'aides,
Certains codes Python qui ne nécessitent pas de fonction pour gcd:
from sys import argv
def lcm(x,y):
tmp=x
while (tmp%y)!=0:
tmp+=x
return tmp
def lcmm(*args):
return reduce(lcm,args)
args=map(int,argv[1:])
print lcmm(*args)
Voici à quoi cela ressemble dans le terminal:
$ python lcm.py 10 15 17
510
Je viens de comprendre cela dans Haskell:
lcm' :: Integral a => a -> a -> a
lcm' a b = a`div`(gcd a b) * b
lcm :: Integral a => [a] -> a
lcm (n:ns) = foldr lcm' n ns
J'ai même pris le temps d'écrire ma propre fonction gcd
, seulement pour la trouver dans Prelude! Beaucoup d'apprentissage pour moi aujourd'hui: D
Voici un one-liner Python (sans compter les importations) pour renvoyer le LCM des nombres entiers de 1 à 20 inclus:
Importations de Python 3.5+:
from functools import reduce
from math import gcd
Importations Python 2.7:
from fractions import gcd
Logique commune:
lcm = reduce(lambda x,y: x*y//gcd(x, y), range(1, 21))
Dans les deux Python 2 et Python 3 , les règles de priorité des opérateurs indiquent que les opérateurs *
et //
ont la même priorité et s'appliquent donc de gauche à droite. En tant que tel, x*y//z
signifie (x*y)//z
et non pas x*(y//z)
. Les deux produisent généralement des résultats différents. Cela n’aurait pas eu autant d’importance pour la division float, mais il en va de même pour floor division .
Voici un portage C # de la mise en oeuvre de Virgil Disgr4ce:
public class MathUtils
{
/// <summary>
/// Calculates the least common multiple of 2+ numbers.
/// </summary>
/// <remarks>
/// Uses recursion based on lcm(a,b,c) = lcm(a,lcm(b,c)).
/// Ported from http://stackoverflow.com/a/2641293/420175.
/// </remarks>
public static Int64 LCM(IList<Int64> numbers)
{
if (numbers.Count < 2)
throw new ArgumentException("you must pass two or more numbers");
return LCM(numbers, 0);
}
public static Int64 LCM(params Int64[] numbers)
{
return LCM((IList<Int64>)numbers);
}
private static Int64 LCM(IList<Int64> numbers, int i)
{
// Recursively iterate through pairs of arguments
// i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))
if (i + 2 == numbers.Count)
{
return LCM(numbers[i], numbers[i+1]);
}
else
{
return LCM(numbers[i], LCM(numbers, i+1));
}
}
public static Int64 LCM(Int64 a, Int64 b)
{
return (a * b / GCD(a, b));
}
/// <summary>
/// Finds the greatest common denominator for 2 numbers.
/// </summary>
/// <remarks>
/// Also from http://stackoverflow.com/a/2641293/420175.
/// </remarks>
public static Int64 GCD(Int64 a, Int64 b)
{
// Euclidean algorithm
Int64 t;
while (b != 0)
{
t = b;
b = a % b;
a = t;
}
return a;
}
}'
Fonction pour trouver lcm de n'importe quelle liste de nombres:
def function(l):
s = 1
for i in l:
s = lcm(i, s)
return s
En utilisant LINQ, vous pouvez écrire:
static int LCM(int[] numbers)
{
return numbers.Aggregate(LCM);
}
static int LCM(int a, int b)
{
return a * b / GCD(a, b);
}
Il faut ajouter using System.Linq;
et ne pas oublier de gérer les exceptions ...
Le voici dans Swift .
// Euclid's algorithm for finding the greatest common divisor
func gcd(_ a: Int, _ b: Int) -> Int {
let r = a % b
if r != 0 {
return gcd(b, r)
} else {
return b
}
}
// Returns the least common multiple of two numbers.
func lcm(_ m: Int, _ n: Int) -> Int {
return m / gcd(m, n) * n
}
// Returns the least common multiple of multiple numbers.
func lcmm(_ numbers: [Int]) -> Int {
return numbers.reduce(1) { lcm($0, $1) }
}
Dans R, nous pouvons utiliser les fonctions mGCD (x) et mLCM (x) du paquet numbers, pour calculer le plus grand commun diviseur et le plus petit commun multiple pour tous les nombres du nombre entier. vecteur x ensemble:
library(numbers)
mGCD(c(4, 8, 12, 16, 20))
[1] 4
mLCM(c(8,9,21))
[1] 504
# Sequences
mLCM(1:20)
[1] 232792560
Et la version Scala:
def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
def gcd(nums: Iterable[Int]): Int = nums.reduce(gcd)
def lcm(a: Int, b: Int): Int = if (a == 0 || b == 0) 0 else a * b / gcd(a, b)
def lcm(nums: Iterable[Int]): Int = nums.reduce(lcm)
Style ES6
function gcd(...numbers) {
return numbers.reduce((a, b) => b === 0 ? a : gcd(b, a % b));
}
function lcm(...numbers) {
return numbers.reduce((a, b) => Math.abs(a * b) / gcd(a, b));
}
Juste pour le plaisir, une implémentation de Shell (presque n’importe quel shell):
#!/bin/sh
gcd() { # Calculate $1 % $2 until $2 becomes zero.
until [ "$2" -eq 0 ]; do set -- "$2" "$(($1%$2))"; done
echo "$1"
}
lcm() { echo "$(( $1 / $(gcd "$1" "$2") * $2 ))"; }
while [ $# -gt 1 ]; do
t="$(lcm "$1" "$2")"
shift 2
set -- "$t" "$@"
done
echo "$1"
essayez-le avec:
$ ./script 2 3 4 5 6
obtenir
60
L'entrée et le résultat les plus importants doivent être inférieurs à (2^63)-1
sinon le calcul mathématique du shell sera terminé.
vous pouvez le faire d’une autre manière - S’il ya n nombres. Prenez une paire de nombres consécutifs et enregistrez son lcm dans un autre tableau. Cela fait au premier programme d’itération n/2 itérations. Ensuite, la prochaine paire à partir de 0, comme (0,1), (2,3), etc., calcule leur MCL et la stocke dans un autre tableau. Faites ceci jusqu'à ce qu'il ne vous reste qu'un tableau . (Il n'est pas possible de trouver lcm si n est impair)
Voici l'implémentation PHP:
// https://stackoverflow.com/q/12412782/1066234
function math_gcd($a,$b)
{
$a = abs($a);
$b = abs($b);
if($a < $b)
{
list($b,$a) = array($a,$b);
}
if($b == 0)
{
return $a;
}
$r = $a % $b;
while($r > 0)
{
$a = $b;
$b = $r;
$r = $a % $b;
}
return $b;
}
function math_lcm($a, $b)
{
return ($a * $b / math_gcd($a, $b));
}
// https://stackoverflow.com/a/2641293/1066234
function math_lcmm($args)
{
// Recursively iterate through pairs of arguments
// i.e. lcm(args[0], lcm(args[1], lcm(args[2], args[3])))
if(count($args) == 2)
{
return math_lcm($args[0], $args[1]);
}
else
{
$arg0 = $args[0];
array_shift($args);
return math_lcm($arg0, math_lcmm($args));
}
}
// fraction bonus
function math_fraction_simplify($num, $den)
{
$g = math_gcd($num, $den);
return array($num/$g, $den/$g);
}
var_dump( math_lcmm( array(4, 7) ) ); // 28
var_dump( math_lcmm( array(5, 25) ) ); // 25
var_dump( math_lcmm( array(3, 4, 12, 36) ) ); // 36
var_dump( math_lcmm( array(3, 4, 7, 12, 36) ) ); // 252
Les crédits vont à @ T3db0t avec sa réponse ci-dessus (code de style ECMA) .
je cherchais gcd et lcm d’éléments de tableau et trouvais une bonne solution dans le lien suivant.
https://www.hackerrank.com/challenges/between-two-sets/forum
qui comprend le code suivant. L'algorithme pour gcd utilise l'algorithme euclidien expliqué dans le lien ci-dessous.
private static int gcd(int a, int b) {
while (b > 0) {
int temp = b;
b = a % b; // % is remainder
a = temp;
}
return a;
}
private static int gcd(int[] input) {
int result = input[0];
for (int i = 1; i < input.length; i++) {
result = gcd(result, input[i]);
}
return result;
}
private static int lcm(int a, int b) {
return a * (b / gcd(a, b));
}
private static int lcm(int[] input) {
int result = input[0];
for (int i = 1; i < input.length; i++) {
result = lcm(result, input[i]);
}
return result;
}
int gcd(int a, int b) {
if (b == 0) return a;
return gcd(b, a%b);
}
int lcm(int[] a, int n) {
int res = 1, i;
for (i = 0; i < n; i++) {
res = res*a[i]/gcd(res, a[i]);
}
return res;
}
clc;
data = [1 2 3 4 5]
LCM=1;
for i=1:1:length(data)
LCM = lcm(LCM,data(i))
end
Pour ceux qui recherchent un code de travail rapide, essayez ceci:
J'ai écrit une fonctionlcm_n(args, num)
qui calcule et retourne le lcm de tous les nombres du tableau args
. Le second paramètrenum
est le nombre de nombres dans le tableau.
Placez tous ces nombres dans un tableau args
, puis appelez la fonction comme suit: lcm_n(args,num);
Cette fonction retourne le lcm de tous ces nombres.
Voici l'implémentation de la fonction lcm_n(args, num)
:
int lcm_n(int args[], int num) //lcm of more than 2 numbers
{
int i, temp[num-1];
if(num==2)
{
return lcm(args[0], args[1]);
}
else
{
for(i=0;i<num-1;i++)
{
temp[i] = args[i];
}
temp[num-2] = lcm(args[num-2], args[num-1]);
return lcm_n(temp,num-1);
}
}
Cette fonction a besoin de moins de deux fonctions pour fonctionner. Alors, ajoutez-les simplement avec elle.
int lcm(int a, int b) //lcm of 2 numbers
{
return (a*b)/gcd(a,b);
}
int gcd(int a, int b) //gcd of 2 numbers
{
int numerator, denominator, remainder;
//Euclid's algorithm for computing GCD of two numbers
if(a > b)
{
numerator = a;
denominator = b;
}
else
{
numerator = b;
denominator = a;
}
remainder = numerator % denominator;
while(remainder != 0)
{
numerator = denominator;
denominator = remainder;
remainder = numerator % denominator;
}
return denominator;
}
Que dis-tu de ça?
from operator import mul as MULTIPLY
def factors(n):
f = {} # a dict is necessary to create 'factor : exponent' pairs
divisor = 2
while n > 1:
while (divisor <= n):
if n % divisor == 0:
n /= divisor
f[divisor] = f.get(divisor, 0) + 1
else:
divisor += 1
return f
def mcm(numbers):
#numbers is a list of numbers so not restricted to two items
high_factors = {}
for n in numbers:
fn = factors(n)
for (key, value) in fn.iteritems():
if high_factors.get(key, 0) < value: # if fact not in dict or < val
high_factors[key] = value
return reduce (MULTIPLY, ((k ** v) for k, v in high_factors.items()))
La méthode compLCM prend un vecteur et retourne LCM. Tous les nombres sont dans le vecteur in_numbers.
int mathOps::compLCM(std::vector<int> &in_numbers)
{
int tmpNumbers = in_numbers.size();
int tmpMax = *max_element(in_numbers.begin(), in_numbers.end());
bool tmpNotDividable = false;
while (true)
{
for (int i = 0; i < tmpNumbers && tmpNotDividable == false; i++)
{
if (tmpMax % in_numbers[i] != 0 )
tmpNotDividable = true;
}
if (tmpNotDividable == false)
return tmpMax;
else
tmpMax++;
}
}
Nous avons une implémentation de travail du plus petit commun multiple sur Calculla qui fonctionne pour un nombre quelconque d'entrées affichant également les étapes.
Ce que nous faisons c'est:
0: Assume we got inputs[] array, filled with integers. So, for example:
inputsArray = [6, 15, 25, ...]
lcm = 1
1: Find minimal prime factor for each input.
Minimal means for 6 it's 2, for 25 it's 5, for 34 it's 17
minFactorsArray = []
2: Find lowest from minFactors:
minFactor = MIN(minFactorsArray)
3: lcm *= minFactor
4: Iterate minFactorsArray and if the factor for given input equals minFactor, then divide the input by it:
for (inIdx in minFactorsArray)
if minFactorsArray[inIdx] == minFactor
inputsArray[inIdx] \= minFactor
5: repeat steps 1-4 until there is nothing to factorize anymore.
So, until inputsArray contains only 1-s.
Et c'est tout - vous avez votre lcm.
C'est ce que j'ai utilisé -
def greater(n):
a=num[0]
for i in range(0,len(n),1):
if(a<n[i]):
a=n[i]
return a
r=input('enter limit')
num=[]
for x in range (0,r,1):
a=input('enter number ')
num.append(a)
a= greater(num)
i=0
while True:
while (a%num[i]==0):
i=i+1
if(i==len(num)):
break
if i==len(num):
print 'L.C.M = ',a
break
else:
a=a+1
i=0
Le LCM est à la fois associatif et commutatif.
LCM (a, b, c) = LCM (LCM (a, b), c) = LCM (a, LCM (b, c))
voici un exemple de code en C:
int main()
{
int a[20],i,n,result=1; // assumption: count can't exceed 20
printf("Enter number of numbers to calculate LCM(less than 20):");
scanf("%d",&n);
printf("Enter %d numbers to calculate their LCM :",n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
result=lcm(result,a[i]);
printf("LCM of given numbers = %d\n",result);
return 0;
}
int lcm(int a,int b)
{
int gcd=gcd_two_numbers(a,b);
return (a*b)/gcd;
}
int gcd_two_numbers(int a,int b)
{
int temp;
if(a>b)
{
temp=a;
a=b;
b=temp;
}
if(b%a==0)
return a;
else
return gcd_two_numbers(b%a,a);
}
En python:
def lcm(*args):
"""Calculates lcm of args"""
biggest = max(args) #find the largest of numbers
rest = [n for n in args if n != biggest] #the list of the numbers without the largest
factor = 1 #to multiply with the biggest as long as the result is not divisble by all of the numbers in the rest
while True:
#check if biggest is divisble by all in the rest:
ans = False in [(biggest * factor) % n == 0 for n in rest]
#if so the clm is found break the loop and return it, otherwise increment factor by 1 and try again
if not ans:
break
factor += 1
biggest *= factor
return "lcm of {0} is {1}".format(args, biggest)
>>> lcm(100,23,98)
'lcm of (100, 23, 98) is 112700'
>>> lcm(*range(1, 20))
'lcm of (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) is 232792560'
pour python 3:
from functools import reduce
gcd = lambda a,b: a if b==0 else gcd(b, a%b)
def lcm(lst):
return reduce(lambda x,y: x*y//gcd(x, y), lst)
GCD nécessite une petite correction pour les nombres négatifs:
def gcd(x,y):
while y:
if y<0:
x,y=-x,-y
x,y=y,x % y
return x
def gcdl(*list):
return reduce(gcd, *list)
def lcm(x,y):
return x*y / gcd(x,y)
def lcml(*list):
return reduce(lcm, *list)