質問するログイン新規登録

回答編集履歴

3

ちょっと追記

2016/09/27 12:16

投稿

raccy
raccy

スコア21800

answer CHANGED
@@ -46,4 +46,6 @@
46
46
  * 単純な添字ループであれば`i`でもかまいませんが、複雑な処理になる場合は、何を意味する物かを示すように変数名を与えてください。`j`についても同様です。また、`cnt`はカウンタと言うよりも数の和です。`total`などにしたほうがわかりやすいでしょう。
47
47
  * 配列の長さが固定でない場合を想定してください。
48
48
  * マジックナンバーを使用しないでください。最初に`hrt_size = $hrt.size`などし、`9`は`hrt_size - 2`、`10`は`hrt_size - 1`などと表現してください。
49
- * 一つのメソッドにおいて、行数が多く、また、インデントが深すぎです。メソッドの分離を検討してください。
49
+ * 一つのメソッドにおいて、行数が多く、また、インデントが深すぎです。メソッドの分離を検討してください。
50
+
51
+ 色々書いてしましたが、私が10年以上前に最初に書いていたRubyのコードもこんな物でした。焦らずに、少しずつ慣れていけば良いのですから。

2

2\.3\.xに対応

2016/09/27 12:16

投稿

raccy
raccy

スコア21800

answer CHANGED
@@ -1,14 +1,21 @@
1
- Ruby 2.4.0-preview2 (2.3.x下で動きません)
1
+ Ruby 2.3系に対応しました。lambda_driverとactivesupportが必要です(2.4.0上の場合activesupportは不要)。`gem instnall lambda_driver activesupport`でインストールしてから実行してください。
2
+
3
+ 主な変更点: `chunk`ではなく`slice_before`で切るようにしました。lambda_driverで関数合成するようにしました。`Enumerable#sum`は2.4.0からのため、2.3系についてはactivesupportの実装を使うようにしました。
4
+
2
5
  ```Ruby
6
+ # frozen_string_literal: true
7
+ require 'lambda_driver'
8
+ require 'active_support/core_ext/enumerable' if RUBY_VERSION < '2.4.0'
9
+
3
10
  def yyyy(hrt)
4
11
  hrt.each_with_index
5
- .chunk { |v, _i| v.zero? }
12
+ .slice_before(&:first >> :zero?)
6
- .find { |r, a| !r && -> (x) { x.sum == 4 && x != [2, 2] }[a.map(&:first)] }
13
+ .find { |a| -> (x) { x.sum == 4 && x != [0, 2, 2] } < a.map(&:first) }
7
- &.last&.inject(0) do |r, vi|
14
+ &.inject do |r, vi|
8
15
  case vi.first
9
16
  when 1 then vi.last
10
17
  when 2, 4 then break vi.last
11
- when 3 then r
18
+ else r
12
19
  end
13
20
  end || -1
14
21
  end
@@ -20,4 +27,23 @@
20
27
  puts yyyy([0,1,1,0,2,0,1,3,0,1,0])
21
28
  ```
22
29
 
30
+ バージョン比較の部分は2.10.0とか出たときは対応できないバグがありますが、その前に3.0.0が出ることを期待して…。
31
+
32
+ ---
33
+ 【質問のコードのレビュー】
34
+
35
+ すいません、全く違う作りにしてしまった理由というか、質問のコードについて指摘事項を羅列します。
36
+
37
+ * Ruby 1.9.4は既にサポートされていません。バグが原因で動かない場合や脆弱性が発生した場合、誰も助けることはできません。サポートされたRubyのバージョンを使用してください。現在サポートされているのは、2.3系、2.2系、2.1系(ただしセキュリティ修正のみ)です。
38
+ * グローバル変数は、グローバル変数を使わなければ実現できない等のどうしても必要な理由が無い限り、使用しないでください。
39
+ * ループは一方向のみにしてください。添字のiが増えたり減ったりすることはわかりにくく、バグの温床になります。高速なアルゴリズムを実現するなどの目的が無い限り、増える方向、または、減る方向のみに絞ってください。
40
+ * 添字のループは`Integer#times`や`Range#each`を使ってください。`while`は数がわからないと言う事情が無い限り、極力避けてください。かといって、代わりに`for in`を使うことは避けてください。`for in`は`each`との違いが理解できない限り、使用しないでください。`for in`で無ければならないことはほとんどありません。
41
+ * 配列を順番に見るときは、`Array#each`を使ってください。添字が必要であれば`Array#each_with_index`を使ってください。
42
+ * `i = i + 1`は`i += 1`と書いてください。他の部分も、複合代入演算子を使用してください。
23
- もうちょっと、工夫したい。合成関数とか使って(Rubyど)
43
+ * 同じ行式が続くので無ければ、`then`は不要です
44
+ * 何もしない`else`は不要です。
45
+ * `if X == a then ... elsif X == b then ... elsif X == c then ... else ... end`と言う形の場合は、case文を使用してください。
46
+ * 単純な添字ループであれば`i`でもかまいませんが、複雑な処理になる場合は、何を意味する物かを示すように変数名を与えてください。`j`についても同様です。また、`cnt`はカウンタと言うよりも数の和です。`total`などにしたほうがわかりやすいでしょう。
47
+ * 配列の長さが固定でない場合を想定してください。
48
+ * マジックナンバーを使用しないでください。最初に`hrt_size = $hrt.size`などし、`9`は`hrt_size - 2`、`10`は`hrt_size - 1`などと表現してください。
49
+ * 一つのメソッドにおいて、行数が多く、また、インデントが深すぎです。メソッドの分離を検討してください。

1

findつかえば一発じゃ無いか!何をオレは…

2016/09/27 12:03

投稿

raccy
raccy

スコア21800

answer CHANGED
@@ -2,9 +2,9 @@
2
2
  ```Ruby
3
3
  def yyyy(hrt)
4
4
  hrt.each_with_index
5
- .chunk { |v, _i| v.zero? }.reject(&:first).map(&:last)
5
+ .chunk { |v, _i| v.zero? }
6
- .select { |a| -> (x) { x.sum == 4 && x != [2, 2] }[a.map(&:first)] }
6
+ .find { |r, a| !r && -> (x) { x.sum == 4 && x != [2, 2] }[a.map(&:first)] }
7
- .first&.inject(0) do |r, vi|
7
+ &.last&.inject(0) do |r, vi|
8
8
  case vi.first
9
9
  when 1 then vi.last
10
10
  when 2, 4 then break vi.last