Mẹo chung để đại diện cho số lượng lớn


21

Đôi khi, trong khi chơi gôn, người ta cần thể hiện số lượng lớn trong mã của họ. Viết chúng như là có thể làm tăng đáng kể số lượng byte.

Bạn có 1 mẹo chung nào để biểu diễn các số dài một cách chính xác trong mã?

Xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.


1 Với chung , ý tôi là mẹo có thể được áp dụng cho hơn một ngôn ngữ duy nhất. Đối với lời khuyên cụ thể về ngôn ngữ, đăng trong chủ đề tương ứng của họ.




Tôi thấy ai đó hiểu nhầm câu hỏi - có lẽ tiêu đề nên nói đây là về việc chơi golf.
Ørjan Johansen

Câu trả lời:


15

Xem ra cho số đặc biệt

Một số ngôn ngữ có các hàm tích hợp cho hình vuông, lũy thừa với cơ sở 2, số nguyên tố thứ n , giai thừa hoặc các thủ tục khác có thể tạo ra số lượng lớn. Kiểm tra xem số của bạn có rơi vào bất kỳ loại nào không.

Và nếu không, có thể xảy ra rằng một số lượng lớn hơn sẽ phù hợp với mục đích của bạn và có thể được sử dụng thay thế.


4
Ngay cả khi số bạn muốn không thể được tạo bằng hàm dựng sẵn, có thể tạo một số mà bạn có thể sử dụng làm cơ sở cho một phép tính đơn giản để đến số của bạn, trong khi vẫn lưu byte bằng cách viết ra.
Xù xì

7
+1 cho "số lớn hơn" - nếu số 1.01e6lần lặp là đủ, sẽ 1e7tiết kiệm được 3 byte với chi phí thời gian chạy.
Chris H

13

Sử dụng các toán tử boolean bitwise

Một số ngôn ngữ có bitwise AND, OR, XOR và đôi khi KHÔNG.

Biểu thị một số lớn cụ thể dưới dạng kết hợp bitwise của kết quả của lũy thừa hoặc dịch chuyển trái và một số khác có thể đưa bạn đến chính xác số bạn cần. Điều này thường chỉ có giá trị nếu con số trở nên khá lớn.

Ví dụ: 2147483722là 10 byte, nhưng 2<<30^74(2 ^ 31 bitwise-XORed với 74) chỉ là 8.


3
Toán tử shift có thể được thay thế bằng lũy ​​thừa, nếu ngôn ngữ có toán tử đó (ví dụ bc). Và XOR không bao giờ hữu ích hơn +-: trong trường hợp này, xor và add cho cùng một kết quả, nhưng trong mọi trường hợp, có một số nguyên có thể được thêm hoặc trừ để tạo ra kết quả tương tự như xor với một số nguyên và phần bổ sung là không lớn hơn và đôi khi ngắn hơn
rici

3
@rici Đúng nếu tất cả các số nguyên được viết dưới dạng số thập phân đơn giản, nhưng có thể rút ngắn số nguyên được sử dụng với xor theo cách mà số nguyên được sử dụng cộng hoặc trừ không thể: nghĩ về một cái gì đó như 1e9^2e9.
hvd

2
@rici Bạn sẽ thể hiện 9<<49^7<<19bằng cách sử dụng phép cộng thay vì xor như thế nào?
L3viathan

2
@rici Không, ý tôi là những gì tôi đã viết. Nó ước tính 1286561280bằng JavaScript và Perl (và có thể là các ngôn ngữ khác) và đó là biểu thức ngắn hơn để tạo ra giá trị đó so với sử dụng tương đương +hoặc -.
hvd

@hvd: OK, lấy điểm.
rici

11

Sử dụng Chuỗi cho các số lặp đi lặp lại

Đối với các số có tính lặp đi lặp lại trong tự nhiên, bạn có thể sử dụng Chuỗi và chuyển chúng thành Số nguyên. Ví dụ: trong JavaScript

+"1".repeat(100) // returns 100 1s (saves 84 bytes!)

2
Hoặc bạn có thể sử dụng một phần rất lớn, 1e100/9trong trường hợp này.
Sản phẩm ETH

11

Sử dụng ký hiệu khoa học

Ký hiệu khoa học có thể lưu byte trong trường hợp số dài. Ví dụ:

