Kod: Mathematica, Çıktı: Julia, ~ 98.9457% (20177/20392 bytes)
optimise[n_] :=
Module[{bits, trimmedBits, shift, unshifted, nString, versions,
inverted, factorised, digits, trimmedDigits, exponent, base,
xored, ored, anded},
nString = ToString@n;
versions = {nString};
(* Try bitshifting *)
bits = IntegerDigits[n, 2];
trimmedBits = bits /. {x___, 1, 0 ..} :> {x, 1};
shift = ToString[Length[bits] - Length[trimmedBits]];
unshifted = ToString@FromDigits[trimmedBits, 2];
AppendTo[versions, unshifted <> "<<" <> shift];
(* Try inverting *)
inverted = ToString@FromDigits[1 - PadLeft[bits, 32], 2];
AppendTo[versions, "~" <> inverted];
(* Try invert/shift/invert *)
trimmedBits = bits /. {x___, 0, 1 ..} :> {x, 1};
shift = ToString[Length[bits] - Length[trimmedBits]];
unshifted = ToString@FromDigits[trimmedBits, 2];
AppendTo[versions, "~(~" <> unshifted <> "<<" <> shift <> ")"];
(* Try factoring *)
factorised = Riffle[
FactorInteger[n]
/. {a_, 1} :> ToString@a
/. {a_Integer, b_Integer} :> ToString[a] <> "^" <> ToString[b]
, "+"] <> "";
AppendTo[versions, factorised];
(* Try scientific notation *)
digits = IntegerDigits[n, 10];
trimmedDigits = digits /. {x___, d_ /; d > 0, 0 ..} :> {x, d};
exponent = ToString[Length[digits] - Length[trimmedDigits]];
base = ToString@FromDigits[trimmedDigits, 10];
AppendTo[versions, base <> "e" <> exponent];
(* Don't try hexadecimal notation. It's never shorter for 32-bit uints. *)
(* Don't try base-36 or base-62, because parsing those requires 12 characters for
parseint("...") *)
SortBy[versions, StringLength][[1]]
];
mathpack[n_] :=
Module[{versions, increments},
increments = Range@9;
versions = Join[
optimise[#2] <> "+" <> ToString@# & @@@ ({#, n - #} &) /@
Reverse@increments,
{optimise@n},
optimise[#2] <> "-" <> ToString@# & @@@ ({#, n + #} &) /@
increments,
optimise[#2] <> "*" <> ToString@# & @@@
Cases[({#, n / #} &) /@ increments, {_, _Integer}],
optimise[#2] <> "/" <> ToString@# & @@@ ({#, n * #} &) /@
increments
];
SortBy[versions, StringLength][[1]]
];
İşlev bir sayı alır ve bulduğu en kısa dizeyi döndürür . Şu anda dört basit optimizasyon uygulanmaktadır (yarın daha fazlasını ekleyebilirim).
Dosyayı (puanını ölçmek için) aşağıdaki gibi tüm dosyaya uygulayabilirsiniz:
input = StringSplit[Import["path/to/benchmark.txt"]];
numbers = ToExpression /@ input;
output = mathpack /@ numbers;
N[StringLength[output <> ""]/StringLength[input <> ""]]
Bu optimizasyonların bazılarının, tamsayı değişmez değerleri size int64
varsayılan olarak bir değer verecek şekilde 64 bit Julia'da olduğunuzu varsaydığını unutmayın. Aksi takdirde, 2 31'den büyük tamsayılar için yine de taşacaksınız . Bu varsayımı kullanarak, ara adımları aslında 2 32'den bile büyük olan birkaç optimizasyon uygulayabiliriz .
DÜZENLEME: Ben Bitsel için OP'ın örneklerde önerilen optimizasyon eklendi xor (tümü için aslında bilimsel gösterimde iki büyük sayılar xor , ya ve ve ). Uzanan o Not xormap
, ormap
ve andmap
2 ötesine işlenen içerecek şekilde 32 kudreti yardım ek optimizasyon bulmakta, ancak verilen test durumları için çalışmalarını yapmaz ve sadece 10 faktör gibi bir şey tarafından işletilen süreyi artırır.
DÜZENLEME: Bunlarınn-9, n-8, ..., n+8, n+9
herhangi birinin kısaltıp kısaltılamayacağını kontrol ederek 16 bayt daha tıraş ettim , bu durumda sayıyı buna dayalı olarak temsil ettim, farkı ekledim veya çıkardım. Bu 18 rakamdan birinin kendisinden 3 veya daha az karakterle temsil edilebileceği birkaç durum vardır, bu durumda bazı ekstra tasarruflar yapabilirim. Şimdi tüm test senaryolarında çalıştırmak yaklaşık 30 saniye sürüyor, ancak elbette, birisi bu işlevi gerçekten "kullandıysa", sadece tek bir sayı üzerinde çalıştırır, bu yüzden hala bir saniyenin altında.n
EDIT: Çarpma ve bölme için aynı yaparak başka bir inanılmaz 4 bayt. Şimdi 50 saniye (bölünmüş olanlar çok uzun sürmüyor, çünkü bunları sadece sayı gerçekten ilgi faktörüne bölünebiliyorsa kontrol ediyorum).
EDIT: Verilen test seti ile gerçekten yardımcı olmayan başka bir optimizasyon. Bu, 2 30 veya 2 31 gibi şeyler için bir bayt kaydedebilir . Bunun yerine uint64'lerimiz olsaydı, bunun büyük bir tasarruf olabileceği çok sayıda sayı olurdu (temel olarak, bit temsili 1'lerde sona erdiğinde).
DÜZENLEME: Kaldırılan xor , ya , ve tamamen optimizasyon. Julia'da bile çalışmadıklarını fark ettim, çünkü (oldukça açık bir şekilde) bilimsel gösterim size biraz akıllı operatörlerin bile tanımlanmadığı bir şamandıra veriyor. İlginç bir şekilde, yeni optimizasyonlardan bir veya daha fazlası bu optimizasyonlarla kısaltılmış tüm vakaları yakalar gibi görünüyor, çünkü puan hiç değişmedi.