原题地址:
https://www.codewars.com/kata/trailing-zeros-in-factorials-in-any-given-integer-base/train/ruby
最开始没有仔细思考,先计算阶乘,再统计0的个数,但测试用例中包括大数情况,例如:
trailing_zeros(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000, 100)
,很明显这种算法无法实现。
后来经过查询,在https://www.cnblogs.com/hutonm/p/5624996.html 发现了新思路;
最新算法:
def trailing_zeros(num, base)
start = Time.now
arr = list(base)
# puts "time_list:#{(Time.now - start) * 1000}"
brr = Hash.new(0)
arr.each do |item|
brr[item] = figure(num, item)
end
# puts "time_figure:#{Time.now - start}"
uniq_arr = arr.uniq
counter = Hash.new(0)
arr.each {|val| counter[val] += 1}
# puts "time_counter:#{Time.now - start}"
crr = []
brr.each do |key, value|
crr.push(value / counter[key])
end
# puts "time_crr:#{Time.now - start}"
crr.min
# puts "time_total:#{Time.now - start}"
end
def figure(num, item)
num >= item ? num / item + figure(num / item, item) : 0
end
def list(base)
i = 2
j = 0
arr = []
while (base > 1) do
if base % i == 0
max = i
while base % i == 0
base /= i
arr[j] = max
j += 1
end
end
i += 1
end
return arr
end
经过测试:
require 'benchmark'
Benchmark.bmbm(10) do |t|
t.report{puts trailing_zeros(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000, 100)}
t.report{puts trailing_zeros(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000, 100)}
t.report{puts trailing_zeros(93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000, 100)}
end
结果如下:
Rehearsal ----------------------------------------------
11665776930493019085212404857033337561339496033047702683574120486902199999153739451117682997019564785781712240103402969781398151364607999999999999999999999950
0.000000 0.000000 0.000000 ( 0.003088)
11665776930493019085212404857033337561339496033047702683574120486902199999153739451117682997019564785781712240103402969781398151364607999999999999999999999950
0.010000 0.000000 0.010000 ( 0.002103)
11665776930493019085212404857033337561339496033047702683574120486902199999153739451117682997019564785781712240103402969781398151364607999999999999999999999950
0.000000 0.000000 0.000000 ( 0.002209)
------------------------------------- total: 0.010000sec
user system total real
11665776930493019085212404857033337561339496033047702683574120486902199999153739451117682997019564785781712240103402969781398151364607999999999999999999999950
0.000000 0.000000 0.000000 ( 0.001200)
11665776930493019085212404857033337561339496033047702683574120486902199999153739451117682997019564785781712240103402969781398151364607999999999999999999999950
0.000000 0.000000 0.000000 ( 0.001220)
11665776930493019085212404857033337561339496033047702683574120486902199999153739451117682997019564785781712240103402969781398151364607999999999999999999999950
0.000000 0.000000 0.000000 ( 0.001380)
每次运行时间在1.5ms以内。
但是还是不符合题目要求,提交反馈结果如下:
Process was terminated. It took longer than 12000ms to complete
尝试优化list()方法,优化效果不明显:
# return the number of trailing zeros in num! (base)
def trailing_zeros(num, base)
arr = list(base)
brr = Hash.new(0)
arr.each_key do |key|
brr[key] = figure(num, key)
end
crr = []
brr.each do |key, value|
crr.push(value / arr[key])
end
crr.min
end
def figure(num, item)
num >= item ? num / item + figure(num / item, item) : 0
end
def list(base)
i = 2
hash = Hash.new(0)
while (base > 1) do
count = 0
if base % i == 0
while base % i == 0
base /= i
count += 1
end
hash[i] = count
end
i += 1
end
return hash
end
待更新。。。。