/var/log/messages

Jan 14, 2019 - 1 minute read - Comments - programming

プログラミング Elixir (4)

ModuleAndFunction - 6 は若干の微妙感あり。以下なヒントが列挙されています。

  • 現時点での推測値を持つヘルパー関数作れ
  • div(a, b) は整数の除算
  • ガード節を使いなさい
  • パタンマッチをうまく使う (a..b = 4..8)

ガード節、actual と推測値を比較するのかどうか。

計算

ええと

  • Chop.guess(273, 1..1000) は Chop.guess(actual, min..max, div(max, 2)) を呼ぶ
  • Chop.guess(273, 1..1000, 500) なのかな
  • ガード節で actual と center を比較して再帰呼び出し

てこれ、どうやって終わるのかと

  • Chop.guess(273, 1..1000, 500) では 273 の方がちっさいので Chop.guess(273, 1..500, 250) を呼び出す
  • Chop.guess(273, 1..500, 250) では 250 の方がちっさいので Chop.guess(273, 250..500, 375) を呼び出す (375 は 250 + 2250)
  • Chop.guess(273, 250..500, 375) では 273 の方がちっさいので Chop.guess(273, 250..375, 312) を呼び出す (312 は 250 + 2/(375-250))
  • Chop.guess(273, 250..375, 312) では 273 の方がちっさいので Chop.guess(273, 250..312, 281) を呼び出す (281 は 250 + 2/(312-250))
  • Chop.guess(273, 250..312, 281) では 273 の方がちっさいので Chop.guess(273, 250..281, 265) を呼び出す (265 は 250 + 2/(281-250))
  • Chop.guess(273, 250..281, 265) では 265 の方がちっさいので Chop.guess(273, 265..281, 273) を呼び出す

この時点で actual と center の値が同じになったので、という記述にすれば良いのか成程。

実装

一応動いてるみたいですが若干の微妙感あり。

defmodule Chop do
  def guess(actual, min..max) do
    guess_helper(actual, min..max, div(max, 2))
  end
  def guess_helper(actual, min..max, center) when actual == center do
    actual
  end
  def guess_helper(actual, min..max, center) when actual > center do
    guess_helper(actual, center..max, center + div(max - center + 1, 2))
  end
  def guess_helper(actual, min..max, center) when actual < center do
    guess_helper(actual, min..center, min + div(max - min + 1, 2))
  end
end