“Google интервью” задача с Codewars
В этой статье решаю задачу основанную на меме от Max Howell(создатель Homebrew), которого на собеседовании в Google заставляли инвертировать бинарное дерево, но он почему-то не смог
Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.
Max Howell не смог, но я верю, что вы сможете! Рекомендую решать самостоятельно.
Хочется сказать, что функция инвертирования в задаче уже реализована и на самом деле мы будем доказывать, что дважды инвертированное дерево равно исходному дереву.
Импорты и определение модуля:
{-# OPTIONS --safe #-}
module Codewars.GoogleInterview where
open import Relation.Binary.PropositionalEquality
open ≡-Reasoning
Определение бинарного дерева:
data Tree (A : Set) : Set where
leaf : A → Tree A
branch : A → Tree A → Tree A → Tree A
Инвертирование дерева:
flipTree : {A : Set} → Tree A → Tree A
flipTree (leaf x) = leaf x
flipTree (branch x l r) = branch x (flipTree r) (flipTree l)
Доказывать будем по индукции, сначала рассмотрим случай листового узла, а потом случай ветви
flipTreeSym : {A : Set} → (t : Tree A) → t ≡ flipTree (flipTree t)
-- в случае листового узла равенство по определению
flipTreeSym (leaf a) = refl
flipTreeSym (branch x l r) =
-- доказывать будет удобнее показывая, что flipTree (flipTree t) ≡ t, а не наоборот, используем sym
sym (
-- применим flipTree к ветви
flipTree (flipTree(branch x l r)) ≡⟨⟩
-- и еще раз
flipTree (branch x (flipTree r) (flipTree l)) ≡⟨⟩
-- теперь можем применить предположение индукции к левому поддереву
branch x (flipTree(flipTree l)) (flipTree(flipTree r)) ≡⟨
cong (λ a → branch x a (flipTree(flipTree r))) (sym(flipTreeSym l))
⟩
-- а теперь к правому
branch x l (flipTree(flipTree r)) ≡⟨
cong (λ a → branch x l a) (sym(flipTreeSym r))
⟩
-- ч.т.д.
branch x l r ∎
)