|
| 1 | +/- |
| 2 | +Copyright (c) 2026 The Compfiles Contributors. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: |
| 5 | +-/ |
| 6 | + |
| 7 | +import Mathlib |
| 8 | + |
| 9 | +import ProblemExtraction |
| 10 | + |
| 11 | +problem_file { tags := [.Combinatorics] } |
| 12 | + |
| 13 | +/-! |
| 14 | +# International Mathematical Olympiad 1988, Problem 2 |
| 15 | +
|
| 16 | +Let n be a positive integer and let A₁, A₂, ..., A₂ₙ₊₁ be subsets |
| 17 | +of a set B. Suppose that |
| 18 | +
|
| 19 | +(i) each Aᵢ has exactly 2n elements, |
| 20 | +(ii) each intersection Aᵢ ∩ Aⱼ (i ≠ j) contains exactly one element, and |
| 21 | +(iii) every element of B belongs to at least two of the Aᵢ. |
| 22 | +
|
| 23 | +For which values of n can one assign to every element of B |
| 24 | +one of the numbers 0 and 1 in such a way that each Aᵢ has |
| 25 | +exactly n elements assigned 0? |
| 26 | +-/ |
| 27 | + |
| 28 | +namespace Imo1988P2 |
| 29 | + |
| 30 | +determine SolutionSet : Set ℕ := {n | 0 < n ∧ Even n} |
| 31 | + |
| 32 | +snip begin |
| 33 | + |
| 34 | +/-- Counting the pairs `(a, b)` with `a ∈ s`, `b ∈ t` and `r a b`, |
| 35 | +fiberwise in either order. -/ |
| 36 | +lemma double_count {α β : Type*} (s : Finset α) (t : Finset β) (r : α → β → Prop) |
| 37 | + [∀ a b, Decidable (r a b)] : |
| 38 | + ∑ a ∈ s, (t.filter (fun b ↦ r a b)).card = |
| 39 | + ∑ b ∈ t, (s.filter (fun a ↦ r a b)).card := by |
| 40 | + simp only [Finset.card_filter] |
| 41 | + exact Finset.sum_comm |
| 42 | + |
| 43 | +/-- If finitely many terms, each at least `1`, sum to the number of terms, |
| 44 | +then every term equals `1`. -/ |
| 45 | +lemma all_eq_one {α : Type*} {s : Finset α} {g : α → ℕ} |
| 46 | + (h1 : ∀ a ∈ s, 1 ≤ g a) (h2 : ∑ a ∈ s, g a = s.card) : |
| 47 | + ∀ a ∈ s, g a = 1 := by |
| 48 | + intro a ha |
| 49 | + have h3 : ∑ a ∈ s, 1 = ∑ a ∈ s, g a := by |
| 50 | + rw [h2, Finset.sum_const_nat fun x _ ↦ rfl, mul_one] |
| 51 | + exact ((Finset.sum_eq_sum_iff_of_le h1).mp h3 a ha).symm |
| 52 | + |
| 53 | +section Structure |
| 54 | + |
| 55 | +variable {n : ℕ} {B : Type} [DecidableEq B] {A : Fin (2 * n + 1) → Finset B} |
| 56 | + |
| 57 | +/-- Under the problem's hypotheses, every element of `A i` lies in exactly one |
| 58 | +set `A j` with `j ≠ i`. -/ |
| 59 | +lemma other_unique |
| 60 | + (hcard : ∀ i, (A i).card = 2 * n) |
| 61 | + (hint : ∀ i j, i ≠ j → (A i ∩ A j).card = 1) |
| 62 | + (hcov : ∀ b : B, 2 ≤ (Finset.univ.filter (fun i ↦ b ∈ A i)).card) |
| 63 | + {i : Fin (2 * n + 1)} {b : B} (hb : b ∈ A i) : |
| 64 | + ((Finset.univ.erase i).filter (fun j ↦ b ∈ A j)).card = 1 := by |
| 65 | + have key : ∀ a ∈ A i, ((Finset.univ.erase i).filter (fun j ↦ a ∈ A j)).card = 1 := by |
| 66 | + refine all_eq_one (fun a ha ↦ ?_) ?_ |
| 67 | + · have h2 := hcov a |
| 68 | + have h3 : (Finset.univ.filter (fun j ↦ a ∈ A j)).card - 1 ≤ |
| 69 | + ((Finset.univ.erase i).filter (fun j ↦ a ∈ A j)).card := by |
| 70 | + rw [Finset.filter_erase] |
| 71 | + exact Finset.pred_card_le_card_erase |
| 72 | + lia |
| 73 | + · rw [double_count (A i) (Finset.univ.erase i) (fun a j ↦ a ∈ A j)] |
| 74 | + have hterm : ∀ j ∈ Finset.univ.erase i, |
| 75 | + ((A i).filter (fun a ↦ a ∈ A j)).card = 1 := by |
| 76 | + intro j hj |
| 77 | + rw [Finset.filter_mem_eq_inter] |
| 78 | + exact hint i j (Finset.mem_erase.mp hj).1.symm |
| 79 | + rw [Finset.sum_const_nat hterm, mul_one, |
| 80 | + Finset.card_erase_of_mem (Finset.mem_univ i), Finset.card_univ, |
| 81 | + Fintype.card_fin, hcard i] |
| 82 | + lia |
| 83 | + exact key b hb |
| 84 | + |
| 85 | +/-- The pair of indices of the sets containing a common element `b` of |
| 86 | +`A i` and `A j`. -/ |
| 87 | +lemma pair_eq |
| 88 | + (hcard : ∀ i, (A i).card = 2 * n) |
| 89 | + (hint : ∀ i j, i ≠ j → (A i ∩ A j).card = 1) |
| 90 | + (hcov : ∀ b : B, 2 ≤ (Finset.univ.filter (fun i ↦ b ∈ A i)).card) |
| 91 | + {i j : Fin (2 * n + 1)} {b : B} (hbi : b ∈ A i) (hbj : b ∈ A j) (hij : i ≠ j) : |
| 92 | + Finset.univ.filter (fun k ↦ b ∈ A k) = {i, j} := by |
| 93 | + have h1 : ((Finset.univ.filter (fun k ↦ b ∈ A k)).erase i).card = 1 := by |
| 94 | + rw [← Finset.filter_erase] |
| 95 | + exact other_unique hcard hint hcov hbi |
| 96 | + have h2 : i ∈ Finset.univ.filter (fun k ↦ b ∈ A k) := |
| 97 | + Finset.mem_filter.mpr ⟨Finset.mem_univ _, hbi⟩ |
| 98 | + have h3 := Finset.card_erase_of_mem h2 |
| 99 | + have h4 : 0 < (Finset.univ.filter (fun k ↦ b ∈ A k)).card := |
| 100 | + Finset.card_pos.mpr ⟨i, h2⟩ |
| 101 | + have hsub : ({i, j} : Finset (Fin (2 * n + 1))) ⊆ |
| 102 | + Finset.univ.filter (fun k ↦ b ∈ A k) := by |
| 103 | + intro k hk |
| 104 | + rw [Finset.mem_insert, Finset.mem_singleton] at hk |
| 105 | + rcases hk with rfl | rfl |
| 106 | + · exact h2 |
| 107 | + · exact Finset.mem_filter.mpr ⟨Finset.mem_univ _, hbj⟩ |
| 108 | + have h5 : ({i, j} : Finset (Fin (2 * n + 1))).card = 2 := |
| 109 | + Finset.card_pair_eq_two_iff.mpr hij |
| 110 | + exact (Finset.eq_of_subset_of_card_le hsub (by lia)).symm |
| 111 | + |
| 112 | +end Structure |
| 113 | + |
| 114 | +/-- Colour an edge `e = {p, q}` of the complete graph on `Fin (K + 1)` with `0` |
| 115 | +iff the difference of its endpoints, in one of the two directions, |
| 116 | +lies in `[1, m]`. -/ |
| 117 | +def colour {K : ℕ} (m : ℕ) (e : Finset (Fin (K + 1))) : Fin 2 := |
| 118 | + if ∃ p ∈ e, ∃ q ∈ e, (q - p).val ∈ Finset.Icc 1 m then 0 else 1 |
| 119 | + |
| 120 | +lemma colour_eq_zero_iff {K m : ℕ} {e : Finset (Fin (K + 1))} : |
| 121 | + colour m e = 0 ↔ ∃ p ∈ e, ∃ q ∈ e, (q - p).val ∈ Finset.Icc 1 m := by |
| 122 | + unfold colour |
| 123 | + split |
| 124 | + · next h => exact iff_of_true rfl h |
| 125 | + · next h => exact iff_of_false (by decide) h |
| 126 | + |
| 127 | +lemma colour_pair_eq_zero_iff {K m : ℕ} {i j : Fin (K + 1)} : |
| 128 | + colour m {i, j} = 0 ↔ |
| 129 | + ((j - i).val ∈ Finset.Icc 1 m ∨ (i - j).val ∈ Finset.Icc 1 m) := by |
| 130 | + rw [colour_eq_zero_iff] |
| 131 | + have hz : ∀ x : Fin (K + 1), (x - x).val ∉ Finset.Icc 1 m := by |
| 132 | + intro x |
| 133 | + rw [sub_self] |
| 134 | + simp |
| 135 | + constructor |
| 136 | + · rintro ⟨p, hp, q, hq, h⟩ |
| 137 | + simp only [Finset.mem_insert, Finset.mem_singleton] at hp hq |
| 138 | + rcases hp with rfl | rfl <;> rcases hq with rfl | rfl |
| 139 | + · exact absurd h (hz _) |
| 140 | + · exact Or.inl h |
| 141 | + · exact Or.inr h |
| 142 | + · exact absurd h (hz _) |
| 143 | + · rintro (h | h) |
| 144 | + · exact ⟨i, Finset.mem_insert_self i _, |
| 145 | + j, Finset.mem_insert_of_mem (Finset.mem_singleton_self j), h⟩ |
| 146 | + · exact ⟨j, Finset.mem_insert_of_mem (Finset.mem_singleton_self j), |
| 147 | + i, Finset.mem_insert_self i _, h⟩ |
| 148 | + |
| 149 | +/-- At each vertex `i` of the complete graph on `Fin (2 * n + 1)` with |
| 150 | +`n = 2 * m`, exactly `n` of the `2 * n` incident edges have a circular |
| 151 | +difference in `[1, m]`: measuring each neighbour `j` by `(j - i).val` |
| 152 | +identifies the good neighbours with `[1, m] ∪ [2 * n + 1 - m, 2 * n]`. -/ |
| 153 | +lemma count_good {n m : ℕ} (hm : n = 2 * m) (i : Fin (2 * n + 1)) : |
| 154 | + ((Finset.univ.erase i).filter |
| 155 | + (fun j ↦ (j - i).val ∈ Finset.Icc 1 m ∨ (i - j).val ∈ Finset.Icc 1 m)).card |
| 156 | + = n := by |
| 157 | + have key : ((Finset.univ.erase i).filter |
| 158 | + (fun j ↦ (j - i).val ∈ Finset.Icc 1 m ∨ (i - j).val ∈ Finset.Icc 1 m)).card = |
| 159 | + ((Finset.range (2 * n + 1)).filter |
| 160 | + (fun x ↦ 1 ≤ x ∧ (x ≤ m ∨ 2 * n + 1 - m ≤ x))).card := by |
| 161 | + refine Finset.card_bij (fun j _ ↦ (j - i).val) ?_ ?_ ?_ |
| 162 | + · intro j hj |
| 163 | + rw [Finset.mem_filter, Finset.mem_erase] at hj |
| 164 | + obtain ⟨⟨hji, -⟩, hgood⟩ := hj |
| 165 | + have hne : j - i ≠ 0 := sub_ne_zero_of_ne hji |
| 166 | + have hne' : (j - i).val ≠ 0 := |
| 167 | + fun h ↦ hne (Fin.val_inj.mp (by rw [h, Fin.val_zero])) |
| 168 | + have hvn := Fin.val_neg (j - i) |
| 169 | + rw [if_neg hne, neg_sub] at hvn |
| 170 | + have hlt := (j - i).isLt |
| 171 | + simp only [Finset.mem_Icc] at hgood |
| 172 | + rw [hvn] at hgood |
| 173 | + rw [Finset.mem_filter, Finset.mem_range] |
| 174 | + refine ⟨hlt, by lia, ?_⟩ |
| 175 | + rcases hgood with h | h |
| 176 | + · exact Or.inl h.2 |
| 177 | + · exact Or.inr (by lia) |
| 178 | + · intro j₁ _ j₂ _ h |
| 179 | + have h' := congrArg (· + i) (Fin.val_inj.mp h) |
| 180 | + simpa [sub_add_cancel] using h' |
| 181 | + · intro x hx |
| 182 | + rw [Finset.mem_filter, Finset.mem_range] at hx |
| 183 | + obtain ⟨hlt, hx1, hxor⟩ := hx |
| 184 | + have hxv : (⟨x, hlt⟩ : Fin (2 * n + 1)) + i - i = ⟨x, hlt⟩ := |
| 185 | + add_sub_cancel_right _ i |
| 186 | + refine ⟨⟨x, hlt⟩ + i, ?_, by rw [hxv]⟩ |
| 187 | + have hc0 : (⟨x, hlt⟩ : Fin (2 * n + 1)) ≠ 0 := by |
| 188 | + intro h |
| 189 | + rw [Fin.ext_iff, Fin.val_zero] at h |
| 190 | + have hx0 : x = 0 := h |
| 191 | + lia |
| 192 | + rw [Finset.mem_filter, Finset.mem_erase] |
| 193 | + refine ⟨⟨fun heq ↦ hc0 (by rw [← hxv, heq, sub_self]), Finset.mem_univ _⟩, ?_⟩ |
| 194 | + have hvn := Fin.val_neg (⟨x, hlt⟩ : Fin (2 * n + 1)) |
| 195 | + rw [if_neg hc0] at hvn |
| 196 | + have hisub : i - ((⟨x, hlt⟩ : Fin (2 * n + 1)) + i) = -⟨x, hlt⟩ := by |
| 197 | + rw [← neg_sub (⟨x, hlt⟩ + i) i, hxv] |
| 198 | + have hval : (⟨x, hlt⟩ : Fin (2 * n + 1)).val = x := rfl |
| 199 | + rw [hxv, hisub, hvn, hval] |
| 200 | + simp only [Finset.mem_Icc] |
| 201 | + rcases hxor with h | h |
| 202 | + · exact Or.inl ⟨hx1, h⟩ |
| 203 | + · refine Or.inr ⟨?_, ?_⟩ <;> lia |
| 204 | + have he : (Finset.range (2 * n + 1)).filter |
| 205 | + (fun x ↦ 1 ≤ x ∧ (x ≤ m ∨ 2 * n + 1 - m ≤ x)) = |
| 206 | + Finset.Icc 1 m ∪ Finset.Icc (n + m + 1) (2 * n) := by |
| 207 | + ext x |
| 208 | + simp only [Finset.mem_filter, Finset.mem_range, Finset.mem_union, Finset.mem_Icc] |
| 209 | + lia |
| 210 | + have hd : Disjoint (Finset.Icc 1 m) (Finset.Icc (n + m + 1) (2 * n)) := by |
| 211 | + rw [Finset.disjoint_left] |
| 212 | + intro x hx hx' |
| 213 | + rw [Finset.mem_Icc] at hx hx' |
| 214 | + lia |
| 215 | + rw [key, he, Finset.card_union_eq_card_add_card.mpr hd, Nat.card_Icc, Nat.card_Icc] |
| 216 | + lia |
| 217 | + |
| 218 | +section VertexCount |
| 219 | + |
| 220 | +variable {n : ℕ} {B : Type} [DecidableEq B] {A : Fin (2 * n + 1) → Finset B} |
| 221 | + |
| 222 | +/-- With `n = 2 * m`, colouring each element by `colour m` of its index pair |
| 223 | +gives exactly `n` elements of colour `0` in each `A i`. -/ |
| 224 | +lemma vertex_count {m : ℕ} (hm : n = 2 * m) |
| 225 | + (hcard : ∀ i, (A i).card = 2 * n) |
| 226 | + (hint : ∀ i j, i ≠ j → (A i ∩ A j).card = 1) |
| 227 | + (hcov : ∀ b : B, 2 ≤ (Finset.univ.filter (fun i ↦ b ∈ A i)).card) |
| 228 | + (i : Fin (2 * n + 1)) : |
| 229 | + ((A i).filter |
| 230 | + (fun b ↦ colour m (Finset.univ.filter (fun k ↦ b ∈ A k)) = 0)).card = n := by |
| 231 | + have key := double_count |
| 232 | + ((A i).filter (fun b ↦ colour m (Finset.univ.filter (fun k ↦ b ∈ A k)) = 0)) |
| 233 | + (Finset.univ.erase i) (fun b j ↦ b ∈ A j) |
| 234 | + have hL : ∀ b ∈ (A i).filter |
| 235 | + (fun b ↦ colour m (Finset.univ.filter (fun k ↦ b ∈ A k)) = 0), |
| 236 | + ((Finset.univ.erase i).filter (fun j ↦ b ∈ A j)).card = 1 := |
| 237 | + fun b hb ↦ other_unique hcard hint hcov (Finset.mem_filter.mp hb).1 |
| 238 | + rw [Finset.sum_const_nat hL, mul_one] at key |
| 239 | + have hR : ∀ j ∈ Finset.univ.erase i, |
| 240 | + (((A i).filter |
| 241 | + (fun b ↦ colour m (Finset.univ.filter (fun k ↦ b ∈ A k)) = 0)).filter |
| 242 | + (fun b ↦ b ∈ A j)).card = |
| 243 | + if (j - i).val ∈ Finset.Icc 1 m ∨ (i - j).val ∈ Finset.Icc 1 m |
| 244 | + then 1 else 0 := by |
| 245 | + intro j hj |
| 246 | + have hij : i ≠ j := (Finset.mem_erase.mp hj).1.symm |
| 247 | + obtain ⟨b₀, hb₀⟩ := Finset.card_eq_one.mp (hint i j hij) |
| 248 | + have hb₀m : b₀ ∈ A i ∩ A j := by |
| 249 | + rw [hb₀] |
| 250 | + exact Finset.mem_singleton_self b₀ |
| 251 | + have hb₀i : b₀ ∈ A i := (Finset.mem_inter.mp hb₀m).1 |
| 252 | + have hb₀j : b₀ ∈ A j := (Finset.mem_inter.mp hb₀m).2 |
| 253 | + have hpair : Finset.univ.filter (fun k ↦ b₀ ∈ A k) = {i, j} := |
| 254 | + pair_eq hcard hint hcov hb₀i hb₀j hij |
| 255 | + have hcol : (colour m (Finset.univ.filter (fun k ↦ b₀ ∈ A k)) = 0) ↔ |
| 256 | + ((j - i).val ∈ Finset.Icc 1 m ∨ (i - j).val ∈ Finset.Icc 1 m) := by |
| 257 | + rw [hpair] |
| 258 | + exact colour_pair_eq_zero_iff |
| 259 | + rw [Finset.filter_comm, Finset.filter_mem_eq_inter, hb₀, Finset.filter_singleton, |
| 260 | + apply_ite Finset.card, Finset.card_singleton, Finset.card_empty] |
| 261 | + simp only [hcol] |
| 262 | + rw [Finset.sum_congr rfl hR, ← Finset.card_filter] at key |
| 263 | + rw [key] |
| 264 | + exact count_good hm i |
| 265 | + |
| 266 | +end VertexCount |
| 267 | + |
| 268 | +/-- The edges of the complete graph on `Fin N`: two-element subsets. -/ |
| 269 | +abbrev Edges (N : ℕ) : Type := {e : Finset (Fin N) // e.card = 2} |
| 270 | + |
| 271 | +/-- The set of edges incident to the vertex `i`. -/ |
| 272 | +def edgeSets (N : ℕ) (i : Fin N) : Finset (Edges N) := |
| 273 | + Finset.univ.filter (fun e ↦ i ∈ e.val) |
| 274 | + |
| 275 | +lemma mem_edgeSets {N : ℕ} {i : Fin N} {e : Edges N} : |
| 276 | + e ∈ edgeSets N i ↔ i ∈ e.val := by |
| 277 | + rw [edgeSets, Finset.mem_filter] |
| 278 | + exact and_iff_right (Finset.mem_univ e) |
| 279 | + |
| 280 | +lemma edgeSets_card {N : ℕ} (i : Fin N) : (edgeSets N i).card = N - 1 := by |
| 281 | + have h : (Finset.univ.erase i).card = (edgeSets N i).card := by |
| 282 | + refine Finset.card_bij |
| 283 | + (fun j hj ↦ ⟨{i, j}, Finset.card_pair_eq_two_iff.mpr |
| 284 | + (Finset.mem_erase.mp hj).1.symm⟩) ?_ ?_ ?_ |
| 285 | + · intro j hj |
| 286 | + exact mem_edgeSets.mpr (Finset.mem_insert_self i _) |
| 287 | + · intro j₁ h₁ j₂ h₂ heq |
| 288 | + have hv : ({i, j₁} : Finset (Fin N)) = {i, j₂} := congrArg Subtype.val heq |
| 289 | + have hmem : j₁ ∈ ({i, j₂} : Finset (Fin N)) := by |
| 290 | + rw [← hv] |
| 291 | + exact Finset.mem_insert_of_mem (Finset.mem_singleton_self j₁) |
| 292 | + rcases Finset.mem_insert.mp hmem with h | h |
| 293 | + · exact absurd h (Finset.mem_erase.mp h₁).1 |
| 294 | + · exact Finset.mem_singleton.mp h |
| 295 | + · intro e he |
| 296 | + obtain ⟨x, y, hxy, hval⟩ := Finset.card_eq_two.mp e.prop |
| 297 | + have hi : i ∈ e.val := mem_edgeSets.mp he |
| 298 | + rw [hval, Finset.mem_insert, Finset.mem_singleton] at hi |
| 299 | + rcases hi with rfl | rfl |
| 300 | + · exact ⟨y, Finset.mem_erase.mpr ⟨hxy.symm, Finset.mem_univ y⟩, |
| 301 | + Subtype.ext hval.symm⟩ |
| 302 | + · refine ⟨x, Finset.mem_erase.mpr ⟨hxy, Finset.mem_univ x⟩, Subtype.ext ?_⟩ |
| 303 | + rw [hval] |
| 304 | + exact Finset.pair_comm i x |
| 305 | + rw [← h, Finset.card_erase_of_mem (Finset.mem_univ i), Finset.card_univ, |
| 306 | + Fintype.card_fin] |
| 307 | + |
| 308 | +lemma edgeSets_inter {N : ℕ} {i j : Fin N} (hij : i ≠ j) : |
| 309 | + edgeSets N i ∩ edgeSets N j = |
| 310 | + {⟨{i, j}, Finset.card_pair_eq_two_iff.mpr hij⟩} := by |
| 311 | + ext e |
| 312 | + rw [Finset.mem_inter, Finset.mem_singleton, mem_edgeSets, mem_edgeSets] |
| 313 | + constructor |
| 314 | + · rintro ⟨hi, hj⟩ |
| 315 | + have hsub : ({i, j} : Finset (Fin N)) ⊆ e.val := |
| 316 | + Finset.insert_subset hi (Finset.singleton_subset_iff.mpr hj) |
| 317 | + have hcards : e.val.card ≤ ({i, j} : Finset (Fin N)).card := by |
| 318 | + rw [e.prop] |
| 319 | + exact le_of_eq (Finset.card_pair_eq_two_iff.mpr hij).symm |
| 320 | + exact Subtype.ext (Finset.eq_of_subset_of_card_le hsub hcards).symm |
| 321 | + · rintro rfl |
| 322 | + exact ⟨Finset.mem_insert_self i _, |
| 323 | + Finset.mem_insert_of_mem (Finset.mem_singleton_self j)⟩ |
| 324 | + |
| 325 | +lemma edgeSets_cov {N : ℕ} (e : Edges N) : |
| 326 | + (Finset.univ.filter (fun i ↦ e ∈ edgeSets N i)).card = 2 := by |
| 327 | + have h : Finset.univ.filter (fun i ↦ e ∈ edgeSets N i) = e.val := by |
| 328 | + ext i |
| 329 | + rw [Finset.mem_filter, mem_edgeSets] |
| 330 | + exact and_iff_right (Finset.mem_univ i) |
| 331 | + rw [h, e.prop] |
| 332 | + |
| 333 | +snip end |
| 334 | + |
| 335 | +problem imo1988_p2 (n : ℕ) : |
| 336 | + n ∈ SolutionSet ↔ |
| 337 | + (0 < n ∧ |
| 338 | + ∀ (B : Type) [DecidableEq B] (A : Fin (2 * n + 1) → Finset B), |
| 339 | + (∀ i, (A i).card = 2 * n) → |
| 340 | + (∀ i j, i ≠ j → (A i ∩ A j).card = 1) → |
| 341 | + (∀ b : B, 2 ≤ (Finset.univ.filter (fun i ↦ b ∈ A i)).card) → |
| 342 | + ∃ f : B → Fin 2, ∀ i, ((A i).filter (fun b ↦ f b = 0)).card = n) := by |
| 343 | + constructor |
| 344 | + · rintro ⟨hn, m, hm⟩ |
| 345 | + refine ⟨hn, ?_⟩ |
| 346 | + intro B _inst A hcard hint hcov |
| 347 | + have hm' : n = 2 * m := by lia |
| 348 | + exact ⟨fun b ↦ colour m (Finset.univ.filter (fun k ↦ b ∈ A k)), |
| 349 | + fun i ↦ vertex_count hm' hcard hint hcov i⟩ |
| 350 | + · rintro ⟨hn, H⟩ |
| 351 | + obtain ⟨f, hf⟩ := H (Edges (2 * n + 1)) (edgeSets (2 * n + 1)) |
| 352 | + (fun i ↦ by rw [edgeSets_card]; lia) |
| 353 | + (fun i j hij ↦ by rw [edgeSets_inter hij, Finset.card_singleton]) |
| 354 | + (fun e ↦ le_of_eq (edgeSets_cov e).symm) |
| 355 | + refine ⟨hn, ?_⟩ |
| 356 | + have key := double_count (Finset.univ.filter (fun e ↦ f e = 0)) |
| 357 | + (Finset.univ : Finset (Fin (2 * n + 1))) (fun e i ↦ e ∈ edgeSets (2 * n + 1) i) |
| 358 | + have hL : ∀ e ∈ Finset.univ.filter (fun e ↦ f e = 0), |
| 359 | + (Finset.univ.filter (fun i ↦ e ∈ edgeSets (2 * n + 1) i)).card = 2 := |
| 360 | + fun e _ ↦ edgeSets_cov e |
| 361 | + rw [Finset.sum_const_nat hL] at key |
| 362 | + have hR : ∀ i ∈ (Finset.univ : Finset (Fin (2 * n + 1))), |
| 363 | + ((Finset.univ.filter (fun e ↦ f e = 0)).filter |
| 364 | + (fun e ↦ e ∈ edgeSets (2 * n + 1) i)).card = n := by |
| 365 | + intro i _ |
| 366 | + have h : (Finset.univ.filter (fun e ↦ f e = 0)).filter |
| 367 | + (fun e ↦ e ∈ edgeSets (2 * n + 1) i) = |
| 368 | + (edgeSets (2 * n + 1) i).filter (fun e ↦ f e = 0) := by |
| 369 | + rw [Finset.filter_comm, Finset.filter_mem_eq_inter, Finset.univ_inter] |
| 370 | + rw [h] |
| 371 | + exact hf i |
| 372 | + rw [Finset.sum_const_nat hR, Finset.card_univ, Fintype.card_fin] at key |
| 373 | + have heven : Even ((2 * n + 1) * n) := |
| 374 | + ⟨(Finset.univ.filter (fun e ↦ f e = 0)).card, by lia⟩ |
| 375 | + exact (Nat.even_mul.mp heven).resolve_left |
| 376 | + fun h ↦ Nat.even_add_one.mp h (even_two_mul n) |
| 377 | + |
| 378 | +end Imo1988P2 |
0 commit comments