有理数的LCM


18

一组数字的最小公倍数(LCM)A是最小整数b,使得b/a对于所有的整数的整数aA。此定义可以扩展为有理数!

任务

找到最小的正有理数, b使得它b/a是输入中所有有理数整数 a

规则

  • 禁止出现标准漏洞。
  • 您可以在输入中分别使用分子和分母,但不能使用双精度数,浮点数等。
  • 输入可能没有完全减少。
  • 您可以将分母为的整数输入作为有理数1
  • 允许将有理数提供给LCM / GCD内置文件的提交是允许的,但不竞争。

测试用例

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

这是,因此使用最少字节的提交会获胜!


4
注意:LCM[numerators]/GCD[denominators]当输入包含未归约的有理数时,计算可能无法正常工作。例如1/3, 2/8
JungHwan Min

所以,如果我减少它,它将起作用吗?
Leaky Nun

@LeakyNun是的,它将。
JungHwan Min

为了鼓励人们提交非内置答案,我编辑了问题,使内置答案不符合要求(仍然允许)。如果出现问题,我将回滚编辑。
JungHwan Min

使用内置LCM但仅与整数竞争(或不竞争)怎么办?
Jonathan Allan

Answers:



6

J,3个字节,无竞争。

*./

给定一系列合理的输入,这将使LCM折叠起来。


4

sed,374(373 + 1)字节

sed的-E标志计为一个字节。注意:我还没有尝试过打高尔夫球,而且可能不会有一段时间了。
输入为一元,输出为一元。空格必须围绕每个分数。范例: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 *,/,

在线尝试!



3

JavaScript(ES6),85个字节

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

看起来没有内置功能!毫无疑问,有人会使用递归方法或其他方法击败它。



2

Perl 6的 46  42个字节

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

测试一下

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

测试一下

输入是有理数的列表。

展开:

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

视网膜,117字节

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

在线尝试!将输入作为不正确分数的空格分隔序列(无整数或带整数)。说明:

\d+
$*

将十进制转换为一元。

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

这会将每个分数降低到最低的条件。捕获组1代表分子和分母的GCD,因此我们计算之前和之后的捕获次数/\b(1+)+/(\1)+\b由于某种原因,似乎无法正确计算捕获次数,因此我使用了一个额外的捕获组,并将结果加1。

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

这可以做很多事情。捕获组2表示前两个分数的分子的GCD,而捕获组3表示分母的GCD。$#4因此是第二个分子除以其GCD。(同样,我无法捕获第一个分子的捕获数量,但我只需要将一个分子除以它们的GCD,就不会花那么多钱。)

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

现在,第二个分子已被其GCD除以,我们只需使用一元算术教程中的此表达式将两者相乘即可得到LCM。然后,我们对剩余的分数重复练习。

1+
$.&

将一元转换回十进制。


2

普通Lisp,154个字节

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

使用的算法(指定为整数,但也适用于有理数)。

首先,将输入数据与其自身建立关联列表,以跟踪元素的初始值,因此操作顺序由列表中的“汽车”给出。

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

测试用例:

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

注意:该解决方案不使用接受整数的build lcmgcd


W00t?在您的REPL上尝试一下(/ (lcm 1 3 5 7) (gcd 2 4 6 8))
卡兹(Kaz)

@Kaz,因为,正如它在问题中所说,“允许向LCM / GCD内建函数提供有理数的提交是允许的,但不竞争”。
Renzo

用Lisp术语严格来说,实际上,我们在调用时实际上是在喂理性(lcm 1 3 5 7),因为整数是理性的子类型,但是我认为规则应该排除使用a lcmgcd允许理性输入的规则。
卡兹(Kaz)

@Kaz,行动...我误解了规则!我应该删除帖子吗?(对于Common Lisp来说,这可能不是很好的营销方法:)
Renzo

我只想指出这是不使用内置整数lcmand 的解决方案gcd
卡兹(Kaz)2013年

1

Mathematica,3字节,无竞争

LCM

Mathematica的内置LCM功能能够处理有理数输入。


3
虽然回答您自己的问题很好,但我认为采用非常有可能获胜的解决方案来回答它不是很运动:P
Beta Decay

@BetaDecay是的...所以它现在不在竞争。
JungHwan Min

1

PHP,194字节

<?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字节的PHP> = 7.1 [$n,$d]=$_GET而不是list($n,$d)=$_GET

在线尝试!


1

通用Lisp,87 78字节

使用lcmgcd具有整数输入:

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

更多高尔夫:

(defun l(a)(eval`(/(lcm,@(mapcar'numerator a))(gcd,@(mapcar'denominator a))))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.