3564e-8 // returns 0.00003564 (saves 3 bytes!)

3
Tại sao không chỉ sử dụng 3564e-8trong trường hợp đó?
Joey

@Joey Vâng, tất nhiên! Cảm ơn bạn! :)
Arjun

Cấp, bạn thường có thể viết số khác như .00003564, một lần nữa ngắn hơn một byte.
Joey

@Joey Không phải ngôn ngữ nào cũng vậy, do đó, tôi sẽ không chỉnh sửa ngôn ngữ đó.
Arjun

Là cố ý rằng 3564 (trái) trở thành 354 (phải) hay đó là một lỗi đánh máy?
Erik

10

Tìm số khác để sử dụng thay thế

Điều này nghe có vẻ như không trả lời, nhưng không phải lúc nào cũng rõ ràng rằng một số lượng lớn hơn có thể được tính bằng mã ngắn hơn. Một ví dụ tôi nhớ là Xuất ra một bản sao googol của một chuỗi , trong đó các câu trả lời rõ ràng yêu cầu tính toán 10 100 . Hóa ra, tính toán bất kỳ bội số nào của 10 100 đều dẫn đến một câu trả lời đúng như nhau, nhưng trong một số ngôn ngữ, câu trả lời ngắn hơn. Câu trả lời của Dennis có 100 100 , riêng tôi sử dụng 250 255 .


4
Một ví dụ khác về điều này là CJam nơi bạn có thể lấy dấu thời gian hiện tại esnếu bạn chỉ cần một số lượng lớn nhưng không quan tâm đến giá trị của nó (hoặc nó luôn giống nhau).
Martin Ender

10

Nén cơ sở

Mã giải nén cơ sở có thể khá phức tạp, nhưng nếu bạn có một số lượng rất lớn đôi khi nó có thể giúp nén nó trong một số cơ sở cao hơn 10.

Nó cũng giúp trong một số ngôn ngữ, mã nén cơ sở rất đơn giản. Ví dụ: PHP có base64_decode(_), Python có int(_,36), JavaScript có parseInt(_,36)và nhiều ngôn ngữ chơi gôn có các phần mềm giải nén cơ sở. Ví dụ: trong CJam:

"+ÜTbô±"256b

Điều này có chứa một không thể in. Hãy thử trực tuyến!

Sản lượng này:

12345678987654321

9

Sử dụng phân số mũ cho số lượng lặp lại lớn

Giả sử bạn muốn tạo số được tạo từ 100 1. Bạn có thể sử dụng int("1"*100), +"1".repeat(100)v.v. nhưng bạn cũng có thể tận dụng thực tế là nó rất gần với

1e100/9

Điều này hoạt động tốt nhất cho các số rất lặp đi lặp lại, chẳng hạn như những số được làm bằng một chữ số. Một vài chữ số lặp lại cũng hoạt động khá tốt:

12e100/99  // Generates 121212121212... (100 digits)

Đôi khi bạn sẽ tìm thấy một số mô hình kỳ lạ khác cũng có thể được thể hiện khá chặt chẽ trong phương pháp này. Nếu bạn tình cờ cần int("123456790"*11), ví dụ:

1e100/81

Tuy nhiên, hãy cẩn thận: những con số như int("1234567890"*10)không có cách biểu diễn dễ dàng như vậy.


9

Sử dụng Bitwise Left Shift để lũy thừa 2 giây

Mặc dù, có nhiều ngôn ngữ hỗ trợ toán tử cho phép lũy thừa, một số ngôn ngữ thì không. Và những cái không, thường yêu cầu các hàm gọi (hoặc phương thức Class / Object), có thể tốn một vài byte.

Nhưng bạn có thể lưu một số byte khi bạn cần tăng 2 lên power n bằng cách sử dụng toán tử Bitwise Left Shift <<như 1<<n. Lưu ý rằng điều này sẽ chỉ giúp bạn tiết kiệm byte nếu n lớn hơn hoặc bằng 17. Tuy nhiên, điều này sẽ luôn giúp bạn tiết kiệm byte nếu n là động. Một vài ví dụ:

1<<2 // returns 4 (3 bytes more :( )
1<<3 // returns 8 (3 bytes more :( )
1<<6 // returns 64 (2 bytes more :( )
1<<14 // returns 16384 (no bytes saved)
1<<17 // returns 131072 (saves 1 byte!)
1<<18 // returns 262114 (saves 1 byte!)

