删除第一个数字


17

我们都知道,只要有理数以十进制表示,结果要么是终止的,要么是(最终)周期性的。例如,以十进制表示41/42时,结果为

0.9 761904 761904 761904 761904 761904 761904 761904 ...

初始数字序列,0.9然后是761904一遍又一遍的序列。(对此0.9(761904),一种方便的表示法是括号括在重复数字的块中。)

您在此挑战中的目标是采用正有理数,删除重复序列中的第一个数字,然后返回结果有理数。例如,如果对41/42执行此操作,则得到

0.9  61904 761904 761904 761904 761904 761904 761904 ...

0.9(619047)简称为101/105。

如果有理数具有一个终止的十进制扩展,例如1/4 = 0.25,则什么也不会发生。您可以将1/4 0.250000000...或视为1/4 ,0.249999999...但无论哪种情况,删除重复部分的第一位数字都不会改变数字。

细节

  • 输入是一个正有理数,可以是代表分子和分母的一对正整数,也可以是(如果您选择的语言允许并且想要)某种有理数对象。
  • 输出也是有理数,也可以是两种形式。如果结果是整数,则可以返回整数而不是有理数。
  • 如果以一对数字作为输入,您可能会认为它们是相对质数的。如果产生一对数字作为输出,则必须使它们相对质数。
  • 请注意,您要找到开始重复块的第一个数字。例如,可以将41/42写为,0.97(619047)但不会使2041/2100(带小数点扩展名0.97(190476))成为有效答案。
  • 您可以假设在输入中,第一个周期数字小数点,使120/11= 10.909090909...无效输入:(其第一个周期数字可以视为0in 10)。您可以在此类输入上执行任何您喜欢的操作。
  • 这是:最短的解决方案获胜。

测试用例

41/42 => 101/105
101/105 => 193/210
193/210 => 104/105
104/105 => 19/21
1/3 => 1/3
1/4 => 1/4
2017/1 => 2017/1
1/7 => 3/7
1/26 => 11/130
1234/9999 => 2341/9999

我们可以2017代替2017/1吗?
JungHwan Min

是的,如果您正在做有理数的事情。(如果您正在执行“一对整数”操作,那么我不确定除了该对之外还会返回什么(2017,1)。)
Misha Lavrov

输入是否可以减少(未完全简化)?例如,可以2/4在输入中发生吗?
user202729 '17

1
如果输入是120/11正确答案111/11210/11
kasperd

2
@kasperd Huh,这是我从未想过的情况...我想说的是,111/11除了目前投票率最高的答案返回之外210/11,我将让您选择避免使现有答案无效。
Misha Lavrov

Answers:


13

Wolfram语言(Mathematica),59个字节

FromDigits@MapAt[RotateLeft@*List@@#&,RealDigits@#,{1,-1}]&

在线尝试!

说明

RealDigits@#

查找输入的十进制数字。

MapAt[RotateLeft@*List@@#&, ..., {1,-1}]

如果有重复的数字, RotateLeft它们。(List@@#如果有理数结尾,则防止代码尝试旋转最后一个十进制数字)。

FromDigits@

转换为理性。


确实很聪明!
DavidC

6

果冻36 32 31 30字节

-1个字节,感谢Outgolfer的Erik

ọ2,5Ṁ⁵*©×Ɠ÷µ×⁵_Ḟ$+Ḟ,®×³+.Ḟ÷g/$

在线尝试!

应该是正确的。浮点数不精确度为3个字节+.Ḟ

依靠不可约的输入。


说明

这取决于:

  • 让分子为n/d最简单的形式。然后,ọ2,5Ṁ应用于的链接d将给出小数点后的非周期数字。

ọ2,5Ṁ⁵*©×Ɠ÷µ×⁵_Ḟ$+Ḟ,®×³+.Ḟ÷g/$     Main link (monad take d as input)

    Ṁ                              Maximum
ọ                                  order of
 2,5                               2 or 5 on d
     ⁵*                            10 power
       ©                           Store value to register ®.
        ×Ɠ                         Multiply by eval(input()) (n)
          ÷                        Divide by first argument (d).
                                   Now the current value is n÷d×®.
           µ                       With that value,
            ×⁵                     Multiply by ⁵ = 10
              _Ḟ$                  subtract floor of self
                 +Ḟ                add floor or value (above)
                                   Given 123.45678, will get 123.5678
                                   (this remove first digit after `.`)
                   ,®              Pair with ®.
                     ׳            Scale
                       +.Ḟ         Round to integer
                          ÷g/$     Simplify fraction


@EriktheOutgolfer谢谢!
user202729 '17

5

Python 2中237 235 214字节

-21个字节,感谢Xcoder先生

from fractions import*
F=Fraction
n,d=input()
i=n/d
n%=d
R=[]
D=[]
while~-(n in R):R+=n,;n*=10;g=n/d;n%=d;D+=g,
x=R.index(n)
r=D[x+1:]+[D[x]]
print i+F(`r`[1::3])/F('9'*len(r))/10**x+F("0."+"".join(map(str,D[:x])))

在线尝试!

输入作为元组完成(numerator, denominator);输出是一个fractions.Fraction对象。

这使用长分格样式的方法来获取答案的起始和重复数字,然后将第一个重复数字移到末尾并使用字符串操作并将fraction.Fraction其转换回比例。

非高尔夫版本:

import fractions

num, denom = input()
integer_part, num = divmod(num, denom)

remainders = []
digits = []
current_remainder = num
while current_remainder not in remainders:
    remainders.append(current_remainder)
    current_remainder *= 10
    digit, current_remainder = divmod(current_remainder, denom)
    digits.append(digit)

remainder_index = remainders.index(current_remainder)
start_digits = digits[:remainder_index]
repeated_digits = digits[remainder_index:]

repeated_digits.append(repeated_digits.pop(0))

start_digits_str = "".join(map(str, start_digits))
repeated_digits_str = "".join(map(str, repeated_digits))

print(integer_part+int(repeated_digits_str)/fractions.Fraction('9'*(len(repeated_digits_str)))/10**len(start_digits_str)+fractions.Fraction("0."+start_digits_str))

5

Python 3中177个 173 169字节

from fractions import*
def f(n,d):
 i=1;r=[]
 while~-(i%d in r):r+=[i%d];i*=10
 r=10**r.index(i%d);u=i-r;v=i//r-1;t=u//d*n
 return Fraction(t-t%v+t%v*10//v+t%v*10%-~v,u)

在线尝试!


@ Mr.Xcoder编辑
Leaky Nun


1

Perl 6,102字节

{$/=.base-repeating;(+$0//$0~0)+([~]([$1.comb].rotate)/(9 x$1.chars)*.1**(($0~~/\.<(.*/).chars)if $1)}

尝试一下

需要一个合理数量,并返回一个理性诠释号。

展开:

{  # bare block lambda with implicit Rational parameter 「$_」

  $/ = .base-repeating; # store in 「$/」 the two strings '0.9' '761904'

    # handle the non-repeating part
    (
      +$0        # turn into a number
      // $0 ~ 0  # if that fails append 0 (handle cases like '0.')
    )

  +

    # handle the repeating part
    (
          [~]( [$1.comb].rotate ) # rotate the repeating part
        /
          ( 9 x $1.chars )        # use a divisor that will result in a repeating number

        *

         # offset it an appropriate amount

         .1 ** (
           ( $0 ~~ / \. <( .* / ).chars # count the characters after '.'
         )

      if $1  # only do the repeating part if there was a repeating part
    )
}

请注意,将uint64.Range.max使用最大FatRat(9 x$1.chars) 尝试处理分母。

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.