3本のひもで作る四角形

3月も下旬になってしまった。

今回もたまたま見つけたネタ。前回と同じブログから。

 cf. 3本のひもで作る四角形 – utthi_fumiの日記

同じ長さの3本のひもを折り曲げて3つの四角形を作ります。 そのうち2本でそれぞれ長方形を作り、残りの1本は正方形を作ります。 このとき、作った2つの長方形の面積の和が、正方形の面積と同じになることがあります。 (ただし、いずれの長方形、正方形も辺の長さは整数)

例)紐の長さが20の時

1本目 縦1×横9の長方形→面積=9

2本目 縦2×横8の長方形→面積=16

3本目 縦5×横5の正方形→面積=25

さらに、ひもの長さを変えてできる長方形と正方形の組をカウントします。 ただし、同じ比で整数倍のものは1つとしてカウント

例)紐の長さが40の時

1本目 縦2×横18の長方形→面積=36

2本目 縦4×横16の長方形→面積=64

3本目 縦10×横10の正方形→面積=100

紐の長さが60の時

1本目 縦3×横27の長方形→面積=81

2本目 縦6×横24の長方形→面積=114

3本目 縦15×横15の正方形→面積=225

紐の長さを1から500まで変化させる時、2つの長方形の面積の和と 正方形の面積が同じなる組が何通りあるか?


Python でやってみる。

import math
from functools import reduce


def main():
    s = set()
    for l in range(1, 501):
        for c in height_of_rectangles(l):
            s.add(reduction(c))
    for c in s:
        print(format_rect(c))
    print(len(s))

def combi(l):
    if l % 4 == 0:
        h3 = int(l / 4)
        return [(h1, h2, h3) for h2 in range(1, h3) for h1 in range(1, h2)]
    else:
        return []

def area(h, l):
    w = int(l / 2) - h
    return h * w

def height_of_rectangles(l):
    hor = []
    for c in combi(l):
        (h1, h2, h3) = c
        if area(h1, l) + area(h2, l) == area(h3, l):
            hor.append(c)
    return hor

def format_rect(c):
    (h1, h2, h3) = c
    l = h3 * 4
    w1 = h3 * 2 - h1
    w2 = h3 * 2 - h2
    return "{l}: {h1} * {w1} + {h2} * {w2} = {h3} * {h3}".format(l=l, h1=h1, w1=w1, h2=h2, w2=w2, h3=h3)

def reduction(c):
    r = reduce(math.gcd, c)
    return tuple(map(lambda x: int(x / r), c))


if __name__ == '__main__':
    main()

実行結果:

116: 8 * 50 + 9 * 49 = 29 * 29
260: 9 * 121 + 32 * 98 = 65 * 65
100: 1 * 49 + 18 * 32 = 25 * 25
340: 8 * 162 + 49 * 121 = 85 * 85
388: 25 * 169 + 32 * 162 = 97 * 97
164: 1 * 81 + 32 * 50 = 41 * 41
404: 2 * 200 + 81 * 121 = 101 * 101
68: 2 * 32 + 9 * 25 = 17 * 17
52: 1 * 25 + 8 * 18 = 13 * 13
260: 2 * 128 + 49 * 81 = 65 * 65
212: 8 * 98 + 25 * 81 = 53 * 53
500: 8 * 242 + 81 * 169 = 125 * 125
436: 18 * 200 + 49 * 169 = 109 * 109
20: 1 * 9 + 2 * 8 = 5 * 5
340: 1 * 169 + 72 * 98 = 85 * 85
244: 1 * 121 + 50 * 72 = 61 * 61
148: 2 * 72 + 25 * 49 = 37 * 37
292: 18 * 128 + 25 * 121 = 73 * 73
356: 9 * 169 + 50 * 128 = 89 * 89
452: 1 * 225 + 98 * 128 = 113 * 113
20

いちばん最後に出力されている 20 が答え。20 通りあるってこと。

整数の割り算の結果が小数になることとか、map の結果が map object とかいうものになるとことかでちょってハマった。map object ってなにさ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください