Answers:
作为未命名的lambda,修改其输入:
[](int&n){int i=n;while(--n)i*=n;do n+=i%10;while(i/=10);}
我的C ++代码比C代码短的罕见情况之一。
如果要支持更大的情况,请切换到C ++ 14并使用:
[](auto&n){auto i=n;while(--n)i*=n;do n+=i%10;while(i/=10);}
并提供带有ull
后缀的调用参数。
用法:
auto f=
[](int&n){int i=n;while(--n)i*=n;do n+=i%10;while(i/=10);}
;
main() {
int n=10;
f(n);
printf("%d\n",n);
}
通过操作的新方法:
->n{eval"#{(1..n).reduce:*}".chars*?+}
旧:
->n{(1..n).reduce(:*).to_s.chars.map(&:hex).reduce:+}
eval
方式:->n{eval"#{(1..n).reduce:*}".chars*?+}
。
编辑:感谢@Jonathan Carroll保存了一个字节,感谢@Micky T保存了两个字节
sum(as.double(el(strsplit(c(prod(1:scan()),""),""))))
不幸的是,对于32位整数,这仅适用于n < 22
。从stdin接受输入,然后输出到stdout。
如果希望更高的精度,则必须使用一些外部库,例如Rmpfr
:
sum(as.numeric(el(strsplit(paste(factorial(Rmpfr::mpfr(scan()))),""))))
c(x,"")
vs paste(x)
:获得了1个字节的增益sum(as.integer(el(strsplit(c(factorial(scan()),""),""))))
。将阶乘结果强制转换为character strsplit
并将其作为第二个列表返回,因此el
仍然可以工作并提取第一个列表元素。
prod(1:scan())
?
as.double
应该足够
strtoi
as.double
我认为可以作为较短的替代品。
int s=1,ret=0;while(i>1){s=s*i; i--;}String y=String.valueOf(s);for(int j=0;j<y.length();j++){ret+=Integer.parseInt(y.substring(j,j+1));}return ret;
当然不是最优雅的,但是挑战
seq -s\* $1|bc|fold -1|jq -s add
fold -1
保存一个字节。
这不是完美的。仅适用于a,因为a开头必须为-1。这个想法是在一个函数中使用两个递归函数。这并不像我最初想象的那么容易。
a=-1;k(i){a=a<0?i-1:a;return a?k(i*a--):i?i%10+k(i/10):0;}
用法和可理解的格式:
a = -1;
k(i){
a = a<0 ? i-1 : a;
return a ? k(i*a--) : i? i%10+k(i/10) :0;
}
main() {
printf("%d\n",k(10));
}
编辑:我发现让多次使用此功能的方法,但长度为62个字节。
a,b;k(i){a=b?a:i+(--b);return a?k(i*a--):i?i%10+k(i/10):++b;}
{[+] [*](2..$_).comb}
{ # bare block lambda with implicit parameter 「$_」
[+] # reduce the following with 「&infix:<+>」
[*]( # reduce with 「&infix:<*>」
2 .. $_ # a Range that include the numbers from 2 to the input (inclusive)
).comb # split the product into digits
}
u*.$s.!(.01I^<W%NW!;<,;;q+p@Opus
净形式:
u * .
$ s .
! ( .
0 1 I ^ < W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
Infinity
数字(从技术上讲,它是window对象的不可写,不可枚举和不可配置的属性)。该程序包含两个循环。第一个计算输入的阶乘,另一个将结果拆分为数字并将它们相加。然后打印总和,程序结束。
首先,我们需要准备堆栈。对于这一部分,我们使用前三个说明。IP从第四行开始,指向东。堆栈为空。
. . .
. . .
. . .
0 1 I . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
我们将总和保留在堆栈的最底部,因此我们需要从0
将总和存储在堆栈的底部开始。然后,我们需要推送一个1
,因为输入将首先乘以之前的数字。如果为零,则阶乘也将始终产生零。最后,我们将输入读取为整数。
现在,堆栈位于[0, 1, input]
,IP位于第四行,第四列,指向东。
这是一个简单的循环,它将堆栈的前两个元素(前一个循环的结果和输入-n相乘),然后递减输入。当输入达到0时中断。$
指令使IP跳过u
-循环是多维数据集的以下部分,IP从第四行第四列开始。
u * .
$ s .
! ( .
. . . ^ < . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . .
. . .
. . .
由于^
字符的原因,IP立即开始向北移动。然后,u
将IP转过来并将其向右移动一个。在底部,还有另一个箭头:<
将IP指向^
。堆栈从开始[previousresult, input-n]
,其中n
是迭代次数。在循环中执行以下字符:
*s(
* # Multiply the top two items
# Stack: [previousresult, input-n, newresult]
s # Swap the top two items
# Stack: [previousresult, newresult, input-n]
( # Decrement the top item
# Stack: [previousresult, newresult, input-n-1]
然后0
,根据!
指令检查堆栈的顶部(输入减少),如果为0
,u
则跳过该字符。
IP环绕立方体,最后到第四行的最后一个字符,最初指向西。以下循环几乎包含所有剩余字符:
. . .
. . .
. . .
. . . . . W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
. . .
. . .
. . .
循环首先从堆栈中删除最上面的项(10
或0
),然后检查阶乘结果的剩余内容。如果减小到0
,则打印堆栈的底部(总和),然后程序停止。否则,将执行以下指令(堆栈以开头[oldsum, ..., factorial]
):
N%p+q;;,s;
N # Push 10
# Stack: [oldsum, ..., factorial, 10]
% # Push factorial % 10
# Stack: [oldsum, ..., factorial, 10, factorial % 10]
p # Take the sum to the top
# Stack: [..., factorial, 10, factorial % 10, oldsum]
+ # Add top items together
# Stack: [..., factorial, 10, factorial % 10, oldsum, newsum]
q # Send that to the bottom
# Stack: [newsum, ..., factorial, 10, factorial % 10, oldsum]
;; # Delete top two items
# Stack: [newsum, ..., factorial, 10]
, # Integer divide top two items
# Stack: [newsum, ..., factorial, 10, factorial/10]
s; # Delete the second item
# Stack: [newsum, ..., factorial, factorial/10]
循环再次开始,直到factorial/10
等于0。
@set/af=1,t=0
@for /l %%i in (1,1,%1)do @set/af*=%%i
:g
@set/at+=f%%10,f/=10
@if %f% gtr 0 goto g
@echo %t%
方便地set/a
处理变量的当前值,因此它通常在循环内工作。由于Batch整数类型的限制,最多只能使用12个,因此理论上我可以通过假设f<1e9
以下内容来保存一个字节:
@set/af=1,t=0
@for /l %%i in (1,1,%1)do @set/af*=%%i
@for /l %%i in (1,1,9)do @set/at+=f%%10,f/=10
@echo %t%
但这就是疯狂。在这种情况下,我不妨对列表进行硬编码(97字节):
@call:l %1 1 1 2 6 6 3 9 9 9 27 27 36 27
@exit/b
:l
@for /l %%i in (1,1,%1)do @shift
@echo %2
保存的2个字节用于使用get而不是引号。这使我将前2行移到1以上,减少了不必要的空白。
&#:<_v#:-1
: \*$<:_^#
g::v>91+%+00
_v#<^p00</+19
@>$$.
说明:
&#:< Gets an integer input (n), and reverses flow direction
&#:< _v#:-1 Pushes n through 0 onto the stack (descending order)
: \*$<:_^# Throws the 0 away and multiplies all the remaining numbers together
(reorganized to better show program flow):
vp00< /+19 _v#< Stores the factorial at cell (0, 0). Pushes 3 of whatever's in
> 91+%+ 00g ::^ cell (0, 0). Pops a, and stores a / 10 at (0, 0),
and adds a % 10 to the sum.
@>$$. Simply discards 2 unneeded 0s and prints the sum.
n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
编辑:谢谢Hedi和ETHproductions削减了7个字节。我必须记住t-=-j的把戏。
n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
感谢科尔节省了1个字节!
1#.10#.inv!
这简单地将sum(1#.
)应用于数字(使用反inv
参数的阶乘()基数转换的,#.
底数为10
)!
。
注意:最后两个测试用例是bigints,用尾随标记x
。
f=:10#.inv!
(,. f"0) 10 19 469x 985x
10 27
19 45
469 4140
985 10053
"."0":
用来获取数字
1#.,.&.":@!
在较小的情况下也需要扩展精度(不确定原因)。也是11个字节:1#.10#.inv!
。
-3个字节用于do...while
循环。
i;f(n){i=n;while(--n)i*=n;do n+=i%10;while(i/=10);return n;}
脱胶和用法:
i;
f(n){
i=n;
while(--n)
i*=n;
do
n+=i%10;
while(i/=10);
return n;
}
main() {
printf("%d\n",f(10));
}
int
默认将f(n)定义为?
int
假定为。
n>21