奇数金字塔,你想得出来最佳解答吗?Ruby 30 天刷题修行篇第七话

大家好,我是 A Fei,又到了我们愉快的解题时间,这次我们要来做一道数列的题型。废话不多说,直接进入题目:

(题目来源为 Codewars


Given the triangle of consecutive odd numbers:

             1
          3     5
       7     9    11
   13    15    17    19
21    23    25    27    29
...

Calculate the sum of the numbers in the nth row of this triangle (starting at index 1) e.g.: (Input --> Output)

1 -->  1
2 --> 3 + 5 = 8

题目给你一个奇数数列的金字塔(或圣诞树),要我们算出第 n 阶上数字的总和。虽然这次题目叙述简单明了,很棒,但是我却解超~级~久~反覆尝试将数列画在纸上,想找出其中的规律,像是每一层第一个数相差 2, 4, 6, 8...,有规律但实在想不出解法,这时候就很佩服「数感」很好的人。

但我最後还是想出来了,耶!

以下为我的解答:

def row_sum_odd_numbers(n)
  x = (1..n).inject(:+)
  odd_arr = (1..x).map {|i| 2 * i - 1}
  y = x - n
  odd_arr[y, n].sum
end

让我来为各位解说,x 代表的是「奇数数列的长度」,第一层有一个数(1)、第二层有三个数(1 + 2 = 3),以此类推。这边用的 inject 就是大家熟悉的 reduce 方法,而 inject(:+) 就是总合的写法,这个官网的范例有教,值得注意的是 inject 是属於 Enumerable 类别下的方法,所以 Array 也可以使用。

接着把 1 ~ x 用 map ,将每个数字换算成奇数,当 n 带入 1 时,odd_arr 为 [1]、当 n 带入 2 时,odd_arr 为 [1, 3, 5],以此类推。到这里我们已经可以得到,第 n 层时,所有会出现的奇数。

最後再把数列的长度 x 减去 n,会得到第 n 层第一个数的索引值 y(这题变数的命名都很随便,请见谅),之後再用 odd_arr[y, n] 撷取出第 y 个值後 n 长度的阵列,再使阵列中的元素相加,就得到答案了!

当我还在沉浸破关的喜悦时,看到最佳解答瞬间让我跌破眼镜...

def row_sum_odd_numbers(n)
  n**3
end

n 的三次方...
n 的三次方...
n 的三次方...

马上试算了一下,还真的是这样,自己绕了一大圈原来最佳解答这麽「朴素」,可恶,最讨厌「数感」好的人啦~


<<:  [Day9] - Docker Compose 介绍与实作

>>:  [Part 1 ] Vue.js 的精随-元件

Day-8 Divide-and-Conquer-3 : 二分搜寻法, 费波那契数列, Strassen’s演算法

二分搜寻法(Binary Search) 前提,在一个已经排序完成的A阵列中 Divide : 元素...

Day7 — GPIO 功能

GPIO 全文为 General purpose input/output,在微控制器当中通常具有控...

Gulp bower(1) DAY85

bower??? 什麽是 bower?? https://bower.io/ bower 为前端套...

[Day29]C# 鸡础观念- 物件导向(oop)~介面(Interface)

书同文,车同轨, 听说召唤恶魔时,需要与恶魔签订契约, 契约内容双方都得遵守, C#也拥有跟类别签订...

【Day27】:STM32实际应用1—马达精准控速(PID初浅教学(上))

前言 这里要先声明,我没有修过专业的控制相关课程,如果想要学习更专业的PID相关内容可能这里不适合,...