LCM des nombres rationnels


18

Le plus petit commun multiple (LCM) d'un ensemble de nombres Aest le plus petit entier btel qu'il b/asoit un entier pour tous les entiers ade A. Cette définition peut être étendue aux nombres rationnels!

Tâche

Trouvez le positif le plus petit rationnel b tel que b/aest un nombre entier pour tous rationals a dans l'entrée.

Règles

  • Les failles standard sont interdites.
  • Vous pouvez prendre les numérateurs et les dénominateurs séparément dans l'entrée, mais pas les doubles, les flottants, etc.
  • L'entrée peut ne pas être complètement réduite.
  • Vous pouvez prendre des entrées entières comme rationnelles avec dénominateur de 1.
  • Les soumissions qui fourniraient des nombres rationnels à un module intégré LCM / GCD sont autorisées, mais non concurrentes.

Cas de test

In:  3
Out: 3

In:  1/17
Out: 1/17

In:  1/2, 3/4
Out: 3/2

In:  1/3, 2/8
Out: 1

In:  1/4, 3
Out: 3

In:  2/5, 3
Out: 6

In:  1/2, 3/4, 5/6, 7/8
Out: 105/2

Il s'agit de , donc les soumissions utilisant le moins d'octets gagnent!


4
Remarque: l'informatique LCM[numerators]/GCD[denominators]peut ne pas fonctionner lorsque l'entrée contient un nombre rationnel non réduit. par exemple 1/3, 2/8.
JungHwan Min

Donc, si je le réduit, cela fonctionnera?
Leaky Nun

@LeakyNun Oui, ce sera le cas.
JungHwan Min

Pour encourager les gens à soumettre des réponses non intégrées, j'ai édité la question, rendant les réponses intégrées non concurrentes (toujours autorisées). Si c'est un problème, je vais annuler ma modification.
JungHwan Min

Qu'en est-il d'un LCM intégré utilisé mais uniquement avec des entiers - en concurrence ou non?
Jonathan Allan

Réponses:



6

J, 3 octets, non concurrent.

*./

Étant donné une liste d'entrées rationnelles, cela fait passer LCM à travers.


4

sed, 374 (373 + 1) octets

Le -Edrapeau de sed compte pour un octet. Remarque: je n'ai pas encore essayé de jouer au golf, et je ne le ferai probablement pas depuis un certain temps.
L'entrée est prise en unaire et la sortie est en unaire. Les espaces doivent entourer chaque fraction. Exemple: echo " 1/111 111/11111 111111/111 ".

:d;s, (1*)/\1(1*), \1/\22,;s,(1*)(1*)/\2 ,2\1/\2 ,;td;s,1*(1/22*),\1,g;s,(22*/1)1*,\1,g;:r;s,((1*)/1*)2,\1\2,;s,2(1*/(1*)),\2\1,;tr;h;s,1*/,,g;:g;s/^(1*) 1(1*) 1(1*)/1\1 \2 \3/;tg;s/  */ /g;s/^/ /;/1 1/bg;x;s,/1*,,g;s/^( 1*)( 1*)/\1\2\2/;:l;s/^(1*) (1*) \2(1*)/\1\2 \2 \3/;tl;/  $/be;/  /{s/^(1*) 1*  1*( 1*)/ \1\2\2/;bl};s/^(1* 1* )(1*) (1*)/\1\2\3 \3/;bl;:e;G;s, *\n *,/,

Essayez-le en ligne!



3

JavaScript (ES6), 85 octets

a=>a.reduce(([b,c],[d,e,g=(b,c)=>c?g(c,b%c):b,h=g(b*e,c*d),i=g(b*d,h)])=>[b*d/i,h/i])

Ne cherchez aucun intégré! Nul doute que quelqu'un va battre cela en utilisant une approche récursive ou quelque chose.



2

Perl 6 ,  46  42 octets

{[lcm](@_».numerator)/[gcd] @_».denominator}

Essaye-le

{[lcm](($/=@_».nude)[*;0])/[gcd] $/[*;1]}

Essaye-le

L'entrée est une liste de nombres rationnels .

Étendu:

{ # bare block lambda with implicit parameter list 「@_」

  [lcm](            # reduce using &infix:<lcm>
    (
      $/ = @_».nude # store in 「$/」 a list of the NUmerators and DEnominiators
                    # ((1,2), (3,4))

    )[
      *;            # from all of the first level 「*」,
      0             # but only the 0th of the second level (numerators)
    ]
  )
  /
  [gcd] $/[ *; 1 ]  # gcd of the denominators
}

2

Rétine , 117 octets

\d+
$*
\b(1+)(\1)*/(\1)+\b
$#2$*11/$#3$*
{`^((1+)\2*)/(1+)+ (\2)+/\3+\b
$1 $#4$*1/$3
}`\G1(?=1* (1+))|\G 1+
$1
1+
$.&

Essayez-le en ligne! Prend l'entrée comme une série séparée par des espaces de fractions impropres (pas d'entiers ou de nombres mixtes). Explication:

\d+
$*

Convertit décimal en unaire.

\b(1+)(\1)*/(\1)+\b
$#2$*11/$#3$*

