Live Note

Remain optimistic

一道有趣的题目

在 CodeWars 上遇见的一道 3kyu 的题目

** Task **
You’re given an array of integers a and two integers x and y. Count the number of elements in the array such that x ≤ a[i] ≤ y, where i is the 0-based index of the element.

** Code Limit **
Less than 48 characters.

** Example **
For a = [2, 5, 6, 7, 1, 3, 4, 11, 56, 49], x = 1 and y = 7,

the output should be 7.

elements 2, 5, 6, 7, 1, 3, 4 should be counted.

这道题有趣的地方在于,代码长度限制在 48 个字符内。
最开始我用的是 forEach 去遍历,结果长度超出了一倍,后面考虑用 filter:

1
checkRange = (a, x, y) => a.filter((e) => e >= x && e <= y).length

但是此时代码长度也有 50,考虑使用 map 来改造,但是 map 和 filter 不一样,数组的长度无法改变,所以就考虑使用一个变量来统计。

1
2
3
4
// 在 JS 中数值与 true 相加会使得结果增加一,所以可以考虑使用变量来与判断的结果相加。
// i=0 未定义,在此是全局变量。
// Array | Number => parseInt(Array) | Number => NaN | Number => Number, 所以 i 就被返回出去了
checkRange = (a, x, y) => a.map((e) => (i += x <= e && e <= y), (i = 0)) | i

但是此时长度还是不够,问题在于 x<=e&&x<=y 这。
仔细分析可知,不满足条件的话,有两种情况,第一种就是 a[i] < x,第二种是 a[i] > y
所以只要 a[i] < x && a[i] > y 的结果为 false 的话 那么就是不满足条件的。
此时可以改造为 x > a[i] == a[i] > y

  1. a[i] < x < y => true == false => false
  2. x < y < a[i] => false == true => false
  3. x < a[i] < y => false == false => true

此时满足条件。

最后答案为:

1
checkRange = (a, x, y) => a.map((e) => (i += x > e == e > y), (i = 0)) | i