Ký hiệu khoa học hiệu quả


12

Một ngày khác, giáo viên hóa học của tôi đã giải thích cho chúng tôi về ký hiệu khoa học (sử dụng một số nhỏ và nhân nó với lũy thừa mười để thể hiện số lượng lớn dễ dàng hơn), điều đó đưa tôi trở lại vài năm trước khi tôi biết nó lần đầu tiên. Sau khi học những điều cơ bản, chúng tôi đã thực hiện một loạt các câu hỏi toán học điển hình, một số câu hỏi như sau:

Trình bày các ký hiệu khoa học sau:
a) 50000000
b) 120000000000000
c) 90000000000000000000000000000000000000
d) pi ^ e ^ i ^ j ^ k ^ std :: vector
...
z) 200
...

Và tôi nghĩ, "Cái gì? Chúng tôi đã nói rằng ký hiệu khoa học đã được sử dụng để làm cho việc viết số lượng lớn hiệu quả hơn, nhưng một số trường hợp không hiệu quả hơn chút nào!"

Xem xét số

300

và đại diện của nó trong ký hiệu khoa học:

3x10^2

Cái gì, phiên bản có ký hiệu khoa học thực sự chiếm nhiều không gian hơn? Chúng ta không thể có điều đó bây giờ được không? (Không gian màn hình là quý giá.)
Chúng tôi có thể tự xác định xem có hiệu quả hơn không gian để viết một số trong ký hiệu khoa học hay không, hoặc ...

Bài tập

Chương trình hoặc chức năng của bạn sẽ lấy đầu vào một số dương nkích thước tùy ý (tối đa với những gì ngôn ngữ của bạn hỗ trợ) và xuất ra phiên bản số được ký hiệu khoa học của số đó.
Tuy nhiên, nếu số gốc n, sau khi loại bỏ các số 0 ở cuối và vị trí thập phân theo sau, sẽ lấy ít hơn hoặc cùng số lượng ký tự để hiển thị so với phiên bản được ký hiệu khoa học của nó, nthay vào đó , bạn phải xuất số gốc đó.

Mã của bạn cần phải càng ngắn càng tốt bởi vì đầu ra cũng phải càng ngắn càng tốt.

Thông số kỹ thuật

Ký hiệu khoa học hiệu quả được định nghĩa như sau:

bx10^e

blà số đầu vào được chia một cách thích hợp cho lũy thừa 10 sao cho 1 <= b < 10. Số này phải xóa tất cả các số 0 (và dấu thập phân nếu cần), nhưng phải có độ chính xác của số gốc (tất nhiên là tối đa giới hạn dấu thập phân trong ngôn ngữ của bạn). Tức là 90000trở thành 9, 13.500trở thành 1.35, 0.000675trở nên 6.75vv Nếu số này kết thúc lên có chứa chữ số thập phân hơn ngôn ngữ của bạn có thể xử lý, nó nên được làm tròn với số lượng tối đa của chữ số thập phân.

elà số mũ mà mười được tăng lên sao cho n = b x 10^e(hãy nhớ rằng con số này cần phải âm nếu nnhỏ hơn 1). Số này không được có bất kỳ số 0 ở cuối hoặc vị trí thập phân nào (chủ yếu vì nếu đó không phải là số nguyên thì có gì đó không ổn ...).

Các ký tự x10^ phải giữ nguyên như trong chuỗi giữa be.

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

Input -> output
1 -> 1
20 -> 20
3000000 -> 3x10^6
400000 -> 400000
0.008093 -> 0.008093
0.007835000000000 -> 0.007835
0.000003000000 -> 3x10^-6
0.00000065 -> 6.5x10^-7
0 -> 0

Chấm điểm

Đây là , vì vậy mã ngắn nhất tính bằng byte thắng.

