GNU sed,377362 + 1(r标志)= 363字节
警告:程序将耗尽所有试图运行的系统内存,并且需要比您愿意等待的时间更多的时间来完成!请参阅下面的说明和快速但不太精确的版本。
s:\.|$:,,,,,,,,:;:i;s:,(,+)(\w):\2\1:;ti
h;:;s:\w::2g;y:9876543210:87654321\t :;/ /!s:,:@,:;/\s/!t;x;s:-?.::;x;G;s:,.*::m;s:\s::g;/\w/{s:@+:&&&&&&&&&&:;t}
/@,-?@/!{s:^:10000000,:;h;t}
:l;s:(@+)(,-?\1):\2;:;tl;s:,::;s:@+;?@+::
s:-?:&0:;:c;s:\b9+:0&:;s:.9*;:/&:;h;s:.*/::;y:0123456789:1234567890:;x;s:/.*::;G;s:\n::;s:;::;/;/tc
:f;s:(\w)(,+),:\2\1:;tf;s:,:.:;y:,:0:
这是基于马丁·恩德(Martin Ender)对视网膜的回答。我\t
从第2行算起文字标签(1个字节)。
我的主要贡献是从十进制到普通一元数的转换方法(第2行),反之亦然(第5行)。与上一个技巧中显示的方法相比,我设法大大减少了执行此操作所需的代码大小(减少了约40个字节)。我用详细信息创建了一个单独的提示答案,在其中提供了可供使用的摘要。由于不允许输入0,因此节省了更多字节。
说明:为了更好地理解除法算法,请先阅读视网膜答案
该程序在理论上是正确的,之所以要消耗大量的计算资源,是因为除法步骤要运行数十万次,或多或少取决于输入,并且所使用的正则表达式引起了回溯的噩梦。快速版本会降低精度(因此会增加除法步数),并更改正则表达式以减少回溯。
不幸的是,sed没有像Retina这样的方法直接计算后向引用适合某种模式的次数。
s:\.|$:,,,,,,,,: # replace decimal point or end of string with 8 commas
:i # loop to generate integer (useful for unary division)
s:,(,+)(\w):\2\1: # move 1 digit in front of commas, and delete 1 comma
ti # repeat (':i')
h;: # backup pattern and start decimal to unary conversion
s:\w::2g # delete decimal digits, except the first (GNU magic)
y:9876543210:87654321\t :; # transliterate characters
/ /!s:,:@,: # if no space is present, append a unary digit ('@')
/\s/!t # if no whitespace is present, go back to ':'
x;s:-?.::;x # delete first digit and the negative sign from backup
G;s:,.*::m;s:\s::g # append backup, delete whitespace and duplicate stuff
/\w/{s:@+:&&&&&&&&&&: # if decimal digit left, multiply unary number by 10
t} # and repeat (':')
/@,-?@/!{ # if only one unary number found (the input)
s:^:10000000,: # prepend decimal 10^7 separated by a comma
h;t} # backup pattern and convert new number to unary also
:l # start unary division loop (tons of RAM and time!!!)
s:(@+)(,-?\1):\2;: # delete as many '@'s from 10^7, as found in unary
#input, and add one ';' (new unary digit)
tl # repeat (':l')
s:,::;s:@+;?@+:: # delete leftover stuff
s:-?:&0:;:c # prepend zero and start unary to decimal conversion
s:\b9+:0&: # if only 9s found, prepend zero to them
s:.9*;:/&: # separate the digit(s) that would change on increment
h;s:.*/:: # backup, delete all (non-changing) digits (till '/')
y:0123456789:1234567890: # increment changing digit(s)
x;s:/.*:: # delete changing digits from backup
G;s:\n:: # append backup, delete newline
s:;:: # delete one unary digit (';')
/;/tc # if unary portion left, repeat (':c')
:f # loop to generate floating-point number
s:(\w)(,+),:\2\1: # move 1 digit after the commas, and delete 1 comma
tf # repeat (':f')
s:,:.: # turn first comma into a decimal point
y:,:0: # turn the rest of commas into zeroes (final result)
# implicit printing
要获得该程序的快速和安全版本,但要降低精度,可以在线进行尝试。