ジュニア算数オリンピック 二次元上のユークリッド幾何の問題 その22
ジュニア算数オリンピックにおけるユークリッド幾何学の問題の解答の自動化を模索している。まず三角形定理ループを回し、回答できなかったら1ステップの作図を試していって、それらで回答できるか探る。それでも駄目だったら2ステップ、3ステップと増やしていく。作業手順は今はこれを参考にする。
07年度トライアル問題 問題5
『xの角度を求めなさい。
』
交点には、上からアルファベット順で名前を付けていく。同じ高さにあるものは、左から右へ付けていく。
graph := [
A : [
[[C, E], []],
[[D, F, H], []],
[[G], []]
]
,
B : [
[[C, D, G], []],
[[E, H], []]
]
,
C : [
[[A], [E]],
[[B], [D, G]]
]
,
D : [
[[A], [F, H]],
[[B, C], [G]
]
,
E : [
[[B], [H]],
[[A, C], []],
[[G, F], []]
]
,
F : [
[[A, D], [H]],
[[E], [G]]
]
,
G : [
[[A], []],
[[B, C, D], []],
[[E, F], []],
[[H], []]
]
,
H : [
[[G], []],
[[A, D, F], []],
[[B, E], []]
]
];
parallel_lines_lst := [
];
triangle_lst := [
];
cluster_lst := [
];
always {
DAG_p == 20; #答えで確認した。紛らわしいが
CBE_p == 50;
BGE_p == 65;
EGH_p == 15;
AHB_p == 30;
}
クラスタをどう設定するかが問題なんだが、今回はそれを探るために、あえて最初はクラスタには何も登録しないことにした。
三角形をまず更新することにする。graphを確認して、keyのvalueの中身で更にgraphを確認し、その中にkeyのvalueの中身と同じものがあれば(ただしkeyと同一直線上のは抜かす)、それらは三角形だ。
更に角のイコールを確認する。平行線のリストには何も無し。対頂角はCとDとFにある。
辺のイコールは定義通り。
辺の和を確認する。graphを確認して、ある点を跨る辺がある時は、辺の和として更新する。
graph := [
A : [
[[C, E], []],
[[D, F, H], []],
[[G], []]
]
,
B : [
[[C, D, G], []],
[[E, H], []]
]
,
C : [
[[A], [E]],
[[B], [D, G]]
]
,
D : [
[[A], [F, H]],
[[B, C], [G]
]
,
E : [
[[B], [H]],
[[A, C], []],
[[G, F], []]
]
,
F : [
[[A, D], [H]],
[[E], [G]]
]
,
G : [
[[A], []],
[[B, C, D], []],
[[E, F], []],
[[H], []]
]
,
H : [
[[G], []],
[[A, D, F], []],
[[B, E], []]
]
];
parallel_lines_lst := [
];
triangle_lst := [
△ACD : [CAD_p, AC, ACD_p, CD, ADB_p, AD],
△ACG : [CAG_p, AC, ACD_p, CG, AGB_p, AG],
△AEF : [CAD_p, AE, AEG_p, EF, AFG_p, AF],
△AEH : [CAD_p, AE, AEH_p, EH, AHB_p, AH],
△AEG : [CAG_p, AE, AEG_p, EG, AGE_p, AG],
△ADG : [DAG_p, AD, ADG_p, DG, AGB_p, AG],
△AFG : [DAG_p, AF, AFG_p, FG, AGE_p, AG],
△AGH : [DAG_p, AG, AGH_p, GH, AHG_p, AH],
△BCE : [CBE_p, BC, BCE_p, CE, AEB_p, BE],
△BDH : [CBE_p, BD, BDF_p, DH, AHB_p, BH],
△BEG : [CBE_p, BE, BEG_p, EG, BGE_p, BG],
△BGH : [CBE_p, BG, BGH_p, GH, BHG_p, BH],
△CEG : [DCE_p, CE, AEG_p, EG, BGE_p, CG], #ミスで抜かしていた
△DFG : [FDG_p, DF, AFG_p, FG, BGE_p, DG],
△DGH : [FDG_p, DG, BGH_p, GH, AHG_p, DH],
△EGH : [GEH_p, EG, EGH_p, GH, BHG_p, EH],
△EFH : [GEH_p, EF, EFH_p, FH, AHB_p, EH],
△FGH : [GFH_p, FG, EGH_p, GH, AHB_p, FH]
];
cluster_lst := [
];
always {
DAG_p == 20; #答えで確認した。紛らわしいが
CBE_p == 50;
BGE_p == 65;
EGH_p == 15;
AHB_p == 30;
ACG_p == DCE_p;
ACD_p == BCE_p;
ADB_p == FDG_p;
ADG_p == BDF_p;
AFE_p == GFH_p;
AFG_p == EFH_p;
AC + CE == AE;
BC + CD == BD;
BC + CG == BG;
AD + DF == AF;
AD + DH == AH;
BD + DG == BG;
CD + DG == CG;
BE + EH == BH;
AF + FH == AH;
DF + FH == DH;
EF + FG == EG;
}
三角形からクラスタを登録する。
更に、クラスタの辺が、辺の和の全体になっていて、例えばその間の点と三角形のクラスタの頂点が結び付いていたら、その点も含めてクラスタとして登録できるし、角の和として登録できる。間の点と点が結び付いていたら、それでもクラスタの分割になって、クラスタとして登録できる。
新しい作業なので、過程を貼る。一番上が三角形で、その後は何となく察してほしい。
ACG
CD + DG == CG;
AD
[[A, C, D, G], [CAG_p, AC, ACD_p, CD, CDG_h, DG, AGB_p, AG]],
CAD_p + DAG_p == CAG_p;
AEF
AC + CE == AE;
AD + DF == AF;
CD
[[C, E, F, D], [DCE_p, CE, AEG_p, EF, AFG_p, DF, BDF_p, CD]]
AEH
AF + FH == AH;
EF
[A, E, H, F], [CAD_p, AE, AEH_p, EH, AHB_p, AF, AFH_h, FH]
AEG_p + GEH_p == AEH_p;
AEH
AC + CE == AE;
AD + DH == AH;
CD
[C, E, H, D], [DCE_p, CE, AEH_p, EH, AHB_p, DH, BDF_p, CD],
AEG
AC + CE == AE;
CG
[[A, C, E, G], [CAG_p, AC, ACD_h, CE, AEG_p, EG, AGE_p, AG]],
AGB_p + BGE_p == AGE_p;
AEG
EF + FG == EG;
AF
[[A, E, F, G], [CAG_p, AE, AEG_p, EF, EFG_h, FG, AGE_p, AG]],
CAD_p + DAG_p == CAG_p;
AFG
AD + DF == AF;
DG
[[A, D, F, G], [DAG_p, AD, ADF_h, DF, AFG_p, FG, AGE_p, AG]],
AGB_p + BGE_p == AGE_p;
AGH
AD + DH == AH;
DG
[[A, G, H, D], [DAG_p, AG, AGH_p, GH, AHG_p, DH, ADF_h, AD]],
AGB_p + BGH_p == AGH_p;
AGH
AF + FH == AH;
FG
[[A, G, H, F], [DAG_p, AG, AGH_p, GH, AHG_p, FH, AFH_h, AF]],
AGE_p + EGH_p == AGH_p;
BDH
BC + CD == BD;
BE + EH == BH;
CE
[[C, D, H, E], [DCE_p, CD, BDF_p, DH, AHB_p, EH, AEH_p, CE]],
BDH
BE + EH == BH;
DF + FH == DH;
EF
[[E, B, D, F], [BEG_p, BE, CBE_p, BD, BDF_p, DF, AFE_p, EF]],
BEG
BC + CG == BG;
CE
[[B, E, G, C], [CBE_p, BE, BEG_p, EG, BGE_p, CG, BCD_h, BC]],
BEA_p + AEG_p == BEG_p;
BEG
BD + DG == BG;
EF + FG == EG;
DF
[[B, E, F, D], [CBE_p, BE, BEG_p, EF, AFE_p, DF, BDF_p, BD]],
BGH
BD + DG == BG;
DH
[[B, D, G, H], [CBE_p, BD, BDG_h, DG, BGH_p, GH, BHG_p, BH]],
AHB_p + AHG_p == BHG_p;
BGH
BE + EH == BH;
EG
[[B, G, H, E], [CBE_p, BG, BGH_p, GH, BHG_p, EH, BEH_h, BE]],
BGE_p + EGH_p == BGH_p;
BGH
BE + EH == BH;
BC + CG == BG;
CE
[[C, G, H, E], [DCE_p, CG, BGH_p, GH, BHG_p, EH, AEH_p, CE]],
???
BGH
BC + CG == BG;
BD + DG == BG;
CD
[[B, G, H], [CBE_p, BG, BGH_p, GH, BHG_p, BH]],
???
CEG
CD + DG == CG;
EF + FG == EG;
DF
[[C, E, F, D], [DCE_p, CE, AEG_p, EF, AFE_p, DF, BDF_p, CD]],
DGH
DF + FH == DH;
FG
[[D, G, H, F], [FDG_p, DG, BGH_p, GH, AHG_p, FH, AFH_h, DF]],
BGE_p + EGH_p == BGH_p;
EGH
EF + FG == EG;
FH
[[E, F, G, H], [GEH_p, EF, EFG_h, FG, EGH_p, GH, BHG_p, EH]],
AHB_p + AHG_p == BHG_p;
更に、graphを確認して、辺によって辺の180°が区切られているようなのを探して登録する。対頂角は登録されているので、半分ほど省けるだろう。
三角形に着目して、外角も登録する。いや、外角は登録しなくても良いな。三角形の内角は自動的に合計180°だと登録されるし、辺を辺で区切ることによる180°も登録されるので(そういう風にする)、自動的に弾き出される。(よく考えると、対頂角も自動的に取得されるか?)(錯角も自動的にと記述していたが、いや、でもそれも?)
graph := [
A : [
[[C, E], []],
[[D, F, H], []],
[[G], []]
]
,
B : [
[[C, D, G], []],
[[E, H], []]
]
,
C : [
[[A], [E]],
[[B], [D, G]]
]
,
D : [
[[A], [F, H]],
[[B, C], [G]
]
,
E : [
[[B], [H]],
[[A, C], []],
[[G, F], []]
]
,
F : [
[[A, D], [H]],
[[E], [G]]
]
,
G : [
[[A], []],
[[B, C, D], []],
[[E, F], []],
[[H], []]
]
,
H : [
[[G], []],
[[A, D, F], []],
[[B, E], []]
]
];
parallel_lines_lst := [
];
triangle_lst := [
△ACD : [CAD_p, AC, ACD_p, CD, ADB_p, AD],
△ACG : [CAG_p, AC, ACD_p, CG, AGB_p, AG],
△AEF : [CAD_p, AE, AEG_p, EF, AFG_p, AF],
△AEH : [CAD_p, AE, AEH_p, EH, AHB_p, AH],
△AEG : [CAG_p, AE, AEG_p, EG, AGE_p, AG],
△ADG : [DAG_p, AD, ADG_p, DG, AGB_p, AG],
△AFG : [DAG_p, AF, AFG_p, FG, AGE_p, AG],
△AGH : [DAG_p, AG, AGH_p, GH, AHG_p, AH],
△BCE : [CBE_p, BC, BCE_p, CE, AEB_p, BE],
△BDH : [CBE_p, BD, BDF_p, DH, AHB_p, BH],
△BEG : [CBE_p, BE, BEG_p, EG, BGE_p, BG],
△BGH : [CBE_p, BG, BGH_p, GH, BHG_p, BH],
△CEG : [DCE_p, CE, AEG_p, EG, BGE_p, CG], #ミスで抜かしていた
△DFG : [FDG_p, DF, AFG_p, FG, BGE_p, DG],
△DGH : [FDG_p, DG, BGH_p, GH, AHG_p, DH],
△EGH : [GEH_p, EG, EGH_p, GH, BHG_p, EH],
△EFH : [GEH_p, EF, EFH_p, FH, AHB_p, EH],
△FGH : [GFH_p, FG, EGH_p, GH, AHB_p, FH]
];
cluster_lst := [
[[A, C, D], [CAD_p, AC, ACD_p, CD, ADB_p, AD]],
[[A, C, G], [CAG_p, AC, ACD_p, CG, AGB_p, AG]],
[[A, E, F], [CAD_p, AE, AEG_p, EF, AFG_p, AF]],
[[A, E, H], [CAD_p, AE, AEH_p, EH, AHB_p, AH]],
[[A, E, G], [CAG_p, AE, AEG_p, EG, AGE_p, AG]],
[[A, D, G], [DAG_p, AD, ADG_p, DG, AGB_p, AG]],
[[A, F, G], [DAG_p, AF, AFG_p, FG, AGE_p, AG]],
[[A, G, H], [DAG_p, AG, AGH_p, GH, AHG_p, AH]],
[[B, C, E], [CBE_p, BC, BCE_p, CE, AEB_p, BE]],
[[B, D, H], [CBE_p, BD, BDF_p, DH, AHB_p, BH]],
[[B, E, G], [CBE_p, BE, BEG_p, EG, BGE_p, BG]],
[[B, G, H], [CBE_p, BG, BGH_p, GH, BHG_p, BH]],
[[C, E, G], [DCE_p, CE, AEG_p, EG, BGE_p, CG]],
[[D, F, G], [FDG_p, DF, AFG_p, FG, BGE_p, DG]],
[[D, G, H], [FDG_p, DG, BGH_p, GH, AHG_p, DH]],
[[E, G, H], [GEH_p, EG, EGH_p, GH, BHG_p, EH]],
[[E, F, H], [GEH_p, EF, EFH_p, FH, AHB_p, EH]],
[[F, G, H], [GFH_p, FG, EGH_p, GH, AHB_p, FH]],
[[A, C, D, G], [CAG_p, AC, ACD_p, CD, CDG_h, DG, AGB_p, AG]],
[[C, E, F, D], [DCE_p, CE, AEG_p, EF, AFG_p, DF, BDF_p, CD]],
[[A, E, H, F], [CAD_p, AE, AEH_p, EH, AHB_p, AF, AFH_h, FH]],
[[C, E, H, D], [DCE_p, CE, AEH_p, EH, AHB_p, DH, BDF_p, CD]],
[[A, C, E, G], [CAG_p, AC, ACD_h, CE, AEG_p, EG, AGE_p, AG]],
[[A, E, F, G], [CAG_p, AE, AEG_p, EF, EFG_h, FG, AGE_p, AG]],
[[A, D, F, G], [DAG_p, AD, ADF_h, DF, AFG_p, FG, AGE_p, AG]],
[[A, G, H, D], [DAG_p, AG, AGH_p, GH, AHG_p, DH, ADF_h, AD]],
[[A, G, H, F], [DAG_p, AG, AGH_p, GH, AHG_p, FH, AFH_h, AF]],
[[C, D, H, E], [DCE_p, CD, BDF_p, DH, AHB_p, EH, AEH_p, CE]],
[[E, B, D, F], [BEG_p, BE, CBE_p, BD, BDF_p, DF, AFE_p, EF]],
[[B, E, G, C], [CBE_p, BE, BEG_p, EG, BGE_p, CG, BCD_h, BC]],
[[B, E, F, D], [CBE_p, BE, BEG_p, EF, AFE_p, DF, BDF_p, BD]],
[[B, D, G, H], [CBE_p, BD, BDG_h, DG, BGH_p, GH, BHG_p, BH]],
[[B, G, H, E], [CBE_p, BG, BGH_p, GH, BHG_p, EH, BEH_h, BE]],
[[C, G, H, E], [DCE_p, CG, BGH_p, GH, BHG_p, EH, AEH_p, CE]],
[[C, E, F, D], [DCE_p, CE, AEG_p, EF, AFE_p, DF, BDF_p, CD]],
[[D, G, H, F], [FDG_p, DG, BGH_p, GH, AHG_p, FH, AFH_h, DF]],
[[E, F, G, H], [GEH_p, EF, EFG_h, FG, EGH_p, GH, BHG_p, EH]]
];
always {
DAG_p == 20; #答えで確認した。紛らわしいが
CBE_p == 50;
BGE_p == 65;
EGH_p == 15;
AHB_p == 30;
ACG_p == DCE_p;
ACD_p == BCE_p;
ADB_p == FDG_p;
ADG_p == BDF_p;
AFE_p == GFH_p;
AFG_p == EFH_p;
AC + CE == AE;
BC + CD == BD;
BC + CG == BG;
AD + DF == AF;
AD + DH == AH;
BD + DG == BG;
CD + DG == CG;
BE + EH == BH;
AF + FH == AH;
DF + FH == DH;
EF + FG == EG;
CAD_p + DAG_p == CAG_p;
AEG_p + GEH_p == AEH_p;
AGB_p + BGE_p == AGE_p;
AGB_p + BGH_p == AGH_p;
AGE_p + EGH_p == AGH_p;
AEB_p + AEG_p == BEG_p;
AHB_p + AHG_p == BHG_p;
BGE_p + EGH_p == BGH_p;
ACB_p + BCE_p == 180;
ACB_p + ACD_p == 180;
ADB_p + BDF_p == 180;
ADB_p + ADG_p == 180;
ABE_p + AEH_p == 180;
BEG_p + GEH_p == 180;
AFE_p + EFH_p == 180;
AFE_p + AFG_p == 180;
}
で、まあ点に着目して確認すると、必要な角の和は取得されてるわけだ。おそらく全体が三角形で構成されていたからだろう。
今回は使わないが、クラスタ内での交点の発生についても考えてみる。
交点さえ考えることができれば、何と何が繋がっているかはgraphにあるので、分割したクラスタもまた分割することができるだろう。
まず2つの辺について考える。
頂点同士から伸びている場合は、同じ頂点から伸びている場合は、交点は発生しない。違う頂点から伸びている場合は、交点は必ず発生する。
頂点から伸びている辺と、辺から辺へ伸びている辺だと、頂点を挟む辺同士で発生している辺だと、必ず交点は発生する。底辺が関わる場合、底辺における2つの辺の位置関係で、交点ができる場合とできない場合の2通りが考えられる。
辺から辺へ伸びている辺同士の場合は、もしその辺が同じ端点を共有している場合は、交点は絶対に発生しない。
また、(三角形の)2辺で完結する場合は、その2辺の間で点と点の位置関係を見れば良い。
(三角形の)3辺が関わる場合も、2つがくっついている辺と、1つずつしかくっついていない辺の、位置関係を見れば良い。
2つの辺の場合は簡単だが、3つの辺が絡んでくると、交点が発生する際の位置関係が難しくなるのではないか。
三角関数?が必要なんじゃないかなあ。そうすると、平面が概念として必要になるのではないか。同一平面上にある点同士で無ければ、そもそも三角関数?は成立しないだろう。交点ができるとしたらどこかを判定することはできるが、いや、それならクラスタの中であれば必要無いのか。
まあ、辺における点の前後関係自体は、graphにおいて、まず片方に点が何も無いのを探して、次にその一つ前だけがあるのを探して、というのを続ければ良いと思うけど。そういう位置関係が曖昧なのは、そもそも入れないとして。いや、入れるんだっけな?まあ実際に詳しくやってみないと分からないが。