รหัส: Mathematica, เอาต์พุต: 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]]
];
ฟังก์ชันใช้ตัวเลขและส่งคืนสตริงที่สั้นที่สุดที่พบ ขณะนี้มันใช้การเพิ่มประสิทธิภาพง่าย ๆ สี่แบบ (ฉันอาจเพิ่มอีกในวันพรุ่งนี้)
คุณสามารถนำไปใช้กับไฟล์ทั้งหมด (เพื่อวัดคะแนน) ดังนี้:
input = StringSplit[Import["path/to/benchmark.txt"]];
numbers = ToExpression /@ input;
output = mathpack /@ numbers;
N[StringLength[output <> ""]/StringLength[input <> ""]]
โปรดทราบว่าการเพิ่มประสิทธิภาพเหล่านี้บางอย่างสมมติว่าคุณอยู่ใน Julia 64 บิตเช่นนั้นตัวอักษรจำนวนเต็มจะให้คุณเป็นint64
ค่าเริ่มต้น มิฉะนั้นคุณจะล้นอยู่แล้วสำหรับจำนวนเต็มมากกว่า 2 วันที่ 31 โดยใช้สมมติฐานที่ว่าเราสามารถใช้ optimisations ไม่กี่ที่มีขั้นตอนกลางเป็นจริงแม้จะมีขนาดใหญ่กว่า 2 32
แก้ไข:ฉันเพิ่มการเพิ่มประสิทธิภาพที่แนะนำในตัวอย่างของ OP เพื่อ bitwise xorตัวเลขสองขนาดใหญ่ในทางวิทยาศาสตร์ (ที่จริงสำหรับทุกxor , หรือและและ ) โปรดทราบว่าการขยายxormap
, ormap
และandmap
จะรวมตัวถูกดำเนินการเกิน 2 32อาจช่วยให้การหา optimisations เพิ่มเติม แต่มันไม่ทำงานสำหรับกรณีทดสอบที่กำหนดและเพียง แต่เพิ่มเวลาทำงานโดยสิ่งที่ต้องการปัจจัยที่ 10
แก้ไข:ฉันโกนออกไปอีก 16 ไบต์โดยตรวจสอบทั้งหมดn-9, n-8, ..., n+8, n+9
ว่ามีส่วนใดที่สั้นลงได้ซึ่งในกรณีนี้ฉันแทนตัวเลขตามนั้นโดยเพิ่มหรือลบความแตกต่าง มีบางกรณีที่หนึ่งใน 18 หมายเลขเหล่านี้สามารถแสดงด้วยอักขระ 3 ตัวหรือน้อยกว่าn
นั้นในกรณีนี้ฉันสามารถประหยัดเพิ่มได้ ใช้เวลาประมาณ 30 วินาทีในการรันในทุกกรณีทดสอบ แต่แน่นอนว่าถ้ามีคน "ใช้" ฟังก์ชั่นนี้จริง ๆ เขาจะเรียกใช้เฉพาะหมายเลขเดียวเท่านั้น
แก้ไข:อีกอย่างไม่น่าเชื่อ 4 ไบต์โดยทำเช่นเดียวกันสำหรับการคูณและการหาร 50 วินาทีในขณะนี้ (ตัวหารจะใช้เวลาไม่นานเพราะฉันแค่ตรวจสอบสิ่งเหล่านี้ถ้าจำนวนหารด้วยปัจจัยที่น่าสนใจจริง ๆ )
แก้ไข:การเพิ่มประสิทธิภาพอื่นที่ไม่ได้ช่วยจริงกับชุดทดสอบที่กำหนด หนึ่งนี้จะสามารถประหยัดไบต์สำหรับสิ่งที่เหมือน 2 วันที่ 30หรือ 2 วันที่ 31 หากเรามี uint64 แทนจะมีตัวเลขมากมายที่สิ่งนี้อาจเป็นการประหยัดขนาดใหญ่ (โดยทั่วไปเมื่อใดก็ตามที่การแสดงบิตสิ้นสุดใน 1 วินาที)
แก้ไข:ถอดxor , หรือ ,และ optimisations โดยสิ้นเชิง ฉันเพิ่งสังเกตเห็นว่าพวกเขาไม่ได้ทำงานในจูเลียเพราะสัญกรณ์ทางวิทยาศาสตร์ (ค่อนข้างชัดเจน) ให้คุณลอยในที่ที่ผู้ประกอบการบิตที่ชาญฉลาดไม่ได้กำหนดไว้ น่าสนใจว่าการเพิ่มประสิทธิภาพที่ใหม่กว่านี้อย่างใดอย่างหนึ่งดูเหมือนจะจับทุกกรณีที่ถูกทำให้สั้นลงโดยการเพิ่มประสิทธิภาพเหล่านี้เนื่องจากคะแนนไม่เปลี่ยนแปลงเลย