LCM di numeri razionali


18

Il minimo comune multiplo (LCM) di un insieme di numeri Aè il numero intero più piccolo in bmodo che b/asia un numero intero per tutti i numeri interi ain A. Questa definizione può essere estesa a numeri razionali!

Compito

Trova il più piccolo razionale positivo in modo btale che b/asia un numero intero per tutti i razionali a nell'input.

Regole

  • Sono vietate le scappatoie standard.
  • È possibile prendere numeratori e denominatori separatamente nell'input, ma non doppi, float, ecc.
  • L'ingresso potrebbe non essere completamente ridotto.
  • Puoi prendere input interi come razionali con denominatore di 1.
  • Sono consentiti invii che fornirebbero numeri razionali a un built-in LCM / GCD, ma non competitivi.

Casi 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

Si tratta di , quindi vinci gli invii utilizzando il minor numero di byte!


4
Nota: il calcolo LCM[numerators]/GCD[denominators]potrebbe non funzionare quando l'input contiene un numero razionale non ridotto. es 1/3, 2/8.
JungHwan Min,

Quindi se lo riduco, funzionerà?
Leaky Nun,

@LeakyNun Sì, lo sarà.
JungHwan Min,

Per incoraggiare le persone a inviare risposte non integrate, ho modificato la domanda, rendendo le risposte integrate non concorrenti (ancora consentite). Se questo è un problema, eseguirò il rollback della mia modifica.
JungHwan Min,

Che dire di un LCM integrato che viene utilizzato ma solo con numeri interi - concorrenti o no?
Jonathan Allan,

Risposte:



6

J, 3 byte, non concorrenti.

*./

Dato un elenco di input razionali, questo piega LCM attraverso di essa.


4

sed, 374 (373 + 1) byte

la -Ebandiera di sed conta come un byte. Nota: non ho ancora provato a giocare a golf, e probabilmente non lo farò per un po 'di tempo.
L'input è preso in unario e l'output è in unario. Gli spazi devono circondare ogni frazione. Esempio: 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 *,/,

Provalo online!



3

JavaScript (ES6), 85 byte

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])

Non cercare builtin! Senza dubbio qualcuno lo batterà usando un approccio ricorsivo o qualcosa del genere.



2

Perl 6 ,  46  42 byte

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

Provalo

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

Provalo

L'input è un elenco di numeri Rational .

Allargato:

{ # 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

Retina , 117 byte

\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+
$.&

Provalo online! Prende l'input come una serie separata da spazi di frazioni improprie (senza numeri interi o numeri misti). Spiegazione:

\d+
$*

Converte i decimali in unari.

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

Ciò riduce ogni frazione ai termini più bassi. Il gruppo di acquisizione 1 rappresenta il GCD del numeratore e del denominatore, quindi contiamo il numero di acquisizioni prima e dopo il /. \b(1+)+/(\1)+\bnon sembra contare correttamente il numero di acquisizioni per qualche motivo, quindi uso un gruppo di acquisizione aggiuntivo e aggiungo 1 al risultato.

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

Questo fa un certo numero di cose. Il gruppo di acquisizione 2 rappresenta il GCD dei numeratori delle prime due frazioni, mentre il gruppo di acquisizione 3 rappresenta il GCD dei denominatori. $#4è quindi il secondo numeratore diviso per il loro GCD. (Ancora una volta, non potevo il numero di acquisizioni del primo numeratore, ma ho solo bisogno di dividere un numeratore per il loro GCD, quindi non mi costa così tanto.)

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

Ora che il secondo numeratore è stato diviso per il loro GCD, usiamo semplicemente questa espressione dal tutorial aritmetico unario per moltiplicare i due insieme, risultando nella LCM. Quindi ripetiamo l'esercizio per tutte le frazioni rimanenti.

1+
$.&

Converte unario in decimale.


2

Lisp comune, 154 byte

(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))))))

Algoritmo utilizzato (specificato per numeri interi, ma funziona anche per valori razionali).

Per prima cosa crea un elenco associativo dei dati di input con se stesso, per tenere traccia dei valori iniziali degli elementi, quindi la sequenza operativa è data dalle "auto" dell'elenco.

(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)

Casi 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

Nota: la soluzione è senza l'uso del build lcme gcd, che accetta numeri interi.


W00t? Prova questo sul tuo REPL (/ (lcm 1 3 5 7) (gcd 2 4 6 8)).
Kaz,

@Kaz, dal momento che, come si è detto nel problema, "Sono consentiti invii che inviano numeri razionali a un built-in LCM / GCD, ma non competitivi".
Renzo,

In termini di Lisp, in senso stretto, in realtà stiamo alimentando le razionali quando chiamiamo (lcm 1 3 5 7), poiché gli interi sono un sottotipo di razionali, ma penso che la regola dovrebbe escludere l'uso di un lcmo gcdche consente input razionali.
Kaz,

@Kaz, ops ... Ho frainteso le regole! Devo rimuovere il post? (forse non è un buon marketing per Common Lisp :)
Renzo,

Vorrei solo sottolineare che questa è una soluzione senza usare il numero intero lcme gcd.
Kaz,

1

Mathematica, 3 byte, non competitiva

LCM

Mathematica incorporato nella LCMfunzione è in grado di gestire ingressi numero razionale.


3
Mentre rispondere alla tua domanda va bene, non credo sia molto sportivo rispondere con una soluzione che ha una reale possibilità di vincere: P
Decadimento beta

@BetaDecay Sì ... Quindi ora non è in competizione.
JungHwan Min

1

PHP , 194 byte

<?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 byte con PHP> = 7.1 [$n,$d]=$_GETanzichélist($n,$d)=$_GET

Provalo online!


1

Lisp comune, 87 78 byte

Usando lcme gcd, che hanno input interi:

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

Più golf:

(defun l(a)(eval`(/(lcm,@(mapcar'numerator a))(gcd,@(mapcar'denominator a))))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.