Các quy tắc khác và làm rõ

  • Các số không theo dõi (và / hoặc vị trí thập phân kéo dài) không được tính vào số ký tự của số đầu vào ban đầu n. Hãy ghi nhớ điều đó cho các trường hợp như test case 6
  • Bạn có thể giả sử rằng nếu số đầu vào nhỏ hơn 1, nó sẽ luôn bắt đầu bằng 0 thay cho chữ số đó (như trong các trường hợp thử nghiệm 5-8).
  • Số đầu vào sẽ không bao giờ âm
  • Được xây dựng để làm cho thách thức này sơ hở và sơ hở tiêu chuẩn không được phép
  • Một dòng mới ở đầu ra là OK

EDIT
Cảm ơn user81655 vì đã chỉ ra các trường hợp thử nghiệm 7 và 8 có quyền hạn không chính xác là mười. Bây giờ tôi đã sửa chúng để đảm bảo mã của bạn đánh giá chúng chính xác.


7
Vì vậy, uh, tôi nên hỏi đầu ra cho đầu vào pi^e^i^j^k^std::vectorsẽ là gì?
Geobits 6/2/2016

@Geobits Hmm, nếu bạn có thể gán giá trị số cho std :: vector thì có thể ... Không, chỉ có số sẽ xuất hiện trong đầu vào (ngoại trừ vị trí thập phân cho đầu vào dấu phẩy động).
MC ΔT

Điều này sẽ dễ dàng hơn nhiều chúng tôi sẽ chiếm ít "không gian màn hình quý giá" của bạn nếu nó được sử dụng e: 9000 -> 9e3(gần 9.000 !)
Cyoce 6/2/2016

1
@Cyoce Tôi đã nghĩ về điều đó, nhưng tôi thực sự dựa trên thử thách này theo cách nó thường được viết (như bằng văn bản vật lý), dường như là với x10^. Và nó sẽ là một chút làm lại cho câu hỏi, mà tôi không nghĩ là nó phù hợp bây giờ nó đã được đăng
MC T

1
@ghosts_in_the_code Cô ấy đã không, do đó "đã đưa tôi trở lại một vài năm trước khi tôi học nó lần đầu tiên [trong lớp toán]"
MC T

Câu trả lời:


4

ES6, 83 81 byte

x=>(e=s=>s.replace(/e\+?/,'x10^'),z=e(x.toExponential()),y=e(''+x))[z.length]?z:y

Có lẽ thất bại đối với một số trường hợp cạnh trong đó toStringnhấn mạnh vào định dạng hàm mũ.

Chỉnh sửa: Đã lưu 2 byte nhờ @ user81655.


Ý kiến ​​hay. Nhân tiện, có vẻ như bạn đã quên /phần cuối của regex.
dùng81655

Ngoài ra, bạn có thể sắp xếp lại thứ này một chút để tiết kiệm 2 byte:x=>(e=s=>s.replace(/e\+?/,'x10^'),z=e(x.toExponential()),y=e(''+x))[z.length]?z:y
user81655

@ user81655 À, chuyện xảy ra là trình duyệt của tôi làm tôi bối rối khi quấn dòng dài theo cách mà tôi nghĩ rằng một dòng mới đã len lỏi vào đó do nhầm lẫn.
Neil

2

Python 3, 346 342 319 302 byte

L=len;N=str(float(input()))
if N.endswith('.0'):N=N[:-2]
if'e'in N:C,P=N.split('e');N=N.replace('e','x10^')
else:
 C=N.strip('.0').replace('.','');F=N.find('.')
 if L(C)>1:C=C[0]+'.'+C[1:]
 P=((L(N) if F==-1 else F)-1-N.lstrip('0').find(C[0]))
print(min([N,'{0}x10^{1}'.format(C,int(P))],key=L))

Có lẽ chơi golf khủng khiếp, nhưng này, đây là lần thử đầu tiên của tôi ở một cái gì đó như thế này. Nó khó đọc, vì vậy nó phải tốt.

Theo như tôi biết, nó sẽ hoạt động trong mọi trường hợp, ngay cả với xu hướng của Python là tự động chuyển đổi các số vượt qua bất kỳ ngưỡng nào thành ký hiệu khoa học (ngoại trừ chữ 'e' thú vị và hấp dẫn đó). Tôi không nhớ chính xác làm thế nào tôi có thể trả về số mẫu tiêu chuẩn, nhưng nó làm điều đó.


