Загальні поради щодо представлення великої кількості


21

Іноді, займаючись гольфом, потрібно представити велику кількість (-ів) у своєму коді. Якщо записати їх так, як є, це може значно збільшити кількість байтів.

Що взагалі 1 поради у вас є для подання довгих чисел стисло в коді?

Будь ласка, опублікуйте одну пораду за кожну відповідь.


1 З взагалі , я маю в виду поради , які можуть бути застосовані до більш ніж на одній мові. Щодо конкретних мовних порад, розмістіть їх у відповідній темі.




Я бачив, як хтось нерозуміє питання - можливо, заголовок повинен сказати, що це стосується гольфу.
Ørjan Johansen

Відповіді:


15

Слідкуйте за спеціальними номерами

Деякі мови мають вбудовані функції для квадратів, експоненціації з базою 2, n -м простим, факторіальним чи іншими процедурами, які можуть генерувати велику кількість. Перевірте, чи не трапляється ваш номер до якоїсь із цих категорій.

І якщо це не так, може статися, що більша кількість, яка все-таки буде відповідати вашим цілям, і може бути використана натомість.


4
Навіть якщо потрібне число не може бути згенеровано за допомогою вбудованої функції, можливо, можливо генерувати число, яке ви можете використовувати як основу для простого обчислення для отримання вашого номера, зберігаючи при цьому байти над його записом.
Кудлатий

7
+1 для "більшої кількості" - якщо 1.01e6ітерацій достатньо, 1e7економиться 3 байти за рахунок часу роботи.
Кріс Н

13

Використовуйте побітові булеві оператори

Деякі мови мають бітові значення І, АБО, XOR, а іноді НЕ.

Висловлення конкретного великого числа у вигляді побітової комбінації в результаті експоненції або зсуву вліво та іншого числа може привести вас до саме потрібного числа. Зазвичай це варто лише того, якщо кількість стає досить великою.

Наприклад, 2147483722це 10 байт, але 2<<30^74(2 ^ 31 порозрядно-XORed з 74) є лише 8.


3
Оператор зсуву може бути замінений експоненціацією, якщо мова має цього оператора (наприклад bc). І XOR ніколи не є кориснішим за +та -: у цьому випадку xor і add дають однаковий результат, але у всіх випадках є якесь ціле число, яке може бути додане або відняте, щоб отримати такий же результат, як xor з цілим числом, а додавання - не більший, а іноді і коротший.
rici

3
@rici Щоправда, якщо всі цілі числа записуються як прості десяткові знаки, але це ціле число, яке можна використовувати з xor, може бути скорочене таким чином, що ціле число, яке використовується з плюсом або мінусом, не може: придумати щось подібне 1e9^2e9.
hvd

2
@rici Як би ви виразили 9<<49^7<<19додавання замість xor?
L3viathan

2
@rici Ні, я мав на увазі те, що написав. Він оцінюється 1286561280в JavaScript та Perl (і, мабуть, інших мовах), і це коротший вираз для отримання цього значення, ніж еквівалент, використовуючи +або -.
hvd

@hvd: Гаразд, точка взята.
rici

11

Використовуйте рядки для повторюваних чисел

Для чисел, що мають дуже повторюваний характер, ви можете використовувати рядки та передавати їх до Integer. Наприклад, у JavaScript

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

2
Або ви могли використовувати дуже велику фракцію 1e100/9в цьому випадку.
ETHproductions

11

Використовуйте наукові позначення

Наукові позначення можуть зберігати байти у випадку великих чисел. Наприклад:

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

3
Чому б просто не використовувати 3564e-8в такому випадку?
Joey

@Joey Так, звичайно! Дякую! :)
Арджун

Звичайно, ви можете зазвичай записати інше число як .00003564, яке також знову на один байт.
Joey

@Joey Не всі мови так, отже, я не буду це редагувати.
Арджун,

Це навмисно, що 3564 (зліва) стає 354 (праворуч) чи це друкарська помилка?
Ерік

10

Шукайте інший номер, який слід використовувати замість цього

Це може здатися невідповіддю, але не завжди очевидно, що більша кількість може бути обчислена за коротшим кодом. Приклад, який я пам’ятаю, - Виведіть googol копії рядка , де очевидні відповіді вимагають обчислення 10 100 . Як виявляється, обчислення будь-якого кратного 10 100 призводить до однаково правильної, але в деяких мовах коротшої відповіді. Відповідь Деніса там використовує 100 100 , моя власна використовує 250 255 .


4
Іншим прикладом цього є CJam, де ви можете отримати поточну мітку часу, esякщо вам просто потрібна велика кількість, але не хвилюйтеся про її значення (або про те, що вона завжди однакова).
Мартін Ендер

10

Стиснення бази

Базовий код декомпресії може бути досить складним, але якщо у вас справді величезна кількість, іноді це може допомогти стиснути його в якійсь базі, що перевищує 10.

