mathpack chữ số


10

lời nói đầu

Trong một tình huống rất nóng, bạn phải đi xa hơn nữa với việc chơi golf.
(ví dụ: trong một thử thách trong đó câu trả lời của bạn dài 100 ký tự và thật xấu hổ khi bạn không thể thực hiện được 99)
Trong trường hợp đó, từ giờ trở đi, bạn sử dụng thuật toán của người chiến thắng trong thử thách này :)

mục tiêu

Bạn phải viết một chương trình có uint32 và trả về dạng nén nhất.

$ mathpack 147456
9<<14
  • Sẽ có nhiều giải pháp cho một số. Chọn cái ngắn nhất
  • Nếu dạng nén dài hơn hoặc bằng số gốc, hãy trả về số gốc

quy tắc

  • viết bằng bất kỳ ngôn ngữ nào - đầu ra bằng bất kỳ ngôn ngữ nào
  • Tôi biết rằng trong C 'abc'6382179và bạn có thể đạt được kết quả khá tốt với chuyển đổi này. nhưng ngôn ngữ bị tách ra trong thử thách này nên đừng mất lòng
  • nó bị cấm sử dụng các biến bên ngoài. chỉ toán tử và chữ và các chức năng liên quan đến toán học!

ghi bàn

đây là các trường hợp kiểm tra: pastebin.com/0bYPzUhX
điểm của bạn (phần trăm) sẽ là tỷ lệ
byte_size_of_your_output / byte_size_of_the_list không có ngắt dòng .
(bạn phải tự làm điều này vì tôi sẽ chỉ xác minh các mã tốt nhất chỉ trong trường hợp)
người chiến thắng sẽ được chọn theo điểm số và ngôn ngữ đầu ra !

ví dụ:

$ mathpack 147456 | mathpack 97787584 |  mathpack 387420489
            9<<14 |           9e7^9e6 |            pow(9,9)

Thử thách đáng yêu, nhưng bạn nên thêm vào một quy tắc chống lại mã hóa cứng.
ɐɔıʇǝɥʇuʎs

y-bạn có nghĩa là hardcoding 10k trường hợp? mặc dù tôi sẽ rất vui mừng khi nhận được một số hỗ trợ về cách tinh chỉnh thách thức này
bebe

chỉnh sửa (một lần nữa và một lần nữa ...) cho rõ ràng. cảm ơn vì lời khuyên
be

Đây cũng không phải là [đá Rosetta] sao? Ngoài ra: write in any language - output in any language- hai ngôn ngữ có thể khác nhau, phải không?
ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs [rosetta-Stone] thực sự là về việc bạn giải quyết nó bằng càng nhiều ngôn ngữ càng tốt. Và có cho câu hỏi sau của bạn - đã được chỉnh sửa để trả lời cho tôi hỏi câu hỏi tương tự.
Martin Ender

Câu trả lời:


1

Mã: Mathicala, Đầu ra: C, ~ 62,1518% (12674/20392)

Tôi nghĩ tôi cũng sẽ thử C vì những chữ nhân vật ngộ nghĩnh đó. Hiện tại đây là điều duy nhất câu trả lời này đang cố gắng và nó hoạt động khá tốt.