Cela réduit chaque fraction à ses termes les plus bas. Le groupe de capture 1 représente le GCD du numérateur et du dénominateur, nous comptons donc le nombre de captures avant et après le /. \b(1+)+/(\1)+\bne semble pas compter correctement le nombre de captures pour une raison quelconque, donc j'utilise un groupe de capture supplémentaire et j'ajoute 1 au résultat.

{`^((1+)\2*)/(1+)+ (\2)+/\3+\b
$1 $#4$*1/$3

Cela fait un certain nombre de choses. Le groupe de capture 2 représente le GCD des numérateurs des deux premières fractions, tandis que le groupe de capture 3 représente le GCD des dénominateurs. $#4est donc le deuxième numérateur divisé par leur GCD. (Encore une fois, je ne pouvais pas connaître le nombre de captures du premier numérateur, mais je n'ai besoin que de diviser un numérateur par leur GCD, donc cela ne me coûte pas si cher.)

}`\G1(?=1* (1+))|\G 1+
$1

Maintenant que le deuxième numérateur a été divisé par leur GCD, nous utilisons simplement cette expression du tutoriel arithmétique unaire pour multiplier les deux ensemble, ce qui donne le LCM. Nous répétons ensuite l'exercice pour toutes les fractions restantes.

1+
$.&

Convertit unaire en décimal.


2

Lisp commun, 154 octets

(defun f(l &aux(s(pairlis l l)))(loop(and(eval`(=,@(mapcar'car s)))(return(caar s)))(let((x(assoc(reduce'min s :key'car)s)))(rplaca x(+(car x)(cdr x))))))

Algorithme utilisé (spécifié pour les entiers, mais fonctionne également pour les rationnels).

Faites d'abord une liste associative des données d'entrée avec elle-même, pour obtenir la trace des valeurs initiales des éléments, de sorte que la séquence de fonctionnement est donnée par les «voitures» de la liste.

(defun f(l &aux (s (pairlis l l)))        ; make the associative list
  (loop
     (when (eval `(= ,@(mapcar 'car s))) ; when the car are all equal
       (return (caar s)))                 ; exit with the first one
     (let ((x (assoc (reduce 'min s :key 'car) s))) ; find the (first) least element
       (rplaca x (+ (car x) (cdr x))))))  ; replace its car adding the original value (cdr)

Cas de test:

CL-USER> (f '(3))
3
CL-USER> (f '(1/17))
1/17
CL-USER> (f '(1/2 3/4))
3/2
CL-USER> (f '(1/3 2/8))
1
CL-USER> (f '(1/4 3))
3
CL-USER> (f '(2/5 3))
6
CL-USER> (f '(1/2 3/4 5/6 7/8))
105/2

Remarque: La solution est sans l'utilisation de la construction lcmet gcd, qui acceptent des entiers.


W00t? Essayez ceci à votre REPL (/ (lcm 1 3 5 7) (gcd 2 4 6 8)).
Kaz

@Kaz, car, comme il l'a dit dans le problème, «les soumissions qui fourniraient des nombres rationnels à un module intégré LCM / GCD sont autorisées, mais non concurrentes».
Renzo

En termes Lisp, à proprement parler, nous nourrissons en fait des rationnels lorsque nous appelons (lcm 1 3 5 7), car les entiers sont un sous-type de rationnels, mais je pense que la règle est censée exclure l'utilisation d'un lcmou gcdqui permet des entrées rationnelles.
Kaz

@Kaz, ops ... J'ai mal interprété les règles! Dois-je supprimer le message? (peut-être que ce n'est pas un bon marketing pour Common Lisp :)
Renzo

Je voudrais juste ajouter que c'est une solution sans utiliser l'entier intégré lcmet gcd.
Kaz

1

Mathematica, 3 octets, sans compétition

LCM

Intégré de Mathematica LCMfonction est capable de gérer les entrées de nombres rationnels.


3
Bien que répondre à votre propre question soit correct, je ne pense pas que ce soit très sportif d'y répondre avec une solution qui a de réelles chances de gagner: P
Beta Decay

@BetaDecay Yep ... Il n'y a donc plus de concurrence maintenant.
JungHwan Min

1

PHP , 194 octets

<?for(list($n,$d)=$_GET,$p=array_product($d);$x=$n[+$k];)$r[]=$x*$p/$d[+$k++];for($l=1;$l&&++$i;$l=!$l)foreach($r as$v)$l*=$i%$v<1;for($t=1+$i;$p%--$t||$i%$t;);echo$p/$t>1?$i/$t."/".$p/$t:$i/$t;

-4 octets avec PHP> = 7.1 [$n,$d]=$_GETau lieu delist($n,$d)=$_GET

Essayez-le en ligne!


1

Lisp commun, 87 78 octets

En utilisant lcmet gcd, qui ont des entrées entières:

(defun l(a)(/(apply #'lcm(mapcar #'numerator a))(apply #'gcd(mapcar #'denominator a))))

Plus golfé:

(defun l(a)(eval`(/(lcm,@(mapcar'numerator a))(gcd,@(mapcar'denominator a))))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.