mathpack数字文字


10

前言

在非常炎热的情况下,您必须进一步打高尔夫球。
(例如,在一个挑战中,您的答案长达100个字符,而您无法将其设为99则令人尴尬)
在这种情况下,从现在开始,您将使用该挑战者的获胜者算法:)

目标

您必须编写一个使用uint32并返回最压缩形式的程序。

$ mathpack 147456
9<<14
  • 一个数字将有多种解决方案。选择最短的一个
  • 如果压缩后的格式大于或等于原始编号,请返回原始编号

规则

  • 用任何语言编写-以任何语言输出
  • 我知道在C语言'abc'6382179,使用此转换可以达到很好的效果。但是在挑战中语言是分开的,所以不要灰心
  • 禁止使用外部变量。仅运算符,文字和数学相关函数!

得分

这是测试用例:pastebin.com/0bYPzUhX
您的分数(百分比)将是
byte_size_of_your_output / byte_size_of_the_list 没有换行符的比率。
(您必须自己做,因为我会验证最佳代码,以防万一)
获胜者将由得分和输出语言选择!

例子:

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

艰巨的挑战,但是您应该添加反对硬编码的规则。
ɐɔıʇǝɥʇuʎs

y-您的意思是硬编码1万个案例?尽管我很乐意在如何完善这一挑战方面获得一些支持
Bebe 2014年

为了清晰起见,我们进行了一次又一次的编辑。感谢您的建议。
贝贝2014年

这不是[罗塞塔石]吗?另外:write in any language - output in any language-两种语言可以不同,对吗?
ɐɔıʇǝɥʇuʎs

@ɐɔıʇǝɥʇuʎs的[rosetta-stone]实际上是关于以尽可能多的语言解决它的方法。是的,您的后一个问题-已针对我提出的相同问题进行了编辑。
Martin Ender 2014年

Answers:


1

代码:Mathematica,输出:C,〜62.1518%(12674/20392)

我以为我也可以尝试一下C,因为这些有趣的字符文字。目前,这是此答案唯一尝试的方法,并且效果很好。

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]]
 ];

我希望我不会错过任何内容,但是此答案可以确保避免反斜杠,单引号以及三引号。有一些注释掉的代码对不可打印字符使用八进制或其他转义序列,但是我认为这实际上不是必需的,因为C应该能够处理字符文字中的任何字节,即afaik(如果我是错的。

与其他提交一样,使用

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

(至少在我的系统上)GCC将接受单引号中的任何字节,但10(\n)和13(\r)除外。零字节将编译正常,但显示错误消息warning: null character(s) preserved in literal
r3mainer 2014年

@squeamishossifrage谢谢,已修复!
Martin Ender 2014年

3

代码:Mathematica,输出:朱莉娅,〜98.9457%(20177/20392字节)

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 <> ""]]

请注意,其中的一些优化假定您使用的是64位Julia,因此int64默认情况下,整数文字会为您提供一个。否则,无论如何您都会溢出大于2 31的整数。使用该假设,我们可以应用一些优化,其中间步骤实际上甚至大于2 32

编辑:我添加了OP的示例中建议的优化,以科学计数形式对两个大数进行按位(实际上,对于所有xororand)。需要注意的是扩展xormapormapandmap包括超过2个操作数32可能有助于找到额外的优化,但它不会工作,为给定的测试用例,并只能通过类似的10倍运行时间的增加。

编辑:通过检查所有这些n-9, n-8, ..., n+8, n+9是否可以缩短,我又减少了16个字节,在这种情况下,我基于此表示了数字,加上或减去了差值。在某些情况下,这18个数字之一可以用比其本身少3个或更多字符来表示,在这种情况下,我可以节省一些额外的费用。现在,在所有测试用例上运行它大约需要30秒钟,但是,当然,如果有人实际上“使用”了此功能,则他只会在单个数字上运行它,因此距离一秒钟还不错。n

编辑:另一个令人难以置信的4字节,用于乘法和除法。现在是50秒(分开的时间不需要那么长,因为我只检查这些数字是否实际上可以被感兴趣的因子整除)。

编辑:另一个实际上对给定测试集没有帮助的优化。这个可以为诸如2 30或2 31之类的内容节省一个字节。如果我们使用uint64s,那么会有很多数字可以节省很多钱(基本上,每当比特表示以1结束时)。

编辑:删除了XOR或者最佳化完全。我只是注意到它们甚至在Julia中也不起作用,因为(很明显)科学计数法为您提供了一个甚至未定义按位运算符的浮点数。有趣的是,一个或多个较新的优化似乎可以涵盖所有因这些优化而缩短的情况,因为分数完全没有变化。


1

J到C(未经测试,但在大多数情况下有效,是一种基准答案。)

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

输出一个字符串文字,如果在C中输入,则代表数字(如OP中所述)。这不是认真的建议,而是我想分享的可以增强我的J技能的东西。

替代单线:

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

当您输入J时,它会尝试这样做:

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

多谢J。此外,对于那些了解J的人来说,visio可以创建更复杂的函数:

在此处输入图片说明


既然不能读取任何的那样:这是什么做的,如果字符是不可打印的,或者性格\ ?还是'
Martin Ender 2014年

@ m.buettner没有(还),我还是要建立一些为
ɐɔıʇǝɥʇuʎs

代替m&u@:v,用于m u v保存宝贵的字符并增强可读性。将其应用到你的代码中,我们得到了f =: [: (,~ 0 $~ 8 - 8 | #) #:g =: [: ($~ 8 ,~ # % 8:) f和最后toCString =: a. {~ [: #. g。我们得到的所有组合a. {~ [: #. [: ($~ 8 ,~ # % 8:) [: (,~ 0 $~ 8 - 8 | #) #:,真的很容易阅读。
FUZxxl 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.