Büyük sayıları temsil etmek için genel ipuçları


21

Bazen, golf oynarken, kodlarında çok sayıda kişi bulunması gerekir. Bunları olduğu gibi yazmak, bayt sayısını önemli ölçüde artırabilir.

Ne genel 1 sen kısaca kodda uzun sayıların gösterimi için ipuçları var mı?

Lütfen cevap başına bir ipucu gönderin.


1 ile genel , tek bir dilden daha uygulanabilir ipuçları demek. Dile özgü ipuçları için, ilgili başlıkları girin.




Birinin soruyu yanlış anladığını gördüm - belki de başlığın bunun golf ile ilgili olduğunu söylemesi gerekir.
Ørjan Johansen

Yanıtlar:


15

Özel numaralara dikkat edin

Bazı diller yerleşik kareler için fonksiyonlar, üs tabanı 2 ile n -inci asal, faktöryel veya çok sayıda üretebilir diğer prosedürler. Numaranızın bu kategorilerden birine girip girmediğini kontrol edin .

Olmazsa, amaçlarınıza uygun ve yerine kullanılabilecek daha büyük bir sayı olabilir.


4
İstediğiniz sayı yerleşik bir işlevle oluşturulamazsa bile, sayılarınıza ulaşmak için basit bir hesaplamanın temeli olarak kullanabileceğiniz bir sayı oluşturmak, sayıları yazarken de baytları kaydetmek mümkün olabilir.
Shaggy

7
"Büyük sayı" için +1 - 1.01e6yineleme yeterliyse, 1e7çalışma süresi pahasına 3 bayt kazandırır.
Chris H,

13

Bitsel boole işleçlerini kullan

Bazı diller bitsel olarak VE, VEYA, XOR ve bazen de DEĞİLDİR.

Bir üs veya sola kayma ve başka bir sayının sonucunun bitsel bir kombinasyonu olarak belirli bir büyük sayıyı ifade etmek, tam olarak ihtiyacınız olan sayıyı elde etmenizi sağlayabilir. Bu genellikle, sadece sayılar oldukça büyürse buna değer.

Örneğin 2147483722, 10 bayttır, ancak 2<<30^74(2 = 31 bit yönünde x 74 ile XORed) yalnızca 8'dir.


3
Dilde bu operatör varsa (örneğin bc) vardiya operatörü üstel ile değiştirilebilir . Ve XOR daha asla daha yararlıdır +ve -: bu durumda, xor ve aynı sonucu verir eklemek, ancak tüm vakalarda orada eklenebilir veya bir tamsayı ile xor aynı sonucu elde etmek için çıkartılabilir bazı tamsayı ve birDeğer olduğunu daha büyük ve bazen daha kısa değil.
rici

3
@rici Bütün tamsayılar basit ondalık sayılar olarak yazılırsa geçerlidir, fakat xor ile kullanılacak tamsayılar, artı veya eksi ile kullanılacak tamsayıların kullanamayacağı şekilde kısaltılabilirse şöyle olabilir: düşünün 1e9^2e9.
HVD

2
@rici 9<<49^7<<19xor yerine ekleme kullanarak nasıl ifade ederdiniz ?
L3viathan

2
@rici Hayır, yazdıklarımı kastetmiştim. Bu sonucunu 1286561280JavaScript ve Perl (ve muhtemelen diğer diller) 'de ve kullanan eşdeğer daha bu değeri üretmek için daha kısa ifadesidir +ya -.
HVD

@ hvd: Tamam, nokta alındı.
rici

11

Tekrarlayan sayılar için Dizeleri kullan

Doğada çok tekrarlayan sayılar için, Dizgileri kullanabilir ve bunları Tamsayıya yayınlayabilirsiniz. Örneğin, JavaScript’te

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

2
Veya 1e100/9bu durumda çok büyük bir kesir kullanabilirsiniz .
ETHproductions

11

Bilimsel Notasyonu Kullan

Bilimsel gösterim, uzun sayılar olması durumunda baytları kurtarabilir. Örneğin:

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

3
Neden sadece 3564e-8bu durumda kullanmıyorsun ?
Joey

@Joey Evet, elbette! Teşekkür ederim! :)
Arjun

Verilirse, diğer sayıyı genellikle .00003564bir bayt daha kısa olan bir sayı olarak yazabilirsiniz .
Joey

@Joey Her dilde değil, bu yüzden, onu düzenlemeyeceğim.
Arjun

3564'ün (solda) 354 (sağda) olması kasıtlı mıdır yoksa bu bir yazım hatası mıdır?
Erik

10

Bunun yerine kullanmak için başka bir numara arayın.

Bu bir cevapsız gibi görünebilir, ancak daha kısa bir kodla daha büyük bir sayının hesaplanabileceği her zaman açık değildir. Hatırladığım bir örnek , bir dizgenin bir googol kopyasını çıktısıdır ; burada bariz cevaplar bilgisayar 10 100 gerektirir . Görünüşe göre, 10 100’den herhangi birini hesaplamak eşit derecede doğru, ancak bazı dillerde daha kısa cevaplara yol açmaktadır. Dennis'in cevabı 100 100 , kendi kullanırım 250 255 .


4
Bunun bir başka örneği, eseğer sadece çok sayıda sayıya ihtiyacınız varsa ancak değerini umursamıyorsanız (veya her zaman aynı olduğunu) mevcut zaman damgasını alabileceğiniz CJam'dır .
Martin Ender

10

Baz Sıkıştırma

Baz dekompresyon kodu oldukça karmaşık olabilir, ancak gerçekten çok büyük bir sayıya sahipseniz bazen 10'dan daha yüksek bir bazda sıkıştırmaya yardımcı olabilir.

