院卒新人サラリーマンのメモ代わり

備忘としてのメモを記載

数学パズルQ16

def check(max)
  cnt = 0
  (1..max).each do |sideLen|
    next if sideLen % 4 != 0

    square = {
      side: sideLen / 4,
      area: sideLen / 4 * sideLen / 4,
    }

    rects = []
    (1..square[:side] - 1).each do |vert|
      rects.push({
        vert: vert,
        hori: sideLen / 2 - vert,
        area: vert * (sideLen / 2 - vert),
      })
    end

    rects.combination(2) do |rect1, rect2|
      cnt += 1 if rect1[:area] + rect2[:area] == square[:area]
    end
  end
  cnt
end

puts check(500)

この長さですらreduce使うと読みづらくなっちゃいそうだから使わないでみた。
ただそもそも、紐の長さを入れたらboolを返す関数を作って
それを外でループで回すほうが良さそう。

def check(himo)
  return false if himo % 4 != 0

  square = {
    side: himo / 4,
    area: himo / 4 * himo / 4,
  }

  rects = (1..square[:side] - 1).to_a.map do |vert|
    {
      vert: vert,
      hori: himo / 2 - vert,
      area: vert * (himo / 2 - vert),
    }
  end

  rects.combination(2) do |rect1, rect2|
    return true if rect1[:area] + rect2[:area] == square[:area]
  end
  false
end

arr = (1..500).to_a.map do |himo|
  check(himo)
end

puts arr.count { |el| el == true }

なんか答え違うから間違っているんだろうけどまぁいいや