Kode: Mathematica, Output: Julia, ~ 98.9457% (20177/20392 byte)
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]]
];
Fungsi mengambil nomor dan mengembalikan string terpendek yang ditemukannya. Saat ini ia menerapkan empat optimisasi sederhana (saya mungkin menambahkan lebih banyak besok).
Anda dapat menerapkannya ke seluruh file (untuk mengukur nilainya) sebagai berikut:
input = StringSplit[Import["path/to/benchmark.txt"]];
numbers = ToExpression /@ input;
output = mathpack /@ numbers;
N[StringLength[output <> ""]/StringLength[input <> ""]]
Perhatikan bahwa beberapa optimisasi ini mengasumsikan bahwa Anda menggunakan Julia 64-bit, sehingga literal integer memberi Anda int64default. Jika tidak, Anda tetap akan kelebihan untuk bilangan bulat lebih besar dari 2 31 . Dengan menggunakan asumsi itu, kita dapat menerapkan beberapa optimasi yang langkah-langkah peralihannya sebenarnya bahkan lebih besar dari 32 .
EDIT: Saya menambahkan optimasi yang disarankan dalam contoh OP untuk bitwise xor dua angka besar dalam notasi ilmiah (sebenarnya, untuk semua xor , atau dan dan ). Perhatikan bahwa memperluas xormap, ormapdan andmapuntuk menyertakan operan di luar 2 32 dapat membantu menemukan optimisasi tambahan, tetapi tidak berfungsi untuk kasus uji yang diberikan dan hanya menambah waktu berjalan dengan sesuatu seperti faktor 10.
EDIT: Saya mencukur 16 byte lagi, dengan memeriksa semua n-9, n-8, ..., n+8, n+9apakah ada yang bisa dipersingkat, dalam hal ini saya mewakili angka berdasarkan itu, menambah atau mengurangi perbedaan. Ada beberapa kasus, di mana salah satu dari 18 angka dapat diwakili dengan 3 atau lebih karakter kurang dari nitu sendiri, dalam hal ini saya dapat melakukan penghematan tambahan. Dibutuhkan sekitar 30 detik sekarang untuk menjalankannya pada semua kasus uji, tetapi tentu saja, jika seseorang benar-benar "menggunakan" fungsi ini, ia hanya akan menjalankannya pada satu nomor, jadi masih di bawah satu detik.
EDIT: Lain 4 byte luar biasa dengan melakukan hal yang sama untuk perkalian dan pembagian. 50 detik sekarang (yang dibagi tidak butuh waktu lama, karena saya hanya memeriksa ini jika jumlahnya benar-benar dapat dibagi oleh faktor yang menarik).
EDIT: Optimalisasi lain yang sebenarnya tidak membantu set tes yang diberikan. Yang ini bisa menghemat satu byte untuk hal-hal seperti 2 30 atau 2 31 . Jika kita memiliki uint64 saja, akan ada banyak angka di mana ini bisa menjadi penghematan besar (pada dasarnya, setiap kali representasi bit berakhir dengan banyak 1s).
EDIT: Menghapus xor , atau , dan optimisasi sama sekali. Saya hanya memperhatikan mereka bahkan tidak bekerja di Julia, karena (sangat jelas) notasi ilmiah memberi Anda pelampung di mana operator bit-bijaksana bahkan tidak didefinisikan. Yang menarik, satu atau lebih optimisasi yang lebih baru nampaknya menangkap semua kasus yang dipersingkat oleh optimisasi ini, karena skornya tidak berubah sama sekali.