Bagaimana cara menyebarkan daftar wawancara yang terhubung sendiri

Hai, Habr.


Suatu hari, saya pergi ke sebuah wawancara di satu perusahaan yang serius, dan di sana mereka menawari saya untuk membalik daftar yang hanya terhubung. Sayangnya, tugas ini mengambil seluruh putaran pertama wawancara, dan pada akhir wawancara, pewawancara mengatakan bahwa semua orang sakit hari ini, dan karena itu saya bisa pulang. Namun demikian, seluruh proses penyelesaian masalah ini, termasuk beberapa opsi untuk algoritma dan diskusi berikutnya, serta diskusi tentang apa daftar balik, di bawah kucing.


gambar


Kami memecahkan masalah


Pewawancara cukup baik dan ramah:


- Baiklah, mari kita selesaikan masalah ini: daftar yang terhubung secara tunggal diberikan, Anda perlu membalikkannya.


- Saya akan melakukannya sekarang! Dan dalam bahasa apa lebih baik melakukan ini?


- Yang mana yang lebih nyaman bagi Anda?


Saya mewawancarai pengembang C ++, tetapi untuk menggambarkan algoritme pada daftar, ini bukan bahasa terbaik. Selain itu, saya membaca di suatu tempat bahwa pada wawancara pertama Anda perlu menawarkan solusi yang tidak efektif, dan kemudian memperbaikinya secara berurutan, jadi saya membuka laptop, meluncurkan vim dan interpreter dan membuat sketsa kode ini:


revDumb : List a -> List a
revDumb [] = []
revDumb (x :: xs) = revDumb xs ++ [x]

, , , - , , :


revOnto : List a -> List a -> List a
revOnto acc [] = acc
revOnto acc (x :: xs) = revOnto (x :: acc) xs

revAcc : List a -> List a
revAcc = revOnto []

โ€” , , , .



- , . , ( ?) - , :


โ€” , , , , , , , .



revsEq : (xs : List a) -> revAcc xs = revDumb xs

, :


โ€” , case split .


โ€” generate definition, case split, obvious proof search โ€”


revsEq : (xs : List a) -> revAcc xs = revDumb xs
revsEq [] = Refl
revsEq (x :: xs) = ?revsEq_rhs_1

, , , :


โ€” , , , . , , , :


revsEq : (xs : List a) -> revAcc xs = revDumb xs
revsEq [] = Refl
revsEq (x :: xs) = let rec = revsEq xs in ?wut

โ€” ?wut,


  rec : revOnto [] xs = revDumb xs
--------------------------------------
wut : revOnto [x] xs = revDumb xs ++ [x]

โ€” revDumb xs , rec. :


revsEq (x :: xs) = let rec = revsEq xs in
                   rewrite sym rec in ?wut


--------------------------------------
wut : revOnto [x] xs = revOnto [] xs ++ [x]

โ€” c :


lemma1 : (x0 : a) -> (xs : List a) -> revOnto [x0] xs = revOnto [] xs ++ [x0]

generate definition, case split xs, obvious proof search


lemma1 : (x0 : a) -> (xs : List a) -> revOnto [x0] xs = revOnto [] xs ++ [x0]
lemma1 x0 [] = Refl
lemma1 x0 (x :: xs) = ?lemma1_rhs_2

โ€” , . lemma1 x xs, lemma1 x0 xs. , , ,


lemma1 x0 (x :: xs) = let rec = lemma1 x xs in ?wut

?wut:


  rec : revOnto [x] xs = revOnto [] xs ++ [x]
--------------------------------------
wut : revOnto [x, x0] xs = revOnto [x] xs ++ [x0]

โ€” revOnto [x] xs rec. :


lemma1 x0 (x :: xs) = let rec = lemma1 x xs in
                      rewrite rec in ?wut

โ€” , :


--------------------------------------
wut : revOnto [x, x0] xs = (revOnto [] xs ++ [x]) ++ [x0]

โ€” , . :


lemma1 x0 (x :: xs) = let rec = lemma1 x xs in
                      rewrite rec in
                      rewrite sym $ appendAssociative (revOnto [] xs) [x] [x0] in ?wut

โ€” -:


--------------------------------------
wut : revOnto [x, x0] xs = revOnto [] xs ++ [x, x0]

โ€” ! , , , . , , :


lemma2 : (acc, lst : List a) -> revOnto acc lst = revOnto [] lst ++ acc

IDE . case split lst, acc, revOnto lst:


lemma2 : (acc, lst : List a) -> revOnto acc lst = revOnto [] lst ++ acc
lemma2 acc [] = Refl
lemma2 acc (x :: xs) = ?wut1

