2022年5月21日 番外編アルゴ式
今回の問題
- 配列の要素と右隣の数字を比較して右隣が大きいケースの回数をカウントするという内容です。
解答
yano's answer
- Array.prototype.reduce()を使用しました。
- countを出す・配列のindexを使って操作する点などでreduceが妥当と判断しました。
//(入力受け取り 省略) type CountUpNumberInArray = { (numArray: number[]): number } const countUpNumberInArray: CountUpNumberInArray = (numArray) => numArray.reduce((accumulator, currentValue, index, array) => { return array[index] < array[index + 1] ? accumulator += 1 : accumulator += 0 }, 0); console.log(countUpNumberInArray(a));
- 関数式の後にreturnを書いた方がわかりやすいかもしれません。
- reduceの第二引数は使用しないため、アンダースコアで省略した方がいいです。
修正
const countUpNumberInArray: CountUpNumberInArray = (numArray) => { return numArray.reduce((accumulator, _, index, array) => { return array[index] < array[index + 1] ? accumulator += 1 : accumulator += 0 }, 0); }
- 命名ももう少し拘れると良さそうです。
Rubyでやってみる
- for in文パターン
n = gets.to_i a = gets.split.map(&:to_i) count = 0 for i in 0..n do count += 1 if a[i].to_i < a[i + 1].to_i end puts count
- each_with_indexパターン
- to_iを書くことでnilが発生した際に0に変換することでエラーを防ぐことができます。
- https://docs.ruby-lang.org/ja/latest/method/NilClass/i/to_i.html
n = gets.to_i a = gets.split.map(&:to_i) count = 0 a.each_with_index do |value, index| count += 1 if a[index] < a[index +1].to_i if index == a.size - 1 puts count end end
yuki's answer
- 素早く命名するのが苦手だと感じました。今後、改善していきます。(現時点の命名も本当に分かりやすいか疑問)
- reduceを使えば、配列の2つの要素を比べられるので、reduceを使えば良かったです。関数型プログラミングをなるべく自分のコードに取り入れたいと思いました。
import * as fs from 'fs' const input = fs.readFileSync("/dev/stdin", "utf8") const [nv, alist] = input.split("\n") const [n, ..._] = nv.split(" ").map(Number) const list = alist.split(" ").map(Number) const countRightThanLeft = (list: number[]): number => { let count = 0; for (let i = 1; i < list.length; i++) { if (list[i-1] < list[i]) { count++; } } return count; } console.log(countRightThanLeft(list));
yui's answer
import * as fs from 'fs' const input = fs.readFileSync("/dev/stdin", "utf8") const [nv, alist] = input.split("\n") const [n,v,..._] = nv.split(" ").map(Number) const list = alist.split(" ").map(Number) type ArrayType = { (previousValue: number, currentValue: number, currentIndex: number, array: number[]): number; } const reducer: ArrayType = (previousValue, _, currentIndex, array) => { const count = (array[currentIndex] < array[currentIndex + 1]) ? 1 : 0; const returnNumber = previousValue + count; return returnNumber; } console.log(list.reduce(reducer, 0));
- 今回は、2つの要素の値を比較したいので
reduce()
を使いました。 reduceメソッドは、配列のそれぞれの要素に対して、順番通りに、コールバック関数を呼び出します。コールバック関数の引数には、
累積値, 要素, インデックス, 配列
を渡すことが出来ます。配列のすべての要素に対してコールバック関数を実行した結果が戻り値となります。関数の引数として、アンダーバー
_
が使われている記述があります。これは、使われない引数であることを明示しています。使われない値であるが、単純に引数として書く必要があるため、アンダーバーを使用しています。