Також допомагає, що в деяких мовах базовий код стиснення дуже простий. Наприклад, PHP має base64_decode(_), Python має int(_,36), JavaScript parseInt(_,36), і багато мов для гольфу мають вбудовані базові декомпресії. Наприклад, у CJam:

"+ÜTbô±"256b

Це містить недруковану версію. Спробуйте в Інтернеті!

Це дає:

12345678987654321

9

Використовуйте експоненціальні дроби для великих повторюваних чисел

Скажіть, ви хотіли генерувати число, що складається з 100 1-х. Ви могли б використовувати int("1"*100), +"1".repeat(100)і т.д. , але ви також можете скористатися тим , що це дуже близько до

1e100/9

Це найкраще підходить для дуже повторюваних чисел, наприклад, таких, що складаються з однієї цифри. Кілька повторних цифр також працює досить добре:

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

Іноді ви знайдете якусь іншу дивну схему, яка також може бути представлена ​​досить коротко у цьому методі. Якщо вам трапилася потреба int("123456790"*11), наприклад:

1e100/81

Однак будьте обережні: такі цифри int("1234567890"*10)не мають такого простого представлення.


9

Використовуйте побітовий лівий зсув для експоненції 2

Хоча існує багато мов, які підтримують оператора експоненції, деякі - ні. А ті, хто цього не робить, зазвичай вимагають виклику функцій (або методів Class / Object), що може коштувати кількох байт.

Але ви можете зберегти кілька байт, коли вам потрібно підняти 2 до потужності n , скориставшись оператором Bitwise Left Shift <<як 1<<n. Зверніть увагу, що це дозволить вам зберегти байти лише тоді, коли n більше або дорівнює 17. Однак це завжди збереже вас байтами, якщо n є динамічним. Кілька прикладів:

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
Зауважте, що ви можете використовувати інші значення замість 1., 8<<9 // 4096щоб ми могли отримати до 99<<616 байт, що дорівнює 6,917,529,027,641,081,856економії 13 байт!
Draco18s

@ Draco18s Так, і це висвітлено тут .
Арджун

Цей ще один охоплює булові оператори побітових розрядів. Так, у нього є також бітшіфтинг, але мова йде про використання двох великих чисел для XOR та отримання третього конкретного числа.
Draco18s

7

Китайська теорема залишків

Якщо довільні великі цілі числа часто з’являються або велике ціле представлення в цільовій мові програмування коштує занадто багато байтів, ви можете розглянути можливість використання китайської теореми залишків.

Виберіть кілька парних відносно простих цілих чисел m i > = 2, і ви можете виразити велике число від 0 до lcm (m 1 , m 2 , ..., m i ) -1

Наприклад, я вибираю 2, 3, 5, 11, 79, 83, 89, 97, тоді я можу однозначно виразити число менше 18680171730. 10000000000 (1e10) можна виразити як 0,1,0,1,38,59,50,49 (1e10 mod 2, 3 ..., 97), які не повинні бути виражені спеціальними класами / структурами Big Integer, які можуть зберегти деякі байти в якійсь мові програмування.

Додавання та субстракція можна здійснити безпосередньо за допомогою цього подання. Приклад:

(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
Хочете детальніше розібратися в цьому?
Скидсдев

@Mayube Я додав пояснення, але я сумніваюся, що це в марності в більшості випадків.
Aria Axe

1
Це "решта теореми".
Ørjan Johansen

6

Використовуйте накладки для рядків (де це можливо)

Якщо велика кількість включає повторювану цифру на початку або в кінці, ви можете зберегти байти, скориставшись одним із методів набивання вашої мови, щоб побудувати рядок потрібного числа, яке потім можна перетворити на ціле число.


Приклад

Щоб генерувати число 1111111111111111111111112(25 байт) у JavaScript (ES8):

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

3

Використовуйте експоненти

Якщо у вашій мові є оператор-експонент, ви, можливо, зможете використовувати її для створення, якщо не потрібного вам числа, принаймні число, яке ви можете виконати простим обчисленням або 2, щоб отримати ваш номер. Навіть без оператора ви все одно зможете зберігати байти за допомогою вбудованої функції чи методу.

Приклад

Максимально безпечне число в JavaScript є 9007199254740991, довжиною 16 цифр. У ES7 це можна обчислити за допомогою наступних 7 байт:

2**53-1

Еквівалент у ES6 та більш ранніх версіях, хоча така ж довжина, як і ціле число у цьому випадку, демонструє, що використання методу більш докладної дії не обов'язково коштуватиме вам жодних байтів.

Math.pow(2,53)-1

Наведене вище, однак, може спрацювати коротше, якщо, наприклад, у вас вже є Mathпсевдонім одного символу в іншому місці коду.


2

Використовуйте дроби на місці поплавця

Приклад: 1./3замість0.333333333

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.