2

Perl 6, 96 90 byte

Tôi cảm thấy như thế này có thể ngắn hơn, nhưng đây là điều tốt nhất của tôi bây giờ

{my \s=($_,*×(1>$_??10!!.1)…10>*>=1);min(s[*-1]~"x10^"~(1>$_??1-s!!s-1),$_,by=>&chars)}

cách sử dụng : Gán điều này cho một biến

Ở đây nó không được chú ý một chút với một số bình luận xấu:

my &f = -> $n {
    my $a = 1 > $n ?? 10 !! .1;             # If $n < 1, we will multiply by 10
                                            # in the sequence below, else by 0.1

    my @seq = ($n, * × $a ... 10 > * >= 1); # Sequence starting at $n, 
                                            # multiply the previous value by $a
                                            # until we reach a number 1 <= x < 10

    # Join the last element in @seq, "x10^", and the length of @seq,
    # with an extra subtraction for numbers less than 1.
    # this gets us our scientific notation.
    my $science = @seq[*-1] ~ "x10^" ~ @seq - (1 > $n ?? @seq*2 !! 1); 

    min($science, $n, by => &chars) # Uses the &chars function to
                                    # choose a min value and return it.
}

Trao đổi $_ <1với 1>$_1 <=* <10với10>*>=1
Brad Gilbert b2gills

Tôi thực sự có ý định làm điều đó tối qua nhưng tôi đã quên. Tôi sẽ cập nhật nó khi tôi về nhà
Hotkeys

2

TI BASIC (nspire): 112 byte

Define f(x)=
Prgm
string(x)➝a
If x≥1 Then
format(x,"s")➝a
EndIf
instring(a,"ᴇ")➝b
left(a,b-1)&"x10^"&mid(a,b+1)➝a
If dim(a)<dim(string(n)) or x<1 Then
Disp a
Else
Disp x
Endif
EndPrgm

Giải trình

If x≥1 Then
format(x,"s")➝a
EndIf

Chuyển đổi đầu vào thành ký hiệu khoa học với chức năng định dạng nếu nó không có trong định dạng đó - vì các số thập phân nhỏ được tự động chuyển đổi.

instring(a,"ᴇ")➝b
left(a,b-1)&"x10^"&mid(a,b+1)➝a

Tìm vị trí của E ưa thích biểu thị số mũ và thay thế nó bằng "x10 ^".

If dim(a)<dim(string(x)) or x<1 Then
Disp a
Else
Disp x
Endif

Kiểm tra đầu ra nào lớn hơn và trả về giá trị tối ưu. Trừ khi nó là một số thập phân nhỏ, mặc định là nhỏ hơn.


0

Python (3.5) 177 byte

Một giải pháp sử dụng biểu thức chính quy

import re
g=lambda s:re.sub(r"e\+?(-?)0?","x10^\\1",s)
def f(i):
 t=g(re.sub(r"\.[0]*e","e","%e"%i))
 u=g(re.sub(r"(\..*)[0]*$","\\1",str(i)))
 return t if len(u)>len(t) else u

Giải trình

Nhập khẩu mô-đun regrec

import re

Xác định hàm lambda để thay thế ebởix10^

g=lambda s:re.sub("e\+?(-?)0?","x10^\\1",s)
def f(i):

Sự hội tụ của chuỗi trong ký hiệu khoa học

 t=g(re.sub(r"\.[0]*e","e","%e"%i))

Xóa 0 phần đệm trong chuỗi gốc

 u=g(re.sub(r"(\..*)[0]*$","\\1",str(i)))

so sánh chiều dài

 return t if len(u)>len(t) else u

Các kết quả

>>> [f(i) for i in [1, 20, 3000000, 400000, 0.008093, 0.007835000000000, 0.000003000000, 0.00000065, 0]]
['1', '20', '3x10^6', '400000', '0.008093', '0.007835', '3x10^-6', '6.5x10^-7', '0']
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.