0

if / else条件があり、ifセクションとelseセクションが同じである場合は、使用する演算子を除きます。ある場合<には、そして他の場合には>。その演算子を条件付きで設定して、コードをドライアウトする方法はありますか?

if count_year < end_year
    while count_year <= end_year
        if count_year % 4 == 0
            if count_year % 100 != 0
                all_years << count_year unless (count_year % 400 == 0)
            end
        end
        count_year += 1
    end
    puts all_years
elsif count_year > end_year
    while count_year >= end_year
        if count_year % 4 == 0
            if count_year % 100 != 0
                all_years << count_year unless (count_year % 400 == 0)
            end
        end
        count_year -= 1
    end
    puts all_years.reverse
end

これは、指定された2年間のうるう年を印刷するためのプログラムの一部です。ループを2回繰り返さなくてもいい方法があるに違いないと思います。次のようなもの:count_year < end_year ? operator = "<" : operator = ">"-次に、その変数を使用して、演算子をコードブロックなどに置き換えますか?何か案は?

4

3 に答える 3

3

1つの小さな改善として、実際に同一のパーツをメソッドに抽出できます。その後、複製はそれほど大規模ではなくなります。

# I'm too lazy to come up with a proper name for it.
def foo count_year, all_years
  if count_year % 4 == 0
    if count_year % 100 != 0
      all_years << count_year unless (count_year % 400 == 0)
    end
  end
end


# later...

if count_year < end_year
  while count_year <= end_year
    foo count_year, all_years
    count_year += 1
  end
  puts all_years
elsif count_year > end_year
  while count_year >= end_year
    foo count_year, all_years
    count_year -= 1
  end
  puts all_years.reverse
end

しかし、演算子の置換...

はい、評価する演算子を動的に選択する方法があります。ご覧のとおり、rubyの演算子は単なるメソッド呼び出しであり、それ以上のものではありません。これらの2行は同等です。

7 > 5
7.>(5)

そして、これが比較のためにランダムな演算子を選択するスニペットです。私はあなたの問題にそれを適応させることをあなたに任せます(あなたが望むなら、それはそうです。私はこれに対してあなたに忠告します)。

def is_7_greater_than_5
  operator = [:<, :>].sample # pick random operator
  7.send(operator, 5)
end

is_7_greater_than_5 # => false
is_7_greater_than_5 # => false
is_7_greater_than_5 # => true
is_7_greater_than_5 # => true
is_7_greater_than_5 # => true
于 2013-01-24T20:56:52.340 に答える
2
def example count_year, end_year
  all_years = []

  dir, test = count_year < end_year                      ?
    [ 1, proc { |c, e| c <= e }] : count_year > end_year ?
    [-1, proc { |c, e| c >  e }] :
    [ 0, proc { |c, e| false  }]

  while test.call count_year, end_year
    if count_year % 4 == 0
      if count_year % 100 != 0
        all_years << count_year unless count_year % 400 == 0
      end
    end
    count_year += dir
    puts dir > 0 ? all_years : all_years.reverse
  end
end
于 2013-01-24T21:00:03.610 に答える
0

ああ。なぜあなたはコードゴルフの練習をして、答えをそんなに早く受け入れたのですか?ブー!:(ふふ。冗談です。早い鳥は虫を捕まえます。あなたが比較を実験しようとしているだけだと思う​​ので、私はおそらく文字通り問題を取りすぎたのでしょう。

私はrubyの組み込み関数を使用し、このメソッドをクラスに分解しました。:)

require 'date'

class LeapYearFinder

  attr_reader :years, :years_reversed

  def initialize(start_year, end_year)
    @start_year    = Date.parse("1/1/#{start_year.to_s}")
    @end_year      = Date.parse("1/1/#{end_year.to_s}")
    @years         ||= leap_years
  end

  def compare_range
    @compare_range ||= Range.new(@start_year, @end_year)
  end

  def leap_years
    years = []
    compare_range.step {|x| years << x.year if x.leap? }
    years.uniq!
  end

  def years_reversed
    @years.reverse
  end

end

lp = LeapYearFinder.new(1900, 2012)

puts "Years putzed"
lp.years.map {|x| puts x}

puts "Years reversed"
lp.years_reversed.map {|x| puts x}

いくつかのコーナーケースの問題

  • 逆の日付入力を処理する
  • 範囲を適切にステップスルーして、一意性を回避します。そして多分より良いパフォーマンスを生み出す
于 2013-01-24T21:52:11.947 に答える