wut1


--------------------------------------
wut1 : revOnto (x :: acc) xs = revOnto [x] xs ++ acc

:


lemma2 acc (x :: xs) = let rec = lemma2 (x :: acc) xs in ?wut1


  rec : revOnto (x :: acc) xs = revOnto [] xs ++ x :: acc
--------------------------------------
wut1 : revOnto (x :: acc) xs = revOnto [x] xs ++ acc

rec:


lemma2 acc (x :: xs) = let rec = lemma2 (x :: acc) xs in
                       rewrite rec in ?wut1


--------------------------------------
wut1 : revOnto [] xs ++ x :: acc = revOnto [x] xs ++ acc

โ€” - . , lemma1 , , lemma2 , lemma1 x xs , lemma2 [x] xs:


lemma2 acc (x :: xs) = let rec1 = lemma2 (x :: acc) xs in
                       let rec2 = lemma2 [x] xs in
                       rewrite rec1 in
                       rewrite rec2 in ?wut1

:


--------------------------------------
wut1 : revOnto [] xs ++ x :: acc = (revOnto [] xs ++ [x]) ++ acc

, :


lemma2 : (acc, lst : List a) -> revOnto acc lst = revOnto [] lst ++ acc
lemma2 acc [] = Refl
lemma2 acc (x :: xs) = let rec1 = lemma2 (x :: acc) xs in
                       let rec2 = lemma2 [x] xs in
                       rewrite rec1 in
                       rewrite rec2 in 
                       rewrite sym $ appendAssociative (revOnto [] xs) [x] acc in Refl

โ€” , lemma1 , , lemma2 lemma. , , , :


lemma : (acc, lst : List a) -> revOnto acc lst = revOnto [] lst ++ acc
lemma acc [] = Refl
lemma acc (x :: xs) = let rec1 = lemma (x :: acc) xs in
                      let rec2 = lemma [x] xs in
                      rewrite rec1 in
                      rewrite rec2 in 
                      rewrite sym $ appendAssociative (revOnto [] xs) [x] acc in Refl

revsEq : (xs : List a) -> revAcc xs = revDumb xs
revsEq [] = Refl
revsEq (x :: xs) = let rec = revsEq xs in
                   rewrite sym rec in lemma [x] xs

15, - , .


โ€” , , - .


โ€” , , . ! , ? ?!



โ€” ! , ! , , ? ยซ ยป? : xs โ€” , xs' ยซยป , , . !


revCorrect : (xs : List a) ->
             (f : b -> a -> b) ->
             (init : b) ->
             foldl f init (revDumb xs) = foldr (flip f) init xs

โ€” , revDumb revAcc ( forall xs. revDumb xs = revAcc xs, , , , ), , , revDumb.


,


revCorrect : (xs : List a) ->
             (f : b -> a -> b) ->
             (init : b) ->
             foldl f init (revDumb xs) = foldr (flip f) init xs
revCorrect [] f init = Refl
revCorrect (x :: xs) f init = let rec = revCorrect xs f init in ?wut

:


  rec : foldl f init (revDumb xs) = foldr (flip f) init xs
--------------------------------------
wut : foldl f init (revDumb xs ++ [x]) = f (foldr (flip f) init xs) x

โ€” :


revCorrect (x :: xs) f init = let rec = revCorrect xs f init in
                              rewrite sym rec in ?wut


--------------------------------------
wut : foldl f init (revDumb xs ++ [x]) = f (foldl f init (revDumb xs)) x

โ€” revDumb xs . : f f, . :


foldlRhs : (f : b -> a -> b) ->
           (init : b) ->
           (x : a) ->
           (xs : List a) ->
           foldl f init (xs ++ [x]) = f (foldl f init xs) x

โ€” , . :


foldlRhs : (f : b -> a -> b) ->
           (init : b) ->
           (x : a) ->
           (xs : List a) ->
           foldl f init (xs ++ [x]) = f (foldl f init xs) x
foldlRhs f init x [] = Refl
foldlRhs f init x (y :: xs) = foldlRhs f (f init y) x xs

revCorrect : (xs : List a) ->
             (f : b -> a -> b) ->
             (init : b) ->
             foldl f init (revDumb xs) = foldr (flip f) init xs
revCorrect [] f init = Refl
revCorrect (x :: xs) f init = let rec = revCorrect xs f init in
                              rewrite sym rec in foldlRhs f init x (revDumb xs)

โ€” - ?
โ€” . , .
โ€” โ€ฆ , , . , , , , .


, - .

Source: https://habr.com/ru/post/id463957/


All Articles