4
Lưu ý rằng bạn có thể sử dụng các giá trị khác thay vì 1. 8<<9 // 4096vì vậy chúng tôi có thể nhận được tối đa 99<<616 byte, tương đương với việc 6,917,529,027,641,081,856tiết kiệm 13 byte!
Draco18

@ Draco18s Vâng, và nó được bảo hiểm ở đây .
Arjun

Đó là một trong những bao gồm các toán tử bit boolean. Vâng, nó cũng có bithifting, nhưng nó đang nói về việc sử dụng hai số lớn cho XOR và nhận được một số thứ ba, cụ thể.
Draco18

7

Định lý còn lại của Trung Quốc

Nếu số nguyên lớn tùy ý thường xuyên xuất hiện hoặc biểu diễn số nguyên lớn trong ngôn ngữ lập trình đích tốn quá nhiều byte, bạn có thể xem xét sử dụng Định lý còn lại của Trung Quốc.

Chọn một số số nguyên tương đối cặp m i > = 2 và bạn có thể biểu thị một số lớn từ 0 đến lcm (m 1 , m 2 , ..., m i ) -1

Ví dụ: tôi chọn 2, 3, 5, 11, 79, 83, 89, 97, sau đó tôi có thể biểu thị số nhỏ hơn 18680171730. 10000000000 (1e10) có thể được biểu thị bằng 0,1,0,1,38,59,50,49 (1e10 mod 2, 3 ..., 97) không cần được biểu thị dưới dạng lớp / cấu trúc Big Integer đặc biệt có thể lưu một số byte trong một số ngôn ngữ lập trình.

Bổ sung và cơ chất có thể được thực hiện trực tiếp bằng cách sử dụng đại diện này. Thí dụ:

(0,1,0,1,38,59,50,49)+(0,2,0,6,23,20,16,53) = 1e10 + 5000 
                                            = (0+0 mod 2, 1+2 mod 3, 0+0 mod 5, 1+6 mod 11, 38+23 mod 79, 59+20 mod 83, 50+16 mod 89, 49+53 mod 97)

1
Quan tâm đến công phu về điều đó?
Skidsdev

@Mayube Tôi đã thêm một số lời giải thích, nhưng tôi nghi ngờ rằng nó là vô dụng trong hầu hết các trường hợp.
Aria Axe

1
Đó là "định lý còn lại".
Ørjan Johansen

6

Sử dụng đệm chuỗi (nếu có thể)

Nếu một số lớn bao gồm một chữ số lặp lại ở đầu hoặc cuối, bạn có thể lưu byte bằng cách sử dụng một trong các phương thức đệm ngôn ngữ của bạn để tạo một chuỗi số bạn đang tìm, sau đó bạn có thể chuyển đổi thành một số số nguyên.


Thí dụ

Để tạo số 1111111111111111111111112(25 byte) trong JavaScript (ES8):

+"2".padStart(25,1) // 19 bytes

3

Sử dụng số mũ

Nếu ngôn ngữ của bạn có toán tử mũ, bạn có thể sử dụng nó để tạo, nếu không phải là số bạn muốn, ít nhất một số bạn có thể thực hiện phép tính đơn giản hoặc 2 để đến số của mình. Ngay cả khi không có toán tử, bạn vẫn có thể lưu byte bằng hàm hoặc phương thức tích hợp.

Thí dụ

Số nguyên an toàn tối đa trong JavaScript9007199254740991, dài 16 chữ số. Trong ES7, điều này có thể được tính bằng 7 byte sau:

2**53-1

Tương đương trong ES6 trở về trước, trong khi có cùng độ dài với chính số nguyên trong trường hợp này, chứng tỏ rằng sử dụng phương thức dài dòng hơn có thể không nhất thiết phải trả cho bạn bất kỳ byte nào.

Math.pow(2,53)-1

Tuy nhiên, ở trên có thể hoạt động ngắn hơn nếu, ví dụ, bạn đã có Mathbí danh cho một ký tự ở nơi khác trong mã của bạn.


2

Sử dụng phân số ở vị trí nổi

Ví dụ: 1./3thay cho0.333333333

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.