mathpack[n_] := Module[{versions, charLiteral},
   charLiteral = "'" <> StringReplace[Map[
        Switch[#,
          (*d_ /; d < 32,
          "\\" <> IntegerString[#, 8],*)
          10,
          "\\n",
          13,
          "\\r"
          39,
          "\\'",
          92 ,
          "\\\\",
          _,
          FromCharacterCode@#] &,
        FromDigits[#, 
           2] & /@ (Partition[PadLeft[IntegerDigits[n, 2], 32], 
            8] //. {{0 ..} .., x__} :> {x})
        ] <> "",
      {(*"\\10" -> "\\b",
       "\\11" -> "\\t",
       "\\13" -> "\\v",
       "\\14" -> "\\f",*)
       RegularExpression["(?!<=\?)\?\?(?=[=/()!<>-]|$)"] -> "?\\?"
       }
      ] <> "'";
   versions = {ToString@n, charLiteral};
   SortBy[versions, StringLength][[1]]
 ];

Tôi hy vọng tôi đã không bỏ lỡ bất cứ điều gì, nhưng câu trả lời này đảm bảo thoát khỏi dấu gạch chéo ngược, dấu ngoặc kép đơn cũng như dấu ba chấm. Có một số mã nhận xét sử dụng bát phân hoặc các chuỗi thoát khác cho các ký tự không in được, nhưng tôi không nghĩ điều đó thực sự cần thiết, bởi vì C nên có thể xử lý bất kỳ byte nào trong các ký tự, afaik (vui lòng sửa lại cho tôi nếu tôi 'tôi sai).

Như với đệ trình khác, kiểm tra điều này với

input = StringSplit[Import["path/to/benchmark.txt"]];
numbers = ToExpression /@ input;
output = mathpack /@ numbers;
N[StringLength[output <> ""]/StringLength[input <> ""]]

(Trên hệ thống của tôi ít nhất) GCC sẽ chấp nhận bất kỳ byte nào trong các dấu ngoặc đơn trừ 10 ( \n) và 13 ( \r). Một byte không sẽ biên dịch OK, nhưng với thông báo lỗi warning: null character(s) preserved in literal.
r3mainer

@squeamishossifrage Cảm ơn, đã sửa!
Martin Ender

3

Mã: Mathicala, Đầu ra: Julia, ~ 98,9456% (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]]
 ];

Hàm lấy một số và trả về chuỗi ngắn nhất mà nó tìm thấy. Hiện tại nó áp dụng bốn tối ưu hóa đơn giản (tôi có thể thêm nhiều hơn vào ngày mai).

Bạn có thể áp dụng nó cho toàn bộ tập tin (để đo điểm của nó) như sau:

input = StringSplit[Import["path/to/benchmark.txt"]];
numbers = ToExpression /@ input;
output = mathpack /@ numbers;
N[StringLength[output <> ""]/StringLength[input <> ""]]

Lưu ý rằng một số tối ưu hóa này cho rằng bạn đang sử dụng Julia 64 bit, như vậy theo nghĩa đen là số nguyên cho bạn một int64mặc định. Mặt khác, dù sao bạn cũng sẽ tràn ra số nguyên lớn hơn 2 31 . Sử dụng giả định đó, chúng ta có thể áp dụng một vài tối ưu hóa mà các bước trung gian thực sự thậm chí còn lớn hơn 2 32 .

EDIT: Tôi thêm vào việc tối ưu hóa gợi ý trong các ví dụ của OP để Bitwise xor hai với số lượng lớn trong ký hiệu khoa học (trên thực tế, đối với tất cả các xor , hay ). Lưu ý rằng việc mở rộng xormap, ormapandmapbao gồm toán hạng vượt 2 32 sức giúp đỡ để tìm optimisations bổ sung, nhưng nó không làm việc cho các trường hợp thử nghiệm nhất định và chỉ tăng thời gian chạy bởi một cái gì đó như một yếu tố của 10.

EDIT: Tôi đã loại bỏ 16 byte khác, bằng cách kiểm tra tất cả n-9, n-8, ..., n+8, n+9xem có thể rút ngắn bất kỳ cái nào trong số đó không, trong trường hợp đó tôi biểu thị số dựa trên đó, thêm hoặc bớt đi sự khác biệt. Có một vài trường hợp, trong đó một trong số 18 số đó có thể được biểu thị với ít hơn 3 ký tự trở nlên, trong trường hợp đó tôi có thể tiết kiệm thêm. Bây giờ mất khoảng 30 giây để chạy nó trên tất cả các trường hợp thử nghiệm, nhưng tất nhiên, nếu ai đó thực sự "sử dụng" chức năng này, anh ta chỉ chạy nó trên một số duy nhất, vì vậy nó vẫn hoạt động tốt trong một giây.

EDIT: Một 4 byte đáng kinh ngạc khác bằng cách làm tương tự cho phép nhân và chia. 50 giây bây giờ (những người được chia không mất nhiều thời gian, bởi vì tôi chỉ kiểm tra những điều này nếu con số thực sự chia hết cho yếu tố quan tâm).

EDIT: Một tối ưu hóa khác không thực sự có ích với bộ thử nghiệm đã cho. Điều này có thể tiết kiệm một byte cho những thứ như 2 30 hoặc 2 31 . Nếu chúng ta có uint64 thay vào đó, sẽ có rất nhiều con số trong đó đây có thể là một khoản tiết kiệm rất lớn (về cơ bản, bất cứ khi nào việc biểu diễn bit kết thúc trong rất nhiều 1 giây).

EDIT: Đã xóa xor , hoặc , tối ưu hóa hoàn toàn. Tôi chỉ nhận thấy rằng họ thậm chí không làm việc ở Julia, bởi vì (khá rõ ràng) ký hiệu khoa học mang đến cho bạn một sự nổi bật trong đó các toán tử bit khôn ngoan thậm chí không được xác định. Thật thú vị, một hoặc nhiều tối ưu hóa mới hơn dường như nắm bắt được tất cả các trường hợp được rút ngắn bởi những tối ưu hóa này, bởi vì điểm số không thay đổi gì cả.


1

J đến C (chưa được kiểm tra, nhưng hoạt động trong hầu hết các trường hợp, loại câu trả lời cơ bản.)

    f=:(,~ (($&0) @: (8&-) @: (8&|) @: #)) @: #:
    g=:($~ ((,&8) @: (%&8) @: #))@:f
    toCString=:({&a.)@:#.@:g
    toCString 6382179
abc    

Xuất ra một chuỗi ký tự, nếu được nhập vào C, đại diện cho số (như được đề cập trong OP). Đây không phải là một bài nộp nghiêm túc, mà là thứ gì đó để củng cố các kỹ năng J của tôi, mà tôi nghĩ tôi muốn chia sẻ.

Thay thế một lớp lót:

toCString=:({&a.) @: #. @: ($~ ((,&8) @: (%&8) @: #))@: (,~ (($&0) @: (8&-) @: (8&|) @: #)) @: #:

Những gì J cố gắng thực hiện điều này khi bạn nhập nó:

{&a.@:#.@:($~ ,&8@:(%&8)@:#)@:(,~ $&0@:(8&-)@:(8&|)@:#)@:#:

Cảm ơn rất nhiều, J. Ngoài ra, đối với những người trong 'hiểu biết' về J, đá visio đã tạo ra các chức năng phức tạp hơn:

nhập mô tả hình ảnh ở đây


Vì tôi không thể đọc bất cứ thứ gì trong số đó: điều này sẽ làm gì nếu nhân vật không thể in được, hoặc nếu nhân vật là \ , ?hoặc '?
Martin Ender

@ m.buettner Không có gì (chưa), tôi vẫn phải xây dựng một cái gì đó cho điều đó
I14uʎs

Thay vì m&u@:v, sử dụng m u vđể lưu các ký tự quý giá và để tăng cường khả năng đọc. Áp dụng điều này để mã của bạn, chúng tôi nhận f =: [: (,~ 0 $~ 8 - 8 | #) #:g =: [: ($~ 8 ,~ # % 8:) fvà cuối cùng toCString =: a. {~ [: #. g. Tất cả kết hợp chúng tôi nhận được a. {~ [: #. [: ($~ 8 ,~ # % 8:) [: (,~ 0 $~ 8 - 8 | #) #:, đó là thực sự dễ đọc.
FUZxxl 14/03/2015
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.