视网膜,56 37字节
该解决方案适用于所有必需的输入值。
Retina在此挑战中面临的最大问题是其字符串的最大长度为2 ^ 30个字符,因此处理数字(一元表示)的通常方法不适用于大于2 ^ 30的值。
为了解决此问题,我采用了另一种方法,即保留一种数字的十进制表示形式,但是其中的每个数字都以一进制表示(我将其表示为digitunary)。例如,数字341
将以数字形式书写111#1111#1#
。有了这种表示形式,我们现在可以使用不超过2^30/10
数位(约一亿位数)的数字。对于任意算术而言,它不如标准一元代码实用,但是通过一些努力,我们可以执行任何类型的运算。
注意:理论上,数字二进制可以使用任何其他基数(例如,二进制110
将以1#1##
2 进制数字二进制为基数),但是由于Retina具有内置函数可以在十进制和一进制之间进行转换,并且没有直接处理其他基数的方法,因此十进制可能是最易于管理的基数。
我使用的算法是将连续的整数除以2,直到达到零为止,除法的次数就是表示该数字所需的位数。
那么,我们如何将数字除以二呢?这是做到这一点的Retina片段:
(1*)(1?)\1# We divide one digit, the first group captures the result, the second group captures the remainder
$1#$2$2$2$2$2 The result is put in place of the old number, the remainder passes to the next digit (so it is multiplied by 10) and is divided by two there -> 5 times the remainder goes to the next digit
这种替换足以将一个数字除以2,如果原始数字是奇数,我们只需要从末尾删除可能的.5s。
因此,这是完整的代码,我们不断除以2,直到数字中仍然有数字为止,并n
在每次迭代时在字符串前放置一个常量:最后的数字n
是结果。
. |
$*1# Convert to digitunary
{`^(.*1) Loop:|
n$1 add an 'n'
(1*)(1?)\1# |
$1#$2$2$2$2$2 divide by 2
)`#1*$ |
# erase leftovers
n Return the number of 'n's in the string
在线尝试!
更新的解决方案,37字节
借助Martin Ender,大量重构了很多好的创意,这些创意大约占了三分之一。
主要思想是_
用作我们的一元符号:通过这种方式,我们可以在字符串中使用常规数字,只要我们_
在需要时将它们转换回s即可:这样可以节省除法和插入多个字节的字节数。数字。
这是代码:
<empty line> |
# put a # before each digit and at the end of the string
{`\d Loop:|
$*_ Replace each digit with the corrisponding number of _
1`_ |
n_ Add an 'n' before the first _
__ |
1 Division by 2 (two _s become a 1)
_# |
#5 Wherever there is a remainder, add 5 to the next digit
}`5$ |
Remove the final 5 you get when you divide odd numbers
n Return the number of 'n's in the string
在线尝试!