2016-11-15 14 views
0

だから私は、現在のコードの戦争で次のような問題に取り組んでいます:カウント/ネガの合計構文エラーが

戻る最初の要素が正の数のカウントと2番目の要素がある配列、の和であります負の数。入力配列が空またはnullの場合は、空の配列を返します。

私は、次のコードを思い付いた、それはかなりではありませんが、私はそれが動作するはずです知っている:

def count_positives_sum_negatives(lst) 
    pos, neg = 0, 0 

    lst.each do |num| 
    if num < 0 
     neg += num 
    else 
     pos++ 
    end 
    end 

    [pos, neg] 
end 

私は、次のテストを呼び出す:

count_positives_sum_negatives([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -11, -12, -13, -14, -15]) 

をし、それが返す必要があります=> 10、-65]

しかし、その戻り、次のエラー:

(repl):11: syntax error, unexpected keyword_end 
(repl):17: syntax error, unexpected end-of-input, expecting keyword_end 
..., 10, -11, -12, -13, -14, -15]) 
...  

誰も私になぜこれが起こっているの説明を与えることができますか?

+7

問題は 'pos ++'です。rubyにはC言語のような演算子がありません。それを 'pos + = 1'に変更してみてください – user1875195

+0

"それはきれいではありません "。エラーを除けば、あなたのコードは私にはよく見えます。 –

+0

ありがとうございました!オペレータが問題でした。それは今素晴らしいです! – wnamen

答えて

7

人々がここでエラーを指摘したように、x++は無効なRubyではなく、x +=1が必要です。接尾辞接頭辞と接頭辞のインクリメント演算子は、ほとんどの言語で野生の混乱の兆候であるため、Rubyは実装していません。のように、x++ + x++ + ++xの結果は何ですか?

はここで最初の配列を分割するpartitionを使用して、異なるの戦略だし、injectを使用して一緒にいるの崩壊:

positives, negatives = list.partition(&:positive?) 

[ positives.length, negatives.inject(0, &:+) ] 
# => [10,-65] 
+1

「陽性?」では分割できますが、「陰性」では分割できないことを賢明に認識してください。 –

+0

@CarySwovelと私は意義を忘れていますか? – SteveTurczyn

+3

@SteveTurczyn 'Negative? 'でパーティション化すると、0がポジティブ(効果的に非ネガティブ)でグループ化されますが、パーティションが「正」に設定されている場合、0はネガティブ(事実上、非ポジティブ)でグループ化されます。技術的には、0を_either_グルーピングに含めてはいけませんが、合計を計算しているネガティブは0になり、影響はありません。陽性の場合、カウントを計算しています。カウントに0を含めると、間違った答えが返されます。 – philomory

2

問題はRubyで有効な操作されていないpos++です。それは単項の後に続くものとして解釈されています。+しかし、単項の後には数字はありませんので、次の行に値が入ることを期待しています。

しかし、次の行が(したがって、最初のエラーunexpected keyword_end)予想外でendendは今、あなたがメソッドの終わり(したがって、2番目のエラーが不足している消費されているのでexpecting keyword_end

だから行を変更しています...ここ

pos += 1 
4

は、あなたがそれを行うことができ、別の方法である。

def count_pos_sum_neg(arr) 
    return [] if arr.empty? 
    arr.each_with_object([0,0]) do |n,a| 
    a[0] += 1 if n > 0 
    a[1] += n if n < 0 
    end 
end 

count_pos_sum_neg [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -11, -12, -13, -14, -15] 
    #=> [10, -65] 

実際のアプリケーションでは、ハッシュを返す方が便利です。

def count_pos_sum_neg(arr) 
    return [] if arr.empty? 
    arr.each_with_object({count_pos: 0, sum_neg: 0}) do |n,h| 
    h[:count_pos] += 1 if n > 0 
    h[:sum_neg] += n if n < 0 
    end 
end 

count_pos_sum_neg [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -11, -12, -13, -14, -15] 
    #=> {:count_pos=>10, :sum_neg=>-65} 
+0

ニースですが、ニックピックにするために、この答え(と賢者)は、 '入力配列が空であるかヌルかを見落としています。空の配列を返します'。もちろん、OPのソリューションにも同じ問題があります。 – SteveTurczyn

+0

@Tadmanからページを取得すると、前の行と最後の行は 'n> 0に置き換えられますか? h [:count_pos] + = 1:h [:sum_neg] + = n'となる。 –

+0

それは私が "空の配列"と考えているものではありませんが、anyhoo ... – SteveTurczyn

1

さらにを使用して別の変形例:

def count_pos_sum_neg(arr) 
    arr.inject([0, 0]) do |(count, sum), n| 
    if n > 0 
     [count + 1, sum] 
    else 
     [count, sum + n] 
    end 
    end 
end 

または圧縮: "入力配列が空またはnullの場合、"

def count_pos_sum_neg(arr) 
    arr.inject([0, 0]) { |(c, s), n| n > 0 ? [c + 1, s] : [c, s + n] } 
end 

コードがチェックされません。

0

私はあなたの最初のアプローチが簡単で読みやすく、シンプルであると思ったので、実際には高速です。fruity比較(コード固め)から、一部の結果:

require 'fruity' 

arr = ((-1000..-1).to_a + (1..1000).to_a).shuffle 

#various methods etc as defined in other answers. 

compare do 
    wnamen { ar = arr; wnamen_method ar } 
    tadman { ar = arr; tadman_method ar } 
    cary { ar = arr; cary_method ar } 
    cary2 { ar = arr; cary2_method ar } 
    stefan { ar = arr; stefan_method ar } 
    stefan2 { ar = arr; stefan2_method ar } 
end 

結果:

Running each test 8 times. Test will take about 1 second. 
wnamen is faster than tadman by 2.0x ± 0.1 
tadman is similar to stefan2 
stefan2 is similar to stefan 
stefan is similar to cary 
cary is faster than cary2 by 19.999999999999996% ± 10.0% (results differ: [1000, -500500] vs {:count_pos=>1000, :sum_neg=>-500500}) 

すべての他のアプローチは、当然のことながら興味深く、それにもかかわらず、知っておく価値があります。

+0

うわー!私はそれを認識しませんでした!この情報を共有してくれてありがとう。 – wnamen