Ayrıca, bazı dillerde, temel sıkıştırma kodunun çok basit olmasına yardımcı olur. Örneğin, PHP'de base64_decode(_)Python'da int(_,36)JavaScript'te var parseInt(_,36)ve birçok golf dilinde baz dekompresyon yerleşikleri var. Örneğin, CJam’de:

"+ÜTbô±"256b

Bu yazdırılamaz bir içerir. Çevrimiçi deneyin!

Bu verim:

12345678987654321

9

Tekrarlayan büyük sayılar için üstel kesirler kullanın

Diyelim ki 100 1'lerden oluşan bir sayı oluşturmak istediniz. Sen kullanabilirsiniz int("1"*100), +"1".repeat(100)vb ama aynı zamanda çok yakın bu kadar gerçeği yararlanabilir

1e100/9

Bu tek basamaktan yapılanlar gibi çok tekrarlayan sayılar için en iyisidir. Birkaç tekrarlanan rakam da oldukça iyi çalışıyor:

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

Bazen, bu yöntemde oldukça ters olarak temsil edilebilecek başka bir garip örüntü bulacaksınız. İhtiyacınız olursa int("123456790"*11), örneğin:

1e100/81

Yine de dikkatli olun: bu kadar int("1234567890"*10)kolay bir temsile sahip olmayan numaralar .


9

2'in üsteli için Bitsel Sola Kaydırma kullanın

Üslup için operatörü destekleyen birçok dil olmasına rağmen, bazıları yoktur. Ve genellikle, birkaç byte'a mal olabilen arama işlevleri (veya Sınıf / Nesne yöntemleri) gerektirmeyenler.

Eğer güç için 2. yükseltmek gerektiğinde Ama bazı bayt kaydedebilirsiniz n Bitwise Sol Shift operatörünü kullanarak <<olarak 1<<n. Bunun sadece n'nin 17'den büyük veya ona eşit olması durumunda baytları kurtaracağını unutmayın . Ancak, n dinamik olduğunda bu her zaman baytları kaydeder. Birkaç Örnek:

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 yerine diğer değerleri kullanabileceğinizi unutmayın, 8<<9 // 4096böylece 99<<616 bayta kadar çıkabiliriz ; bu, 6,917,529,027,641,081,85613 bayta tasarruf anlamına gelir!
Draco18

@ Draco18s Evet ve burada kaplıdır .
Arjun

Bir tane daha boolean bitwise operatörleri kapsar. Evet, parça değişimi de var, ancak XOR'a iki büyük sayı kullanmaktan ve üçüncü bir numara almaktan bahsediyor.
Draco18,

7

Çin Kalan Teoremi

Rasgele büyük tamsayılar sıklıkla görünürse veya hedef programlama dilindeki büyük tamsayı gösterimi çok fazla bayt tutarsa, Çin Kalan Teoremi'ni kullanmayı düşünebilirsiniz.

M i > = 2 olarak bazı çiftler cinsinden göreceli asal tamsayıları seçin ve 0 ile 1 cm arasında (m 1 , m 2 , ..., m i ) -1 ile büyük bir sayı ifade edebilirsiniz.

Örneğin, 2, 3, 5, 11, 79, 83, 89, 97'yi seçiyorum, ardından 18680171730'dan daha az bir sayıya özel olarak ifade edebilirim. 10000000000 (1e10), kurtarabilecek özel Big Integer sınıfı / yapı olarak ifade edilmesi gerekmeyen 0,1,0,1,38,59,50,49 (1e10 mod 2, 3 ..., 97) olarak ifade edilebilir. bazı programlama dillerinde bazı baytlar.

Toplama ve çıkarma işlemi doğrudan bu temsil kullanılarak yapılabilir. Örnek:

(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
Bunu detaylandırmak ister misin?
Skidsdev

@ Mayube Bazı açıklamalar ekledim, ancak çoğu durumda yararsız olduğundan şüpheliyim.
Aria Axe

1
"Kalan teoremi".
Ørjan Johansen

6

String Padding kullanın (mümkünse)

Büyük bir sayı, başında veya sonunda yinelenen bir rakam içeriyorsa, aradığınız numaranın bir dizesini oluşturmak için dilinizin doldurma yöntemlerinden birini kullanarak baytları kaydedebilirsiniz. tamsayı.


Örnek

1111111111111111111111112JavaScript'te (ES8) sayıyı (25 bayt) oluşturmak için :

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

3

Üscüleri Kullan

Dilinizde bir üs operatörü varsa, bunu oluşturmak için kullanabilirsiniz, istediğiniz numara olmasa da, en azından bir numarayı basit bir hesaplama yapabilir veya numaranıza ulaşmak için 2 üzerinde kullanabilirsiniz. Bir operatör olmasa bile, baytları yerleşik bir işlev veya yöntemle kaydedebilirsiniz.

Örnek

JavaScript maksimum güvenli bir tamsayı olduğu 900719925474099116 basamak uzunluğunda olan. ES7'de bu, aşağıdaki 7 bayt ile hesaplanabilir:

2**53-1

ES6 ve önceki değerlerdeki eşdeğer, bu örnekteki tamsayı ile aynı uzunluktayken, daha ayrıntılı bir yöntem kullanmanın size herhangi bir bayt için maliyet getirmeyebileceğini göstermektedir.

Math.pow(2,53)-1

Yukarıdaki kod , örneğin, kodunuzda başka bir yerde tek bir karaktere zaten takma adınız varsa, daha kısa süredeMath sonuçlanabilir.


2

Yüzen yerde kesirler kullanın

Örnek: 1./3yerine0.333333333

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.