Xóa chữ số định kỳ đầu tiên


17

Chúng ta đều biết rằng bất cứ khi nào một số hữu tỷ được viết bằng số thập phân, kết quả là chấm dứt hoặc (cuối cùng) định kỳ. Ví dụ: khi 41/42 được viết bằng số thập phân, kết quả là

0.9 761904 761904 761904 761904 761904 761904 761904 ...

với một chuỗi các chữ số ban đầu 0.9theo sau là chuỗi 761904lặp đi lặp lại nhiều lần. (Một ký hiệu thuận tiện cho việc này là 0.9(761904)nơi các dấu ngoặc đơn bao quanh khối các chữ số lặp lại.)

Mục tiêu của bạn trong thử thách này là lấy số hữu tỷ dương, xóa chữ số đầu tiên là một phần của chuỗi lặp lại và trả về số hữu tỷ kết quả. Ví dụ: nếu chúng tôi làm điều này đến 41/42, chúng tôi sẽ nhận được

0.9  61904 761904 761904 761904 761904 761904 761904 ...

hoặc 0.9(619047)viết tắt là 101/105.

Nếu số hữu tỷ có phần mở rộng thập phân kết thúc, như 1/4 = 0.25không, sẽ không có gì xảy ra. Bạn có thể nghĩ 1/4 0.250000000...hoặc là 0.249999999...nhưng trong cả hai trường hợp, việc xóa chữ số đầu tiên của phần lặp lại sẽ khiến số đó không thay đổi.

Chi tiết

  • Đầu vào là một số hữu tỷ dương, dưới dạng một cặp số nguyên dương đại diện cho tử số và mẫu số, hoặc (nếu ngôn ngữ bạn chọn cho phép và bạn muốn) như một loại đối tượng số hữu tỷ.
  • Đầu ra cũng là một số hữu tỷ, cũng ở dạng nào. Nếu kết quả là một số nguyên, bạn có thể trả về số nguyên thay vì số hữu tỷ.
  • Nếu lấy một cặp số làm đầu vào, bạn có thể cho rằng chúng tương đối chính; nếu tạo ra một cặp số làm đầu ra, bạn phải làm cho chúng tương đối nguyên tố.
  • Hãy cẩn thận rằng bạn tìm thấy chữ số đầu tiên bắt đầu một khối lặp lại. Ví dụ: người ta có thể viết 41/42 0.97(619047)nhưng điều đó không làm cho 2041/2100 (với phần mở rộng thập phân 0.97(190476)) trở thành một câu trả lời hợp lệ.
  • Bạn có thể giả sử rằng trong đầu vào bạn nhận được, chữ số định kỳ đầu tiên nằm sau dấu thập phân, làm 120/11= 10.909090909...đầu vào không hợp lệ: (chữ số định kỳ đầu tiên của nó có thể được coi là chữ số đầu 0vào 10). Bạn có thể làm bất cứ điều gì bạn thích trên đầu vào như vậy.
  • Đây là : giải pháp ngắn nhất sẽ thắng.

Các trường hợp thử nghiệm

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

Chúng ta có thể trở lại 2017thay vì 2017/1?
JungHwan Min

Có, nếu bạn đang làm điều số lượng hợp lý. (Nếu bạn đang thực hiện điều cặp số nguyên, thì tôi không chắc bạn sẽ trả lại gì khác ngoài cặp (2017,1).)
Misha Lavrov

Đầu vào có thể được giảm (không đơn giản hóa hoàn toàn)? Ví dụ, có thể 2/4xảy ra trong đầu vào?
dùng202729

1
Nếu đầu vào là 120/11câu trả lời đúng 111/11hay 210/11?
kasperd

2
@kasperd Huh, đó là trường hợp tôi chưa từng nghĩ đến ... Tôi muốn nói 111/11ngoại trừ câu trả lời được đánh giá cao nhất vào lúc này 210/11, vì vậy tôi sẽ cho phép bạn chọn để tránh làm mất hiệu lực câu trả lời hiện có.
Misha Lavrov

Câu trả lời:


13

Ngôn ngữ Wolfram (Mathicala) , 59 byte

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

Hãy thử trực tuyến!

Giải trình

RealDigits@#

Tìm các chữ số thập phân của đầu vào.

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

Nếu có các chữ số lặp lại, RotateLeftchúng. ( List@@#ngăn không cho mã cố gắng xoay chữ số thập phân cuối cùng nếu số hữu tỷ kết thúc).

FromDigits@

Chuyển đổi để hợp lý.


Thực sự rất thông minh!
DavidC

6

Thạch , 36 32 31 30 byte

-1 byte nhờ Erik the Outgolfer !

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

Hãy thử trực tuyến!

Nên chính xác. Không chính xác điểm nổi thêm 3 byte cho +.Ḟ.

Dựa vào đầu vào là không thể giảm được.


Giải trình

Điều này dựa vào:

  • Hãy để tử số n/dở dạng đơn giản nhất của nó. Sau đó, liên kết ọ2,5Ṁđược áp dụng dsẽ đưa ra số chữ số không định kỳ sau điểm cơ số.

ọ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 Cảm ơn!
dùng202729

5

Python 2 , 237 235 214 byte

-21 byte nhờ ông 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])))

Hãy thử trực tuyến!

Đầu vào được thực hiện như một tuple (numerator, denominator); đầu ra là một fractions.Fractionđối tượng.

Phương pháp này sử dụng phương pháp kiểu phân chia dài để lấy các chữ số bắt đầu và lặp lại của câu trả lời, sau đó di chuyển chữ số lặp lại đầu tiên đến cuối và sử dụng thao tác chuỗi và fraction.Fractionchuyển đổi lại thành tỷ lệ.

Phiên bản bị đánh cắp:

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



1

Perl 6 , 102 byte

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

Thử nó

Lấy số Rational và trả về số Rational hoặc Int .

Mở rộng:

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

Lưu ý sẽ xử lý mẫu số tối đa uint64.Range.maxđể xử lý mẫu số lớn hơn sử dụng FatRat(9 x$1.chars) Dùng thử .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.