Julia : 如何生成一个水仙花数?

上一篇写了Rust版本的产生水仙花数的尝试,如果用Julia来写一下,会有什么不同?

function get_nums(n::Int64)
    str =string(n);
    len =length(str)
    nums =Int64[]
    for i =1:len
        push!(nums,parse(Int64,str[i]))
    end
    return nums,len;
end
function is_fit_num(n::Int64)
    nums,len =get_nums(n);
    return sum(nums.^len)==n
end

list =100:1:9000000;
@time data =[x for x in list if is_fit_num(x)]

output: 13个水仙花数的运行情况

  2.985466 seconds (63.00 M allocations: 4.008 GiB, 17.54% gc time)
list =100:1:50000000;

output: 17个水仙花数的运行情况

 17.599224 seconds (350.00 M allocations: 22.337 GiB, 16.64% gc time)

和Rust的比较:可见Rust是优势较大。

这里写图片描述

尝试一:改成下面的方式,效率也差不多:

list =100:1:50000000;
function get_result(list)
    vec =Int64[]
    for i in list
       if is_fit_num(i)
           push!(vec,i);
       end
    end
    return vec
end
@time  get_result(list)

尝试二:启用digits函数

Julia内置了一个digits函数,如,可以把5016,拆成5,0,1,6四个数字。这样,我们就不用手写一个了。

1、更简洁方式
如果是追求代码短小,你完全可以一行搞定:

@time data =[x for x in list if sum(digits(x).^length(digits(x)))==x]

代价是,速度并没有提升,还是在原来17秒的水平上(17位水仙花数)。

2、更快的方式
重要的是:

因此,优化后的程序:(digits/@inline两个方面)

function get_nums(n::Int64)  # 在函数前面可以加@inline
    nums =digits(n)
    return nums,length(nums);
end
function is_fit_num(n::Int64)  # 在函数前面可以加@inline
    nums,len =get_nums(n);
    return sum(nums.^len)==n
end

list =100:1:50000000;
@time data =[x for x in list if is_fit_num(x)]

这样,可以从原来17秒的基础上,优化到11秒左右。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值