From: Neil Smith Date: Fri, 21 Jul 2017 09:43:06 +0000 (+0100) Subject: Various changes to day 4 X-Git-Url: https://git.njae.me.uk/?p=ou-summer-of-code-2017.git;a=commitdiff_plain;h=55f602f3ca4d1297233e471706caaad9c7a99b5e Various changes to day 4 --- diff --git a/04-08-amidakuji/04-lines.txt b/04-08-amidakuji/04-lines.txt deleted file mode 100644 index c859642..0000000 --- a/04-08-amidakuji/04-lines.txt +++ /dev/null @@ -1,10135 +0,0 @@ -(15, 25) -(5, 21) -(1, 19) -(7, 8) -(6, 14) -(2, 9) -(11, 16) -(1, 10) -(14, 22) -(2, 25) -(7, 9) -(8, 18) -(6, 23) -(4, 6) -(2, 13) -(9, 14) -(12, 18) -(0, 10) -(2, 3) -(6, 19) -(1, 10) -(8, 10) -(0, 19) -(10, 25) -(19, 20) -(2, 25) -(10, 23) -(3, 19) -(17, 20) -(3, 5) -(8, 25) -(19, 23) -(2, 21) -(16, 17) -(1, 10) -(2, 18) -(8, 13) -(3, 4) -(1, 5) -(1, 21) -(11, 13) -(4, 12) -(0, 8) -(3, 4) -(1, 5) -(4, 10) -(1, 21) -(5, 22) -(1, 12) -(10, 15) -(4, 9) -(5, 24) -(8, 21) -(3, 8) -(1, 14) -(14, 24) -(8, 13) -(1, 12) -(3, 22) -(13, 19) -(0, 3) -(1, 10) -(12, 18) -(5, 22) -(4, 19) -(5, 7) -(10, 16) -(0, 17) -(9, 13) -(3, 18) -(6, 13) -(0, 14) -(19, 25) -(2, 17) -(4, 21) -(3, 16) -(10, 15) -(11, 19) -(2, 22) -(3, 4) -(9, 15) -(11, 21) -(2, 18) -(8, 19) -(8, 23) -(2, 25) -(10, 18) -(2, 22) -(7, 25) -(6, 18) -(22, 25) -(7, 11) -(2, 12) -(0, 18) -(9, 11) -(12, 19) -(2, 10) -(22, 24) -(10, 15) -(24, 25) -(20, 22) -(19, 23) -(8, 10) -(0, 19) -(16, 22) -(15, 21) -(1, 21) -(13, 22) -(12, 16) -(15, 17) -(2, 10) -(0, 18) -(6, 10) -(21, 23) -(9, 15) -(2, 7) -(9, 23) -(0, 6) -(10, 24) -(7, 21) -(5, 23) -(14, 24) -(1, 10) -(6, 7) -(5, 21) -(4, 6) -(9, 10) -(1, 20) -(2, 23) -(1, 25) -(0, 20) -(9, 16) -(13, 20) -(2, 25) -(1, 17) -(16, 24) -(9, 10) -(19, 25) -(3, 16) -(20, 21) -(13, 18) -(14, 24) -(1, 23) -(0, 17) -(0, 10) -(17, 19) -(9, 23) -(1, 15) -(12, 25) -(13, 24) -(0, 3) -(2, 19) -(23, 24) -(4, 10) -(3, 8) -(4, 7) -(2, 9) -(20, 23) -(5, 7) -(2, 18) -(9, 11) -(0, 3) -(2, 12) -(7, 24) -(0, 16) -(3, 9) -(10, 18) -(6, 7) -(9, 20) -(3, 21) -(15, 16) -(16, 23) -(5, 7) -(3, 8) -(0, 9) -(8, 12) -(7, 15) -(5, 9) -(0, 6) -(16, 19) -(9, 18) -(12, 21) -(1, 6) -(16, 23) -(0, 3) -(16, 19) -(3, 14) -(0, 18) -(6, 20) -(21, 24) -(1, 17) -(2, 12) -(12, 13) -(2, 8) -(17, 24) -(5, 20) -(1, 16) -(3, 19) -(8, 22) -(19, 20) -(2, 10) -(12, 25) -(4, 8) -(2, 7) -(13, 25) -(9, 20) -(20, 21) -(5, 8) -(4, 10) -(0, 9) -(5, 14) -(6, 9) -(2, 20) -(0, 16) -(5, 10) -(14, 20) -(0, 11) -(1, 16) -(3, 9) -(3, 6) -(2, 16) -(0, 12) -(11, 22) -(2, 25) -(11, 23) -(0, 17) -(12, 18) -(3, 14) -(1, 22) -(8, 25) -(5, 12) -(0, 24) -(15, 23) -(3, 21) -(2, 22) -(0, 12) -(7, 23) -(1, 25) -(5, 18) -(11, 24) -(3, 6) -(12, 18) -(7, 19) -(5, 20) -(10, 23) -(3, 4) -(3, 21) -(4, 19) -(7, 15) -(0, 10) -(20, 22) -(14, 23) -(21, 24) -(3, 20) -(8, 14) -(6, 23) -(10, 18) -(4, 20) -(6, 9) -(8, 13) -(16, 23) -(11, 14) -(13, 17) -(8, 10) -(16, 19) -(11, 15) -(9, 10) -(13, 14) -(17, 25) -(9, 16) -(6, 17) -(0, 14) -(10, 23) -(11, 25) -(0, 4) -(3, 23) -(20, 25) -(14, 24) -(6, 8) -(10, 22) -(17, 23) -(5, 6) -(14, 16) -(0, 10) -(8, 12) -(10, 13) -(2, 12) -(4, 6) -(1, 17) -(14, 21) -(6, 15) -(2, 3) -(0, 10) -(2, 22) -(0, 8) -(3, 18) -(10, 13) -(2, 15) -(3, 19) -(8, 17) -(0, 18) -(10, 23) -(12, 13) -(17, 20) -(5, 13) -(3, 25) -(0, 9) -(6, 12) -(15, 16) -(14, 23) -(5, 14) -(15, 21) -(1, 23) -(6, 24) -(13, 18) -(10, 23) -(13, 22) -(4, 24) -(3, 14) -(1, 6) -(5, 6) -(13, 25) -(6, 15) -(5, 21) -(13, 19) -(9, 25) -(13, 16) -(9, 22) -(18, 25) -(6, 22) -(10, 25) -(9, 24) -(3, 13) -(6, 11) -(16, 22) -(10, 18) -(3, 17) -(15, 24) -(8, 25) -(9, 23) -(2, 23) -(10, 12) -(13, 17) -(8, 15) -(0, 25) -(19, 24) -(16, 24) -(12, 15) -(13, 25) -(7, 10) -(3, 17) -(0, 2) -(7, 11) -(16, 19) -(5, 10) -(12, 17) -(2, 24) -(14, 25) -(4, 10) -(2, 22) -(5, 8) -(1, 14) -(5, 18) -(12, 14) -(8, 20) -(4, 15) -(10, 21) -(18, 19) -(10, 23) -(8, 16) -(20, 22) -(5, 7) -(7, 9) -(0, 22) -(8, 11) -(19, 20) -(4, 16) -(11, 20) -(4, 17) -(9, 21) -(8, 15) -(6, 22) -(3, 16) -(1, 19) -(0, 19) -(5, 6) -(7, 16) -(1, 24) -(8, 10) -(8, 14) -(3, 10) -(7, 11) -(2, 5) -(12, 19) -(6, 18) -(13, 24) -(10, 13) -(1, 3) -(12, 16) -(6, 9) -(19, 23) -(14, 17) -(4, 24) -(3, 20) -(15, 16) -(1, 7) -(11, 12) -(0, 24) -(10, 18) -(2, 13) -(12, 22) -(0, 17) -(4, 10) -(15, 25) -(10, 23) -(13, 15) -(1, 25) -(4, 17) -(13, 18) -(2, 10) -(21, 25) -(4, 14) -(1, 11) -(0, 4) -(14, 19) -(8, 11) -(9, 18) -(1, 15) -(13, 18) -(5, 11) -(2, 8) -(3, 13) -(5, 16) -(15, 18) -(3, 23) -(7, 18) -(13, 17) -(0, 15) -(5, 9) -(5, 15) -(1, 23) -(18, 20) -(17, 24) -(6, 13) -(12, 15) -(5, 14) -(20, 23) -(1, 21) -(16, 17) -(20, 24) -(16, 23) -(10, 17) -(7, 14) -(11, 16) -(7, 23) -(24, 25) -(10, 21) -(22, 23) -(10, 18) -(4, 16) -(17, 21) -(15, 22) -(18, 19) -(13, 21) -(16, 20) -(15, 23) -(21, 24) -(14, 16) -(3, 13) -(5, 20) -(17, 19) -(7, 22) -(9, 21) -(7, 23) -(2, 13) -(14, 25) -(5, 24) -(3, 8) -(6, 16) -(0, 6) -(3, 7) -(13, 22) -(14, 18) -(3, 12) -(4, 6) -(0, 8) -(6, 9) -(7, 8) -(1, 3) -(4, 25) -(0, 20) -(17, 20) -(8, 18) -(5, 6) -(10, 25) -(8, 15) -(6, 23) -(10, 21) -(4, 5) -(14, 18) -(14, 20) -(11, 21) -(6, 24) -(4, 18) -(3, 4) -(7, 24) -(6, 17) -(17, 19) -(4, 25) -(18, 24) -(7, 10) -(6, 12) -(10, 18) -(5, 19) -(6, 23) -(12, 16) -(0, 17) -(4, 14) -(3, 19) -(9, 12) -(11, 23) -(6, 21) -(1, 17) -(16, 22) -(1, 24) -(5, 12) -(0, 9) -(19, 21) -(6, 8) -(17, 24) -(5, 9) -(2, 12) -(1, 15) -(17, 22) -(20, 24) -(2, 23) -(14, 15) -(1, 13) -(3, 20) -(4, 24) -(2, 23) -(0, 1) -(13, 25) -(10, 17) -(7, 10) -(20, 24) -(13, 22) -(1, 9) -(0, 3) -(0, 20) -(18, 24) -(22, 23) -(5, 7) -(10, 11) -(2, 11) -(8, 24) -(14, 20) -(7, 12) -(0, 25) -(4, 18) -(2, 3) -(23, 25) -(0, 15) -(14, 21) -(16, 18) -(13, 24) -(6, 12) -(0, 21) -(7, 23) -(2, 14) -(10, 24) -(6, 17) -(3, 22) -(9, 12) -(15, 22) -(11, 24) -(6, 21) -(3, 14) -(0, 9) -(10, 16) -(5, 17) -(6, 13) -(22, 25) -(2, 10) -(8, 15) -(4, 25) -(13, 19) -(8, 24) -(10, 13) -(4, 6) -(3, 25) -(0, 24) -(18, 19) -(8, 9) -(8, 19) -(18, 20) -(7, 13) -(5, 10) -(17, 25) -(6, 25) -(20, 24) -(16, 18) -(12, 16) -(2, 20) -(15, 18) -(5, 24) -(4, 25) -(9, 20) -(3, 18) -(8, 16) -(2, 22) -(2, 15) -(7, 16) -(11, 20) -(1, 7) -(0, 11) -(2, 6) -(11, 15) -(2, 22) -(0, 14) -(1, 16) -(1, 10) -(16, 20) -(14, 17) -(6, 15) -(4, 11) -(0, 15) -(5, 20) -(12, 17) -(1, 11) -(10, 20) -(5, 9) -(12, 18) -(17, 24) -(15, 20) -(4, 12) -(14, 18) -(5, 16) -(14, 19) -(5, 13) -(8, 16) -(1, 12) -(18, 23) -(10, 13) -(5, 11) -(9, 19) -(8, 21) -(14, 25) -(12, 17) -(0, 16) -(23, 24) -(15, 18) -(6, 18) -(16, 25) -(15, 19) -(10, 21) -(0, 13) -(5, 17) -(18, 22) -(11, 15) -(0, 24) -(7, 19) -(5, 8) -(2, 10) -(10, 21) -(23, 24) -(0, 24) -(11, 23) -(2, 10) -(0, 16) -(6, 11) -(2, 25) -(10, 21) -(12, 24) -(10, 22) -(1, 16) -(12, 13) -(4, 25) -(0, 9) -(12, 22) -(19, 25) -(10, 20) -(7, 13) -(1, 2) -(16, 19) -(2, 3) -(0, 25) -(4, 22) -(6, 13) -(13, 15) -(0, 5) -(6, 9) -(22, 24) -(1, 2) -(8, 16) -(12, 25) -(7, 16) -(8, 21) -(13, 24) -(3, 5) -(9, 23) -(3, 18) -(0, 8) -(9, 11) -(2, 5) -(10, 13) -(6, 21) -(15, 23) -(9, 13) -(15, 23) -(1, 11) -(8, 20) -(3, 10) -(4, 6) -(14, 18) -(8, 15) -(1, 2) -(0, 6) -(10, 19) -(20, 21) -(20, 24) -(21, 23) -(10, 16) -(6, 22) -(23, 25) -(5, 21) -(8, 20) -(14, 24) -(8, 21) -(6, 14) -(10, 23) -(4, 5) -(4, 20) -(6, 25) -(5, 19) -(10, 12) -(8, 9) -(1, 20) -(9, 18) -(11, 19) -(0, 6) -(8, 13) -(7, 13) -(17, 18) -(20, 21) -(3, 9) -(6, 11) -(2, 18) -(4, 20) -(7, 8) -(13, 22) -(12, 21) -(3, 6) -(6, 11) -(2, 24) -(12, 14) -(20, 23) -(5, 7) -(2, 17) -(5, 12) -(3, 6) -(0, 7) -(8, 24) -(18, 23) -(15, 23) -(7, 20) -(1, 2) -(8, 13) -(22, 24) -(17, 24) -(1, 25) -(16, 23) -(8, 19) -(17, 18) -(20, 25) -(14, 16) -(0, 1) -(9, 23) -(3, 19) -(22, 23) -(19, 20) -(24, 25) -(9, 12) -(6, 23) -(2, 22) -(17, 25) -(8, 23) -(1, 6) -(19, 25) -(2, 16) -(14, 22) -(0, 14) -(6, 16) -(4, 23) -(1, 13) -(21, 22) -(17, 25) -(8, 18) -(6, 15) -(1, 3) -(7, 22) -(14, 24) -(1, 23) -(7, 9) -(10, 22) -(19, 24) -(1, 2) -(3, 22) -(5, 10) -(3, 8) -(5, 12) -(11, 12) -(12, 15) -(10, 11) -(10, 15) -(0, 11) -(10, 14) -(5, 15) -(11, 21) -(0, 9) -(8, 14) -(6, 21) -(5, 18) -(11, 12) -(0, 5) -(4, 12) -(18, 22) -(11, 13) -(3, 8) -(3, 16) -(10, 13) -(12, 15) -(5, 20) -(12, 16) -(8, 15) -(20, 22) -(4, 5) -(1, 5) -(14, 20) -(6, 12) -(3, 8) -(4, 7) -(10, 22) -(5, 22) -(2, 6) -(9, 20) -(0, 12) -(8, 23) -(10, 21) -(1, 10) -(7, 20) -(7, 24) -(1, 14) -(14, 18) -(2, 24) -(1, 20) -(7, 22) -(9, 20) -(1, 8) -(2, 21) -(18, 19) -(7, 23) -(16, 22) -(1, 12) -(13, 23) -(9, 25) -(5, 21) -(12, 20) -(2, 21) -(13, 18) -(20, 23) -(5, 21) -(16, 21) -(5, 19) -(10, 23) -(16, 24) -(4, 21) -(5, 14) -(14, 18) -(22, 24) -(0, 16) -(7, 21) -(14, 16) -(8, 21) -(1, 24) -(0, 15) -(16, 23) -(2, 14) -(21, 22) -(15, 18) -(12, 18) -(3, 22) -(8, 14) -(5, 15) -(2, 4) -(3, 10) -(1, 14) -(4, 9) -(13, 22) -(6, 8) -(18, 21) -(11, 12) -(16, 18) -(12, 17) -(4, 21) -(0, 14) -(9, 23) -(10, 15) -(0, 11) -(14, 18) -(7, 16) -(12, 22) -(5, 23) -(3, 9) -(14, 24) -(10, 11) -(5, 7) -(6, 22) -(0, 19) -(16, 25) -(1, 9) -(5, 9) -(14, 23) -(6, 11) -(0, 15) -(1, 3) -(20, 24) -(1, 7) -(14, 18) -(20, 22) -(11, 12) -(0, 7) -(18, 25) -(9, 12) -(6, 22) -(2, 11) -(13, 18) -(16, 25) -(0, 7) -(1, 9) -(10, 11) -(18, 20) -(13, 25) -(11, 12) -(7, 17) -(0, 2) -(10, 19) -(7, 15) -(8, 13) -(0, 24) -(5, 19) -(22, 25) -(4, 22) -(18, 24) -(8, 9) -(2, 13) -(14, 15) -(7, 14) -(13, 23) -(16, 18) -(14, 15) -(2, 16) -(6, 7) -(22, 23) -(22, 23) -(1, 14) -(6, 8) -(15, 25) -(6, 24) -(17, 25) -(8, 11) -(15, 21) -(4, 15) -(10, 24) -(17, 23) -(7, 11) -(13, 15) -(6, 11) -(17, 23) -(7, 21) -(3, 21) -(4, 7) -(12, 15) -(4, 14) -(6, 21) -(9, 15) -(12, 13) -(3, 5) -(19, 21) -(4, 25) -(3, 24) -(6, 7) -(5, 18) -(9, 22) -(14, 23) -(5, 7) -(14, 15) -(16, 22) -(20, 24) -(2, 18) -(0, 3) -(0, 6) -(21, 22) -(18, 23) -(3, 12) -(9, 16) -(5, 17) -(14, 19) -(11, 23) -(14, 24) -(19, 20) -(12, 22) -(7, 20) -(5, 19) -(17, 24) -(0, 20) -(5, 6) -(4, 19) -(7, 25) -(10, 17) -(1, 10) -(4, 8) -(3, 25) -(7, 18) -(8, 14) -(5, 7) -(22, 25) -(3, 6) -(4, 10) -(3, 20) -(0, 7) -(4, 15) -(16, 25) -(2, 6) -(3, 8) -(0, 9) -(7, 24) -(16, 18) -(17, 20) -(17, 19) -(1, 20) -(22, 24) -(0, 12) -(12, 13) -(2, 17) -(3, 24) -(20, 22) -(0, 11) -(4, 24) -(10, 11) -(14, 20) -(1, 3) -(6, 17) -(3, 25) -(6, 16) -(1, 5) -(0, 20) -(2, 17) -(4, 8) -(19, 25) -(3, 9) -(2, 21) -(8, 18) -(0, 12) -(4, 21) -(2, 16) -(15, 19) -(3, 25) -(10, 15) -(8, 19) -(9, 25) -(11, 19) -(7, 8) -(10, 14) -(3, 8) -(2, 10) -(13, 14) -(5, 11) -(6, 7) -(6, 20) -(3, 9) -(11, 16) -(7, 14) -(5, 24) -(17, 24) -(0, 11) -(20, 22) -(10, 16) -(6, 18) -(11, 12) -(8, 18) -(14, 16) -(17, 22) -(1, 20) -(5, 6) -(8, 9) -(17, 18) -(10, 14) -(16, 21) -(6, 7) -(5, 7) -(4, 6) -(11, 16) -(2, 4) -(10, 11) -(6, 15) -(7, 22) -(15, 25) -(7, 24) -(13, 22) -(2, 5) -(5, 18) -(2, 19) -(1, 7) -(4, 25) -(2, 12) -(4, 21) -(7, 16) -(9, 18) -(1, 24) -(13, 24) -(7, 21) -(14, 16) -(21, 23) -(8, 14) -(6, 23) -(14, 17) -(8, 22) -(23, 25) -(6, 13) -(12, 14) -(11, 17) -(20, 25) -(16, 23) -(13, 21) -(11, 14) -(9, 11) -(16, 20) -(15, 25) -(0, 23) -(11, 18) -(0, 2) -(16, 20) -(9, 14) -(9, 18) -(2, 3) -(0, 19) -(8, 20) -(3, 4) -(0, 5) -(4, 24) -(3, 10) -(4, 23) -(3, 19) -(10, 21) -(1, 21) -(3, 6) -(2, 10) -(6, 21) -(2, 17) -(3, 22) -(1, 23) -(1, 2) -(3, 13) -(0, 22) -(14, 21) -(7, 17) -(21, 22) -(13, 16) -(14, 19) -(2, 4) -(1, 17) -(6, 19) -(21, 24) -(15, 16) -(1, 3) -(4, 25) -(8, 22) -(5, 22) -(19, 20) -(14, 21) -(13, 22) -(0, 14) -(11, 19) -(5, 15) -(13, 23) -(6, 15) -(19, 24) -(17, 22) -(10, 23) -(7, 15) -(13, 21) -(8, 15) -(10, 14) -(7, 25) -(4, 23) -(9, 21) -(13, 16) -(2, 21) -(5, 9) -(4, 18) -(15, 19) -(0, 8) -(15, 25) -(13, 21) -(5, 11) -(0, 19) -(4, 22) -(8, 11) -(7, 15) -(14, 22) -(5, 9) -(13, 24) -(6, 21) -(3, 14) -(4, 21) -(1, 5) -(20, 22) -(9, 24) -(5, 18) -(9, 17) -(0, 14) -(4, 13) -(1, 6) -(1, 23) -(3, 6) -(13, 22) -(5, 8) -(5, 7) -(13, 18) -(1, 9) -(3, 19) -(11, 23) -(13, 25) -(1, 2) -(0, 23) -(11, 14) -(0, 18) -(13, 24) -(8, 14) -(13, 17) -(0, 3) -(4, 18) -(6, 24) -(6, 25) -(12, 17) -(18, 21) -(4, 16) -(13, 19) -(15, 16) -(17, 20) -(0, 13) -(9, 18) -(4, 24) -(21, 25) -(5, 12) -(15, 24) -(18, 25) -(3, 16) -(1, 20) -(7, 13) -(4, 19) -(7, 11) -(4, 6) -(1, 10) -(10, 21) -(7, 13) -(1, 17) -(2, 4) -(10, 22) -(2, 5) -(7, 11) -(12, 21) -(7, 16) -(17, 21) -(10, 13) -(1, 22) -(1, 9) -(13, 16) -(3, 21) -(17, 23) -(1, 22) -(15, 21) -(10, 23) -(12, 17) -(5, 10) -(2, 15) -(11, 22) -(17, 19) -(0, 12) -(1, 25) -(9, 12) -(19, 24) -(2, 20) -(17, 19) -(2, 4) -(8, 24) -(3, 24) -(9, 17) -(19, 21) -(3, 20) -(16, 24) -(9, 18) -(9, 14) -(3, 13) -(1, 20) -(1, 6) -(14, 15) -(16, 20) -(8, 9) -(9, 19) -(16, 22) -(15, 24) -(12, 14) -(7, 20) -(8, 15) -(14, 19) -(3, 24) -(12, 21) -(16, 18) -(9, 10) -(6, 9) -(2, 16) -(12, 18) -(20, 24) -(11, 19) -(0, 8) -(5, 14) -(4, 15) -(14, 25) -(7, 8) -(5, 13) -(0, 19) -(0, 2) -(23, 25) -(14, 15) -(13, 18) -(19, 24) -(20, 24) -(5, 15) -(0, 9) -(12, 25) -(8, 13) -(3, 23) -(2, 17) -(1, 8) -(2, 11) -(14, 15) -(5, 15) -(2, 7) -(14, 16) -(5, 12) -(14, 25) -(15, 17) -(0, 5) -(15, 21) -(12, 20) -(17, 24) -(6, 21) -(12, 25) -(9, 15) -(15, 18) -(21, 22) -(6, 17) -(0, 9) -(20, 22) -(4, 21) -(6, 15) -(9, 24) -(0, 8) -(5, 17) -(7, 21) -(1, 4) -(17, 20) -(11, 15) -(1, 7) -(14, 20) -(12, 21) -(0, 11) -(2, 4) -(7, 13) -(2, 10) -(5, 12) -(1, 3) -(14, 15) -(12, 13) -(10, 19) -(2, 23) -(0, 5) -(1, 16) -(7, 20) -(15, 23) -(12, 18) -(10, 14) -(16, 24) -(6, 13) -(0, 8) -(17, 24) -(1, 8) -(3, 16) -(9, 23) -(12, 21) -(7, 13) -(15, 19) -(1, 19) -(12, 25) -(13, 15) -(18, 21) -(5, 8) -(4, 12) -(0, 18) -(1, 14) -(15, 17) -(5, 23) -(7, 17) -(8, 23) -(0, 6) -(13, 18) -(4, 22) -(14, 25) -(6, 22) -(13, 20) -(1, 23) -(11, 25) -(0, 24) -(5, 14) -(11, 13) -(2, 5) -(18, 23) -(6, 7) -(16, 24) -(16, 19) -(0, 13) -(2, 3) -(9, 24) -(4, 13) -(15, 16) -(17, 24) -(0, 21) -(19, 22) -(0, 6) -(4, 12) -(9, 19) -(13, 25) -(1, 4) -(15, 25) -(9, 23) -(12, 21) -(17, 23) -(3, 15) -(9, 20) -(2, 17) -(9, 13) -(15, 22) -(0, 20) -(14, 15) -(3, 17) -(15, 25) -(3, 5) -(14, 18) -(2, 17) -(10, 18) -(2, 4) -(0, 14) -(3, 24) -(15, 19) -(7, 19) -(22, 24) -(15, 25) -(5, 24) -(7, 16) -(12, 25) -(4, 25) -(16, 20) -(7, 18) -(1, 5) -(4, 21) -(7, 14) -(20, 23) -(8, 18) -(9, 16) -(3, 9) -(10, 18) -(8, 22) -(13, 23) -(7, 11) -(9, 20) -(7, 25) -(10, 11) -(3, 6) -(15, 23) -(2, 13) -(0, 11) -(21, 23) -(3, 13) -(8, 9) -(12, 20) -(15, 22) -(9, 22) -(15, 23) -(16, 21) -(7, 12) -(0, 8) -(1, 20) -(5, 21) -(7, 20) -(10, 15) -(23, 25) -(8, 11) -(5, 6) -(7, 15) -(23, 24) -(14, 25) -(8, 12) -(2, 5) -(0, 6) -(12, 13) -(8, 24) -(14, 17) -(3, 23) -(8, 14) -(4, 13) -(5, 10) -(24, 25) -(6, 21) -(0, 16) -(19, 21) -(10, 20) -(5, 22) -(1, 6) -(16, 18) -(9, 14) -(4, 15) -(2, 21) -(5, 12) -(6, 23) -(0, 20) -(1, 19) -(3, 22) -(2, 14) -(10, 22) -(0, 15) -(8, 21) -(1, 24) -(4, 22) -(6, 15) -(10, 11) -(18, 21) -(23, 24) -(10, 25) -(8, 22) -(1, 11) -(8, 18) -(1, 7) -(3, 11) -(1, 4) -(3, 16) -(7, 15) -(7, 8) -(1, 2) -(16, 19) -(3, 25) -(19, 24) -(6, 8) -(1, 9) -(3, 18) -(10, 16) -(3, 14) -(10, 15) -(12, 16) -(9, 13) -(18, 25) -(11, 24) -(0, 10) -(11, 14) -(3, 12) -(18, 21) -(16, 19) -(19, 23) -(0, 16) -(7, 14) -(8, 10) -(8, 20) -(14, 25) -(1, 23) -(10, 17) -(16, 19) -(1, 5) -(7, 19) -(13, 17) -(0, 16) -(2, 5) -(13, 19) -(1, 20) -(4, 5) -(1, 9) -(2, 23) -(15, 23) -(5, 22) -(5, 11) -(15, 22) -(0, 11) -(5, 23) -(20, 22) -(3, 22) -(8, 23) -(3, 6) -(4, 23) -(4, 7) -(17, 23) -(6, 9) -(7, 10) -(17, 22) -(12, 23) -(4, 6) -(1, 12) -(17, 24) -(5, 10) -(7, 11) -(16, 23) -(5, 8) -(1, 11) -(10, 13) -(3, 17) -(7, 18) -(8, 13) -(6, 11) -(0, 18) -(10, 22) -(3, 24) -(7, 21) -(5, 23) -(4, 22) -(8, 18) -(0, 9) -(3, 15) -(7, 20) -(10, 13) -(5, 19) -(10, 12) -(9, 25) -(2, 20) -(4, 7) -(1, 5) -(13, 22) -(5, 19) -(12, 20) -(1, 21) -(16, 21) -(1, 7) -(5, 23) -(14, 19) -(18, 21) -(11, 14) -(9, 18) -(8, 11) -(14, 21) -(11, 19) -(1, 21) -(0, 18) -(9, 23) -(7, 18) -(1, 3) -(2, 19) -(16, 23) -(3, 5) -(7, 15) -(9, 23) -(1, 8) -(6, 16) -(4, 15) -(13, 23) -(0, 3) -(4, 21) -(3, 22) -(0, 17) -(6, 23) -(15, 16) -(12, 22) -(8, 15) -(0, 13) -(14, 16) -(7, 23) -(2, 23) -(14, 24) -(3, 12) -(7, 25) -(16, 21) -(4, 7) -(1, 25) -(2, 10) -(0, 23) -(2, 20) -(7, 22) -(4, 9) -(13, 25) -(0, 14) -(0, 24) -(7, 18) -(4, 12) -(20, 21) -(9, 23) -(1, 14) -(0, 6) -(24, 25) -(9, 13) -(11, 20) -(16, 21) -(1, 22) -(0, 3) -(10, 11) -(20, 24) -(21, 23) -(7, 16) -(8, 13) -(1, 25) -(10, 18) -(3, 16) -(2, 11) -(5, 21) -(21, 24) -(10, 17) -(3, 4) -(11, 14) -(6, 18) -(12, 18) -(3, 22) -(6, 7) -(0, 14) -(15, 24) -(6, 9) -(12, 22) -(18, 19) -(0, 21) -(3, 7) -(14, 18) -(19, 20) -(3, 15) -(9, 22) -(5, 18) -(14, 23) -(2, 5) -(12, 18) -(9, 14) -(17, 23) -(5, 21) -(16, 17) -(9, 20) -(2, 6) -(19, 20) -(10, 16) -(18, 21) -(9, 25) -(5, 13) -(13, 14) -(7, 25) -(2, 16) -(11, 21) -(19, 22) -(12, 22) -(5, 19) -(0, 13) -(7, 21) -(10, 12) -(0, 18) -(13, 17) -(1, 19) -(22, 24) -(17, 19) -(18, 25) -(11, 12) -(10, 15) -(0, 21) -(1, 8) -(12, 13) -(17, 21) -(14, 25) -(5, 15) -(0, 12) -(7, 21) -(8, 15) -(14, 18) -(6, 25) -(20, 25) -(1, 8) -(0, 24) -(14, 16) -(8, 15) -(1, 17) -(5, 24) -(0, 10) -(10, 22) -(1, 25) -(8, 12) -(4, 17) -(12, 13) -(21, 25) -(2, 8) -(23, 25) -(0, 8) -(2, 6) -(13, 15) -(16, 21) -(15, 17) -(6, 11) -(21, 24) -(3, 13) -(16, 20) -(2, 5) -(3, 7) -(17, 20) -(6, 22) -(4, 13) -(14, 15) -(5, 9) -(2, 25) -(15, 19) -(9, 10) -(5, 24) -(14, 22) -(3, 20) -(0, 6) -(12, 15) -(0, 17) -(4, 14) -(3, 5) -(19, 24) -(2, 22) -(22, 25) -(16, 19) -(7, 12) -(13, 15) -(12, 20) -(8, 22) -(20, 23) -(8, 10) -(1, 22) -(4, 12) -(10, 20) -(3, 22) -(4, 11) -(4, 9) -(8, 20) -(2, 11) -(11, 18) -(5, 9) -(9, 23) -(5, 14) -(3, 11) -(5, 20) -(4, 11) -(23, 24) -(7, 23) -(21, 24) -(12, 23) -(7, 18) -(9, 24) -(0, 21) -(14, 24) -(20, 21) -(0, 2) -(18, 25) -(11, 14) -(0, 6) -(16, 24) -(6, 14) -(10, 11) -(6, 9) -(10, 19) -(7, 11) -(11, 18) -(2, 19) -(7, 12) -(10, 16) -(7, 25) -(5, 19) -(11, 17) -(10, 21) -(16, 18) -(4, 12) -(19, 24) -(4, 22) -(9, 17) -(19, 24) -(22, 25) -(3, 9) -(4, 14) -(8, 17) -(1, 8) -(7, 25) -(17, 23) -(11, 19) -(6, 23) -(15, 19) -(8, 18) -(12, 25) -(0, 11) -(8, 17) -(22, 25) -(9, 18) -(0, 10) -(19, 21) -(14, 22) -(1, 10) -(5, 19) -(4, 18) -(0, 2) -(9, 25) -(6, 18) -(3, 5) -(9, 21) -(7, 19) -(17, 25) -(0, 13) -(13, 24) -(3, 19) -(9, 21) -(2, 5) -(14, 18) -(14, 22) -(8, 13) -(2, 9) -(5, 23) -(0, 24) -(3, 4) -(5, 9) -(20, 24) -(14, 18) -(0, 15) -(13, 17) -(2, 13) -(12, 20) -(4, 14) -(15, 21) -(0, 8) -(16, 18) -(1, 16) -(4, 24) -(21, 25) -(0, 17) -(3, 20) -(11, 12) -(7, 18) -(17, 22) -(10, 18) -(4, 19) -(5, 21) -(7, 15) -(8, 25) -(14, 24) -(11, 23) -(0, 8) -(5, 10) -(12, 22) -(11, 21) -(9, 25) -(14, 18) -(4, 21) -(0, 6) -(7, 11) -(10, 16) -(14, 17) -(3, 12) -(7, 20) -(11, 24) -(2, 14) -(17, 23) -(4, 19) -(0, 23) -(2, 11) -(5, 14) -(9, 24) -(10, 17) -(3, 4) -(3, 12) -(5, 19) -(4, 18) -(8, 9) -(6, 24) -(2, 16) -(1, 19) -(4, 9) -(13, 18) -(12, 22) -(3, 25) -(8, 14) -(5, 19) -(3, 10) -(2, 5) -(1, 19) -(1, 20) -(0, 19) -(19, 22) -(9, 20) -(1, 21) -(9, 12) -(17, 19) -(0, 21) -(9, 22) -(0, 1) -(15, 21) -(13, 17) -(12, 20) -(11, 15) -(20, 24) -(0, 25) -(9, 12) -(22, 25) -(0, 8) -(11, 16) -(7, 8) -(2, 22) -(4, 25) -(11, 15) -(0, 23) -(1, 16) -(4, 6) -(1, 23) -(11, 14) -(0, 5) -(8, 14) -(0, 22) -(4, 19) -(11, 24) -(5, 18) -(8, 16) -(4, 12) -(5, 7) -(11, 21) -(3, 22) -(0, 2) -(14, 23) -(7, 20) -(5, 11) -(3, 15) -(11, 18) -(13, 20) -(3, 25) -(6, 7) -(0, 15) -(7, 23) -(3, 20) -(8, 25) -(13, 22) -(0, 7) -(3, 24) -(3, 16) -(4, 24) -(0, 6) -(0, 8) -(6, 23) -(22, 24) -(4, 17) -(3, 16) -(12, 24) -(16, 25) -(0, 17) -(4, 23) -(18, 22) -(2, 22) -(16, 21) -(4, 12) -(8, 24) -(0, 6) -(5, 25) -(4, 13) -(2, 22) -(10, 25) -(0, 15) -(16, 18) -(3, 21) -(22, 24) -(7, 21) -(14, 15) -(0, 15) -(14, 15) -(0, 3) -(3, 23) -(15, 25) -(15, 19) -(10, 25) -(7, 10) -(2, 19) -(1, 15) -(1, 24) -(2, 16) -(6, 19) -(7, 18) -(15, 21) -(8, 10) -(18, 20) -(9, 24) -(5, 16) -(15, 24) -(2, 16) -(18, 20) -(9, 25) -(18, 22) -(4, 24) -(11, 15) -(2, 8) -(16, 20) -(4, 12) -(6, 18) -(8, 11) -(13, 16) -(7, 22) -(24, 25) -(0, 8) -(2, 18) -(16, 24) -(7, 19) -(3, 11) -(6, 14) -(0, 22) -(3, 17) -(7, 23) -(7, 19) -(4, 17) -(0, 25) -(6, 22) -(12, 23) -(16, 19) -(20, 23) -(0, 1) -(9, 16) -(19, 24) -(10, 20) -(0, 8) -(0, 12) -(9, 11) -(18, 19) -(1, 8) -(10, 25) -(5, 10) -(0, 2) -(13, 19) -(12, 24) -(17, 25) -(9, 25) -(10, 19) -(13, 14) -(0, 11) -(15, 17) -(4, 5) -(4, 23) -(15, 22) -(14, 19) -(8, 13) -(5, 21) -(7, 23) -(18, 22) -(3, 19) -(13, 17) -(8, 20) -(4, 6) -(0, 15) -(8, 11) -(6, 16) -(12, 20) -(2, 3) -(19, 23) -(11, 13) -(2, 24) -(5, 20) -(14, 23) -(4, 11) -(2, 19) -(3, 14) -(3, 6) -(4, 5) -(17, 19) -(0, 6) -(3, 8) -(14, 19) -(7, 17) -(2, 17) -(14, 23) -(0, 1) -(3, 6) -(19, 25) -(1, 10) -(0, 21) -(6, 20) -(3, 24) -(13, 23) -(15, 19) -(0, 16) -(1, 9) -(6, 10) -(18, 23) -(2, 20) -(1, 12) -(4, 18) -(2, 3) -(8, 16) -(0, 22) -(10, 13) -(1, 23) -(4, 11) -(0, 8) -(18, 22) -(1, 4) -(16, 18) -(9, 23) -(0, 24) -(11, 13) -(2, 4) -(8, 9) -(14, 23) -(11, 17) -(1, 15) -(11, 20) -(1, 25) -(2, 19) -(4, 9) -(14, 18) -(12, 17) -(14, 18) -(11, 21) -(5, 21) -(13, 14) -(5, 17) -(6, 21) -(13, 23) -(11, 13) -(6, 12) -(10, 17) -(5, 25) -(6, 23) -(15, 17) -(13, 14) -(10, 19) -(0, 12) -(0, 23) -(9, 14) -(6, 7) -(3, 15) -(7, 16) -(1, 15) -(6, 8) -(17, 23) -(1, 25) -(0, 17) -(3, 7) -(4, 6) -(13, 25) -(0, 5) -(7, 23) -(4, 21) -(1, 14) -(2, 3) -(16, 25) -(11, 14) -(5, 6) -(1, 8) -(13, 17) -(8, 20) -(1, 13) -(0, 14) -(12, 25) -(4, 17) -(4, 5) -(11, 13) -(8, 10) -(2, 17) -(3, 14) -(1, 15) -(17, 23) -(0, 4) -(4, 16) -(15, 17) -(0, 24) -(4, 13) -(16, 19) -(23, 24) -(14, 15) -(11, 19) -(13, 22) -(0, 24) -(4, 21) -(3, 16) -(1, 4) -(0, 2) -(20, 22) -(16, 24) -(5, 13) -(10, 21) -(3, 9) -(4, 23) -(6, 20) -(8, 22) -(9, 25) -(23, 24) -(8, 14) -(2, 14) -(9, 23) -(6, 8) -(14, 22) -(5, 6) -(2, 15) -(7, 8) -(11, 22) -(2, 4) -(1, 7) -(14, 25) -(14, 22) -(0, 11) -(2, 3) -(6, 25) -(0, 9) -(23, 25) -(3, 10) -(14, 20) -(1, 6) -(1, 12) -(9, 22) -(0, 19) -(10, 25) -(9, 16) -(12, 20) -(17, 19) -(0, 7) -(6, 22) -(5, 20) -(12, 18) -(1, 9) -(16, 19) -(14, 22) -(6, 8) -(4, 6) -(18, 19) -(8, 13) -(1, 11) -(17, 22) -(9, 24) -(1, 17) -(2, 13) -(6, 20) -(7, 9) -(4, 21) -(15, 20) -(10, 21) -(4, 22) -(0, 13) -(0, 24) -(5, 10) -(13, 23) -(1, 4) -(2, 22) -(14, 21) -(16, 21) -(14, 18) -(0, 15) -(13, 19) -(8, 23) -(7, 23) -(8, 25) -(3, 16) -(6, 18) -(8, 14) -(3, 11) -(6, 12) -(12, 21) -(6, 16) -(13, 14) -(18, 21) -(1, 14) -(7, 13) -(10, 14) -(4, 13) -(0, 13) -(4, 6) -(3, 10) -(9, 13) -(3, 23) -(6, 20) -(17, 20) -(3, 7) -(2, 23) -(5, 6) -(12, 23) -(7, 19) -(14, 17) -(3, 24) -(1, 2) -(6, 9) -(11, 23) -(11, 22) -(17, 23) -(22, 25) -(11, 16) -(4, 22) -(4, 10) -(4, 18) -(10, 22) -(5, 18) -(4, 24) -(1, 10) -(12, 24) -(1, 13) -(0, 10) -(12, 25) -(7, 12) -(21, 25) -(14, 25) -(10, 12) -(20, 21) -(7, 11) -(12, 18) -(1, 20) -(16, 21) -(11, 17) -(8, 10) -(6, 8) -(12, 15) -(3, 20) -(1, 19) -(4, 8) -(12, 18) -(1, 23) -(13, 23) -(6, 8) -(4, 25) -(20, 25) -(4, 15) -(6, 9) -(1, 13) -(3, 13) -(1, 23) -(6, 10) -(11, 25) -(0, 20) -(3, 5) -(18, 25) -(22, 23) -(7, 13) -(3, 20) -(4, 22) -(7, 12) -(13, 21) -(9, 25) -(5, 17) -(11, 25) -(20, 24) -(16, 17) -(6, 21) -(9, 10) -(19, 25) -(13, 21) -(16, 17) -(5, 13) -(4, 16) -(1, 17) -(7, 19) -(6, 21) -(11, 21) -(5, 24) -(1, 14) -(2, 7) -(7, 14) -(11, 25) -(16, 21) -(1, 20) -(17, 24) -(5, 12) -(15, 25) -(5, 17) -(1, 22) -(3, 24) -(12, 23) -(1, 4) -(15, 16) -(18, 23) -(13, 17) -(0, 17) -(4, 21) -(1, 10) -(19, 23) -(6, 13) -(23, 25) -(4, 22) -(8, 19) -(3, 6) -(17, 24) -(1, 11) -(13, 19) -(20, 24) -(6, 18) -(3, 6) -(17, 24) -(5, 20) -(13, 14) -(1, 3) -(21, 24) -(16, 20) -(6, 9) -(8, 16) -(11, 21) -(7, 20) -(10, 21) -(7, 12) -(9, 11) -(5, 16) -(12, 20) -(17, 21) -(9, 24) -(8, 16) -(10, 15) -(12, 21) -(1, 10) -(6, 15) -(16, 21) -(1, 7) -(5, 15) -(6, 18) -(5, 7) -(14, 18) -(2, 6) -(5, 24) -(4, 6) -(0, 2) -(6, 13) -(0, 23) -(13, 22) -(0, 2) -(3, 23) -(2, 17) -(0, 4) -(11, 13) -(14, 23) -(2, 15) -(9, 11) -(4, 19) -(1, 13) -(6, 11) -(4, 25) -(9, 18) -(2, 12) -(15, 18) -(22, 25) -(3, 11) -(4, 10) -(0, 4) -(23, 25) -(10, 21) -(14, 22) -(6, 14) -(0, 15) -(17, 25) -(9, 14) -(17, 20) -(8, 15) -(6, 11) -(0, 18) -(2, 9) -(6, 21) -(10, 17) -(18, 24) -(14, 19) -(3, 18) -(10, 23) -(11, 24) -(2, 4) -(13, 14) -(5, 19) -(5, 18) -(19, 25) -(2, 23) -(4, 9) -(10, 17) -(7, 23) -(0, 9) -(1, 19) -(4, 12) -(2, 17) -(0, 23) -(1, 16) -(14, 19) -(2, 12) -(5, 16) -(7, 23) -(2, 9) -(7, 22) -(5, 17) -(16, 18) -(17, 21) -(7, 13) -(16, 24) -(6, 21) -(4, 7) -(13, 15) -(17, 19) -(19, 20) -(1, 21) -(20, 25) -(12, 21) -(14, 19) -(1, 23) -(10, 25) -(0, 12) -(18, 20) -(16, 21) -(0, 6) -(5, 10) -(16, 22) -(2, 20) -(8, 12) -(1, 16) -(8, 13) -(7, 10) -(17, 22) -(0, 4) -(8, 23) -(2, 17) -(5, 13) -(0, 19) -(7, 20) -(8, 20) -(15, 17) -(2, 23) -(9, 19) -(0, 1) -(1, 24) -(11, 15) -(18, 19) -(0, 16) -(10, 20) -(4, 24) -(0, 14) -(15, 22) -(0, 18) -(2, 15) -(13, 14) -(14, 16) -(5, 15) -(6, 13) -(3, 16) -(6, 8) -(0, 14) -(5, 17) -(17, 25) -(4, 8) -(3, 6) -(14, 24) -(16, 19) -(14, 18) -(7, 16) -(13, 19) -(3, 20) -(6, 10) -(18, 24) -(14, 22) -(2, 13) -(24, 25) -(13, 23) -(2, 17) -(6, 25) -(17, 21) -(16, 24) -(22, 25) -(11, 24) -(13, 16) -(8, 17) -(10, 13) -(7, 25) -(8, 15) -(9, 16) -(5, 22) -(18, 25) -(4, 9) -(16, 24) -(2, 7) -(4, 5) -(11, 24) -(18, 19) -(14, 16) -(18, 21) -(0, 14) -(5, 22) -(9, 11) -(16, 25) -(21, 23) -(6, 16) -(0, 24) -(13, 25) -(11, 19) -(17, 22) -(14, 20) -(0, 7) -(12, 21) -(13, 19) -(11, 18) -(1, 16) -(2, 21) -(1, 15) -(11, 23) -(12, 25) -(6, 11) -(16, 21) -(2, 18) -(16, 25) -(4, 18) -(21, 23) -(5, 16) -(18, 24) -(13, 25) -(17, 21) -(8, 25) -(2, 16) -(13, 20) -(1, 18) -(17, 22) -(13, 24) -(3, 8) -(15, 16) -(2, 19) -(20, 23) -(11, 23) -(6, 8) -(2, 12) -(7, 16) -(13, 18) -(2, 9) -(4, 18) -(12, 25) -(12, 23) -(22, 25) -(14, 18) -(9, 19) -(2, 14) -(18, 21) -(0, 22) -(5, 25) -(4, 23) -(17, 22) -(14, 16) -(12, 23) -(5, 18) -(2, 11) -(1, 17) -(9, 18) -(20, 23) -(0, 11) -(2, 19) -(9, 25) -(17, 23) -(0, 22) -(0, 7) -(14, 22) -(1, 23) -(7, 16) -(17, 23) -(6, 14) -(7, 24) -(10, 17) -(1, 23) -(5, 16) -(5, 9) -(11, 23) -(10, 15) -(17, 18) -(4, 17) -(10, 23) -(15, 20) -(11, 13) -(0, 4) -(11, 15) -(8, 13) -(3, 23) -(12, 17) -(19, 23) -(11, 24) -(2, 3) -(8, 25) -(12, 15) -(9, 13) -(13, 22) -(6, 9) -(7, 19) -(1, 2) -(18, 25) -(8, 16) -(1, 23) -(19, 20) -(2, 15) -(8, 10) -(5, 19) -(0, 10) -(2, 24) -(8, 22) -(19, 20) -(3, 10) -(7, 22) -(0, 17) -(3, 13) -(17, 19) -(7, 8) -(0, 23) -(4, 13) -(0, 19) -(7, 12) -(23, 25) -(7, 9) -(12, 16) -(16, 25) -(7, 15) -(6, 9) -(12, 18) -(7, 13) -(4, 6) -(15, 17) -(3, 25) -(14, 15) -(13, 23) -(7, 11) -(4, 9) -(15, 19) -(0, 23) -(11, 21) -(10, 14) -(4, 17) -(18, 23) -(1, 17) -(6, 15) -(5, 15) -(4, 6) -(10, 23) -(1, 20) -(4, 14) -(9, 15) -(23, 24) -(2, 6) -(10, 22) -(2, 18) -(5, 23) -(4, 12) -(7, 14) -(5, 6) -(12, 13) -(14, 19) -(16, 18) -(2, 15) -(0, 7) -(5, 7) -(4, 13) -(6, 23) -(2, 10) -(15, 17) -(8, 19) -(11, 18) -(4, 9) -(2, 25) -(16, 18) -(14, 19) -(10, 15) -(11, 24) -(4, 10) -(13, 19) -(23, 25) -(15, 18) -(8, 18) -(10, 24) -(15, 17) -(4, 21) -(13, 22) -(19, 21) -(14, 15) -(2, 4) -(18, 23) -(10, 11) -(0, 18) -(3, 19) -(2, 25) -(14, 17) -(6, 25) -(2, 20) -(1, 14) -(3, 18) -(5, 19) -(0, 11) -(20, 22) -(15, 19) -(4, 18) -(1, 24) -(2, 17) -(7, 11) -(0, 25) -(6, 11) -(21, 24) -(13, 22) -(7, 25) -(12, 15) -(8, 17) -(10, 17) -(23, 24) -(11, 13) -(15, 20) -(2, 22) -(17, 19) -(3, 10) -(24, 25) -(2, 7) -(16, 20) -(21, 22) -(1, 20) -(3, 8) -(0, 25) -(10, 23) -(7, 14) -(2, 4) -(3, 5) -(11, 20) -(2, 13) -(1, 22) -(1, 6) -(22, 24) -(2, 14) -(4, 22) -(1, 7) -(7, 15) -(1, 6) -(22, 25) -(19, 25) -(6, 17) -(7, 17) -(4, 25) -(6, 11) -(17, 21) -(6, 8) -(3, 11) -(0, 6) -(3, 16) -(15, 17) -(3, 23) -(6, 8) -(0, 21) -(14, 15) -(12, 16) -(12, 23) -(6, 11) -(7, 15) -(14, 16) -(2, 8) -(5, 23) -(8, 9) -(10, 11) -(14, 20) -(17, 20) -(5, 14) -(9, 13) -(5, 17) -(0, 20) -(1, 13) -(7, 9) -(20, 25) -(1, 15) -(9, 12) -(13, 24) -(7, 23) -(10, 17) -(5, 11) -(14, 24) -(1, 8) -(0, 12) -(3, 9) -(11, 22) -(3, 15) -(1, 13) -(17, 22) -(5, 14) -(2, 13) -(1, 15) -(11, 22) -(11, 21) -(8, 13) -(9, 22) -(4, 9) -(10, 13) -(20, 21) -(8, 23) -(2, 4) -(16, 20) -(19, 21) -(10, 24) -(13, 19) -(1, 16) -(3, 10) -(5, 20) -(12, 19) -(13, 14) -(5, 7) -(3, 8) -(20, 23) -(16, 18) -(20, 25) -(16, 17) -(6, 7) -(13, 23) -(5, 8) -(7, 15) -(6, 11) -(3, 11) -(5, 15) -(7, 18) -(14, 15) -(5, 24) -(1, 11) -(1, 7) -(5, 21) -(15, 18) -(8, 21) -(9, 18) -(9, 24) -(13, 21) -(8, 25) -(8, 15) -(14, 24) -(10, 21) -(3, 13) -(1, 3) -(4, 15) -(5, 21) -(11, 13) -(8, 20) -(11, 14) -(1, 9) -(15, 19) -(4, 23) -(20, 22) -(13, 17) -(2, 3) -(12, 19) -(11, 20) -(17, 25) -(1, 7) -(13, 21) -(6, 23) -(4, 20) -(13, 15) -(18, 19) -(1, 25) -(14, 17) -(7, 9) -(8, 23) -(3, 20) -(16, 19) -(6, 14) -(8, 9) -(18, 23) -(0, 13) -(7, 21) -(4, 19) -(5, 16) -(3, 6) -(8, 25) -(15, 20) -(11, 21) -(2, 16) -(5, 23) -(1, 4) -(6, 10) -(7, 19) -(21, 22) -(15, 25) -(0, 19) -(11, 25) -(15, 18) -(1, 20) -(20, 24) -(9, 25) -(1, 7) -(4, 18) -(6, 15) -(0, 10) -(11, 16) -(3, 4) -(12, 24) -(6, 11) -(5, 18) -(2, 10) -(8, 20) -(2, 13) -(5, 8) -(10, 21) -(1, 12) -(17, 24) -(0, 20) -(0, 16) -(10, 23) -(9, 24) -(7, 8) -(20, 22) -(6, 12) -(3, 5) -(16, 24) -(7, 20) -(6, 8) -(3, 23) -(7, 25) -(8, 15) -(3, 14) -(19, 25) -(3, 15) -(8, 15) -(21, 25) -(6, 21) -(3, 15) -(15, 20) -(12, 20) -(15, 18) -(17, 20) -(15, 16) -(0, 12) -(18, 22) -(18, 19) -(13, 15) -(17, 24) -(16, 22) -(16, 25) -(5, 22) -(12, 19) -(1, 16) -(21, 25) -(2, 5) -(10, 22) -(18, 21) -(5, 9) -(2, 20) -(7, 22) -(5, 22) -(9, 12) -(2, 4) -(11, 20) -(12, 14) -(2, 16) -(10, 20) -(22, 25) -(4, 13) -(9, 14) -(4, 7) -(2, 24) -(1, 25) -(3, 22) -(6, 10) -(2, 21) -(19, 22) -(3, 13) -(6, 15) -(0, 24) -(10, 18) -(11, 15) -(7, 18) -(19, 20) -(4, 21) -(2, 8) -(2, 4) -(15, 18) -(19, 23) -(12, 21) -(1, 7) -(0, 1) -(2, 25) -(5, 7) -(12, 20) -(2, 13) -(7, 11) -(22, 25) -(12, 25) -(15, 22) -(1, 7) -(13, 14) -(2, 17) -(9, 17) -(5, 15) -(22, 24) -(8, 9) -(13, 24) -(2, 22) -(5, 24) -(2, 11) -(3, 9) -(8, 21) -(9, 20) -(3, 18) -(2, 7) -(7, 24) -(3, 12) -(8, 20) -(18, 25) -(3, 25) -(8, 17) -(1, 12) -(10, 20) -(17, 20) -(10, 12) -(6, 25) -(3, 17) -(8, 20) -(10, 19) -(12, 21) -(0, 25) -(6, 7) -(0, 1) -(4, 19) -(22, 25) -(21, 24) -(6, 14) -(6, 20) -(15, 19) -(0, 23) -(9, 24) -(5, 14) -(21, 22) -(2, 15) -(0, 10) -(9, 20) -(3, 19) -(13, 23) -(18, 22) -(23, 25) -(10, 19) -(12, 15) -(3, 24) -(1, 24) -(10, 17) -(12, 16) -(2, 15) -(13, 15) -(2, 4) -(1, 3) -(20, 24) -(17, 25) -(15, 16) -(10, 13) -(1, 6) -(12, 24) -(3, 23) -(2, 11) -(1, 19) -(11, 20) -(3, 13) -(4, 15) -(16, 17) -(0, 2) -(6, 9) -(1, 15) -(11, 14) -(6, 8) -(4, 7) -(13, 25) -(16, 20) -(10, 15) -(18, 25) -(2, 4) -(6, 11) -(1, 24) -(1, 3) -(10, 23) -(19, 25) -(2, 10) -(1, 5) -(21, 25) -(3, 12) -(3, 4) -(10, 22) -(19, 25) -(2, 8) -(1, 14) -(13, 21) -(19, 20) -(7, 10) -(5, 21) -(11, 22) -(3, 8) -(19, 24) -(15, 20) -(0, 10) -(9, 22) -(3, 17) -(7, 20) -(4, 22) -(12, 17) -(10, 13) -(24, 25) -(2, 9) -(1, 15) -(17, 22) -(10, 18) -(11, 25) -(3, 12) -(0, 2) -(7, 13) -(2, 23) -(12, 24) -(0, 14) -(10, 16) -(9, 25) -(8, 17) -(2, 18) -(10, 15) -(6, 25) -(11, 17) -(14, 21) -(6, 18) -(2, 8) -(23, 25) -(11, 19) -(16, 21) -(15, 20) -(9, 15) -(0, 21) -(10, 25) -(14, 23) -(1, 16) -(16, 17) -(5, 16) -(0, 17) -(13, 17) -(5, 7) -(0, 19) -(16, 23) -(7, 22) -(2, 17) -(10, 16) -(12, 19) -(3, 5) -(15, 23) -(1, 22) -(7, 24) -(5, 8) -(3, 6) -(14, 22) -(6, 20) -(2, 24) -(2, 17) -(11, 22) -(4, 24) -(6, 8) -(3, 20) -(8, 9) -(19, 20) -(1, 22) -(0, 3) -(10, 22) -(9, 25) -(4, 19) -(18, 25) -(10, 13) -(8, 19) -(4, 24) -(0, 24) -(5, 19) -(2, 4) -(23, 25) -(0, 20) -(4, 12) -(17, 19) -(5, 8) -(1, 20) -(4, 11) -(5, 6) -(13, 20) -(5, 19) -(4, 17) -(1, 16) -(20, 22) -(9, 17) -(13, 24) -(15, 16) -(20, 25) -(13, 18) -(2, 22) -(16, 23) -(5, 13) -(9, 20) -(18, 24) -(1, 2) -(16, 25) -(18, 22) -(2, 6) -(1, 12) -(7, 12) -(3, 6) -(10, 22) -(1, 8) -(22, 23) -(0, 7) -(1, 12) -(18, 23) -(1, 24) -(0, 7) -(18, 19) -(7, 24) -(13, 23) -(0, 8) -(1, 6) -(8, 12) -(6, 16) -(7, 10) -(0, 15) -(0, 24) -(2, 12) -(7, 15) -(3, 6) -(2, 8) -(5, 24) -(4, 15) -(0, 16) -(8, 13) -(5, 7) -(4, 21) -(0, 25) -(14, 16) -(9, 24) -(8, 10) -(9, 25) -(0, 11) -(3, 14) -(21, 24) -(4, 17) -(7, 18) -(3, 22) -(0, 12) -(7, 8) -(4, 19) -(16, 24) -(18, 23) -(15, 17) -(1, 24) -(4, 7) -(20, 23) -(19, 22) -(16, 17) -(1, 15) -(18, 20) -(21, 23) -(10, 15) -(16, 18) -(14, 20) -(2, 23) -(7, 16) -(15, 24) -(1, 2) -(20, 25) -(14, 16) -(1, 6) -(7, 20) -(9, 24) -(14, 18) -(5, 9) -(2, 6) -(1, 4) -(4, 21) -(14, 25) -(1, 23) -(5, 11) -(9, 10) -(11, 16) -(9, 17) -(23, 24) -(10, 17) -(7, 11) -(0, 23) -(15, 24) -(9, 12) -(6, 24) -(15, 21) -(17, 19) -(4, 10) -(4, 22) -(20, 21) -(2, 15) -(7, 19) -(2, 3) -(15, 23) -(3, 6) -(0, 15) -(8, 23) -(2, 10) -(3, 4) -(6, 13) -(8, 15) -(0, 7) -(10, 21) -(2, 10) -(7, 24) -(12, 15) -(1, 15) -(8, 24) -(12, 19) -(1, 5) -(3, 19) -(7, 24) -(3, 18) -(8, 24) -(19, 21) -(5, 23) -(23, 25) -(5, 9) -(15, 24) -(8, 17) -(13, 17) -(9, 25) -(8, 11) -(0, 5) -(19, 23) -(15, 20) -(5, 9) -(6, 17) -(8, 13) -(1, 20) -(2, 6) -(10, 20) -(4, 8) -(14, 17) -(11, 20) -(8, 13) -(6, 24) -(4, 8) -(13, 25) -(2, 11) -(8, 14) -(4, 8) -(4, 22) -(8, 25) -(4, 15) -(3, 8) -(15, 18) -(4, 7) -(4, 16) -(12, 18) -(7, 19) -(15, 22) -(18, 22) -(6, 7) -(15, 17) -(4, 21) -(3, 12) -(5, 21) -(20, 22) -(3, 7) -(13, 17) -(16, 17) -(1, 22) -(7, 19) -(15, 20) -(10, 17) -(11, 15) -(2, 22) -(1, 2) -(4, 22) -(16, 17) -(11, 14) -(0, 15) -(3, 16) -(5, 11) -(21, 22) -(6, 14) -(0, 6) -(16, 17) -(3, 16) -(17, 20) -(9, 20) -(4, 17) -(9, 21) -(17, 24) -(4, 16) -(15, 24) -(17, 24) -(15, 23) -(8, 17) -(13, 23) -(11, 17) -(8, 16) -(4, 17) -(11, 13) -(8, 19) -(8, 10) -(11, 15) -(2, 17) -(19, 22) -(1, 22) -(19, 24) -(13, 17) -(2, 12) -(5, 13) -(6, 17) -(3, 12) -(2, 25) -(2, 10) -(11, 12) -(1, 6) -(5, 24) -(3, 16) -(11, 14) -(12, 22) -(8, 24) -(15, 16) -(9, 10) -(3, 21) -(6, 19) -(16, 23) -(15, 20) -(6, 17) -(11, 19) -(17, 22) -(9, 19) -(3, 11) -(6, 14) -(0, 17) -(19, 25) -(6, 10) -(11, 21) -(7, 14) -(4, 10) -(6, 9) -(13, 21) -(14, 16) -(3, 17) -(6, 24) -(7, 9) -(2, 16) -(20, 21) -(12, 14) -(11, 14) -(8, 20) -(9, 25) -(16, 22) -(2, 18) -(16, 20) -(6, 11) -(9, 21) -(16, 24) -(6, 12) -(6, 14) -(13, 24) -(16, 25) -(5, 12) -(14, 17) -(1, 13) -(10, 25) -(12, 23) -(6, 16) -(0, 10) -(3, 14) -(4, 16) -(22, 23) -(3, 7) -(2, 23) -(14, 20) -(16, 18) -(3, 24) -(6, 20) -(7, 12) -(17, 24) -(3, 8) -(6, 10) -(17, 19) -(11, 24) -(0, 6) -(10, 13) -(3, 20) -(9, 19) -(8, 20) -(0, 24) -(11, 16) -(17, 22) -(11, 15) -(12, 20) -(1, 22) -(3, 19) -(17, 22) -(1, 2) -(3, 13) -(1, 2) -(5, 22) -(3, 9) -(16, 17) -(4, 5) -(22, 24) -(1, 15) -(6, 22) -(0, 15) -(14, 24) -(3, 5) -(1, 13) -(8, 22) -(18, 24) -(3, 11) -(1, 16) -(17, 22) -(18, 19) -(7, 24) -(16, 23) -(0, 24) -(8, 16) -(13, 22) -(7, 19) -(9, 19) -(17, 22) -(13, 14) -(16, 23) -(24, 25) -(9, 18) -(12, 17) -(7, 14) -(21, 22) -(16, 19) -(2, 13) -(13, 24) -(1, 9) -(11, 14) -(7, 20) -(4, 24) -(11, 21) -(7, 23) -(1, 18) -(0, 20) -(14, 21) -(3, 20) -(11, 21) -(0, 3) -(12, 14) -(3, 22) -(12, 20) -(13, 21) -(10, 11) -(4, 14) -(4, 20) -(15, 21) -(3, 6) -(8, 13) -(0, 21) -(6, 22) -(1, 4) -(14, 15) -(3, 19) -(8, 9) -(0, 25) -(1, 24) -(9, 23) -(8, 15) -(2, 19) -(15, 20) -(0, 14) -(5, 23) -(3, 8) -(6, 19) -(9, 10) -(8, 9) -(6, 11) -(20, 24) -(10, 21) -(2, 23) -(10, 12) -(6, 13) -(1, 21) -(2, 14) -(17, 23) -(12, 13) -(18, 23) -(17, 25) -(0, 10) -(14, 24) -(6, 24) -(14, 16) -(5, 18) -(4, 10) -(9, 24) -(5, 12) -(6, 19) -(4, 18) -(10, 11) -(12, 17) -(3, 19) -(1, 18) -(4, 20) -(10, 23) -(6, 7) -(5, 17) -(10, 16) -(6, 22) -(1, 11) -(2, 12) -(12, 23) -(4, 17) -(2, 13) -(5, 8) -(5, 18) -(4, 7) -(11, 12) -(10, 13) -(0, 23) -(13, 15) -(1, 10) -(16, 23) -(5, 9) -(3, 7) -(1, 25) -(10, 20) -(15, 21) -(5, 6) -(2, 23) -(16, 18) -(9, 24) -(19, 21) -(2, 24) -(9, 20) -(12, 16) -(6, 25) -(0, 5) -(1, 14) -(18, 19) -(6, 8) -(7, 21) -(5, 14) -(13, 25) -(16, 23) -(0, 2) -(2, 8) -(1, 6) -(3, 14) -(5, 21) -(24, 25) -(12, 18) -(13, 17) -(12, 22) -(2, 16) -(14, 21) -(6, 9) -(8, 25) -(10, 17) -(8, 16) -(4, 6) -(10, 21) -(2, 5) -(14, 19) -(17, 18) -(0, 8) -(14, 22) -(16, 20) -(15, 19) -(3, 17) -(7, 18) -(7, 13) -(17, 23) -(15, 24) -(3, 22) -(18, 19) -(12, 13) -(4, 24) -(5, 23) -(19, 21) -(1, 17) -(12, 18) -(5, 14) -(15, 17) -(20, 23) -(8, 18) -(7, 17) -(14, 16) -(12, 15) -(18, 19) -(7, 25) -(11, 16) -(0, 15) -(1, 14) -(16, 21) -(17, 18) -(0, 11) -(13, 15) -(3, 15) -(0, 23) -(8, 23) -(0, 9) -(9, 11) -(0, 22) -(5, 8) -(1, 22) -(0, 23) -(6, 8) -(11, 14) -(14, 15) -(8, 20) -(1, 23) -(3, 22) -(3, 21) -(19, 23) -(8, 11) -(17, 20) -(6, 22) -(3, 16) -(6, 21) -(23, 25) -(4, 17) -(17, 25) -(6, 21) -(4, 15) -(11, 23) -(3, 9) -(6, 14) -(17, 21) -(3, 25) -(9, 23) -(5, 11) -(14, 18) -(4, 5) -(3, 10) -(9, 20) -(1, 23) -(6, 15) -(0, 25) -(2, 11) -(0, 7) -(15, 21) -(14, 19) -(4, 8) -(1, 2) -(22, 23) -(14, 20) -(4, 15) -(2, 9) -(16, 22) -(5, 23) -(0, 13) -(1, 3) -(6, 8) -(8, 19) -(5, 17) -(14, 23) -(6, 11) -(10, 14) -(2, 6) -(11, 21) -(5, 25) -(3, 17) -(8, 16) -(14, 20) -(6, 22) -(10, 17) -(16, 18) -(9, 11) -(7, 25) -(2, 24) -(1, 24) -(0, 10) -(18, 25) -(4, 9) -(14, 23) -(3, 22) -(2, 16) -(6, 15) -(11, 12) -(10, 23) -(3, 13) -(1, 15) -(6, 11) -(4, 8) -(0, 14) -(21, 25) -(3, 6) -(11, 16) -(23, 24) -(9, 25) -(2, 15) -(4, 18) -(7, 21) -(14, 25) -(6, 17) -(13, 15) -(11, 23) -(12, 25) -(2, 15) -(1, 14) -(14, 22) -(7, 12) -(1, 10) -(2, 3) -(13, 15) -(5, 15) -(4, 7) -(13, 18) -(1, 2) -(3, 25) -(7, 20) -(5, 6) -(4, 19) -(15, 22) -(11, 25) -(18, 20) -(8, 25) -(4, 24) -(9, 22) -(8, 16) -(9, 10) -(2, 20) -(24, 25) -(1, 22) -(7, 18) -(6, 10) -(4, 7) -(16, 22) -(12, 18) -(7, 24) -(11, 18) -(5, 12) -(8, 16) -(5, 21) -(15, 18) -(8, 9) -(6, 16) -(1, 11) -(7, 19) -(1, 6) -(18, 20) -(8, 21) -(15, 25) -(7, 17) -(1, 10) -(2, 20) -(12, 15) -(18, 24) -(23, 25) -(5, 23) -(15, 16) -(9, 24) -(16, 23) -(2, 24) -(14, 15) -(5, 7) -(5, 25) -(7, 17) -(4, 23) -(7, 22) -(4, 25) -(15, 23) -(14, 15) -(0, 7) -(19, 22) -(18, 25) -(4, 11) -(9, 23) -(15, 16) -(4, 18) -(8, 25) -(5, 23) -(3, 14) -(4, 24) -(11, 18) -(14, 17) -(1, 15) -(10, 25) -(5, 11) -(21, 25) -(6, 14) -(15, 19) -(8, 17) -(10, 17) -(7, 8) -(2, 15) -(6, 12) -(1, 5) -(0, 14) -(0, 22) -(17, 18) -(6, 13) -(7, 11) -(15, 16) -(3, 13) -(2, 15) -(0, 12) -(6, 9) -(1, 22) -(0, 18) -(4, 12) -(2, 5) -(15, 16) -(11, 13) -(1, 17) -(3, 20) -(4, 20) -(18, 22) -(5, 6) -(2, 8) -(11, 13) -(13, 14) -(1, 11) -(10, 18) -(4, 22) -(8, 12) -(1, 8) -(4, 9) -(14, 24) -(13, 15) -(3, 24) -(6, 15) -(9, 11) -(1, 5) -(13, 16) -(2, 13) -(4, 15) -(8, 16) -(4, 20) -(0, 13) -(2, 17) -(16, 19) -(13, 24) -(0, 22) -(2, 7) -(4, 14) -(5, 20) -(9, 17) -(0, 3) -(6, 17) -(10, 20) -(2, 8) -(14, 23) -(8, 20) -(2, 25) -(9, 23) -(6, 13) -(3, 24) -(10, 15) -(18, 20) -(22, 24) -(0, 10) -(4, 15) -(9, 25) -(1, 9) -(8, 22) -(2, 10) -(15, 17) -(14, 24) -(4, 12) -(7, 9) -(15, 20) -(4, 23) -(12, 16) -(16, 19) -(6, 20) -(7, 21) -(11, 12) -(8, 23) -(13, 15) -(4, 5) -(1, 4) -(10, 13) -(19, 25) -(9, 19) -(1, 3) -(4, 21) -(9, 17) -(1, 12) -(3, 22) -(12, 22) -(3, 15) -(1, 3) -(15, 23) -(23, 25) -(1, 2) -(3, 9) -(14, 25) -(2, 3) -(1, 15) -(16, 23) -(2, 20) -(8, 16) -(1, 4) -(13, 15) -(1, 5) -(15, 24) -(4, 23) -(10, 16) -(8, 21) -(8, 13) -(5, 19) -(4, 18) -(14, 21) -(10, 24) -(19, 23) -(17, 24) -(4, 6) -(5, 15) -(13, 20) -(4, 8) -(17, 18) -(2, 15) -(1, 19) -(5, 6) -(1, 12) -(4, 15) -(2, 11) -(7, 8) -(9, 19) -(5, 21) -(2, 25) -(8, 10) -(6, 7) -(5, 24) -(0, 12) -(16, 25) -(10, 21) -(2, 20) -(6, 8) -(7, 22) -(21, 24) -(5, 8) -(6, 19) -(4, 10) -(1, 22) -(16, 18) -(3, 8) -(12, 19) -(6, 24) -(5, 22) -(4, 7) -(1, 15) -(15, 23) -(8, 17) -(13, 19) -(6, 16) -(2, 23) -(14, 15) -(2, 9) -(14, 20) -(7, 23) -(2, 24) -(9, 21) -(13, 23) -(4, 20) -(7, 22) -(14, 25) -(4, 19) -(5, 9) -(6, 21) -(7, 20) -(10, 23) -(18, 25) -(1, 22) -(7, 21) -(13, 18) -(17, 22) -(1, 11) -(0, 5) -(15, 25) -(8, 17) -(23, 25) -(5, 12) -(3, 15) -(7, 17) -(3, 10) -(20, 25) -(6, 23) -(2, 15) -(8, 10) -(7, 18) -(2, 14) -(6, 11) -(2, 15) -(6, 19) -(11, 23) -(5, 8) -(4, 19) -(2, 14) -(5, 13) -(6, 8) -(0, 11) -(15, 16) -(14, 20) -(6, 10) -(0, 9) -(3, 16) -(2, 12) -(3, 11) -(14, 25) -(10, 13) -(1, 2) -(12, 21) -(6, 14) -(23, 25) -(0, 12) -(23, 24) -(15, 25) -(0, 2) -(4, 14) -(14, 16) -(4, 17) -(20, 25) -(8, 23) -(7, 15) -(7, 12) -(6, 23) -(8, 19) -(21, 23) -(5, 6) -(8, 18) -(19, 21) -(14, 18) -(22, 23) -(5, 15) -(12, 19) -(13, 22) -(8, 21) -(11, 18) -(5, 8) -(13, 23) -(18, 25) -(7, 22) -(4, 23) -(13, 15) -(21, 22) -(15, 16) -(13, 18) -(4, 11) -(15, 19) -(0, 16) -(15, 17) -(10, 16) -(6, 19) -(1, 10) -(2, 17) -(18, 19) -(6, 7) -(3, 15) -(2, 11) -(7, 12) -(13, 18) -(8, 17) -(15, 23) -(5, 10) -(6, 22) -(3, 14) -(18, 19) -(8, 17) -(5, 15) -(11, 22) -(8, 17) -(2, 19) -(15, 21) -(8, 10) -(1, 17) -(2, 14) -(10, 15) -(8, 22) -(13, 17) -(2, 3) -(3, 4) -(17, 24) -(5, 10) -(15, 25) -(9, 13) -(16, 17) -(20, 24) -(6, 9) -(7, 13) -(0, 25) -(7, 8) -(5, 16) -(0, 3) -(17, 19) -(6, 12) -(9, 12) -(8, 14) -(6, 24) -(2, 5) -(1, 7) -(17, 23) -(0, 23) -(7, 22) -(1, 6) -(9, 21) -(13, 14) -(8, 12) -(5, 16) -(4, 21) -(13, 19) -(8, 20) -(10, 12) -(9, 24) -(2, 5) -(1, 8) -(4, 10) -(15, 24) -(9, 18) -(11, 20) -(16, 21) -(5, 22) -(5, 7) -(22, 25) -(20, 21) -(6, 11) -(8, 10) -(14, 18) -(2, 11) -(3, 5) -(16, 25) -(13, 14) -(10, 25) -(2, 6) -(3, 4) -(11, 24) -(21, 24) -(5, 6) -(1, 2) -(5, 22) -(9, 24) -(2, 23) -(6, 17) -(1, 16) -(2, 14) -(21, 22) -(4, 9) -(1, 18) -(6, 19) -(5, 16) -(7, 24) -(0, 19) -(1, 2) -(13, 21) -(17, 22) -(14, 16) -(0, 3) -(17, 18) -(2, 6) -(20, 22) -(1, 8) -(16, 23) -(14, 21) -(9, 19) -(16, 25) -(0, 20) -(2, 15) -(9, 22) -(3, 17) -(19, 20) -(0, 3) -(9, 16) -(15, 22) -(2, 23) -(0, 1) -(12, 23) -(3, 5) -(13, 23) -(0, 5) -(3, 17) -(4, 12) -(1, 10) -(13, 14) -(6, 10) -(1, 4) -(4, 9) -(13, 19) -(1, 11) -(6, 15) -(14, 20) -(11, 24) -(7, 13) -(10, 14) -(15, 16) -(8, 19) -(6, 14) -(24, 25) -(11, 22) -(0, 22) -(1, 25) -(23, 24) -(11, 15) -(2, 6) -(0, 20) -(6, 10) -(1, 17) -(14, 15) -(9, 25) -(17, 24) -(9, 18) -(12, 20) -(3, 6) -(0, 16) -(1, 25) -(19, 20) -(3, 5) -(6, 21) -(9, 20) -(21, 22) -(6, 17) -(3, 11) -(5, 24) -(2, 19) -(20, 22) -(5, 6) -(8, 11) -(2, 7) -(15, 19) -(2, 24) -(5, 12) -(0, 11) -(6, 14) -(10, 15) -(0, 16) -(5, 7) -(14, 24) -(16, 19) -(0, 25) -(0, 18) -(16, 17) -(16, 25) -(17, 25) -(16, 19) -(18, 19) -(1, 17) -(24, 25) -(13, 16) -(15, 24) -(3, 16) -(17, 21) -(1, 9) -(0, 17) -(8, 24) -(2, 21) -(1, 15) -(10, 21) -(3, 17) -(9, 24) -(8, 22) -(9, 24) -(3, 15) -(16, 21) -(17, 18) -(8, 19) -(9, 17) -(12, 24) -(18, 23) -(18, 21) -(9, 20) -(16, 17) -(12, 15) -(13, 15) -(10, 20) -(0, 17) -(9, 14) -(14, 24) -(2, 13) -(6, 10) -(0, 3) -(20, 25) -(6, 17) -(7, 14) -(18, 25) -(19, 24) -(10, 22) -(11, 24) -(0, 22) -(16, 18) -(8, 19) -(15, 25) -(5, 6) -(12, 16) -(3, 5) -(4, 18) -(1, 6) -(14, 24) -(15, 20) -(2, 4) -(15, 18) -(13, 24) -(3, 22) -(2, 9) -(5, 24) -(13, 14) -(4, 19) -(18, 19) -(4, 8) -(9, 12) -(9, 22) -(3, 19) -(12, 23) -(4, 11) -(12, 24) -(10, 11) -(6, 23) -(10, 16) -(16, 21) -(10, 14) -(11, 16) -(20, 21) -(10, 20) -(8, 11) -(14, 21) -(15, 16) -(0, 16) -(14, 15) -(5, 10) -(8, 13) -(7, 11) -(13, 24) -(0, 20) -(2, 7) -(1, 11) -(0, 16) -(2, 18) -(5, 24) -(1, 6) -(7, 25) -(1, 17) -(16, 21) -(6, 8) -(5, 12) -(0, 11) -(19, 25) -(11, 24) -(6, 10) -(21, 22) -(12, 13) -(5, 11) -(12, 22) -(0, 24) -(13, 21) -(4, 10) -(2, 6) -(3, 6) -(18, 24) -(18, 23) -(6, 9) -(3, 19) -(11, 19) -(9, 16) -(6, 14) -(16, 24) -(2, 6) -(3, 14) -(9, 23) -(6, 7) -(9, 14) -(15, 16) -(2, 13) -(9, 24) -(13, 18) -(8, 16) -(4, 7) -(2, 10) -(0, 6) -(7, 21) -(1, 2) -(5, 18) -(13, 15) -(6, 20) -(0, 17) -(6, 15) -(1, 22) -(2, 16) -(3, 21) -(17, 19) -(14, 18) -(0, 4) -(0, 25) -(11, 16) -(18, 22) -(2, 19) -(12, 21) -(6, 20) -(8, 15) -(21, 25) -(9, 18) -(8, 13) -(0, 16) -(4, 20) -(5, 16) -(0, 19) -(13, 20) -(3, 21) -(12, 25) -(9, 24) -(10, 12) -(11, 16) -(2, 3) -(14, 21) -(8, 25) -(1, 20) -(9, 18) -(4, 25) -(21, 24) -(10, 23) -(11, 12) -(8, 17) -(17, 22) -(3, 8) -(2, 25) -(1, 21) -(10, 12) -(18, 23) -(7, 10) -(2, 3) -(18, 19) -(1, 25) -(16, 23) -(0, 22) -(4, 18) -(15, 19) -(0, 16) -(14, 22) -(3, 19) -(2, 14) -(14, 19) -(2, 13) -(14, 18) -(2, 21) -(19, 20) -(13, 15) -(4, 15) -(3, 21) -(2, 10) -(6, 19) -(11, 20) -(3, 13) -(15, 22) -(4, 20) -(0, 21) -(1, 22) -(21, 24) -(11, 15) -(4, 5) -(3, 16) -(9, 11) -(3, 19) -(5, 21) -(4, 12) -(8, 15) -(8, 11) -(3, 15) -(4, 25) -(2, 21) -(6, 8) -(12, 21) -(1, 25) -(13, 21) -(12, 23) -(18, 23) -(5, 13) -(4, 18) -(5, 21) -(12, 13) -(2, 23) -(17, 18) -(12, 20) -(3, 4) -(0, 2) -(21, 24) -(5, 19) -(15, 18) -(0, 17) -(6, 20) -(14, 24) -(2, 5) -(10, 20) -(0, 1) -(8, 14) -(15, 16) -(2, 9) -(5, 25) -(19, 24) -(12, 18) -(11, 17) -(7, 16) -(0, 5) -(1, 3) -(11, 25) -(4, 25) -(15, 16) -(7, 22) -(11, 20) -(15, 22) -(7, 12) -(0, 4) -(16, 17) -(12, 24) -(8, 17) -(7, 23) -(13, 16) -(3, 22) -(15, 25) -(12, 14) -(5, 8) -(22, 23) -(2, 16) -(9, 17) -(11, 12) -(16, 21) -(8, 10) -(16, 18) -(1, 8) -(10, 18) -(16, 19) -(1, 17) -(17, 25) -(0, 16) -(5, 18) -(13, 19) -(6, 18) -(3, 5) -(0, 15) -(2, 6) -(18, 24) -(2, 4) -(20, 24) -(2, 16) -(8, 20) -(10, 24) -(4, 20) -(2, 22) -(19, 24) -(8, 9) -(2, 9) -(13, 19) -(10, 24) -(13, 18) -(14, 19) -(2, 12) -(13, 20) -(18, 23) -(14, 22) -(9, 18) -(21, 23) -(6, 22) -(4, 20) -(18, 24) -(20, 21) -(4, 11) -(9, 20) -(3, 4) -(14, 24) -(11, 13) -(11, 22) -(9, 21) -(4, 25) -(3, 12) -(8, 20) -(9, 23) -(2, 25) -(3, 13) -(0, 8) -(22, 25) -(8, 16) -(2, 19) -(0, 15) -(10, 22) -(8, 13) -(6, 16) -(0, 21) -(16, 19) -(8, 11) -(6, 17) -(2, 8) -(4, 6) -(4, 8) -(6, 21) -(6, 16) -(4, 9) -(13, 21) -(1, 13) -(9, 14) -(6, 19) -(12, 16) -(3, 21) -(2, 12) -(6, 18) -(0, 14) -(7, 13) -(10, 14) -(0, 16) -(18, 23) -(8, 23) -(0, 3) -(16, 24) -(10, 16) -(8, 9) -(17, 23) -(1, 17) -(8, 25) -(2, 9) -(1, 11) -(2, 14) -(5, 9) -(8, 20) -(5, 6) -(14, 24) -(9, 19) -(11, 16) -(12, 20) -(8, 14) -(11, 22) -(10, 20) -(24, 25) -(6, 19) -(3, 5) -(3, 17) -(14, 20) -(5, 23) -(15, 24) -(16, 25) -(5, 21) -(3, 13) -(12, 15) -(19, 23) -(9, 24) -(22, 25) -(15, 18) -(5, 8) -(16, 21) -(9, 12) -(2, 21) -(7, 15) -(12, 20) -(0, 8) -(0, 1) -(8, 20) -(3, 15) -(7, 14) -(12, 19) -(7, 25) -(18, 19) -(2, 12) -(8, 14) -(3, 10) -(1, 12) -(5, 10) -(14, 23) -(24, 25) -(3, 9) -(12, 23) -(5, 13) -(9, 17) -(3, 25) -(9, 11) -(0, 25) -(8, 13) -(17, 20) -(9, 16) -(14, 17) -(20, 24) -(5, 16) -(20, 21) -(4, 9) -(9, 18) -(4, 13) -(1, 5) -(10, 16) -(2, 18) -(3, 5) -(16, 22) -(4, 23) -(2, 14) -(4, 23) -(11, 22) -(5, 6) -(16, 17) -(5, 17) -(2, 6) -(8, 16) -(9, 22) -(4, 5) -(16, 22) -(1, 9) -(19, 22) -(1, 15) -(10, 19) -(3, 22) -(7, 15) -(1, 14) -(3, 11) -(19, 24) -(1, 6) -(10, 16) -(12, 22) -(4, 19) -(3, 20) -(16, 23) -(11, 23) -(3, 13) -(16, 17) -(6, 13) -(3, 10) -(1, 23) -(12, 16) -(17, 18) -(9, 23) -(16, 24) -(0, 17) -(12, 25) -(6, 21) -(8, 18) -(2, 18) -(13, 25) -(5, 9) -(10, 23) -(12, 14) -(17, 20) -(6, 20) -(12, 15) -(1, 17) -(0, 15) -(6, 10) -(3, 20) -(4, 6) -(3, 12) -(11, 20) -(0, 19) -(8, 19) -(16, 20) -(3, 22) -(11, 12) -(6, 9) -(6, 23) -(4, 8) -(7, 19) -(5, 9) -(9, 10) -(8, 15) -(4, 17) -(0, 7) -(5, 11) -(0, 17) -(2, 11) -(4, 20) -(6, 9) -(11, 21) -(9, 10) -(6, 12) -(6, 16) -(8, 9) -(3, 10) -(3, 23) -(6, 22) -(0, 16) -(0, 7) -(12, 16) -(3, 9) -(7, 24) -(0, 19) -(15, 19) -(7, 8) -(22, 24) -(0, 24) -(19, 25) -(15, 23) -(3, 8) -(3, 13) -(10, 23) -(0, 25) -(9, 13) -(3, 11) -(6, 25) -(19, 23) -(16, 19) -(0, 25) -(11, 24) -(13, 21) -(10, 23) -(9, 15) -(3, 21) -(14, 15) -(3, 20) -(13, 21) -(14, 15) -(8, 13) -(14, 15) -(3, 25) -(21, 24) -(13, 24) -(4, 21) -(10, 15) -(8, 16) -(11, 14) -(6, 25) -(14, 20) -(5, 15) -(9, 11) -(12, 15) -(4, 9) -(11, 14) -(5, 16) -(0, 20) -(15, 22) -(8, 11) -(14, 20) -(3, 4) -(0, 23) -(2, 9) -(18, 20) -(4, 10) -(3, 25) -(14, 16) -(0, 24) -(1, 22) -(8, 19) -(2, 21) -(12, 19) -(7, 16) -(10, 17) -(4, 5) -(8, 25) -(9, 24) -(2, 21) -(12, 20) -(3, 4) -(15, 19) -(11, 21) -(4, 6) -(11, 14) -(12, 15) -(4, 25) -(3, 15) -(11, 21) -(5, 6) -(21, 22) -(0, 4) -(11, 14) -(6, 20) -(10, 14) -(1, 6) -(0, 2) -(11, 18) -(4, 23) -(22, 25) -(8, 21) -(3, 6) -(7, 10) -(17, 23) -(2, 15) -(12, 18) -(11, 16) -(9, 21) -(17, 25) -(11, 14) -(5, 23) -(18, 22) -(6, 19) -(4, 19) -(6, 15) -(14, 20) -(16, 23) -(0, 25) -(4, 13) -(5, 14) -(15, 22) -(0, 8) -(18, 19) -(4, 11) -(22, 25) -(12, 19) -(14, 18) -(16, 22) -(6, 25) -(15, 19) -(2, 18) -(19, 21) -(4, 6) -(15, 17) -(4, 12) -(11, 19) -(3, 17) -(14, 21) -(2, 15) -(15, 24) -(3, 9) -(13, 17) -(12, 21) -(2, 19) -(2, 14) -(5, 12) -(13, 18) -(6, 9) -(6, 8) -(13, 24) -(2, 3) -(18, 20) -(9, 24) -(8, 15) -(2, 7) -(6, 24) -(7, 25) -(8, 17) -(9, 11) -(1, 8) -(11, 16) -(14, 17) -(7, 10) -(6, 13) -(10, 11) -(8, 22) -(5, 13) -(17, 23) -(1, 24) -(8, 15) -(13, 16) -(14, 24) -(21, 22) -(17, 21) -(22, 23) -(16, 20) -(10, 15) -(23, 25) -(4, 21) -(13, 17) -(0, 22) -(9, 20) -(11, 16) -(13, 20) -(6, 9) -(3, 23) -(8, 16) -(0, 3) -(2, 9) -(22, 23) -(16, 19) -(1, 19) -(5, 16) -(3, 8) -(2, 6) -(12, 22) -(14, 23) -(8, 14) -(22, 25) -(17, 23) -(15, 16) -(1, 6) -(8, 20) -(0, 15) -(5, 16) -(14, 22) -(3, 25) -(9, 15) -(12, 25) -(14, 21) -(13, 20) -(0, 18) -(7, 15) -(20, 25) -(13, 24) -(17, 21) -(18, 20) -(3, 13) -(9, 21) -(14, 24) -(12, 25) -(10, 25) -(13, 22) -(3, 17) -(1, 24) -(7, 20) -(14, 23) -(12, 16) -(1, 13) -(12, 23) -(2, 3) -(6, 14) -(1, 15) -(2, 19) -(6, 20) -(12, 16) -(23, 24) -(2, 22) -(20, 23) -(16, 25) -(11, 19) -(13, 25) -(7, 16) -(0, 11) -(19, 23) -(14, 22) -(3, 22) -(17, 23) -(7, 24) -(12, 16) -(11, 14) -(5, 7) -(8, 12) -(4, 17) -(12, 23) -(4, 25) -(1, 7) -(8, 9) -(21, 23) -(2, 12) -(9, 19) -(8, 16) -(4, 13) -(15, 19) -(3, 4) -(11, 13) -(2, 5) -(15, 18) -(4, 20) -(13, 22) -(1, 19) -(3, 14) -(0, 5) -(22, 24) -(15, 17) -(14, 16) -(3, 11) -(24, 25) -(13, 14) -(10, 22) -(2, 15) -(12, 17) -(23, 25) -(1, 15) -(11, 14) -(8, 22) -(24, 25) -(0, 11) -(9, 14) -(15, 19) -(8, 16) -(2, 9) -(8, 19) -(1, 11) -(0, 13) -(9, 20) -(1, 4) -(2, 22) -(0, 10) -(0, 15) -(3, 9) -(4, 13) -(19, 20) -(10, 12) -(14, 15) -(5, 13) -(6, 12) -(10, 17) -(0, 21) -(3, 7) -(10, 14) -(6, 9) -(0, 13) -(15, 22) -(2, 3) -(1, 5) -(7, 16) -(3, 11) -(9, 14) -(0, 8) -(1, 12) -(5, 13) -(2, 10) -(4, 7) -(11, 20) -(6, 10) -(12, 22) -(3, 7) -(2, 21) -(5, 24) -(14, 19) -(4, 19) -(10, 13) -(3, 14) -(9, 11) -(18, 21) -(2, 17) -(0, 13) -(19, 20) -(12, 21) -(1, 4) -(2, 15) -(2, 16) -(20, 21) -(5, 19) -(13, 15) -(0, 14) -(12, 25) -(4, 25) -(9, 15) -(2, 6) -(5, 18) -(16, 19) -(3, 16) -(12, 19) -(4, 7) -(6, 10) -(10, 22) -(19, 21) -(16, 24) -(6, 20) -(10, 11) -(23, 24) -(9, 22) -(12, 20) -(2, 24) -(5, 9) -(10, 16) -(6, 22) -(11, 15) -(10, 20) -(8, 15) -(6, 22) -(1, 16) -(15, 22) -(16, 21) -(10, 13) -(8, 23) -(13, 15) -(17, 22) -(8, 25) -(3, 10) -(9, 15) -(23, 25) -(0, 8) -(6, 9) -(4, 8) -(20, 23) -(8, 11) -(2, 4) -(8, 22) -(11, 19) -(4, 25) -(5, 11) -(6, 8) -(2, 4) -(14, 19) -(5, 17) -(4, 21) -(11, 13) -(14, 22) -(18, 21) -(2, 5) -(1, 4) -(14, 23) -(16, 17) -(4, 21) -(2, 24) -(13, 18) -(1, 9) -(3, 17) -(5, 8) -(7, 16) -(17, 24) -(1, 7) -(18, 20) -(3, 22) -(3, 13) -(14, 22) -(24, 25) -(18, 21) -(4, 22) -(14, 15) -(23, 24) -(2, 25) -(18, 19) -(4, 23) -(12, 25) -(6, 24) -(2, 3) -(11, 23) -(10, 24) -(4, 8) -(20, 25) -(9, 25) -(3, 24) -(10, 16) -(6, 23) -(1, 20) -(7, 11) -(2, 8) -(4, 20) -(12, 24) -(11, 18) -(0, 7) -(13, 25) -(3, 15) -(10, 23) -(6, 18) -(2, 23) -(3, 14) -(16, 24) -(0, 5) -(7, 19) -(4, 8) -(1, 18) -(4, 15) -(7, 12) -(8, 13) -(11, 19) -(8, 23) -(7, 17) -(0, 11) -(5, 19) -(2, 15) -(4, 13) -(11, 19) -(13, 15) -(1, 17) -(7, 12) -(0, 6) -(5, 9) -(5, 21) -(13, 15) -(9, 25) -(1, 24) -(10, 19) -(1, 24) -(10, 22) -(3, 25) -(5, 7) -(5, 25) -(1, 20) -(12, 22) -(10, 18) -(12, 24) -(14, 22) -(10, 11) -(20, 21) -(11, 19) -(6, 20) -(4, 21) -(2, 24) -(15, 22) -(1, 10) -(7, 22) -(21, 24) -(12, 20) -(10, 17) -(10, 18) -(16, 20) -(22, 23) -(13, 17) -(12, 14) -(4, 7) -(10, 15) -(18, 21) -(5, 7) -(14, 24) -(0, 16) -(11, 12) -(16, 17) -(12, 20) -(13, 21) -(9, 24) -(6, 10) -(5, 14) -(17, 22) -(12, 15) -(9, 23) -(14, 25) -(10, 16) -(0, 16) -(8, 22) -(3, 23) -(1, 25) -(6, 10) -(3, 19) -(8, 11) -(6, 9) -(6, 19) -(8, 22) -(7, 11) -(5, 22) -(2, 11) -(7, 13) -(12, 19) -(8, 20) -(8, 17) -(7, 15) -(1, 20) -(18, 20) -(9, 15) -(17, 25) -(1, 20) -(24, 25) -(9, 10) -(15, 23) -(10, 17) -(3, 25) -(5, 23) -(9, 16) -(12, 15) -(1, 4) -(3, 7) -(4, 22) -(17, 21) -(13, 25) -(0, 9) -(8, 15) -(9, 10) -(3, 19) -(0, 21) -(13, 22) -(7, 13) -(21, 25) -(12, 22) -(7, 20) -(2, 13) -(5, 12) -(12, 22) -(8, 20) -(2, 18) -(13, 14) -(15, 18) -(1, 2) -(8, 21) -(12, 16) -(13, 22) -(7, 20) -(2, 4) -(22, 24) -(0, 20) -(1, 9) -(16, 23) -(1, 14) -(9, 17) -(15, 22) -(4, 5) -(6, 23) -(5, 7) -(1, 18) -(4, 9) -(11, 17) -(0, 6) -(4, 10) -(7, 18) -(9, 13) -(0, 23) -(5, 14) -(14, 17) -(5, 11) -(6, 7) -(13, 19) -(0, 2) -(10, 14) -(19, 21) -(4, 6) -(0, 8) -(13, 16) -(5, 17) -(6, 9) -(13, 18) -(5, 11) -(2, 16) -(1, 4) -(9, 20) -(6, 13) -(5, 7) -(3, 11) -(4, 10) -(18, 22) -(4, 9) -(6, 21) -(2, 5) -(7, 14) -(1, 20) -(3, 15) -(6, 22) -(7, 13) -(9, 20) -(4, 14) -(12, 15) -(6, 19) -(20, 22) -(7, 18) -(10, 12) -(13, 21) -(10, 15) -(11, 18) -(12, 24) -(7, 20) -(3, 24) -(15, 23) -(18, 25) -(2, 11) -(6, 23) -(12, 15) -(2, 13) -(8, 11) -(4, 24) -(1, 11) -(24, 25) -(12, 23) -(8, 9) -(3, 13) -(2, 5) -(8, 18) -(0, 25) -(9, 15) -(23, 24) -(5, 22) -(2, 12) -(1, 17) -(9, 25) -(0, 11) -(17, 21) -(12, 22) -(7, 18) -(5, 20) -(16, 18) -(13, 20) -(1, 7) -(12, 15) -(0, 14) -(4, 21) -(17, 21) -(4, 8) -(0, 11) -(1, 5) -(2, 21) -(0, 14) -(4, 18) -(17, 19) -(4, 20) -(6, 17) -(18, 25) -(14, 16) -(3, 19) -(13, 16) -(9, 25) -(0, 14) -(15, 18) -(0, 2) -(11, 25) -(13, 21) -(9, 21) -(12, 25) -(0, 24) -(8, 13) -(11, 22) -(10, 25) -(1, 12) -(8, 17) -(16, 22) -(15, 24) -(11, 15) -(8, 21) -(16, 23) -(1, 9) -(10, 19) -(8, 17) -(10, 25) -(18, 19) -(13, 23) -(21, 23) -(14, 17) -(1, 8) -(0, 25) -(10, 16) -(3, 18) -(16, 22) -(14, 24) -(3, 4) -(18, 25) -(3, 7) -(0, 4) -(11, 16) -(17, 25) -(15, 18) -(13, 16) -(0, 25) -(4, 22) -(5, 15) -(3, 23) -(4, 21) -(0, 17) -(2, 13) -(16, 19) -(5, 25) -(6, 17) -(13, 18) -(3, 16) -(0, 25) -(12, 21) -(2, 22) -(0, 10) -(12, 23) -(8, 22) -(15, 21) -(2, 25) -(12, 20) -(9, 10) -(2, 8) -(0, 24) -(4, 21) -(4, 13) -(1, 10) -(17, 24) -(7, 20) -(12, 14) -(9, 19) -(4, 7) -(9, 22) -(10, 11) -(20, 23) -(14, 17) -(23, 24) -(11, 12) -(17, 18) -(6, 14) -(10, 20) -(12, 22) -(2, 10) -(1, 20) -(24, 25) -(4, 23) -(14, 17) -(3, 20) -(0, 4) -(5, 24) -(6, 22) -(12, 25) -(4, 11) -(12, 23) -(6, 14) -(9, 22) -(1, 25) -(0, 16) -(5, 18) -(14, 15) -(1, 5) -(12, 17) -(16, 22) -(6, 7) -(18, 21) -(7, 10) -(18, 20) -(14, 24) -(18, 23) -(4, 10) -(3, 14) -(5, 24) -(1, 20) -(1, 17) -(0, 23) -(3, 16) -(13, 24) -(8, 10) -(3, 22) -(6, 16) -(18, 23) -(7, 8) -(17, 23) -(5, 7) -(8, 24) -(18, 25) -(3, 22) -(21, 23) -(3, 16) -(11, 25) -(4, 25) -(11, 19) -(0, 16) -(2, 25) -(11, 20) -(9, 19) -(20, 22) -(17, 19) -(23, 25) -(11, 18) -(1, 18) -(9, 20) -(4, 19) -(15, 22) -(17, 24) -(11, 16) -(18, 19) -(10, 11) -(1, 14) -(4, 21) -(5, 20) -(6, 15) -(8, 24) -(11, 23) -(0, 14) -(2, 10) -(17, 18) -(0, 10) -(5, 18) -(13, 17) -(11, 21) -(21, 22) -(0, 2) -(15, 18) -(5, 24) -(9, 18) -(24, 25) -(11, 21) -(8, 15) -(10, 22) -(2, 16) -(5, 14) -(15, 24) -(11, 14) -(13, 21) -(7, 9) -(17, 18) -(4, 8) -(6, 8) -(11, 23) -(1, 15) -(9, 20) -(7, 12) -(15, 16) -(9, 24) -(8, 25) -(12, 17) -(19, 20) -(2, 7) -(2, 19) -(1, 7) -(12, 21) -(16, 20) -(3, 9) -(5, 15) -(10, 20) -(9, 11) -(17, 21) -(15, 18) -(0, 7) -(10, 13) -(1, 20) -(9, 17) -(7, 12) -(3, 11) -(6, 21) -(12, 15) -(5, 20) -(10, 25) -(4, 9) -(0, 13) -(12, 18) -(13, 22) -(10, 23) -(1, 5) -(14, 25) -(4, 10) -(8, 13) -(21, 22) -(12, 24) -(3, 14) -(7, 8) -(6, 13) -(4, 9) -(12, 18) -(1, 3) -(8, 11) -(3, 19) -(4, 10) -(12, 24) -(13, 16) -(8, 20) -(9, 10) -(24, 25) -(6, 16) -(18, 19) -(10, 11) -(15, 25) -(9, 23) -(18, 20) -(6, 14) -(12, 16) -(8, 24) -(10, 23) -(13, 18) -(5, 11) -(17, 24) -(6, 21) -(4, 25) -(7, 15) -(7, 8) -(3, 17) -(11, 21) -(18, 23) -(13, 16) -(5, 20) -(4, 15) -(5, 23) -(1, 11) -(8, 24) -(9, 13) -(4, 19) -(15, 18) -(0, 21) -(7, 10) -(11, 24) -(6, 19) -(9, 25) -(5, 10) -(8, 14) -(21, 22) -(0, 22) -(7, 24) -(2, 9) -(3, 14) -(9, 18) -(2, 10) -(4, 22) -(7, 15) -(0, 17) -(4, 13) -(0, 23) -(12, 22) -(16, 18) -(3, 7) -(5, 18) -(6, 16) -(3, 24) -(7, 20) -(0, 17) -(8, 22) -(9, 22) -(0, 23) -(2, 20) -(8, 13) -(6, 17) -(10, 20) -(23, 25) -(0, 11) -(14, 17) -(6, 18) -(19, 23) -(0, 2) -(12, 17) -(1, 18) -(23, 25) -(2, 19) -(3, 18) -(1, 11) -(8, 17) -(1, 5) -(10, 23) -(11, 21) -(6, 17) -(7, 21) -(5, 16) -(1, 9) -(11, 15) -(2, 10) -(4, 7) -(15, 17) -(5, 25) -(11, 14) -(8, 10) -(11, 19) -(7, 9) -(20, 25) -(1, 7) -(0, 9) -(16, 20) -(1, 21) -(7, 20) -(4, 9) -(6, 16) -(7, 15) -(11, 20) -(8, 21) -(1, 6) -(9, 18) -(16, 25) -(8, 13) -(20, 22) -(7, 11) -(0, 6) -(4, 16) -(10, 15) -(16, 17) -(6, 19) -(2, 10) -(9, 22) -(15, 19) -(4, 16) -(15, 19) -(16, 17) -(4, 8) -(3, 8) -(4, 19) -(16, 23) -(6, 15) -(1, 3) -(5, 16) -(23, 24) -(3, 13) -(16, 18) -(12, 23) -(12, 24) -(1, 13) -(12, 17) -(0, 24) -(12, 14) -(0, 9) -(5, 24) -(12, 21) -(5, 20) -(14, 25) -(19, 24) -(20, 23) -(15, 24) -(17, 19) -(12, 16) -(18, 21) -(5, 16) -(4, 12) -(6, 18) -(20, 21) -(5, 21) -(4, 22) -(2, 16) -(1, 2) -(12, 16) -(5, 13) -(19, 21) -(10, 21) -(13, 19) -(5, 14) -(2, 4) -(16, 23) -(3, 16) -(0, 23) -(19, 20) -(13, 19) -(16, 22) -(20, 24) -(3, 6) -(4, 24) -(3, 21) -(7, 22) -(16, 23) -(6, 11) -(0, 13) -(13, 22) -(16, 18) -(3, 7) -(11, 20) -(2, 11) -(14, 22) -(12, 13) -(20, 21) -(3, 12) -(5, 20) -(11, 15) -(13, 14) -(2, 8) -(1, 8) -(3, 20) -(0, 15) -(13, 16) -(2, 19) -(10, 13) -(7, 19) -(6, 15) -(0, 25) -(11, 25) -(9, 15) -(6, 18) -(10, 16) -(4, 25) -(0, 15) -(10, 17) -(2, 16) -(7, 9) -(11, 13) -(16, 23) -(1, 15) -(10, 21) -(9, 12) -(0, 5) -(17, 19) -(13, 21) -(0, 25) -(3, 15) -(2, 19) -(16, 17) -(18, 21) -(19, 23) -(22, 25) -(0, 7) -(1, 15) -(18, 20) -(11, 25) -(17, 23) -(15, 19) -(1, 21) -(4, 19) -(10, 20) -(13, 23) -(1, 14) -(6, 21) -(4, 17) -(14, 25) -(21, 24) -(2, 24) -(5, 17) -(2, 25) -(3, 17) -(18, 24) -(4, 24) -(17, 21) -(0, 18) -(3, 22) -(10, 24) -(4, 11) -(1, 4) -(11, 20) -(0, 10) -(12, 20) -(0, 2) -(9, 11) -(8, 11) -(9, 25) -(6, 20) -(12, 24) -(8, 23) -(6, 13) -(7, 11) -(5, 8) -(7, 14) -(11, 13) -(7, 10) -(11, 17) -(1, 14) -(13, 20) -(1, 19) -(4, 20) -(13, 22) -(6, 13) -(4, 15) -(5, 22) -(15, 18) -(6, 8) -(13, 14) -(1, 4) -(20, 22) -(8, 25) -(7, 20) -(5, 22) -(13, 18) -(8, 10) -(2, 22) -(0, 5) -(13, 24) -(7, 14) -(5, 21) -(2, 7) -(15, 22) -(13, 17) -(5, 24) -(15, 23) -(18, 21) -(1, 2) -(11, 17) -(7, 8) -(5, 13) -(19, 23) -(21, 22) -(14, 15) -(10, 24) -(2, 25) -(12, 18) -(11, 14) -(0, 24) -(17, 21) -(4, 22) -(16, 18) -(6, 10) -(13, 20) -(5, 24) -(8, 17) -(1, 10) -(0, 9) -(13, 19) -(8, 23) -(0, 18) -(7, 9) -(3, 24) -(14, 17) -(8, 19) -(14, 20) -(7, 13) -(16, 17) -(8, 25) -(14, 21) -(16, 22) -(12, 13) -(3, 25) -(16, 21) -(8, 11) -(14, 24) -(2, 22) -(0, 25) -(13, 22) -(11, 19) -(6, 24) -(8, 16) -(8, 22) -(0, 18) -(9, 25) -(6, 15) -(20, 24) -(3, 19) -(12, 19) -(15, 24) -(0, 23) -(17, 23) -(0, 18) -(18, 23) -(1, 23) -(10, 18) -(0, 23) -(4, 18) -(0, 3) -(7, 23) -(5, 18) -(4, 13) -(3, 19) -(0, 1) -(14, 23) -(5, 16) -(13, 24) -(3, 21) -(0, 11) -(16, 18) -(23, 24) -(2, 5) -(6, 11) -(0, 19) -(5, 7) -(12, 16) -(4, 21) -(3, 18) -(2, 3) -(6, 13) -(4, 22) -(1, 7) -(11, 12) -(5, 9) -(0, 1) -(5, 14) -(11, 13) -(9, 20) -(20, 24) -(13, 25) -(7, 9) -(0, 10) -(14, 15) -(14, 16) -(0, 15) -(9, 19) -(21, 25) -(19, 21) -(12, 16) -(9, 17) -(0, 6) -(10, 15) -(6, 25) -(9, 22) -(2, 15) -(0, 24) -(3, 17) -(7, 10) -(12, 14) -(1, 10) -(3, 15) -(8, 9) -(22, 23) -(0, 14) -(11, 24) -(1, 4) -(11, 24) -(0, 14) -(14, 19) -(4, 25) -(18, 24) -(11, 24) -(4, 7) -(6, 19) -(5, 14) -(21, 25) -(14, 16) -(18, 24) -(6, 22) -(2, 5) -(0, 21) -(7, 15) -(17, 19) -(15, 25) -(1, 22) -(0, 16) -(4, 21) -(8, 18) -(13, 14) -(7, 17) -(0, 11) -(9, 16) -(4, 18) -(7, 10) -(3, 8) -(23, 25) -(5, 14) -(9, 18) -(3, 25) -(7, 17) -(8, 10) -(0, 24) -(14, 21) -(10, 23) -(9, 21) -(0, 1) -(3, 5) -(24, 25) -(6, 17) -(4, 24) -(3, 7) -(2, 17) -(21, 25) -(8, 10) -(5, 14) -(7, 23) -(4, 6) -(19, 24) -(12, 21) -(3, 15) -(0, 5) -(15, 24) -(4, 22) -(2, 3) -(5, 14) -(9, 12) -(6, 20) -(11, 23) -(19, 25) -(14, 21) -(3, 13) -(10, 12) -(2, 16) -(1, 4) -(5, 17) -(5, 10) -(21, 22) -(16, 20) -(1, 25) -(3, 8) -(6, 20) -(10, 21) -(5, 25) -(16, 20) -(9, 25) -(13, 25) -(7, 16) -(9, 10) -(4, 20) -(7, 18) -(2, 4) -(13, 24) -(15, 16) -(3, 10) -(4, 10) -(0, 18) -(11, 16) -(7, 14) -(15, 19) -(7, 23) -(8, 18) -(14, 17) -(11, 24) -(0, 3) -(22, 23) -(17, 25) -(6, 7) -(18, 21) -(19, 21) -(6, 15) -(10, 25) -(5, 22) -(7, 12) -(14, 18) -(14, 15) -(0, 5) -(9, 19) -(17, 18) -(16, 25) -(6, 21) -(6, 18) -(0, 7) -(12, 17) -(21, 25) -(14, 22) -(10, 15) -(2, 22) -(12, 13) -(4, 7) -(20, 25) -(10, 17) -(10, 12) -(4, 9) -(3, 13) -(7, 11) -(3, 23) -(11, 13) -(6, 7) -(6, 10) -(22, 23) -(12, 13) -(3, 19) -(5, 7) -(10, 14) -(7, 9) -(6, 24) -(17, 19) -(11, 23) -(5, 21) -(2, 19) -(11, 15) -(6, 25) -(3, 14) -(10, 20) -(19, 23) -(15, 16) -(1, 2) -(4, 6) -(11, 13) -(12, 20) -(6, 25) -(12, 22) -(0, 1) -(2, 18) -(3, 15) -(6, 14) -(1, 18) -(0, 8) -(2, 13) -(15, 17) -(8, 24) -(1, 19) -(13, 23) -(2, 20) -(0, 3) -(5, 6) -(17, 22) -(9, 18) -(4, 15) -(9, 21) -(4, 7) -(13, 22) -(17, 23) -(14, 15) -(5, 8) -(3, 17) -(2, 14) -(17, 23) -(2, 18) -(2, 4) -(3, 17) -(12, 18) -(16, 18) -(3, 21) -(10, 17) -(18, 23) -(10, 14) -(13, 17) -(2, 16) -(0, 2) -(8, 18) -(17, 21) -(10, 15) -(14, 23) -(16, 22) -(21, 25) -(20, 23) -(5, 10) -(2, 11) -(0, 9) -(6, 15) -(6, 7) -(0, 8) -(2, 19) -(3, 20) -(9, 11) -(23, 24) -(19, 25) -(3, 22) -(21, 23) -(1, 11) -(8, 9) -(9, 18) -(5, 25) -(0, 19) -(1, 6) -(0, 8) -(18, 25) -(9, 20) -(8, 16) -(9, 21) -(12, 20) -(0, 4) -(20, 25) -(0, 1) -(15, 16) -(1, 22) -(21, 25) -(20, 23) -(14, 15) -(9, 25) -(13, 14) -(4, 23) -(18, 23) -(17, 25) -(14, 23) -(17, 24) -(2, 18) -(11, 14) -(9, 24) -(16, 23) -(2, 4) -(1, 18) -(1, 7) -(0, 23) -(16, 22) -(16, 25) -(0, 21) -(1, 19) -(7, 23) -(1, 3) -(16, 17) -(0, 18) -(5, 25) -(7, 9) -(4, 19) -(7, 23) -(12, 16) -(19, 20) -(18, 24) -(13, 17) -(1, 15) -(5, 9) -(4, 20) -(13, 25) -(5, 15) -(12, 22) -(18, 21) -(16, 24) -(12, 13) -(3, 25) -(1, 24) -(0, 4) -(14, 22) -(8, 14) -(3, 17) -(6, 24) -(1, 10) -(7, 12) -(4, 18) -(1, 9) -(0, 10) -(21, 24) -(4, 13) -(18, 23) -(6, 11) -(12, 15) -(6, 20) -(18, 22) -(2, 11) -(8, 13) -(0, 21) -(10, 20) -(8, 23) -(11, 21) -(2, 3) -(9, 10) -(3, 24) -(4, 24) -(10, 25) -(9, 17) -(2, 3) -(2, 16) -(17, 24) -(22, 25) -(9, 13) -(3, 7) -(0, 2) -(17, 21) -(9, 16) -(6, 7) -(1, 2) -(10, 21) -(0, 20) -(6, 11) -(0, 8) -(21, 24) -(6, 25) -(1, 8) -(0, 13) -(0, 2) -(11, 13) -(1, 3) -(8, 20) -(3, 21) -(5, 8) -(13, 22) -(7, 20) -(8, 23) -(13, 25) -(5, 20) -(13, 18) -(23, 24) -(5, 22) -(19, 25) -(3, 8) -(10, 22) -(3, 9) -(12, 25) -(6, 18) -(4, 8) -(17, 23) -(8, 11) -(10, 20) -(2, 25) -(21, 23) -(7, 21) -(2, 12) -(4, 8) -(7, 25) -(9, 21) -(8, 17) -(8, 15) -(14, 21) -(17, 24) -(7, 16) -(9, 19) -(11, 16) -(19, 25) -(5, 9) -(3, 17) -(20, 21) -(7, 25) -(11, 18) -(20, 23) -(14, 21) -(2, 9) -(13, 19) -(6, 11) -(15, 21) -(17, 25) -(4, 18) -(16, 23) -(19, 20) -(10, 19) -(12, 17) -(0, 20) -(8, 11) -(3, 16) -(15, 25) -(0, 9) -(14, 19) -(2, 15) -(5, 10) -(17, 22) -(3, 21) -(7, 19) -(10, 23) -(2, 6) -(6, 25) -(7, 24) -(2, 4) -(0, 19) -(18, 23) -(23, 24) -(6, 21) -(0, 15) -(2, 5) -(4, 11) -(9, 19) -(0, 20) -(2, 10) -(19, 25) -(22, 24) -(3, 11) -(8, 9) -(5, 17) -(13, 24) -(17, 23) -(14, 20) -(0, 16) -(3, 4) -(14, 22) -(3, 9) -(0, 7) -(12, 20) -(4, 21) -(2, 7) -(6, 14) -(16, 20) -(0, 15) -(22, 23) -(9, 11) -(6, 8) -(0, 25) -(7, 18) -(3, 11) -(9, 13) -(16, 24) -(15, 20) -(1, 24) -(5, 15) -(11, 20) -(19, 25) -(4, 6) -(14, 19) -(4, 21) -(2, 20) -(11, 18) -(8, 15) -(5, 9) -(17, 21) -(15, 20) -(2, 13) -(4, 12) -(10, 18) -(0, 8) -(0, 11) -(2, 14) -(20, 25) -(3, 15) -(10, 24) -(16, 17) -(13, 23) -(21, 25) -(0, 4) -(5, 23) -(14, 24) -(15, 18) -(12, 20) -(3, 20) -(8, 21) -(13, 24) -(12, 25) -(15, 19) -(8, 10) -(16, 21) -(15, 25) -(3, 19) -(1, 13) -(14, 20) -(10, 20) -(6, 21) -(1, 3) -(7, 19) -(13, 17) -(17, 20) -(9, 21) -(7, 22) -(2, 6) -(6, 24) -(18, 22) -(7, 8) -(2, 11) -(10, 17) -(8, 20) -(17, 24) -(6, 16) -(17, 21) -(16, 23) -(2, 20) -(15, 21) -(10, 23) -(16, 22) -(7, 17) -(6, 20) -(6, 9) -(15, 16) -(13, 20) -(8, 17) -(14, 23) -(7, 25) -(6, 15) -(12, 23) -(10, 14) -(11, 13) -(8, 16) -(19, 25) -(5, 23) -(12, 18) -(4, 15) -(14, 17) -(11, 13) -(7, 10) -(13, 20) -(4, 5) -(6, 23) -(7, 11) -(2, 12) -(1, 18) -(15, 18) -(22, 23) -(4, 13) -(3, 6) -(6, 9) -(8, 23) -(22, 25) -(9, 10) -(7, 23) -(10, 21) -(8, 23) -(7, 23) -(0, 10) -(3, 8) -(0, 13) -(20, 23) -(6, 7) -(3, 11) -(10, 16) -(7, 24) -(10, 15) -(12, 23) -(9, 11) -(6, 21) -(7, 22) -(19, 24) -(6, 16) -(1, 10) -(0, 21) -(8, 10) -(3, 22) -(1, 15) -(18, 21) -(5, 19) -(20, 24) -(20, 23) -(3, 18) -(2, 15) -(9, 10) -(1, 11) -(14, 24) -(0, 22) -(12, 24) -(4, 20) -(23, 25) -(17, 18) -(11, 25) -(4, 16) -(2, 25) -(13, 16) -(9, 16) -(6, 13) -(2, 20) -(6, 18) -(9, 12) -(4, 16) -(13, 17) -(0, 18) -(7, 16) -(5, 12) -(9, 16) -(5, 23) -(0, 6) -(8, 12) -(0, 11) -(12, 17) -(8, 12) -(17, 23) -(2, 8) -(5, 12) -(20, 23) -(8, 24) -(4, 5) -(12, 17) -(20, 25) -(17, 18) -(12, 22) -(8, 21) -(1, 20) -(12, 20) -(11, 17) -(1, 7) -(2, 18) -(16, 22) -(5, 8) -(13, 18) -(1, 21) -(22, 23) -(7, 17) -(8, 10) -(18, 25) -(13, 14) -(6, 21) -(9, 22) -(13, 24) -(11, 18) -(4, 14) -(9, 25) -(0, 24) -(11, 15) -(14, 23) -(9, 16) -(12, 13) -(4, 14) -(11, 12) -(7, 16) -(15, 18) -(16, 24) -(4, 15) -(5, 11) -(14, 23) -(12, 13) -(14, 23) -(15, 18) -(0, 12) -(5, 10) -(4, 11) -(16, 17) -(7, 11) -(5, 25) -(2, 14) -(16, 24) -(19, 23) -(0, 10) -(4, 7) -(13, 14) -(0, 1) -(3, 23) -(19, 25) -(1, 21) -(18, 19) -(14, 22) -(0, 1) -(2, 14) -(12, 22) -(13, 14) -(2, 24) -(1, 21) -(17, 22) -(9, 24) -(4, 17) -(2, 10) -(8, 22) -(3, 14) -(10, 20) -(19, 22) -(2, 7) -(16, 24) -(13, 14) -(4, 23) -(4, 8) -(10, 14) -(5, 19) -(12, 13) -(15, 22) -(6, 7) -(6, 23) -(0, 12) -(19, 20) -(8, 11) -(15, 18) -(3, 5) -(11, 24) -(5, 20) -(8, 23) -(1, 3) -(6, 10) -(3, 22) -(1, 2) -(7, 8) -(0, 20) -(10, 21) -(3, 14) -(15, 20) -(18, 22) -(1, 5) -(2, 23) -(12, 18) -(1, 13) -(11, 20) -(5, 15) -(11, 17) -(0, 13) -(5, 16) -(4, 15) -(10, 17) -(16, 24) -(11, 20) -(5, 15) -(10, 14) -(8, 17) -(11, 25) -(5, 22) -(3, 11) -(17, 25) -(2, 3) -(11, 21) -(4, 17) -(11, 19) -(13, 21) -(3, 9) -(2, 10) -(1, 11) -(18, 19) -(7, 21) -(8, 19) -(18, 19) -(12, 19) -(13, 19) -(12, 24) -(19, 25) -(13, 16) -(20, 24) -(3, 12) -(16, 18) -(15, 25) -(17, 24) -(15, 19) -(12, 18) -(22, 25) -(11, 15) -(2, 25) -(0, 12) -(19, 23) -(4, 18) -(18, 22) -(4, 10) -(6, 15) -(0, 23) -(9, 12) -(11, 17) -(2, 19) -(1, 15) -(6, 7) -(9, 14) -(8, 18) -(12, 18) -(3, 15) -(0, 1) -(6, 20) -(3, 11) -(1, 10) -(6, 24) -(15, 22) -(6, 16) -(1, 19) -(4, 15) -(24, 25) -(15, 22) -(5, 24) -(5, 7) -(2, 24) -(4, 5) -(17, 24) -(2, 10) -(7, 8) -(1, 24) -(4, 17) -(8, 23) -(7, 14) -(9, 24) -(4, 5) -(7, 14) -(11, 17) -(7, 15) -(14, 23) -(9, 13) -(0, 11) -(15, 22) -(3, 9) -(0, 18) -(8, 11) -(13, 21) -(6, 14) -(9, 12) -(10, 14) -(3, 22) -(7, 15) -(3, 7) -(17, 22) -(1, 12) -(5, 12) -(2, 17) -(3, 4) -(15, 22) -(1, 5) -(19, 22) -(10, 15) -(7, 12) -(10, 17) -(15, 24) -(12, 14) -(1, 6) -(9, 17) -(1, 16) -(15, 21) -(8, 10) -(9, 13) -(17, 21) -(1, 19) -(8, 12) -(19, 23) -(9, 24) -(8, 25) -(13, 15) -(3, 17) -(4, 17) -(0, 23) -(8, 20) -(16, 24) -(2, 9) -(3, 11) -(4, 21) -(10, 24) -(9, 18) -(13, 20) -(0, 12) -(6, 23) -(16, 24) -(0, 15) -(11, 23) -(6, 17) -(5, 6) -(14, 16) -(9, 23) -(4, 11) -(2, 24) -(8, 16) -(2, 19) -(3, 23) -(1, 14) -(10, 24) -(6, 12) -(6, 23) -(2, 22) -(1, 4) -(14, 16) -(5, 19) -(15, 19) -(4, 24) -(2, 11) -(21, 24) -(2, 25) -(9, 19) -(7, 11) -(5, 15) -(5, 6) -(7, 18) -(2, 20) -(14, 18) -(8, 20) -(12, 14) -(20, 22) -(8, 15) -(8, 18) -(13, 15) -(14, 23) -(10, 20) -(8, 13) -(20, 25) -(10, 17) -(8, 12) -(11, 17) -(10, 24) -(13, 14) -(7, 11) -(23, 24) -(10, 21) -(3, 17) -(3, 5) -(6, 24) -(1, 10) -(11, 22) -(18, 21) -(4, 17) -(8, 17) -(10, 16) -(5, 18) -(19, 22) -(6, 9) -(0, 10) -(14, 22) -(12, 18) -(2, 8) -(9, 15) -(4, 15) -(14, 21) -(0, 11) -(20, 22) -(3, 9) -(10, 13) -(17, 22) -(5, 9) -(11, 13) -(12, 20) -(3, 16) -(15, 25) -(1, 4) -(12, 18) -(11, 14) -(4, 7) -(16, 21) -(1, 23) -(1, 22) -(6, 16) -(11, 13) -(7, 19) -(2, 23) -(3, 18) -(12, 20) -(12, 15) -(1, 17) -(5, 22) -(3, 20) -(9, 18) -(0, 7) -(7, 10) -(1, 23) -(3, 19) -(0, 15) -(9, 14) -(4, 7) -(19, 23) -(3, 6) -(4, 24) -(20, 23) -(2, 7) -(2, 11) -(21, 24) -(7, 22) -(16, 23) -(17, 21) -(8, 24) -(11, 18) -(13, 18) -(7, 21) -(14, 17) -(0, 21) -(10, 17) -(6, 18) -(14, 19) -(5, 6) -(13, 18) -(21, 23) -(10, 24) -(7, 17) -(3, 10) -(18, 22) -(5, 9) -(1, 5) -(0, 10) -(9, 12) -(14, 22) -(9, 18) -(1, 22) -(12, 15) -(12, 13) -(2, 18) -(14, 15) -(9, 20) -(12, 16) -(1, 2) -(18, 24) -(8, 20) -(4, 9) -(14, 22) -(13, 25) -(9, 13) -(14, 21) -(6, 22) -(16, 17) -(5, 8) -(7, 12) -(0, 5) -(7, 15) -(22, 25) -(6, 12) -(17, 18) -(14, 20) -(14, 22) -(5, 8) -(6, 13) -(4, 12) -(0, 9) -(9, 10) -(5, 21) -(1, 13) -(0, 23) -(3, 22) -(8, 17) -(20, 23) -(5, 12) -(3, 7) -(11, 21) -(12, 25) -(3, 16) -(0, 5) -(11, 24) -(18, 21) -(5, 24) -(11, 25) -(18, 22) -(17, 21) -(8, 12) -(7, 25) -(16, 21) -(18, 19) -(4, 12) -(11, 15) -(8, 20) -(7, 11) -(8, 20) -(13, 18) -(12, 15) -(1, 21) -(4, 6) -(8, 12) -(19, 20) -(20, 22) -(6, 12) -(8, 24) -(19, 20) -(11, 22) -(3, 24) -(15, 24) -(17, 24) -(15, 16) -(23, 24) -(8, 16) -(3, 17) -(1, 15) -(5, 16) -(1, 7) -(2, 17) -(3, 22) -(8, 15) -(10, 16) -(0, 5) -(0, 4) -(8, 16) -(5, 25) -(5, 15) -(1, 8) -(13, 25) -(14, 16) -(13, 17) -(4, 14) -(0, 16) -(18, 25) -(1, 7) -(1, 2) -(0, 25) -(14, 18) -(15, 16) -(17, 22) -(5, 25) -(14, 18) -(2, 10) -(11, 18) -(10, 25) -(2, 19) -(19, 22) -(3, 18) -(2, 13) -(18, 19) -(3, 21) -(11, 21) -(3, 9) -(11, 15) -(20, 21) -(9, 23) -(9, 22) -(10, 11) -(5, 15) -(18, 21) -(0, 20) -(3, 9) -(4, 10) -(22, 24) -(5, 17) -(16, 24) -(2, 3) -(5, 15) -(12, 22) -(13, 22) -(3, 12) -(15, 18) -(2, 7) -(16, 17) -(13, 16) -(1, 15) -(6, 17) -(22, 24) -(18, 19) -(4, 18) -(13, 19) -(1, 7) -(10, 17) -(6, 10) -(3, 17) -(4, 15) -(8, 15) -(10, 20) -(4, 9) -(6, 8) -(9, 11) -(3, 4) -(8, 20) -(11, 12) -(3, 7) -(0, 4) -(4, 5) -(12, 25) -(7, 14) -(8, 9) -(0, 21) -(11, 25) -(1, 9) -(10, 14) -(6, 21) -(4, 12) -(2, 8) -(0, 16) -(7, 18) -(12, 18) -(10, 19) -(6, 16) -(11, 13) -(5, 7) -(14, 15) -(16, 23) -(7, 9) -(6, 19) -(3, 11) -(13, 20) -(6, 14) -(13, 23) -(16, 17) -(4, 14) -(3, 13) -(5, 6) -(2, 17) -(16, 22) -(10, 23) -(1, 13) -(8, 16) -(2, 18) -(16, 21) -(8, 12) -(1, 11) -(7, 13) -(5, 21) -(11, 17) -(3, 13) -(1, 20) -(0, 8) -(16, 22) -(12, 24) -(0, 23) -(10, 12) -(3, 25) -(18, 24) -(1, 22) -(14, 24) -(9, 12) -(6, 23) -(10, 15) -(5, 22) -(11, 15) -(7, 14) -(0, 24) -(2, 23) -(12, 13) -(13, 24) -(5, 15) -(7, 19) -(1, 11) -(14, 18) -(22, 23) -(7, 16) -(15, 21) -(5, 14) -(8, 18) -(10, 24) -(15, 23) -(16, 17) -(3, 8) -(10, 25) -(22, 24) -(0, 14) -(1, 18) -(6, 16) -(5, 8) -(15, 18) -(1, 13) -(17, 20) -(8, 23) -(14, 16) -(5, 19) -(6, 7) -(13, 24) -(0, 17) -(14, 21) -(4, 23) -(3, 19) -(0, 17) -(7, 22) -(12, 21) -(0, 16) -(17, 18) -(6, 22) -(9, 23) -(4, 14) -(18, 19) -(0, 8) -(5, 16) -(2, 4) -(1, 23) -(14, 24) -(9, 22) -(13, 24) -(0, 2) -(10, 16) -(9, 17) -(4, 11) -(5, 12) -(14, 24) -(7, 12) -(4, 22) -(16, 18) -(1, 5) -(8, 13) -(1, 14) -(9, 18) -(0, 8) -(5, 24) -(9, 16) -(3, 8) -(1, 7) -(5, 21) -(6, 21) -(3, 20) -(5, 23) -(14, 21) -(6, 7) -(13, 23) -(5, 25) -(5, 15) -(2, 14) -(11, 25) -(10, 21) -(7, 8) -(0, 15) -(14, 24) -(1, 2) -(5, 19) -(7, 8) -(6, 25) -(4, 19) -(2, 18) -(1, 11) -(15, 23) -(5, 22) -(9, 14) -(2, 14) -(19, 25) -(4, 12) -(10, 15) -(5, 7) -(1, 12) -(0, 25) -(5, 18) -(15, 22) -(4, 20) -(7, 8) -(2, 11) -(15, 25) -(1, 13) -(5, 24) -(8, 21) -(11, 13) -(1, 23) -(17, 21) -(8, 9) -(11, 16) -(6, 23) -(2, 17) -(1, 21) -(9, 10) -(13, 24) -(3, 6) -(4, 9) -(8, 23) -(14, 21) -(3, 24) -(8, 19) -(4, 12) -(10, 14) -(9, 22) -(6, 23) -(11, 19) -(3, 21) -(8, 25) -(7, 22) -(11, 23) -(6, 8) -(7, 19) -(3, 24) -(8, 17) -(3, 21) -(0, 11) -(6, 19) -(3, 24) -(9, 21) -(3, 5) -(13, 24) -(20, 21) -(5, 13) -(15, 24) -(20, 22) -(1, 5) -(13, 18) -(2, 24) -(9, 22) -(4, 22) -(5, 20) -(3, 9) -(5, 23) -(4, 11) -(3, 25) -(0, 25) -(3, 15) -(4, 9) -(7, 25) -(9, 10) -(0, 8) -(21, 25) -(1, 9) -(1, 4) -(3, 9) -(8, 25) -(12, 21) -(1, 5) -(19, 25) -(20, 21) -(4, 17) -(8, 15) -(15, 25) -(14, 21) -(10, 20) -(10, 16) -(9, 21) -(2, 20) -(3, 20) -(2, 7) -(2, 13) -(7, 22) -(3, 12) -(14, 22) -(12, 18) -(0, 3) -(0, 5) -(3, 13) -(2, 22) -(12, 20) -(2, 21) -(13, 14) -(7, 12) -(17, 20) -(15, 20) -(10, 17) -(7, 16) -(1, 14) -(12, 25) -(1, 7) -(2, 16) -(3, 10) -(8, 15) -(9, 20) -(7, 21) -(4, 10) -(6, 8) -(9, 19) -(15, 23) -(3, 11) -(17, 23) -(3, 25) -(9, 24) -(8, 13) -(13, 21) -(12, 17) -(0, 25) -(5, 24) -(3, 11) -(6, 23) -(4, 24) -(12, 20) -(1, 5) -(16, 25) -(10, 17) -(2, 10) -(8, 16) -(4, 9) -(19, 24) -(20, 22) -(0, 12) -(17, 24) -(7, 9) -(6, 8) -(2, 15) -(18, 20) -(5, 19) -(11, 18) -(15, 23) -(7, 14) -(9, 21) -(2, 4) -(5, 25) -(17, 19) -(10, 19) -(1, 25) -(5, 16) -(11, 20) -(5, 13) -(10, 17) -(18, 25) -(13, 14) -(5, 23) -(17, 22) -(21, 22) -(3, 5) -(7, 23) -(14, 19) -(15, 23) -(8, 19) -(7, 12) -(4, 15) -(8, 24) -(12, 14) -(9, 19) -(15, 17) -(19, 25) -(2, 14) -(12, 21) -(18, 24) -(5, 24) -(12, 18) -(2, 16) -(10, 21) -(6, 25) -(4, 14) -(9, 21) -(0, 4) -(10, 17) -(2, 15) -(22, 25) -(2, 23) -(4, 7) -(8, 25) -(1, 15) -(0, 18) -(9, 19) -(7, 13) -(9, 16) -(0, 21) -(1, 11) -(7, 8) -(11, 25) -(13, 21) -(8, 20) -(0, 21) -(6, 7) -(13, 21) -(4, 20) -(8, 24) -(6, 23) -(1, 13) -(9, 20) -(21, 25) -(4, 19) -(3, 24) -(9, 16) -(1, 7) -(13, 19) -(15, 24) -(11, 21) -(3, 12) -(5, 25) -(1, 17) -(19, 20) -(15, 25) -(3, 16) -(0, 9) -(6, 13) -(13, 15) -(7, 9) -(19, 23) -(8, 17) -(1, 24) -(2, 19) -(8, 16) -(7, 12) -(1, 16) -(7, 9) -(8, 10) -(16, 23) -(7, 12) -(7, 20) -(12, 21) -(4, 20) -(9, 12) -(13, 21) -(12, 22) -(4, 21) -(9, 13) -(9, 17) -(12, 14) -(6, 22) -(4, 16) -(22, 24) -(14, 21) -(5, 17) -(2, 12) -(6, 19) -(7, 24) -(11, 14) -(0, 12) -(6, 13) -(21, 22) -(4, 6) -(13, 25) -(20, 22) -(17, 24) -(0, 21) -(19, 22) -(3, 24) -(0, 2) -(6, 22) -(0, 18) -(2, 5) -(8, 19) -(5, 15) -(11, 18) -(1, 11) -(0, 5) -(2, 15) -(7, 11) -(1, 25) -(5, 18) -(7, 9) -(18, 21) -(1, 3) -(3, 25) -(7, 15) -(19, 21) -(9, 11) -(11, 14) -(9, 18) -(2, 25) -(5, 25) -(9, 14) -(2, 6) -(9, 15) -(2, 22) -(24, 25) -(12, 24) -(21, 25) -(6, 22) -(8, 24) -(9, 12) -(13, 21) -(2, 25) -(11, 22) -(11, 16) -(5, 25) -(13, 17) -(8, 10) -(2, 9) -(1, 21) -(23, 24) -(12, 20) -(13, 15) -(9, 14) -(17, 25) -(19, 24) -(1, 7) -(11, 24) -(1, 15) -(0, 19) -(17, 22) -(1, 11) -(22, 25) -(7, 19) -(0, 3) -(13, 25) -(4, 19) -(7, 15) -(5, 11) -(0, 23) -(5, 8) -(3, 11) -(2, 19) -(4, 16) -(7, 18) -(3, 9) -(4, 25) -(0, 11) -(19, 23) -(10, 23) -(4, 13) -(19, 20) -(11, 16) -(9, 15) -(2, 25) -(14, 20) -(21, 23) -(6, 16) -(10, 12) -(10, 16) -(14, 23) -(6, 22) -(17, 20) -(16, 24) -(11, 22) -(7, 23) -(14, 18) -(6, 15) -(1, 10) -(4, 11) -(16, 22) -(0, 1) -(10, 14) -(6, 19) -(15, 16) -(19, 25) -(1, 5) -(12, 22) -(2, 10) -(7, 12) -(6, 15) -(3, 25) -(10, 21) -(22, 25) -(10, 20) -(2, 21) -(2, 23) -(17, 21) -(10, 18) -(8, 25) -(3, 22) -(0, 25) -(9, 22) -(2, 12) -(8, 24) -(0, 14) -(5, 8) -(2, 11) -(9, 21) -(4, 24) -(2, 3) -(7, 24) -(1, 14) -(0, 19) -(4, 24) -(2, 14) -(3, 19) -(7, 16) -(13, 24) -(7, 10) -(4, 22) -(22, 23) -(13, 21) -(4, 9) -(10, 11) -(13, 19) -(20, 22) -(2, 11) -(5, 23) -(6, 10) -(11, 16) -(13, 25) -(2, 18) -(10, 24) -(5, 17) -(21, 22) -(14, 16) -(5, 19) -(6, 11) -(9, 21) -(5, 23) -(6, 15) -(12, 21) -(14, 17) -(19, 25) -(8, 16) -(14, 23) -(7, 8) -(5, 16) -(2, 15) -(3, 17) -(0, 3) -(1, 8) -(17, 19) -(7, 25) -(19, 24) -(7, 22) -(1, 15) -(16, 24) -(7, 20) -(8, 15) -(5, 19) -(8, 13) -(7, 23) -(10, 24) -(20, 22) -(8, 25) -(2, 20) -(7, 18) -(7, 23) -(1, 18) -(1, 10) -(4, 7) -(22, 23) -(11, 23) -(7, 18) -(4, 25) -(8, 22) -(9, 18) -(8, 10) -(21, 22) -(5, 7) -(6, 11) -(3, 7) -(11, 15) -(6, 13) -(13, 24) -(11, 14) -(4, 15) -(7, 20) -(6, 16) -(0, 14) -(6, 23) -(10, 16) -(2, 24) -(6, 8) -(0, 17) -(14, 25) -(11, 25) -(0, 20) -(14, 15) -(19, 20) -(3, 25) -(11, 21) -(12, 14) -(14, 23) -(3, 12) -(19, 24) -(0, 25) -(2, 12) -(3, 22) -(7, 12) -(3, 24) -(1, 22) -(1, 17) -(0, 22) -(7, 20) -(8, 24) -(12, 22) -(11, 20) -(8, 18) -(7, 10) -(0, 13) -(21, 22) -(16, 18) -(11, 24) -(0, 20) -(10, 19) -(2, 13) -(10, 15) -(12, 19) -(4, 22) -(21, 23) -(9, 20) -(1, 13) -(3, 16) -(6, 10) -(17, 20) -(16, 23) -(1, 24) -(11, 15) -(3, 19) -(22, 25) -(5, 17) -(21, 25) -(1, 11) -(7, 22) -(8, 24) -(2, 24) -(6, 22) -(9, 21) -(7, 8) -(2, 18) -(0, 22) -(15, 21) -(7, 25) -(2, 20) -(0, 19) -(22, 23) -(11, 15) -(18, 19) -(2, 10) -(3, 20) -(16, 23) -(17, 22) -(3, 25) -(6, 16) -(2, 7) -(9, 10) -(4, 25) -(6, 23) -(7, 8) -(9, 15) -(1, 16) -(5, 8) -(9, 17) -(3, 7) -(14, 23) -(13, 25) -(6, 21) -(9, 14) -(0, 6) -(5, 12) -(8, 10) -(4, 13) -(14, 24) -(8, 16) -(4, 25) -(10, 17) -(13, 20) -(3, 4) -(20, 22) -(17, 21) -(8, 16) -(9, 24) -(3, 7) -(12, 24) -(4, 21) -(9, 18) -(14, 21) -(10, 12) -(4, 23) -(12, 19) -(7, 21) -(2, 23) -(4, 17) -(1, 14) -(7, 20) -(9, 17) -(16, 19) -(2, 14) -(1, 24) -(14, 25) -(15, 24) -(4, 19) -(1, 23) -(16, 20) -(17, 23) -(19, 20) -(8, 24) -(12, 15) -(1, 3) -(2, 15) -(0, 1) -(6, 8) -(3, 11) -(19, 24) -(7, 23) -(12, 13) -(6, 18) -(8, 20) -(22, 24) -(4, 13) -(1, 13) -(21, 24) -(2, 20) -(8, 15) -(3, 18) -(12, 22) -(2, 10) -(1, 8) -(6, 22) -(0, 3) -(16, 20) -(7, 15) -(1, 7) -(18, 22) -(5, 10) -(6, 12) -(3, 13) -(9, 20) -(10, 15) -(8, 22) -(2, 12) -(6, 16) -(13, 21) -(9, 22) -(0, 12) -(4, 13) -(8, 18) -(2, 5) -(6, 22) -(0, 7) -(6, 25) -(2, 22) -(4, 7) -(0, 11) -(2, 16) -(12, 22) -(11, 14) -(0, 4) -(5, 12) -(2, 17) -(20, 22) -(8, 12) -(5, 18) -(2, 15) -(8, 24) -(16, 18) -(12, 23) -(10, 12) -(9, 23) -(8, 25) -(6, 18) -(20, 23) -(10, 14) -(4, 8) -(9, 18) -(2, 8) -(3, 23) -(16, 20) -(1, 9) -(0, 10) -(5, 14) -(18, 25) -(6, 8) -(18, 24) -(22, 25) -(1, 13) -(6, 22) -(2, 8) -(21, 24) -(1, 14) -(9, 21) -(6, 19) -(1, 23) -(8, 25) -(17, 22) -(2, 3) -(5, 24) -(8, 20) -(3, 24) -(6, 18) -(2, 4) -(12, 21) -(6, 17) -(2, 18) -(9, 21) -(4, 13) -(21, 23) -(5, 17) -(2, 16) -(18, 25) -(7, 9) -(6, 11) -(11, 23) -(0, 2) -(8, 21) -(1, 17) -(15, 25) -(11, 20) -(6, 17) -(20, 22) -(6, 14) -(13, 17) -(20, 21) -(12, 17) -(2, 20) -(10, 17) -(12, 22) -(2, 16) -(0, 22) -(11, 17) -(1, 22) -(17, 23) -(0, 5) -(11, 13) -(13, 24) -(21, 23) -(5, 22) -(1, 8) -(11, 19) -(11, 25) -(3, 19) -(2, 23) -(14, 24) -(3, 17) -(6, 11) -(12, 24) -(18, 25) -(18, 23) -(8, 25) -(6, 12) -(3, 15) -(17, 21) -(10, 12) -(13, 25) -(6, 8) -(12, 25) -(8, 22) -(6, 14) -(13, 20) -(7, 10) -(5, 12) -(8, 25) -(0, 7) -(2, 14) -(10, 22) -(9, 13) -(2, 15) -(4, 13) -(12, 16) -(9, 17) -(3, 5) -(1, 12) -(0, 4) -(15, 23) -(11, 16) -(9, 25) -(13, 21) -(16, 18) -(19, 21) -(2, 9) -(14, 25) -(1, 12) -(1, 13) -(12, 19) -(11, 21) -(7, 12) -(1, 4) -(8, 13) -(16, 21) -(11, 14) -(8, 20) -(1, 19) -(16, 18) -(13, 24) -(4, 8) -(15, 20) -(1, 21) -(12, 13) -(9, 24) -(9, 15) -(2, 13) -(16, 24) -(4, 7) -(6, 8) -(6, 12) -(2, 18) -(7, 14) -(2, 6) -(13, 18) -(12, 17) -(7, 20) -(14, 19) -(10, 14) -(6, 20) -(13, 21) -(2, 8) -(9, 12) -(17, 22) -(4, 18) -(19, 24) -(7, 14) -(5, 6) -(18, 23) -(19, 20) -(1, 8) -(12, 17) -(22, 23) -(0, 5) -(1, 16) -(9, 17) -(8, 21) -(2, 18) -(7, 19) -(8, 25) -(2, 10) -(16, 24) -(7, 14) -(13, 22) -(2, 15) -(10, 18) -(16, 20) -(23, 24) -(10, 25) -(5, 15) -(1, 16) -(20, 23) -(1, 8) -(24, 25) -(5, 6) -(20, 21) -(22, 24) -(4, 21) -(2, 6) -(1, 25) -(8, 10) -(16, 22) -(2, 18) -(1, 15) -(10, 20) -(21, 24) -(6, 14) -(1, 23) -(15, 21) -(7, 16) -(17, 20) -(0, 10) -(10, 24) -(11, 20) -(23, 25) -(13, 17) -(0, 9) -(9, 25) -(8, 24) -(19, 23) -(13, 18) -(0, 14) -(1, 11) -(1, 17) -(13, 23) -(9, 11) -(14, 16) -(6, 18) -(10, 24) -(8, 24) -(11, 15) -(6, 19) -(5, 23) -(1, 22) -(9, 16) -(4, 17) -(22, 24) -(8, 25) -(4, 14) -(17, 21) -(0, 9) -(8, 19) -(13, 25) -(2, 4) -(0, 3) -(17, 23) -(13, 16) -(4, 23) -(15, 16) -(9, 13) -(3, 4) -(4, 23) -(12, 15) -(13, 18) -(8, 13) -(7, 15) -(3, 4) -(17, 18) -(5, 23) -(12, 24) -(12, 15) -(3, 14) -(20, 24) -(10, 14) -(9, 15) -(13, 24) -(3, 7) -(12, 25) -(5, 20) -(0, 3) -(12, 23) -(5, 21) -(4, 20) -(11, 24) -(8, 15) -(7, 18) -(6, 21) -(16, 18) -(5, 25) -(7, 24) -(4, 17) -(2, 6) -(21, 24) -(7, 11) -(19, 25) -(12, 21) -(2, 25) -(19, 23) -(3, 25) -(8, 21) -(13, 19) -(15, 23) -(8, 16) -(2, 19) -(9, 13) -(4, 23) -(2, 4) -(6, 13) -(17, 19) -(2, 25) -(3, 13) -(4, 23) -(17, 20) -(6, 24) -(19, 25) -(15, 20) -(18, 23) -(3, 5) -(9, 13) -(2, 10) -(12, 23) -(13, 21) -(0, 9) -(5, 24) -(18, 22) -(10, 20) -(4, 24) -(12, 15) -(19, 21) -(0, 14) -(7, 9) -(10, 16) -(0, 16) -(15, 25) -(8, 12) -(1, 14) -(20, 21) -(4, 22) -(7, 23) -(8, 11) -(14, 15) -(18, 25) -(19, 21) -(15, 19) -(8, 14) -(9, 11) -(5, 15) -(14, 18) -(2, 9) -(17, 19) -(11, 23) -(0, 15) -(11, 21) -(5, 18) -(9, 16) -(1, 2) -(7, 14) -(1, 23) -(18, 19) -(3, 21) -(4, 15) -(2, 14) -(7, 12) -(11, 13) -(1, 11) -(13, 20) -(2, 4) -(3, 7) -(21, 22) -(6, 22) -(3, 10) -(0, 21) -(16, 20) -(4, 25) -(6, 11) -(2, 21) -(24, 25) -(9, 10) -(12, 22) -(0, 14) -(16, 21) -(0, 17) -(22, 23) -(12, 13) -(8, 10) -(10, 14) -(9, 21) -(3, 23) -(15, 17) -(12, 20) -(0, 8) -(8, 10) -(1, 3) -(4, 15) -(19, 20) -(11, 21) -(4, 14) -(3, 19) -(6, 20) -(2, 19) -(4, 24) -(3, 12) -(14, 25) -(20, 23) -(7, 14) -(8, 12) -(20, 23) -(10, 23) -(10, 22) -(16, 23) -(15, 22) -(17, 23) -(4, 10) -(5, 17) -(10, 24) -(1, 23) -(6, 15) -(4, 20) -(11, 22) -(8, 17) -(3, 24) -(18, 22) -(10, 19) -(5, 21) -(18, 19) -(8, 13) -(5, 12) -(3, 21) -(7, 22) -(6, 12) -(5, 23) -(1, 3) -(2, 13) -(5, 23) -(1, 11) -(13, 20) -(3, 7) -(4, 6) -(5, 21) -(6, 13) -(4, 17) -(1, 20) -(11, 25) -(5, 24) -(16, 17) -(13, 15) -(9, 16) -(10, 13) -(5, 12) -(16, 20) -(6, 9) -(10, 18) -(12, 22) -(2, 5) -(0, 9) -(8, 12) -(22, 25) -(2, 7) -(16, 23) -(5, 21) -(13, 23) -(12, 17) -(16, 24) -(11, 22) -(7, 8) -(19, 25) -(11, 18) -(17, 21) -(14, 19) -(16, 18) -(9, 17) -(21, 25) -(19, 21) -(9, 13) -(12, 25) -(0, 17) -(12, 15) -(0, 3) -(14, 21) -(10, 13) -(1, 25) -(8, 9) -(3, 8) -(0, 23) -(9, 11) -(2, 14) -(6, 12) -(13, 17) -(5, 21) -(4, 23) -(11, 22) -(6, 25) -(6, 9) -(19, 22) -(21, 25) -(1, 4) -(18, 19) -(12, 22) -(1, 2) -(4, 7) -(1, 14) -(7, 13) -(22, 24) -(11, 13) -(1, 2) -(12, 14) -(7, 25) -(14, 19) -(2, 10) -(1, 9) -(7, 20) -(13, 25) -(11, 16) -(8, 16) -(13, 21) -(2, 23) -(17, 19) -(18, 20) -(4, 8) -(3, 23) -(17, 24) -(1, 20) -(18, 19) -(12, 13) -(10, 23) -(18, 19) -(3, 15) -(21, 24) -(7, 13) -(12, 14) -(5, 17) -(17, 22) -(9, 21) -(6, 14) -(6, 8) -(21, 22) -(5, 21) -(6, 15) -(8, 25) -(8, 12) -(14, 25) -(1, 6) -(23, 25) -(12, 21) -(1, 7) -(8, 15) -(8, 13) -(0, 7) -(9, 25) -(6, 15) -(1, 11) -(6, 8) -(9, 18) -(11, 23) -(24, 25) -(10, 13) -(7, 21) -(4, 9) -(6, 17) -(7, 12) -(14, 18) -(23, 25) -(13, 22) -(8, 19) -(0, 10) -(20, 22) -(14, 23) -(10, 19) -(2, 4) -(7, 25) -(8, 18) -(17, 23) -(14, 24) -(2, 19) -(15, 25) -(4, 14) -(2, 19) -(16, 17) -(23, 24) -(3, 24) -(10, 14) -(17, 20) -(4, 21) -(9, 16) -(10, 23) -(19, 20) -(3, 6) -(1, 16) -(4, 11) -(17, 21) -(1, 7) -(0, 17) -(9, 23) -(2, 10) -(10, 16) -(2, 14) -(9, 25) -(12, 23) -(10, 20) -(3, 12) -(2, 24) -(8, 16) -(14, 21) -(13, 23) -(1, 24) -(0, 21) -(8, 12) -(11, 13) -(2, 5) -(13, 15) -(1, 22) -(9, 11) -(12, 20) -(5, 25) -(2, 18) -(9, 13) -(14, 20) -(11, 24) -(15, 17) -(1, 3) -(23, 25) -(8, 23) -(1, 10) -(0, 20) -(17, 21) -(11, 19) -(14, 18) -(4, 25) -(2, 14) -(8, 16) -(11, 12) -(4, 10) -(1, 9) -(17, 25) -(4, 6) -(2, 19) -(14, 24) -(7, 8) -(3, 19) -(6, 22) -(2, 8) -(2, 12) -(3, 4) -(5, 6) -(8, 9) -(4, 13) -(3, 9) -(7, 8) -(5, 14) -(8, 15) -(0, 5) -(7, 11) -(3, 17) -(1, 14) -(13, 22) -(10, 13) -(14, 24) -(7, 12) -(1, 21) -(19, 22) -(1, 6) -(2, 13) -(3, 24) -(12, 15) -(18, 21) -(6, 14) -(1, 18) -(2, 3) -(0, 21) -(2, 4) -(1, 6) -(0, 9) -(19, 21) -(6, 25) -(1, 17) -(5, 21) -(0, 2) -(19, 22) -(22, 23) -(14, 19) -(5, 12) -(7, 14) -(6, 22) -(4, 23) -(13, 19) -(9, 19) -(14, 17) -(2, 23) -(6, 10) -(13, 18) -(3, 7) -(18, 20) -(0, 23) -(8, 13) -(3, 19) -(10, 16) -(7, 17) -(12, 17) -(20, 25) -(14, 16) -(3, 11) -(0, 10) -(4, 18) -(7, 15) -(5, 25) -(12, 17) -(4, 24) -(3, 15) -(9, 17) -(3, 11) -(8, 24) -(12, 18) -(13, 24) -(4, 9) -(12, 20) -(8, 21) -(3, 22) -(3, 14) -(18, 21) -(15, 20) -(2, 24) -(2, 17) -(8, 14) -(18, 19) -(1, 20) -(6, 15) -(1, 22) -(15, 25) -(2, 5) -(16, 17) -(19, 23) -(15, 21) -(5, 8) -(2, 8) -(5, 25) -(11, 15) -(11, 21) -(18, 25) -(2, 12) -(3, 5) -(3, 9) -(19, 25) -(2, 4) -(1, 11) -(15, 25) -(2, 20) -(5, 9) -(1, 24) -(4, 22) -(3, 7) -(7, 11) -(9, 13) -(17, 24) -(2, 3) -(4, 14) -(8, 24) -(17, 19) -(13, 21) -(4, 7) -(9, 23) -(18, 24) -(19, 23) -(7, 15) -(8, 19) -(4, 7) -(3, 24) -(3, 21) -(4, 18) -(7, 15) -(24, 25) -(3, 4) -(6, 7) -(3, 18) -(7, 12) -(0, 6) -(0, 2) -(7, 20) -(6, 18) -(3, 9) -(2, 18) -(0, 11) -(15, 20) -(1, 20) -(8, 15) -(4, 11) -(0, 16) -(3, 18) -(2, 7) -(8, 19) -(12, 18) -(7, 10) -(1, 11) -(20, 23) -(0, 22) -(0, 6) -(10, 16) -(8, 15) -(23, 24) -(11, 21) -(9, 11) -(21, 25) -(17, 24) -(6, 22) -(4, 15) -(3, 11) -(20, 25) -(14, 25) -(3, 12) -(11, 23) -(16, 20) -(7, 16) -(14, 19) -(4, 23) -(21, 23) -(8, 16) -(1, 19) -(2, 8) -(7, 19) -(3, 16) -(8, 11) -(17, 19) -(2, 10) -(7, 13) -(18, 19) -(1, 13) -(8, 10) -(11, 12) -(19, 20) -(5, 18) -(7, 8) -(2, 18) -(20, 23) -(5, 15) -(4, 19) -(15, 16) -(5, 7) -(2, 6) -(9, 18) -(9, 24) -(3, 18) -(10, 15) -(2, 23) -(2, 22) -(1, 9) -(16, 18) -(10, 20) -(17, 23) -(12, 15) -(8, 20) -(0, 16) -(1, 2) -(13, 15) -(12, 24) -(21, 23) -(16, 25) -(0, 18) -(3, 24) -(11, 13) -(15, 21) -(19, 24) -(4, 13) -(10, 11) -(3, 15) -(2, 21) -(6, 16) -(18, 25) -(11, 15) -(22, 24) -(12, 13) -(16, 19) -(18, 20) -(5, 6) -(4, 21) -(18, 25) -(14, 24) -(4, 10) -(6, 13) -(5, 15) -(4, 18) -(2, 14) -(10, 25) -(8, 14) -(10, 21) -(2, 8) -(9, 10) -(2, 23) -(10, 11) -(5, 8) -(5, 16) -(10, 12) -(21, 23) -(8, 11) -(5, 13) -(18, 23) -(9, 21) -(11, 19) -(0, 11) -(6, 19) -(14, 23) -(1, 21) -(9, 20) -(4, 11) -(0, 12) -(10, 21) -(3, 14) -(13, 19) -(1, 7) -(16, 19) -(1, 13) -(7, 8) -(14, 25) -(19, 22) -(6, 25) -(14, 18) -(8, 9) -(16, 24) -(17, 25) -(9, 21) -(16, 20) -(0, 24) -(3, 22) -(12, 16) -(10, 20) -(4, 22) -(8, 9) -(6, 10) -(22, 25) -(8, 12) -(7, 20) -(3, 16) -(2, 20) -(3, 19) -(7, 22) -(8, 15) -(4, 16) -(0, 6) -(4, 24) -(7, 18) -(2, 10) -(6, 17) -(11, 16) -(5, 7) -(10, 19) -(17, 18) -(6, 16) -(4, 21) -(22, 24) -(9, 19) -(8, 10) -(5, 14) -(3, 24) -(2, 19) -(6, 24) -(9, 11) -(8, 22) -(2, 13) -(1, 19) -(6, 25) -(2, 20) -(1, 16) -(19, 21) -(2, 10) -(13, 19) -(1, 4) -(9, 20) -(7, 21) -(12, 21) -(13, 15) -(0, 19) -(1, 9) -(7, 11) -(2, 24) -(23, 24) -(17, 21) -(4, 13) -(7, 19) -(13, 16) -(14, 17) -(21, 22) -(1, 24) -(17, 18) -(0, 24) -(21, 25) -(20, 22) -(10, 18) -(11, 17) -(3, 25) -(15, 21) -(1, 22) -(1, 7) -(12, 25) -(13, 21) -(5, 15) -(12, 16) -(0, 13) -(3, 5) -(11, 16) -(3, 4) -(10, 12) -(6, 16) -(11, 21) -(9, 10) -(4, 5) -(12, 23) -(6, 20) -(8, 16) -(7, 21) -(12, 19) -(16, 25) -(12, 14) -(2, 19) -(15, 25) -(0, 19) -(12, 24) -(16, 18) -(17, 24) -(5, 15) -(0, 1) -(2, 16) -(12, 21) -(3, 25) -(1, 24) -(3, 11) -(7, 25) -(0, 6) -(4, 5) -(8, 15) -(1, 5) -(19, 24) -(15, 20) -(7, 12) -(4, 14) -(10, 14) -(20, 22) -(7, 12) -(8, 19) -(15, 20) -(13, 22) -(4, 20) -(12, 15) -(2, 22) -(4, 12) -(20, 23) -(2, 21) -(6, 22) -(16, 20) -(2, 12) -(0, 23) -(9, 21) -(18, 23) -(1, 16) -(20, 25) -(11, 18) -(3, 23) -(5, 25) -(20, 22) -(0, 18) -(1, 3) -(5, 19) -(17, 23) -(8, 20) -(3, 25) -(0, 10) -(5, 18) -(1, 21) -(19, 21) -(0, 15) -(4, 10) -(10, 14) -(7, 19) -(4, 12) -(0, 21) -(12, 17) -(8, 14) -(0, 20) -(12, 24) -(5, 14) -(17, 23) -(7, 20) -(13, 14) -(17, 22) -(9, 23) -(17, 18) -(23, 24) -(16, 22) -(11, 13) -(0, 22) -(2, 18) -(17, 19) -(24, 25) -(5, 23) -(13, 14) -(21, 23) -(14, 24) -(6, 17) -(1, 19) -(11, 22) -(0, 7) -(12, 25) -(18, 23) -(6, 9) -(4, 25) -(20, 21) -(10, 12) -(17, 20) -(2, 4) -(12, 22) -(9, 13) -(6, 8) -(5, 23) -(2, 15) -(4, 10) -(5, 20) -(1, 6) -(17, 21) -(6, 13) -(0, 4) -(1, 12) -(15, 20) -(9, 13) -(11, 20) -(6, 22) -(12, 25) -(10, 15) -(1, 16) -(11, 14) -(1, 8) -(10, 16) -(13, 19) -(12, 23) -(5, 20) -(9, 21) -(12, 25) -(4, 9) -(19, 22) -(11, 13) -(19, 20) -(12, 21) -(7, 22) -(24, 25) -(11, 21) -(17, 19) -(0, 22) -(7, 18) -(23, 25) -(9, 12) -(14, 18) -(6, 12) -(19, 25) -(2, 9) -(7, 14) -(3, 6) -(18, 20) -(2, 23) -(7, 16) -(17, 20) -(14, 25) -(3, 13) -(7, 16) -(2, 20) -(5, 17) -(14, 18) -(20, 23) -(2, 6) -(14, 25) -(7, 16) -(5, 18) -(17, 21) -(6, 16) -(15, 23) -(2, 8) -(9, 21) -(5, 24) -(7, 20) -(17, 23) -(8, 14) -(10, 20) -(0, 7) -(14, 25) -(1, 17) -(18, 23) -(0, 4) -(10, 19) -(13, 18) -(7, 19) -(12, 23) -(0, 2) -(11, 19) -(13, 14) -(2, 15) -(6, 7) -(1, 7) -(4, 11) -(6, 16) -(19, 22) -(2, 9) -(1, 14) -(10, 16) -(3, 19) -(9, 15) -(6, 20) -(11, 22) -(2, 19) -(15, 21) -(5, 22) -(3, 17) -(0, 20) -(5, 17) -(19, 25) -(12, 21) -(0, 24) -(9, 12) -(18, 21) -(0, 4) -(0, 17) -(8, 21) -(10, 12) -(4, 7) -(6, 9) -(2, 17) -(9, 25) -(4, 22) -(10, 20) -(3, 6) -(2, 5) -(9, 13) -(0, 6) -(4, 20) -(3, 15) -(15, 24) -(3, 11) -(13, 17) -(0, 8) -(5, 18) -(16, 18) -(6, 15) -(11, 12) -(3, 7) -(8, 14) -(3, 13) -(11, 21) -(10, 12) -(1, 8) -(9, 18) -(6, 17) -(13, 16) -(5, 21) -(9, 19) -(6, 14) -(7, 10) -(17, 23) -(5, 20) -(16, 24) -(1, 7) -(15, 21) -(10, 12) -(4, 23) -(2, 20) -(16, 25) -(9, 12) -(5, 17) -(7, 17) -(0, 20) -(5, 11) -(1, 16) -(4, 16) -(11, 21) -(17, 24) -(0, 2) -(10, 20) -(0, 16) -(4, 7) -(6, 17) -(2, 20) -(10, 14) -(21, 23) -(7, 9) -(16, 22) -(14, 15) -(1, 6) -(4, 5) -(10, 17) -(15, 20) -(1, 2) -(6, 10) -(0, 4) -(14, 17) -(10, 16) -(4, 8) -(1, 13) -(15, 18) -(0, 24) -(2, 15) -(8, 18) -(3, 4) -(0, 1) -(1, 16) -(0, 19) -(15, 21) -(2, 15) -(19, 25) -(11, 21) -(15, 23) -(2, 10) -(4, 19) -(8, 25) -(19, 20) -(12, 25) -(2, 18) -(11, 12) -(8, 25) -(16, 19) -(2, 7) -(0, 16) -(13, 25) -(8, 14) -(10, 19) -(8, 9) -(7, 16) -(10, 24) -(3, 25) -(9, 25) -(10, 15) -(3, 8) -(10, 16) -(3, 13) -(6, 9) -(2, 8) -(1, 8) -(13, 23) -(0, 6) -(10, 15) -(10, 16) -(18, 23) -(1, 10) -(12, 23) -(3, 18) -(13, 16) -(3, 5) -(20, 23) -(12, 25) -(0, 13) -(3, 22) -(20, 25) -(15, 23) -(5, 19) -(1, 19) -(8, 23) -(3, 16) -(14, 22) -(5, 10) -(1, 9) -(10, 14) -(15, 22) -(2, 16) -(0, 3) -(14, 23) -(16, 21) -(0, 19) -(2, 25) -(3, 11) -(1, 17) -(3, 18) -(4, 25) -(6, 17) -(20, 21) -(2, 17) -(10, 18) -(3, 24) -(1, 4) -(6, 22) -(1, 9) -(14, 17) -(3, 7) -(4, 19) -(22, 24) -(10, 15) -(1, 16) -(2, 22) -(14, 24) -(7, 17) -(12, 15) -(10, 20) -(7, 23) -(11, 20) -(0, 10) -(3, 22) -(9, 14) -(1, 11) -(7, 16) -(20, 25) -(9, 17) -(10, 15) -(0, 8) -(14, 25) -(9, 13) -(17, 19) -(1, 12) -(9, 24) -(13, 19) -(14, 21) -(1, 3) -(11, 25) -(17, 23) -(0, 14) -(9, 10) -(3, 12) -(14, 22) -(10, 24) -(8, 9) -(0, 12) -(10, 20) -(2, 9) -(18, 24) -(11, 12) -(18, 22) -(3, 11) -(9, 24) -(5, 10) -(6, 12) -(12, 25) -(9, 20) -(6, 8) -(2, 24) -(11, 19) -(16, 18) -(3, 17) -(12, 19) -(7, 18) -(11, 17) -(1, 2) -(3, 23) -(24, 25) -(0, 9) -(17, 22) -(19, 25) -(2, 24) -(11, 20) -(5, 9) -(1, 16) -(0, 6) -(15, 20) -(5, 10) -(3, 9) -(14, 17) -(6, 22) -(5, 8) -(1, 15) -(2, 6) -(18, 20) -(9, 25) -(10, 21) -(3, 8) -(4, 5) -(6, 24) -(17, 18) -(11, 21) -(1, 19) -(10, 12) -(0, 11) -(12, 22) -(1, 6) -(0, 3) -(13, 22) -(5, 11) -(0, 1) -(5, 23) -(3, 14) -(10, 22) -(19, 23) -(10, 13) -(18, 22) -(3, 5) -(6, 23) -(5, 9) -(3, 16) -(19, 24) -(22, 25) -(5, 14) -(4, 19) -(7, 24) -(11, 16) -(7, 8) -(15, 16) -(6, 24) -(1, 14) -(3, 4) -(19, 22) -(5, 19) -(2, 24) -(7, 12) -(8, 23) -(3, 25) -(4, 10) -(4, 13) -(6, 8) -(23, 25) -(0, 10) -(12, 14) -(2, 9) -(10, 15) -(11, 13) -(18, 25) -(2, 20) -(6, 9) -(4, 16) -(0, 7) -(7, 25) -(1, 13) -(0, 8) -(9, 16) -(14, 18) -(2, 21) -(11, 17) -(1, 15) -(2, 20) -(18, 22) -(12, 17) -(21, 25) -(0, 17) -(1, 13) -(8, 12) -(14, 20) -(1, 10) -(13, 24) -(3, 20) -(14, 18) -(0, 22) -(22, 24) -(3, 17) -(20, 23) -(1, 4) -(10, 11) -(4, 6) -(10, 21) -(7, 22) -(22, 24) -(6, 9) -(9, 17) -(24, 25) -(7, 22) -(4, 7) -(1, 22) -(12, 17) -(10, 22) -(5, 12) -(7, 8) -(1, 25) -(7, 19) -(24, 25) -(8, 23) -(3, 19) -(5, 25) -(15, 23) -(6, 24) -(16, 19) -(3, 4) -(3, 21) -(7, 19) -(4, 22) -(13, 16) -(13, 17) -(2, 19) -(7, 18) -(1, 21) -(0, 4) -(4, 15) -(1, 24) -(7, 11) -(13, 21) -(2, 3) -(9, 18) -(18, 25) -(0, 11) -(16, 24) -(3, 12) -(2, 8) -(0, 14) -(2, 13) -(6, 8) -(15, 24) -(10, 18) -(8, 12) -(10, 11) -(19, 24) -(2, 23) -(13, 18) -(13, 25) -(1, 8) -(10, 11) -(2, 6) -(8, 14) -(11, 22) -(6, 21) -(1, 12) -(12, 20) -(15, 22) -(1, 23) -(5, 6) -(19, 21) -(7, 8) -(1, 4) -(12, 16) -(8, 24) -(17, 23) -(6, 14) -(4, 20) -(2, 24) -(5, 6) -(15, 16) -(21, 23) -(7, 20) -(11, 16) -(6, 14) -(3, 4) -(6, 10) -(16, 22) -(9, 14) -(5, 16) -(1, 10) -(6, 17) -(3, 9) -(14, 24) -(17, 25) -(10, 12) -(5, 21) -(6, 13) -(9, 24) -(16, 24) -(10, 15) -(4, 13) -(0, 12) -(2, 6) -(0, 11) -(16, 24) -(4, 6) -(3, 15) -(10, 23) -(12, 19) -(3, 22) -(2, 19) -(15, 18) -(1, 11) -(16, 24) -(0, 11) -(2, 25) -(12, 24) -(10, 16) -(8, 22) -(1, 17) -(14, 15) -(18, 20) -(17, 24) -(0, 22) -(2, 15) -(1, 23) -(18, 19) -(14, 21) -(3, 16) -(5, 10) -(0, 8) -(7, 19) -(3, 6) -(20, 23) -(1, 18) -(3, 14) -(6, 13) -(20, 21) -(8, 24) -(0, 7) -(1, 9) -(4, 13) -(21, 25) -(6, 19) -(9, 11) -(7, 15) -(1, 17) -(8, 23) -(8, 12) -(19, 22) -(9, 25) -(4, 13) -(1, 15) -(11, 18) -(7, 22) -(8, 17) -(4, 13) -(5, 25) -(4, 11) -(22, 23) -(15, 25) -(3, 17) -(2, 8) -(5, 8) -(2, 12) -(6, 11) -(7, 17) -(4, 16) -(10, 23) -(19, 23) -(0, 2) -(1, 6) -(9, 12) -(16, 21) -(9, 22) -(12, 19) -(0, 5) -(1, 11) -(2, 8) -(1, 24) -(4, 11) -(17, 19) -(1, 3) -(10, 24) -(11, 20) -(15, 24) -(20, 25) -(21, 25) -(15, 19) -(14, 20) -(17, 24) -(6, 25) -(14, 23) -(13, 21) -(4, 20) -(3, 13) -(12, 14) -(4, 22) -(4, 16) -(3, 5) -(7, 22) -(14, 25) -(16, 18) -(4, 6) -(5, 19) -(17, 18) -(4, 21) -(6, 11) -(11, 18) -(20, 21) -(16, 20) -(4, 16) -(4, 13) -(0, 16) -(4, 17) -(13, 14) -(7, 13) -(17, 23) -(5, 14) -(4, 25) -(2, 7) -(10, 17) -(11, 13) -(4, 24) -(14, 23) -(13, 15) -(2, 25) -(14, 17) -(21, 23) -(1, 4) -(12, 25) -(1, 15) -(16, 17) -(14, 23) -(8, 13) -(2, 22) -(16, 18) -(11, 14) -(2, 5) -(6, 12) -(4, 13) -(14, 22) -(13, 24) -(5, 15) -(6, 19) -(2, 25) -(9, 11) -(6, 21) -(10, 13) -(19, 25) -(6, 18) -(19, 22) -(13, 17) -(10, 16) -(2, 19) -(4, 13) -(10, 15) -(8, 18) -(6, 21) -(4, 17) -(18, 23) -(19, 24) -(3, 6) -(1, 13) -(19, 24) -(1, 21) -(6, 13) -(4, 18) -(3, 7) -(19, 22) -(1, 14) -(2, 3) -(4, 18) -(6, 25) -(0, 13) -(0, 2) -(4, 24) -(5, 14) -(18, 25) -(13, 15) -(15, 16) -(13, 19) -(5, 22) -(0, 3) -(4, 9) -(9, 10) -(19, 21) -(1, 22) -(16, 17) -(0, 5) -(4, 11) -(17, 23) -(4, 8) -(6, 9) -(10, 13) -(0, 7) -(2, 6) -(9, 11) -(20, 23) -(8, 16) -(10, 21) -(10, 22) -(1, 9) -(3, 11) -(5, 20) -(3, 21) -(1, 13) -(9, 22) -(10, 16) -(3, 19) -(15, 21) -(3, 19) \ No newline at end of file diff --git a/04-08-amidakuji/04-small.txt b/04-08-amidakuji/04-small.txt deleted file mode 100644 index 75e0d3d..0000000 --- a/04-08-amidakuji/04-small.txt +++ /dev/null @@ -1,15 +0,0 @@ -(2, 5) -(1, 4) -(0, 3) -(0, 3) -(0, 5) -(3, 5) -(0, 2) -(3, 4) -(2, 4) -(1, 2) -(0, 4) -(1, 2) -(2, 4) -(0, 4) -(1, 4) \ No newline at end of file diff --git a/04-08-amidakuji/amidakuji-creation.ipynb b/04-08-amidakuji/amidakuji-creation.ipynb deleted file mode 100644 index 65d9751..0000000 --- a/04-08-amidakuji/amidakuji-creation.ipynb +++ /dev/null @@ -1,2514 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import collections\n", - "import random\n", - "import string\n", - "import itertools" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "Link = collections.namedtuple('Link', 'height left right')" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def link_ends(link):\n", - " return set((link.left, link.right))" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def can_add(link, links):\n", - " ends = link_ends(link)\n", - " same_height_links = [l for l in links if l.height == link.height]\n", - " return all(ends.isdisjoint(link_ends(l)) for l in same_height_links)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def make_net(num_links, lines=10, height=50):\n", - " links = set()\n", - " while len(links) < num_links:\n", - " a = random.randrange(lines)\n", - " b = random.randrange(lines)\n", - " if a != b:\n", - " l = min(a, b)\n", - " r = max(a, b)\n", - " h = random.randrange(height)\n", - " link = Link(h, l, r)\n", - " if can_add(link, links):\n", - " links.add(link)\n", - " return links" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{Link(height=4, left=0, right=3),\n", - " Link(height=8, left=1, right=5),\n", - " Link(height=16, left=0, right=4),\n", - " Link(height=17, left=1, right=5),\n", - " Link(height=18, left=3, right=5),\n", - " Link(height=20, left=0, right=1),\n", - " Link(height=25, left=0, right=3),\n", - " Link(height=30, left=1, right=4),\n", - " Link(height=33, left=0, right=4),\n", - " Link(height=34, left=4, right=5),\n", - " Link(height=35, left=0, right=3),\n", - " Link(height=36, left=1, right=4),\n", - " Link(height=37, left=2, right=5),\n", - " Link(height=45, left=4, right=5),\n", - " Link(height=46, left=2, right=5)}" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "net = make_net(15, lines=6)\n", - "net" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow(initial_line, links):\n", - " line = initial_line\n", - " heights = sorted(set(l.height for l in links))\n", - " for h in heights:\n", - " for l in [l for l in links if l.height == h]:\n", - " if line in link_ends(l):\n", - " line = [e for e in link_ends(l) if e != line][0]\n", - "# print(l, line)\n", - " return line" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "follow(4, net)" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def pack(net):\n", - " packed_links = []\n", - " line_heights = collections.defaultdict(lambda: -1)\n", - " for link in sorted(net):\n", - " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", - " line_heights[link.left] = link_height\n", - " line_heights[link.right] = link_height\n", - " packed_links += [Link(link_height, link.left, link.right)]\n", - " return sorted(packed_links)" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow_many_slow(in_sequence, links):\n", - " out_sequence = [(follow(i, links), term) \n", - " for i, term in enumerate(in_sequence)]\n", - " return [term for i, term in sorted(out_sequence)]" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow_many(in_sequence, net):\n", - " height_groups = [list(g) for _, g in itertools.groupby(pack(net), lambda l: l.height)]\n", - " seq = list(in_sequence)\n", - " for links in height_groups:\n", - " for link in links:\n", - "# l = seq[link.left]\n", - "# r = seq[link.right]\n", - "# seq[link.right] = l\n", - "# seq[link.left] = r\n", - " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", - " return seq" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10000 loops, best of 3: 39.2 µs per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many('abcdef', net)" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# %%timeit\n", - "# follow_many_slow('abcdefghij', net)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def show_net(links, randomise=False, pair_sep=', '):\n", - " if randomise:\n", - " output = []\n", - " heights = sorted(set(l.height for l in links))\n", - " for h in heights:\n", - " ls = [l for l in links if l.height == h]\n", - " random.shuffle(ls)\n", - " output += ['({}, {})'.format(l.left, l.right) for l in ls]\n", - " return pair_sep.join(output)\n", - " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(0, 3), (1, 5), (0, 4), (1, 5), (3, 5), (0, 1), (0, 3), (1, 4), (0, 4), (4, 5), (0, 3), (1, 4), (2, 5), (4, 5), (2, 5)'" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_net(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(0, 3), (1, 5), (0, 4), (1, 5), (3, 5), (0, 1), (0, 3), (1, 4), (0, 4), (4, 5), (0, 3), (1, 4), (2, 5), (4, 5), (2, 5)'" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_net(net, randomise=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(0, 3) : (1, 5) : (0, 4) : (1, 5) : (3, 5) : (0, 1) : (0, 3) : (1, 4) : (0, 4) : (4, 5) : (0, 3) : (1, 4) : (2, 5) : (4, 5) : (2, 5)'" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_net(net, pair_sep=' : ')" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(0, 3)\\n(1, 5)\\n(0, 4)\\n(1, 5)\\n(3, 5)\\n(0, 1)\\n(0, 3)\\n(1, 4)\\n(0, 4)\\n(4, 5)\\n(0, 3)\\n(1, 4)\\n(2, 5)\\n(4, 5)\\n(2, 5)'" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_net(net, pair_sep='\\n')" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(0, 3)\n", - "(1, 5)\n", - "(0, 4)\n", - "(1, 5)\n", - "(3, 5)\n", - "(0, 1)\n", - "(0, 3)\n", - "(1, 4)\n", - "(0, 4)\n", - "(4, 5)\n", - "(0, 3)\n", - "(1, 4)\n", - "(2, 5)\n", - "(4, 5)\n", - "(2, 5)\n" - ] - } - ], - "source": [ - "print(show_net(net, pair_sep='\\n'))" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [], - "source": [ - "# open('04-small.txt', 'w').write(show_net(net))" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(0, 3), (1, 5), (0, 4), (1, 5), (3, 5), (0, 1), (0, 3), (1, 4), (0, 4), (4, 5), (0, 3), (1, 4), (2, 5), (4, 5), (2, 5)'" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_net(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "ls = [l for l in net if l.height == 1]\n", - "ls" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "random.shuffle(ls)" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def read_net(net_string):\n", - " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def extract_pairs(net_string):\n", - " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "net = read_net('(1, 5), (2, 4), (0, 2), (0, 4), (0, 1), (0, 2), (1, 5), (0, 3), (1, 2), (4, 5), (0, 5), (3, 5), (1, 4), (0, 1), (2, 3)')" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=1, right=5),\n", - " Link(height=1, left=2, right=4),\n", - " Link(height=2, left=0, right=2),\n", - " Link(height=3, left=0, right=4),\n", - " Link(height=4, left=0, right=1),\n", - " Link(height=5, left=0, right=2),\n", - " Link(height=6, left=1, right=5),\n", - " Link(height=7, left=0, right=3),\n", - " Link(height=8, left=1, right=2),\n", - " Link(height=9, left=4, right=5),\n", - " Link(height=10, left=0, right=5),\n", - " Link(height=11, left=3, right=5),\n", - " Link(height=12, left=1, right=4),\n", - " Link(height=13, left=0, right=1),\n", - " Link(height=14, left=2, right=3)]" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "read_net(show_net(net))" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=1, right=5),\n", - " Link(height=0, left=2, right=4),\n", - " Link(height=1, left=0, right=2),\n", - " Link(height=2, left=0, right=4),\n", - " Link(height=3, left=0, right=1),\n", - " Link(height=4, left=0, right=2),\n", - " Link(height=4, left=1, right=5),\n", - " Link(height=5, left=0, right=3),\n", - " Link(height=5, left=1, right=2),\n", - " Link(height=5, left=4, right=5),\n", - " Link(height=6, left=0, right=5),\n", - " Link(height=6, left=1, right=4),\n", - " Link(height=7, left=0, right=1),\n", - " Link(height=7, left=3, right=5),\n", - " Link(height=8, left=2, right=3)]" - ] - }, - "execution_count": 63, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pack(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=1, right=5),\n", - " Link(height=0, left=2, right=4),\n", - " Link(height=1, left=0, right=2),\n", - " Link(height=2, left=0, right=4),\n", - " Link(height=3, left=0, right=1),\n", - " Link(height=4, left=0, right=2),\n", - " Link(height=4, left=1, right=5),\n", - " Link(height=5, left=0, right=3),\n", - " Link(height=5, left=1, right=2),\n", - " Link(height=5, left=4, right=5),\n", - " Link(height=6, left=0, right=5),\n", - " Link(height=6, left=1, right=4),\n", - " Link(height=7, left=0, right=1),\n", - " Link(height=7, left=3, right=5),\n", - " Link(height=8, left=2, right=3)]" - ] - }, - "execution_count": 64, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pack(read_net(show_net(net)))" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(True, True)" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pnet = pack(net)\n", - "rrnet = read_net(show_net(net, randomise=True))\n", - "rnet = read_net(show_net(net))\n", - "rnet == rrnet, pack(rrnet) == pnet" - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "lnet = make_net(10207, 26, 100000)\n", - "plnet = pack(lnet)\n", - "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, plnet)\n", - "# for i in range(204):\n", - "# assert follow(i, lnet) == follow(i, plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 67, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "rlnet = read_net(show_net(lnet))\n", - "prlnet = pack(rlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 68, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2239" - ] - }, - "execution_count": 68, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "99989" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10206" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in rlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2239" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in prlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, prlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 25.9 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many(string.ascii_lowercase, lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# %%timeit\n", - "# follow_many_slow(string.ascii_lowercase, lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 75, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pairs_slow(net):\n", - " eps = []\n", - " for l in net:\n", - " o = Link(l.height + 1, l.left, l.right)\n", - " if o in net:\n", - " eps += [(l, o)]\n", - " return eps " - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pairs(net):\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - " eps = []\n", - " for h in range(1, max(height_groups.keys())):\n", - " for l in height_groups[h]:\n", - " o = Link(l.height - 1, l.left, l.right)\n", - " if o in height_groups[h-1]:\n", - " eps += [(l, o)]\n", - " return eps" - ] - }, - { - "cell_type": "code", - "execution_count": 77, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 24.1 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "eliminable_pairs(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 78, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pair(net):\n", - " for l in net:\n", - " o = Link(l.height + 1, l.left, l.right)\n", - " if o in net:\n", - " return l, o\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pair_hg(height_groups):\n", - " for h in range(1, max(height_groups.keys())):\n", - " for l in height_groups[h]:\n", - " o = Link(l.height - 1, l.left, l.right)\n", - " if o in height_groups[h-1]:\n", - " return l, o\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_pairs_slow(net):\n", - " eliminable_links = eliminable_pair(net)\n", - " while eliminable_links:\n", - " net = pack(l for l in net if l not in eliminable_links)\n", - " eliminable_links = eliminable_pair(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_pairs(net):\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - " eliminable_links = eliminable_pair_hg(height_groups)\n", - " while eliminable_links:\n", - " net = pack(l for l in net if l not in eliminable_links)\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - " eliminable_links = eliminable_pair_hg(height_groups)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10207\n" - ] - }, - { - "data": { - "text/plain": [ - "(10207, 9813)" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(len(plnet))\n", - "elnet = eliminate_pairs(plnet)\n", - "len(plnet), len(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 83, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eliminable_pairs(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, elnet)\n", - "assert follow_many(string.ascii_lowercase, plnet) == follow_many(string.ascii_lowercase, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 85, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 loop, best of 3: 6.08 s per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "elnet = eliminate_pairs(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# for i in range(26):\n", - "# assert follow(i, plnet) == follow(i, elnet)\n", - "# assert follow(i, lnet) == follow(i, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 87, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# follow(0, plnet), follow(0, elnet), follow(0, lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple_slow(net):\n", - " x = None\n", - " y = None\n", - " ts = []\n", - " for a in net:\n", - " bs = [l for l in net if l.height == a.height + 1 \n", - " if l.left == a.right or l.right == a.left]\n", - " for b in bs:\n", - " c = Link(a.height + 2, a.left, a.right)\n", - " if c in net:\n", - " ts += [(a, b, c)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple_pair_slow(net):\n", - " ts = []\n", - " for a in net:\n", - " a_ends = link_ends(a)\n", - " bs = [l for l in net if l.height == a.height + 1 \n", - " if link_ends(l) & a_ends]\n", - " if len(bs) == 1:\n", - " b = bs[0]\n", - " lines = set((a.left, a.right, b.left, b.right))\n", - " cs = [l for l in net \n", - " if l.height == a.height + 2\n", - " if link_ends(l) & lines]\n", - " if len(cs) == 1:\n", - " c = Link(a.height + 2, a.left, a.right)\n", - " if c in cs:\n", - " ds = [l for l in net \n", - " if l.height == a.height + 3\n", - " if link_ends(l) & lines]\n", - " d = Link(a.height + 3, b.left, b.right)\n", - " if d in ds:\n", - " ts += [(a, b, c, d)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 90, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def find_height_groups(net):\n", - " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}" - ] - }, - { - "cell_type": "code", - "execution_count": 91, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple_pair_hg(height_groups, debug=False):\n", - " ts = []\n", - " for h in range(3, max(height_groups.keys())):\n", - " for d in height_groups[h]:\n", - " if debug: print('d:', d)\n", - " ch = h - 1\n", - " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", - " if debug: print('cs:', cs)\n", - " while ch > 2 and not cs:\n", - " ch -= 1\n", - " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", - " if debug: print('cs:', cs)\n", - " if len(cs) == 1:\n", - " c = cs[0]\n", - " lines = set((d.left, d.right, c.left, c.right))\n", - " if debug: print('c:', '; lines:', lines)\n", - " bs = [l for l in height_groups[ch-1] if link_ends(l) & lines]\n", - " b = Link(ch - 1, d.left, d.right)\n", - " if debug: print('b:', b, '; bs:', bs)\n", - " if len(bs) == 1 and b in bs:\n", - " ah = b.height - 1\n", - " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", - " if debug: print('ah:', ah, '; als:', als)\n", - " while ah > 0 and not als:\n", - " ah -= 1\n", - " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", - " if debug: print('ah:', ah, '; als:', als)\n", - " a = Link(ah, c.left, c.right)\n", - " if debug: print('a:', a)\n", - " if a in als:\n", - " if debug: print('adding:', a, b, c, d)\n", - " ts += [(a, b, c, d)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 92, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_a_triple_pair_slow(net, debug=False):\n", - " tps = triple_pair_slow(net)\n", - " if debug: print('eatp', tps)\n", - "\n", - " if tps:\n", - " a, b, c, d = tps[0]\n", - "# x = Link(a.height, b.left, b.right)\n", - "# y = Link(b.height, a.left, a.right)\n", - " x = Link(b.height - 0.5, b.left, b.right)\n", - " y = Link(b.height, a.left, a.right)\n", - " if debug: print('removing', a, b, c, d, '; adding', x, y)\n", - " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 93, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_a_triple_pair(net, debug=False):\n", - " height_groups = find_height_groups(net)\n", - "\n", - " tps = triple_pair_hg(height_groups)\n", - " if debug: print('eatp', tps)\n", - " if tps:\n", - " a, b, c, d = tps[0]\n", - " x = Link(b.height - 0.5, b.left, b.right)\n", - " y = Link(b.height, a.left, a.right)\n", - " if debug: print('removing', a, b, c, d, '; adding', x, y)\n", - " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=1126, left=8, right=17),\n", - " Link(height=1127, left=1, right=8),\n", - " Link(height=1128, left=8, right=17),\n", - " Link(height=1129, left=1, right=8)),\n", - " (Link(height=1952, left=12, right=25),\n", - " Link(height=1953, left=10, right=12),\n", - " Link(height=1954, left=12, right=25),\n", - " Link(height=1955, left=10, right=12))]" - ] - }, - "execution_count": 94, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "height_groups = find_height_groups(elnet)\n", - "triple_pair_hg(height_groups)" - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 98.7 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "height_groups = find_height_groups(elnet)\n", - "triple_pair_hg(height_groups)" - ] - }, - { - "cell_type": "code", - "execution_count": 96, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_triple_pairs_slow(net):\n", - " print(len(net))\n", - " new_net = eliminate_a_triple_pair_slow(net)\n", - " while new_net:\n", - " print(len(net))\n", - " net = new_net\n", - " new_net = eliminate_a_triple_pair_slow(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 97, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_triple_pairs(net):\n", - " print(len(net))\n", - " new_net = eliminate_a_triple_pair(net)\n", - " while new_net:\n", - " print(len(net))\n", - " net = new_net\n", - " new_net = eliminate_a_triple_pair(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 98, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "etlnet = eliminate_a_triple_pair(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 99, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 100, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9813\n", - "9813\n", - "9811\n" - ] - } - ], - "source": [ - "setlnet = eliminate_triple_pairs(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 101, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9809" - ] - }, - "execution_count": 101, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(setlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 102, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ypetfugkzdsacbvwjohqlnirmx'" - ] - }, - "execution_count": 103, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, etlnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 104, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ypetfugkzdsacbvwjohqlnirmx'" - ] - }, - "execution_count": 104, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, setlnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 105, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ypetfugkzdsacbvwjohqlnirmx'" - ] - }, - "execution_count": 105, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, elnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 106, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ypetfugkzdsacbvwjohqlnirmx'" - ] - }, - "execution_count": 106, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 107, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 107, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eliminable_pairs(etlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 108, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(10207, 9811)" - ] - }, - "execution_count": 108, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(lnet), len(etlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 109, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def simplify(net0):\n", - " netp = eliminate_pairs(net0)\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " while new_net:\n", - "# print('sipl', len(net0), len(netp), len(new_net))\n", - " netp = eliminate_pairs(new_net)\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " return netp" - ] - }, - { - "cell_type": "code", - "execution_count": 110, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "simple_lnet = simplify(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 111, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 111, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, simple_lnet)) == ''.join(follow_many(string.ascii_lowercase, lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 112, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ypetfugkzdsacbvwjohqlnirmx'" - ] - }, - "execution_count": 112, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, simple_lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 113, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'ypetfugkzdsacbvwjohqlnirmx'" - ] - }, - "execution_count": 113, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9809" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(simple_lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 115, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def add_triple_pair(net, max_lines=None, trace=False):\n", - " if not max_lines:\n", - " max_lines = max(l.right for l in net)\n", - " a, b, c = 0, 0, 0\n", - " while len(set((a, b, c))) != 3:\n", - " a = random.randrange(max_lines)\n", - " b = random.randrange(max_lines)\n", - " c = random.randrange(max_lines)\n", - " tp = [(min(a, b), max(a, b)), (min(b, c), max(b, c))] * 2\n", - " \n", - " pairs = [(l.left, l.right) for l in sorted(net)]\n", - " i = random.randrange(len(pairs))\n", - " if trace: print(i, tp)\n", - " new_pairs = pairs[:i] + tp + pairs[i:]\n", - " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " - ] - }, - { - "cell_type": "code", - "execution_count": 116, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def add_pair(net, max_lines=None, trace=False):\n", - " if not max_lines:\n", - " max_lines = max(l.right for l in net)\n", - "\n", - " a, b = 0, 0\n", - " while a == b:\n", - " a = random.randrange(max_lines)\n", - " b = random.randrange(max_lines)\n", - " p = [(min(a, b), max(a, b))] * 2\n", - " \n", - " pairs = [(l.left, l.right) for l in sorted(net)]\n", - " i = random.randrange(len(pairs))\n", - " \n", - " if trace: print(i, p)\n", - " new_pairs = pairs[:i] + p + pairs[i:]\n", - " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " - ] - }, - { - "cell_type": "code", - "execution_count": 117, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 117, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 118, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lnettp = simple_lnet\n", - "for _ in range(10):\n", - " lnettp = add_pair(lnettp)\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": 119, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=301, left=7, right=23),\n", - " Link(height=302, left=16, right=23),\n", - " Link(height=303, left=7, right=23),\n", - " Link(height=304, left=16, right=23)),\n", - " (Link(height=362, left=11, right=23),\n", - " Link(height=363, left=3, right=23),\n", - " Link(height=364, left=11, right=23),\n", - " Link(height=365, left=3, right=23)),\n", - " (Link(height=363, left=3, right=23),\n", - " Link(height=364, left=11, right=23),\n", - " Link(height=365, left=3, right=23),\n", - " Link(height=366, left=11, right=23)),\n", - " (Link(height=595, left=12, right=15),\n", - " Link(height=596, left=10, right=15),\n", - " Link(height=597, left=12, right=15),\n", - " Link(height=598, left=10, right=15)),\n", - " (Link(height=796, left=12, right=21),\n", - " Link(height=797, left=4, right=12),\n", - " Link(height=798, left=12, right=21),\n", - " Link(height=799, left=4, right=12)),\n", - " (Link(height=879, left=0, right=18),\n", - " Link(height=880, left=0, right=8),\n", - " Link(height=881, left=0, right=18),\n", - " Link(height=882, left=0, right=8)),\n", - " (Link(height=930, left=3, right=17),\n", - " Link(height=931, left=3, right=21),\n", - " Link(height=932, left=3, right=17),\n", - " Link(height=933, left=3, right=21)),\n", - " (Link(height=1120, left=5, right=19),\n", - " Link(height=1121, left=18, right=19),\n", - " Link(height=1122, left=5, right=19),\n", - " Link(height=1123, left=18, right=19)),\n", - " (Link(height=2040, left=9, right=21),\n", - " Link(height=2041, left=9, right=15),\n", - " Link(height=2042, left=9, right=21),\n", - " Link(height=2043, left=9, right=15)),\n", - " (Link(height=2110, left=13, right=21),\n", - " Link(height=2111, left=13, right=24),\n", - " Link(height=2112, left=13, right=21),\n", - " Link(height=2113, left=13, right=24))]" - ] - }, - "execution_count": 119, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lnettp = simple_lnet\n", - "for _ in range(10):\n", - " lnettp = add_triple_pair(lnettp)\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": 120, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=49, left=10, right=20),\n", - " Link(height=50, left=2, right=20),\n", - " Link(height=51, left=10, right=20),\n", - " Link(height=52, left=2, right=20)),\n", - " (Link(height=54, left=2, right=24),\n", - " Link(height=55, left=3, right=24),\n", - " Link(height=56, left=2, right=24),\n", - " Link(height=57, left=3, right=24)),\n", - " (Link(height=62, left=2, right=15),\n", - " Link(height=63, left=0, right=15),\n", - " Link(height=64, left=2, right=15),\n", - " Link(height=65, left=0, right=15)),\n", - " (Link(height=114, left=14, right=18),\n", - " Link(height=115, left=3, right=18),\n", - " Link(height=116, left=14, right=18),\n", - " Link(height=117, left=3, right=18)),\n", - " (Link(height=138, left=13, right=19),\n", - " Link(height=139, left=8, right=19),\n", - " Link(height=140, left=13, right=19),\n", - " Link(height=141, left=8, right=19)),\n", - " (Link(height=160, left=12, right=13),\n", - " Link(height=161, left=4, right=12),\n", - " Link(height=162, left=12, right=13),\n", - " Link(height=163, left=4, right=12)),\n", - " (Link(height=315, left=23, right=24),\n", - " Link(height=320, left=20, right=23),\n", - " Link(height=321, left=23, right=24),\n", - " Link(height=322, left=20, right=23)),\n", - " (Link(height=324, left=3, right=18),\n", - " Link(height=325, left=16, right=18),\n", - " Link(height=326, left=3, right=18),\n", - " Link(height=327, left=16, right=18)),\n", - " (Link(height=342, left=21, right=22),\n", - " Link(height=345, left=1, right=22),\n", - " Link(height=346, left=21, right=22),\n", - " Link(height=347, left=1, right=22)),\n", - " (Link(height=405, left=8, right=19),\n", - " Link(height=406, left=4, right=8),\n", - " Link(height=407, left=8, right=19),\n", - " Link(height=408, left=4, right=8)),\n", - " (Link(height=468, left=11, right=22),\n", - " Link(height=469, left=15, right=22),\n", - " Link(height=470, left=11, right=22),\n", - " Link(height=471, left=15, right=22)),\n", - " (Link(height=549, left=1, right=2),\n", - " Link(height=550, left=1, right=6),\n", - " Link(height=551, left=1, right=2),\n", - " Link(height=552, left=1, right=6)),\n", - " (Link(height=568, left=16, right=21),\n", - " Link(height=569, left=11, right=21),\n", - " Link(height=570, left=16, right=21),\n", - " Link(height=571, left=11, right=21)),\n", - " (Link(height=608, left=17, right=20),\n", - " Link(height=609, left=2, right=17),\n", - " Link(height=610, left=17, right=20),\n", - " Link(height=611, left=2, right=17)),\n", - " (Link(height=613, left=18, right=21),\n", - " Link(height=618, left=18, right=19),\n", - " Link(height=619, left=18, right=21),\n", - " Link(height=620, left=18, right=19)),\n", - " (Link(height=635, left=2, right=4),\n", - " Link(height=636, left=4, right=20),\n", - " Link(height=637, left=2, right=4),\n", - " Link(height=638, left=4, right=20)),\n", - " (Link(height=681, left=7, right=20),\n", - " Link(height=682, left=20, right=22),\n", - " Link(height=683, left=7, right=20),\n", - " Link(height=684, left=20, right=22)),\n", - " (Link(height=750, left=23, right=24),\n", - " Link(height=751, left=18, right=24),\n", - " Link(height=752, left=23, right=24),\n", - " Link(height=753, left=18, right=24)),\n", - " (Link(height=760, left=12, right=18),\n", - " Link(height=761, left=17, right=18),\n", - " Link(height=762, left=12, right=18),\n", - " Link(height=763, left=17, right=18)),\n", - " (Link(height=765, left=0, right=9),\n", - " Link(height=766, left=0, right=14),\n", - " Link(height=767, left=0, right=9),\n", - " Link(height=768, left=0, right=14)),\n", - " (Link(height=805, left=16, right=22),\n", - " Link(height=806, left=0, right=16),\n", - " Link(height=807, left=16, right=22),\n", - " Link(height=808, left=0, right=16)),\n", - " (Link(height=834, left=1, right=6),\n", - " Link(height=835, left=3, right=6),\n", - " Link(height=836, left=1, right=6),\n", - " Link(height=837, left=3, right=6)),\n", - " (Link(height=881, left=2, right=12),\n", - " Link(height=882, left=2, right=23),\n", - " Link(height=883, left=2, right=12),\n", - " Link(height=884, left=2, right=23)),\n", - " (Link(height=904, left=12, right=23),\n", - " Link(height=905, left=12, right=14),\n", - " Link(height=906, left=12, right=23),\n", - " Link(height=907, left=12, right=14)),\n", - " (Link(height=936, left=7, right=17),\n", - " Link(height=937, left=15, right=17),\n", - " Link(height=938, left=7, right=17),\n", - " Link(height=939, left=15, right=17)),\n", - " (Link(height=1010, left=4, right=6),\n", - " Link(height=1011, left=6, right=17),\n", - " Link(height=1012, left=4, right=6),\n", - " Link(height=1013, left=6, right=17)),\n", - " (Link(height=1030, left=1, right=12),\n", - " Link(height=1031, left=1, right=20),\n", - " Link(height=1032, left=1, right=12),\n", - " Link(height=1033, left=1, right=20)),\n", - " (Link(height=1197, left=2, right=9),\n", - " Link(height=1198, left=9, right=22),\n", - " Link(height=1199, left=2, right=9),\n", - " Link(height=1200, left=9, right=22)),\n", - " (Link(height=1222, left=2, right=3),\n", - " Link(height=1223, left=2, right=5),\n", - " Link(height=1224, left=2, right=3),\n", - " Link(height=1225, left=2, right=5)),\n", - " (Link(height=1318, left=12, right=23),\n", - " Link(height=1319, left=4, right=12),\n", - " Link(height=1320, left=12, right=23),\n", - " Link(height=1321, left=4, right=12)),\n", - " (Link(height=1341, left=17, right=22),\n", - " Link(height=1342, left=11, right=17),\n", - " Link(height=1343, left=17, right=22),\n", - " Link(height=1344, left=11, right=17)),\n", - " (Link(height=1396, left=4, right=9),\n", - " Link(height=1397, left=3, right=9),\n", - " Link(height=1398, left=4, right=9),\n", - " Link(height=1399, left=3, right=9)),\n", - " (Link(height=1426, left=18, right=24),\n", - " Link(height=1427, left=17, right=18),\n", - " Link(height=1428, left=18, right=24),\n", - " Link(height=1429, left=17, right=18)),\n", - " (Link(height=1456, left=2, right=15),\n", - " Link(height=1457, left=3, right=15),\n", - " Link(height=1458, left=2, right=15),\n", - " Link(height=1459, left=3, right=15)),\n", - " (Link(height=1505, left=13, right=18),\n", - " Link(height=1506, left=13, right=21),\n", - " Link(height=1507, left=13, right=18),\n", - " Link(height=1508, left=13, right=21)),\n", - " (Link(height=1551, left=10, right=12),\n", - " Link(height=1552, left=4, right=12),\n", - " Link(height=1553, left=10, right=12),\n", - " Link(height=1554, left=4, right=12)),\n", - " (Link(height=1622, left=4, right=11),\n", - " Link(height=1623, left=11, right=16),\n", - " Link(height=1624, left=4, right=11),\n", - " Link(height=1625, left=11, right=16)),\n", - " (Link(height=1653, left=8, right=24),\n", - " Link(height=1654, left=4, right=8),\n", - " Link(height=1655, left=8, right=24),\n", - " Link(height=1656, left=4, right=8)),\n", - " (Link(height=1688, left=0, right=5),\n", - " Link(height=1689, left=0, right=23),\n", - " Link(height=1690, left=0, right=5),\n", - " Link(height=1691, left=0, right=23)),\n", - " (Link(height=1724, left=10, right=23),\n", - " Link(height=1725, left=10, right=11),\n", - " Link(height=1726, left=10, right=23),\n", - " Link(height=1727, left=10, right=11)),\n", - " (Link(height=1863, left=1, right=12),\n", - " Link(height=1864, left=1, right=13),\n", - " Link(height=1865, left=1, right=12),\n", - " Link(height=1866, left=1, right=13)),\n", - " (Link(height=1873, left=10, right=22),\n", - " Link(height=1874, left=10, right=15),\n", - " Link(height=1875, left=10, right=22),\n", - " Link(height=1876, left=10, right=15)),\n", - " (Link(height=1879, left=18, right=20),\n", - " Link(height=1880, left=17, right=20),\n", - " Link(height=1881, left=18, right=20),\n", - " Link(height=1882, left=17, right=20)),\n", - " (Link(height=1916, left=18, right=19),\n", - " Link(height=1917, left=7, right=18),\n", - " Link(height=1918, left=18, right=19),\n", - " Link(height=1919, left=7, right=18)),\n", - " (Link(height=1961, left=11, right=20),\n", - " Link(height=1962, left=7, right=20),\n", - " Link(height=1963, left=11, right=20),\n", - " Link(height=1964, left=7, right=20)),\n", - " (Link(height=1962, left=9, right=18),\n", - " Link(height=1963, left=18, right=19),\n", - " Link(height=1964, left=9, right=18),\n", - " Link(height=1965, left=18, right=19)),\n", - " (Link(height=2031, left=3, right=6),\n", - " Link(height=2032, left=3, right=4),\n", - " Link(height=2033, left=3, right=6),\n", - " Link(height=2034, left=3, right=4)),\n", - " (Link(height=2077, left=2, right=9),\n", - " Link(height=2078, left=2, right=23),\n", - " Link(height=2079, left=2, right=9),\n", - " Link(height=2080, left=2, right=23)),\n", - " (Link(height=2165, left=1, right=8),\n", - " Link(height=2166, left=4, right=8),\n", - " Link(height=2167, left=1, right=8),\n", - " Link(height=2168, left=4, right=8)),\n", - " (Link(height=2185, left=6, right=21),\n", - " Link(height=2186, left=11, right=21),\n", - " Link(height=2187, left=6, right=21),\n", - " Link(height=2188, left=11, right=21))]" - ] - }, - "execution_count": 120, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lnettp = simple_lnet\n", - "for _ in range(50):\n", - " lnettp = add_pair(lnettp)\n", - "for _ in range(50):\n", - " lnettp = add_triple_pair(lnettp)\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": 121, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 121, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lnettp == pack(lnettp)" - ] - }, - { - "cell_type": "code", - "execution_count": 122, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "9909" - ] - }, - "execution_count": 122, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "lnettps = simplify(lnettp)\n", - "len(lnettps)" - ] - }, - { - "cell_type": "code", - "execution_count": 123, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(9809, 10109, 9909)" - ] - }, - "execution_count": 123, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(simple_lnet), len(lnettp), len(lnettps)" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 124, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnet)) == ''.join(follow_many(string.ascii_lowercase, simple_lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 125, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnettps)) == ''.join(follow_many(string.ascii_lowercase, lnettp))" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2285" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in lnettp)" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def simplify_with_checks(net0):\n", - " netp = eliminate_pairs(net0)\n", - " if follow_many(string.ascii_lowercase, net0) != follow_many(string.ascii_lowercase, netp):\n", - " print('pairs', eliminable_pairs(net0))\n", - " return net0\n", - " else:\n", - " print('pairs ok')\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", - " hg = find_height_groups(netp)\n", - " print('triple', triple_pair_hg(hg))\n", - " return netp\n", - " else:\n", - " print('triple ok')\n", - " while new_net:\n", - "# print('sipl', len(net0), len(netp), len(new_net))\n", - " netp = eliminate_pairs(new_net)\n", - " if follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", - " print('pairs', eliminable_pairs(new_net))\n", - " return new_net\n", - " else:\n", - " print('pairs ok')\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", - " hg = find_height_groups(netp)\n", - " print('triple', triple_pair_hg(hg))\n", - " return netp\n", - " else:\n", - " print('triple ok')\n", - " print('** done')\n", - " return netp" - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "** done\n" - ] - } - ], - "source": [ - "lnettps = simplify_with_checks(lnettp)" - ] - }, - { - "cell_type": "code", - "execution_count": 129, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 129, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnettps)) == ''.join(follow_many(string.ascii_lowercase, lnettp))" - ] - }, - { - "cell_type": "code", - "execution_count": 130, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10109" - ] - }, - "execution_count": 130, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(lnettp)" - ] - }, - { - "cell_type": "code", - "execution_count": 131, - "metadata": {}, - "outputs": [], - "source": [ - "# open('04-lines.txt', 'w').write(show_net(lnettp, randomise=True, pair_sep='\\n'))" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "139" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# open('04-small.txt', 'w').write(show_net(make_net(20), randomise=True, pair_sep='\\n'))" - ] - }, - { - "cell_type": "code", - "execution_count": 143, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "8 [(2, 4), (0, 4), (2, 4), (0, 4)]\n", - "10 [(1, 2), (1, 2)]\n" - ] - }, - { - "data": { - "text/plain": [ - "[Link(height=0, left=2, right=5),\n", - " Link(height=1, left=1, right=4),\n", - " Link(height=2, left=0, right=3),\n", - " Link(height=3, left=0, right=3),\n", - " Link(height=4, left=0, right=5),\n", - " Link(height=5, left=3, right=5),\n", - " Link(height=6, left=0, right=2),\n", - " Link(height=7, left=3, right=4),\n", - " Link(height=8, left=2, right=4),\n", - " Link(height=9, left=1, right=2),\n", - " Link(height=10, left=0, right=4),\n", - " Link(height=11, left=1, right=2),\n", - " Link(height=12, left=2, right=4),\n", - " Link(height=13, left=1, right=2),\n", - " Link(height=14, left=0, right=4),\n", - " Link(height=15, left=1, right=4)]" - ] - }, - "execution_count": 143, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "net = make_net(10, lines=6)\n", - "net = add_triple_pair(net, trace=True)\n", - "net = add_pair(net, trace=True)\n", - "net = read_net(show_net(net, randomise=True))\n", - "net" - ] - }, - { - "cell_type": "code", - "execution_count": 147, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(2, 5), (1, 4), (0, 3), (0, 3), (0, 5), (3, 5), (0, 2), (3, 4), (2, 4), (1, 2), (0, 4), (1, 2), (2, 4), (1, 2), (0, 4), (1, 4)'" - ] - }, - "execution_count": 147, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_net(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 149, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=2, right=5),\n", - " Link(height=1, left=1, right=4),\n", - " Link(height=2, left=0, right=3),\n", - " Link(height=3, left=0, right=3),\n", - " Link(height=4, left=0, right=5),\n", - " Link(height=5, left=3, right=5),\n", - " Link(height=6, left=0, right=2),\n", - " Link(height=7, left=3, right=4),\n", - " Link(height=8, left=2, right=4),\n", - " Link(height=9, left=1, right=2),\n", - " Link(height=10, left=0, right=4),\n", - " Link(height=11, left=1, right=2),\n", - " Link(height=12, left=2, right=4),\n", - " Link(height=13, left=0, right=4),\n", - " Link(height=14, left=1, right=4)]" - ] - }, - "execution_count": 149, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "net = read_net('(2, 5), (1, 4), (0, 3), (0, 3), (0, 5), (3, 5), (0, 2), (3, 4), (2, 4), (1, 2), (0, 4), (1, 2), (2, 4), (0, 4), (1, 4)')\n", - "net" - ] - }, - { - "cell_type": "code", - "execution_count": 150, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=0, right=3),\n", - " Link(height=0, left=1, right=4),\n", - " Link(height=0, left=2, right=5),\n", - " Link(height=1, left=0, right=3),\n", - " Link(height=2, left=0, right=5),\n", - " Link(height=3, left=0, right=2),\n", - " Link(height=3, left=3, right=5),\n", - " Link(height=4, left=3, right=4),\n", - " Link(height=5, left=2, right=4),\n", - " Link(height=6, left=0, right=4),\n", - " Link(height=6, left=1, right=2),\n", - " Link(height=7, left=1, right=2),\n", - " Link(height=8, left=2, right=4),\n", - " Link(height=9, left=0, right=4),\n", - " Link(height=10, left=1, right=4)]" - ] - }, - "execution_count": 150, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pack(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=1, right=4),\n", - " Link(height=0, left=2, right=5),\n", - " Link(height=1, left=0, right=5),\n", - " Link(height=2, left=0, right=2),\n", - " Link(height=2, left=3, right=5),\n", - " Link(height=3, left=3, right=4),\n", - " Link(height=4, left=2, right=4),\n", - " Link(height=5, left=0, right=4),\n", - " Link(height=6, left=2, right=4),\n", - " Link(height=7, left=0, right=4),\n", - " Link(height=8, left=1, right=4)]" - ] - }, - "execution_count": 151, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "epnet = eliminate_pairs(net)\n", - "pack(epnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 152, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "11\n", - "11\n" - ] - }, - { - "data": { - "text/plain": [ - "[Link(height=0, left=1, right=4),\n", - " Link(height=0, left=2, right=5),\n", - " Link(height=1, left=0, right=5),\n", - " Link(height=2, left=0, right=2),\n", - " Link(height=2, left=3, right=5),\n", - " Link(height=3, left=3, right=4),\n", - " Link(height=4, left=0, right=4),\n", - " Link(height=5, left=2, right=4),\n", - " Link(height=6, left=1, right=4)]" - ] - }, - "execution_count": 152, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eptnet = eliminate_triple_pairs(epnet)\n", - "pack(eptnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 153, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 153, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, net)) == ''.join(follow_many(string.ascii_lowercase, eptnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 155, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "104" - ] - }, - "execution_count": 155, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "open('04-small.txt', 'w').write(show_net(net, pair_sep='\\n'))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2+" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/04-08-amidakuji/amidakuji-solution-1-slow.ipynb b/04-08-amidakuji/amidakuji-solution-1-slow.ipynb deleted file mode 100644 index 345321d..0000000 --- a/04-08-amidakuji/amidakuji-solution-1-slow.ipynb +++ /dev/null @@ -1,1881 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import collections\n", - "import string\n", - "import itertools" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "Link = collections.namedtuple('Link', 'height left right')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def link_ends(link):\n", - " return set((link.left, link.right))" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def read_net(net_string):\n", - " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow(initial_line, links):\n", - " line = initial_line\n", - " heights = sorted(set(l.height for l in links))\n", - " for h in heights:\n", - " for l in [l for l in links if l.height == h]:\n", - " if line in link_ends(l):\n", - " line = [e for e in link_ends(l) if e != line][0]\n", - "# print(l, line)\n", - " return line" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def pack(net):\n", - " packed_links = []\n", - " line_heights = collections.defaultdict(lambda: -1)\n", - " for link in sorted(net):\n", - " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", - " line_heights[link.left] = link_height\n", - " line_heights[link.right] = link_height\n", - " packed_links += [Link(link_height, link.left, link.right)]\n", - " return sorted(packed_links)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow_many_slow(in_sequence, links):\n", - " out_sequence = [(follow(i, links), term) \n", - " for i, term in enumerate(in_sequence)]\n", - " return [term for i, term in sorted(out_sequence)]" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow_many(in_sequence, net):\n", - " height_groups = [list(g) for _, g in itertools.groupby(pack(net), lambda l: l.height)]\n", - " seq = list(in_sequence)\n", - " for links in height_groups:\n", - " for link in links:\n", - " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", - " return seq" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10000 loops, best of 3: 47.5 µs per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many('abcdefghij', net)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# %%timeit\n", - "# follow_many_slow('abcdefghij', net)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def show_net(links, randomise=False):\n", - " if randomise:\n", - " output = []\n", - " heights = sorted(set(l.height for l in links))\n", - " for h in heights:\n", - " ls = [l for l in links if l.height == h]\n", - " random.shuffle(ls)\n", - " output += ['({}, {})'.format(l.left, l.right) for l in ls]\n", - " return ', '.join(output)\n", - " return ', '.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def extract_pairs(net_string):\n", - " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(True, True)" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "rrnet = read_net(show_net(net, randomise=True))\n", - "rnet = read_net(show_net(net))\n", - "rnet == rrnet, pack(rrnet) == pnet" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "lnet = make_net(10207, 26, 100000)\n", - "plnet = pack(lnet)\n", - "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, plnet)\n", - "# for i in range(204):\n", - "# assert follow(i, lnet) == follow(i, plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "rlnet = read_net(show_net(lnet))\n", - "prlnet = pack(rlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2251" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "99998" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10206" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in rlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2251" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(link.height for link in prlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, prlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 24.5 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many(string.ascii_lowercase, lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# %%timeit\n", - "# follow_many_slow(string.ascii_lowercase, lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pairs_slow(net):\n", - " eps = []\n", - " for l in net:\n", - " o = Link(l.height + 1, l.left, l.right)\n", - " if o in net:\n", - " eps += [(l, o)]\n", - " return eps " - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pairs(net):\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - " eps = []\n", - " for h in range(1, max(height_groups.keys())):\n", - " for l in height_groups[h]:\n", - " o = Link(l.height - 1, l.left, l.right)\n", - " if o in height_groups[h-1]:\n", - " eps += [(l, o)]\n", - " return eps" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 23.5 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "eliminable_pairs(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 loop, best of 3: 2.33 s per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "eliminable_pairs_slow(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert sorted(sorted(p) for p in eliminable_pairs(plnet)) == sorted(sorted(p) for p in eliminable_pairs_slow(plnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pair(net):\n", - " for l in net:\n", - " o = Link(l.height + 1, l.left, l.right)\n", - " if o in net:\n", - " return l, o\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pair_hg(height_groups):\n", - " for h in range(1, max(height_groups.keys())):\n", - " for l in height_groups[h]:\n", - " o = Link(l.height - 1, l.left, l.right)\n", - " if o in height_groups[h-1]:\n", - " return l, o\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_pairs_slow(net):\n", - " eliminable_links = eliminable_pair(net)\n", - " while eliminable_links:\n", - " net = pack(l for l in net if l not in eliminable_links)\n", - " eliminable_links = eliminable_pair(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_pairs(net):\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - " eliminable_links = eliminable_pair_hg(height_groups)\n", - " while eliminable_links:\n", - " net = pack(l for l in net if l not in eliminable_links)\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - " eliminable_links = eliminable_pair_hg(height_groups)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10207\n" - ] - }, - { - "data": { - "text/plain": [ - "(10207, 9811)" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(len(plnet))\n", - "elnet = eliminate_pairs_slow(plnet)\n", - "len(plnet), len(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10207\n" - ] - }, - { - "data": { - "text/plain": [ - "(10207, 9811)" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print(len(plnet))\n", - "elnet = eliminate_pairs(plnet)\n", - "len(plnet), len(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 46, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eliminable_pairs(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert eliminate_pairs_slow(plnet) == eliminate_pairs(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, elnet)\n", - "assert follow_many(string.ascii_lowercase, plnet) == follow_many(string.ascii_lowercase, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 loop, best of 3: 3min 30s per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "elnet = eliminate_pairs_slow(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 loop, best of 3: 6.27 s per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "elnet = eliminate_pairs(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# for i in range(26):\n", - "# assert follow(i, plnet) == follow(i, elnet)\n", - "# assert follow(i, lnet) == follow(i, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "# follow(0, plnet), follow(0, elnet), follow(0, lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple(net):\n", - " x = None\n", - " y = None\n", - " ts = []\n", - " for a in net:\n", - " bs = [l for l in net if l.height == a.height + 1 \n", - " if l.left == a.right or l.right == a.left]\n", - " for b in bs:\n", - " c = Link(a.height + 2, a.left, a.right)\n", - " if c in net:\n", - " ts += [(a, b, c)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple_pair(net):\n", - " ts = []\n", - " for a in net:\n", - " a_ends = link_ends(a)\n", - " bs = [l for l in net if l.height == a.height + 1 \n", - " if link_ends(l) & a_ends]\n", - " if len(bs) == 1:\n", - " b = bs[0]\n", - " lines = set((a.left, a.right, b.left, b.right))\n", - " cs = [l for l in net \n", - " if l.height == a.height + 2\n", - " if link_ends(l) & lines]\n", - " if len(cs) == 1:\n", - " c = Link(a.height + 2, a.left, a.right)\n", - " if c in cs:\n", - " ds = [l for l in net \n", - " if l.height == a.height + 3\n", - " if link_ends(l) & lines]\n", - " d = Link(a.height + 3, b.left, b.right)\n", - " if d in ds:\n", - " ts += [(a, b, c, d)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 129, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple_pair_hg(height_groups, debug=False):\n", - " ts = []\n", - " for h in range(3, max(height_groups.keys())):\n", - " for d in height_groups[h]:\n", - " if debug: print('d:', d)\n", - " ch = h - 1\n", - " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", - " if debug: print('cs:', cs)\n", - " while ch > 2 and not cs:\n", - " ch -= 1\n", - " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", - " if debug: print('cs:', cs)\n", - " if len(cs) == 1:\n", - " c = cs[0]\n", - " lines = set((d.left, d.right, c.left, c.right))\n", - " if debug: print('c:', '; lines:', lines)\n", - " bs = [l for l in height_groups[ch-1] if link_ends(l) & lines]\n", - " b = Link(ch - 1, d.left, d.right)\n", - " if debug: print('b:', b, '; bs:', bs)\n", - " if len(bs) == 1 and b in bs:\n", - " ah = b.height - 1\n", - " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", - " if debug: print('ah:', ah, '; als:', als)\n", - " while ah > 0 and not als:\n", - " ah -= 1\n", - " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", - " if debug: print('ah:', ah, '; als:', als)\n", - " a = Link(ah, c.left, c.right)\n", - " if debug: print('a:', a)\n", - " if a in als:\n", - " if debug: print('adding:', a, b, c, d)\n", - " ts += [(a, b, c, d)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 132, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_a_triple_pair_slow(net):\n", - " tps = triple_pair(net)\n", - " print('eatp', tps)\n", - "\n", - " if tps:\n", - " a, b, c, d = tps[0]\n", - "# x = Link(a.height, b.left, b.right)\n", - "# y = Link(b.height, a.left, a.right)\n", - " x = Link(a.height, b.left, b.right)\n", - " y = Link(b.height, a.left, a.right)\n", - " print('removing', a, b, c, d, '; adding', x, y)\n", - " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_a_triple_pair(net):\n", - " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - "\n", - " tps = triple_pair_hg(height_groups)\n", - " print('eatp', tps)\n", - " if tps:\n", - " a, b, c, d = tps[0]\n", - " x = Link(a.height, b.left, b.right)\n", - " y = Link(b.height, a.left, a.right)\n", - " print('removing', a, b, c, d, '; adding', x, y)\n", - " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 58, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=12, left=0, right=5),\n", - " Link(height=13, left=5, right=11),\n", - " Link(height=14, left=0, right=5)),\n", - " (Link(height=29, left=2, right=18),\n", - " Link(height=30, left=1, right=2),\n", - " Link(height=31, left=2, right=18)),\n", - " (Link(height=40, left=2, right=3),\n", - " Link(height=41, left=3, right=18),\n", - " Link(height=42, left=2, right=3)),\n", - " (Link(height=43, left=1, right=10),\n", - " Link(height=44, left=10, right=20),\n", - " Link(height=45, left=1, right=10)),\n", - " (Link(height=91, left=5, right=8),\n", - " Link(height=92, left=3, right=5),\n", - " Link(height=93, left=5, right=8)),\n", - " (Link(height=91, left=5, right=8),\n", - " Link(height=92, left=8, right=18),\n", - " Link(height=93, left=5, right=8)),\n", - " (Link(height=99, left=13, right=17),\n", - " Link(height=100, left=4, right=13),\n", - " Link(height=101, left=13, right=17)),\n", - " (Link(height=120, left=18, right=20),\n", - " Link(height=121, left=9, right=18),\n", - " Link(height=122, left=18, right=20)),\n", - " (Link(height=147, left=19, right=21),\n", - " Link(height=148, left=7, right=19),\n", - " Link(height=149, left=19, right=21)),\n", - " (Link(height=147, left=19, right=21),\n", - " Link(height=148, left=21, right=23),\n", - " Link(height=149, left=19, right=21)),\n", - " (Link(height=179, left=13, right=25),\n", - " Link(height=180, left=12, right=13),\n", - " Link(height=181, left=13, right=25)),\n", - " (Link(height=265, left=3, right=20),\n", - " Link(height=266, left=20, right=23),\n", - " Link(height=267, left=3, right=20)),\n", - " (Link(height=291, left=5, right=23),\n", - " Link(height=292, left=2, right=5),\n", - " Link(height=293, left=5, right=23)),\n", - " (Link(height=292, left=18, right=25),\n", - " Link(height=293, left=0, right=18),\n", - " Link(height=294, left=18, right=25)),\n", - " (Link(height=302, left=11, right=19),\n", - " Link(height=303, left=6, right=11),\n", - " Link(height=304, left=11, right=19)),\n", - " (Link(height=309, left=15, right=20),\n", - " Link(height=310, left=20, right=25),\n", - " Link(height=311, left=15, right=20)),\n", - " (Link(height=325, left=13, right=18),\n", - " Link(height=326, left=11, right=13),\n", - " Link(height=327, left=13, right=18)),\n", - " (Link(height=362, left=11, right=22),\n", - " Link(height=363, left=22, right=24),\n", - " Link(height=364, left=11, right=22)),\n", - " (Link(height=372, left=22, right=23),\n", - " Link(height=373, left=1, right=22),\n", - " Link(height=374, left=22, right=23)),\n", - " (Link(height=386, left=4, right=17),\n", - " Link(height=387, left=17, right=21),\n", - " Link(height=388, left=4, right=17)),\n", - " (Link(height=393, left=4, right=16),\n", - " Link(height=394, left=0, right=4),\n", - " Link(height=395, left=4, right=16)),\n", - " (Link(height=531, left=0, right=4),\n", - " Link(height=532, left=4, right=15),\n", - " Link(height=533, left=0, right=4)),\n", - " (Link(height=575, left=5, right=21),\n", - " Link(height=576, left=1, right=5),\n", - " Link(height=577, left=5, right=21)),\n", - " (Link(height=639, left=7, right=11),\n", - " Link(height=640, left=11, right=17),\n", - " Link(height=641, left=7, right=11)),\n", - " (Link(height=687, left=2, right=4),\n", - " Link(height=688, left=4, right=15),\n", - " Link(height=689, left=2, right=4)),\n", - " (Link(height=706, left=8, right=11),\n", - " Link(height=707, left=11, right=22),\n", - " Link(height=708, left=8, right=11)),\n", - " (Link(height=722, left=22, right=23),\n", - " Link(height=723, left=21, right=22),\n", - " Link(height=724, left=22, right=23)),\n", - " (Link(height=768, left=9, right=11),\n", - " Link(height=769, left=11, right=17),\n", - " Link(height=770, left=9, right=11)),\n", - " (Link(height=792, left=5, right=12),\n", - " Link(height=793, left=12, right=17),\n", - " Link(height=794, left=5, right=12)),\n", - " (Link(height=805, left=20, right=22),\n", - " Link(height=806, left=19, right=20),\n", - " Link(height=807, left=20, right=22)),\n", - " (Link(height=806, left=19, right=20),\n", - " Link(height=807, left=18, right=19),\n", - " Link(height=808, left=19, right=20)),\n", - " (Link(height=806, left=19, right=20),\n", - " Link(height=807, left=20, right=22),\n", - " Link(height=808, left=19, right=20)),\n", - " (Link(height=882, left=7, right=14),\n", - " Link(height=883, left=14, right=22),\n", - " Link(height=884, left=7, right=14)),\n", - " (Link(height=884, left=6, right=11),\n", - " Link(height=885, left=11, right=19),\n", - " Link(height=886, left=6, right=11)),\n", - " (Link(height=892, left=12, right=17),\n", - " Link(height=893, left=10, right=12),\n", - " Link(height=894, left=12, right=17)),\n", - " (Link(height=916, left=18, right=24),\n", - " Link(height=917, left=16, right=18),\n", - " Link(height=918, left=18, right=24)),\n", - " (Link(height=919, left=14, right=17),\n", - " Link(height=920, left=6, right=14),\n", - " Link(height=921, left=14, right=17)),\n", - " (Link(height=994, left=0, right=3),\n", - " Link(height=995, left=3, right=24),\n", - " Link(height=996, left=0, right=3)),\n", - " (Link(height=1012, left=9, right=12),\n", - " Link(height=1013, left=12, right=24),\n", - " Link(height=1014, left=9, right=12)),\n", - " (Link(height=1034, left=1, right=6),\n", - " Link(height=1035, left=6, right=12),\n", - " Link(height=1036, left=1, right=6)),\n", - " (Link(height=1035, left=7, right=21),\n", - " Link(height=1036, left=4, right=7),\n", - " Link(height=1037, left=7, right=21)),\n", - " (Link(height=1047, left=3, right=10),\n", - " Link(height=1048, left=10, right=11),\n", - " Link(height=1049, left=3, right=10)),\n", - " (Link(height=1088, left=7, right=8),\n", - " Link(height=1089, left=8, right=14),\n", - " Link(height=1090, left=7, right=8)),\n", - " (Link(height=1104, left=3, right=10),\n", - " Link(height=1105, left=10, right=11),\n", - " Link(height=1106, left=3, right=10)),\n", - " (Link(height=1135, left=5, right=8),\n", - " Link(height=1136, left=8, right=19),\n", - " Link(height=1137, left=5, right=8)),\n", - " (Link(height=1138, left=1, right=3),\n", - " Link(height=1139, left=3, right=23),\n", - " Link(height=1140, left=1, right=3)),\n", - " (Link(height=1146, left=5, right=7),\n", - " Link(height=1147, left=7, right=24),\n", - " Link(height=1148, left=5, right=7)),\n", - " (Link(height=1197, left=5, right=14),\n", - " Link(height=1198, left=14, right=15),\n", - " Link(height=1199, left=5, right=14)),\n", - " (Link(height=1205, left=7, right=23),\n", - " Link(height=1206, left=3, right=7),\n", - " Link(height=1207, left=7, right=23)),\n", - " (Link(height=1276, left=18, right=25),\n", - " Link(height=1277, left=17, right=18),\n", - " Link(height=1278, left=18, right=25)),\n", - " (Link(height=1319, left=14, right=20),\n", - " Link(height=1320, left=20, right=24),\n", - " Link(height=1321, left=14, right=20)),\n", - " (Link(height=1328, left=8, right=21),\n", - " Link(height=1329, left=1, right=8),\n", - " Link(height=1330, left=8, right=21)),\n", - " (Link(height=1329, left=2, right=14),\n", - " Link(height=1330, left=14, right=25),\n", - " Link(height=1331, left=2, right=14)),\n", - " (Link(height=1385, left=10, right=14),\n", - " Link(height=1386, left=14, right=15),\n", - " Link(height=1387, left=10, right=14)),\n", - " (Link(height=1419, left=2, right=8),\n", - " Link(height=1420, left=8, right=15),\n", - " Link(height=1421, left=2, right=8)),\n", - " (Link(height=1465, left=13, right=21),\n", - " Link(height=1466, left=21, right=24),\n", - " Link(height=1467, left=13, right=21)),\n", - " (Link(height=1514, left=11, right=15),\n", - " Link(height=1515, left=15, right=21),\n", - " Link(height=1516, left=11, right=15)),\n", - " (Link(height=1545, left=3, right=11),\n", - " Link(height=1546, left=11, right=25),\n", - " Link(height=1547, left=3, right=11)),\n", - " (Link(height=1561, left=7, right=18),\n", - " Link(height=1562, left=0, right=7),\n", - " Link(height=1563, left=7, right=18)),\n", - " (Link(height=1671, left=9, right=15),\n", - " Link(height=1672, left=15, right=23),\n", - " Link(height=1673, left=9, right=15)),\n", - " (Link(height=1701, left=13, right=21),\n", - " Link(height=1702, left=4, right=13),\n", - " Link(height=1703, left=13, right=21)),\n", - " (Link(height=1706, left=5, right=13),\n", - " Link(height=1707, left=13, right=23),\n", - " Link(height=1708, left=5, right=13)),\n", - " (Link(height=1730, left=7, right=16),\n", - " Link(height=1731, left=1, right=7),\n", - " Link(height=1732, left=7, right=16)),\n", - " (Link(height=1781, left=0, right=8),\n", - " Link(height=1782, left=8, right=17),\n", - " Link(height=1783, left=0, right=8)),\n", - " (Link(height=1784, left=8, right=18),\n", - " Link(height=1785, left=1, right=8),\n", - " Link(height=1786, left=8, right=18)),\n", - " (Link(height=1804, left=19, right=24),\n", - " Link(height=1805, left=7, right=19),\n", - " Link(height=1806, left=19, right=24)),\n", - " (Link(height=1827, left=3, right=23),\n", - " Link(height=1828, left=23, right=25),\n", - " Link(height=1829, left=3, right=23)),\n", - " (Link(height=1837, left=1, right=16),\n", - " Link(height=1838, left=16, right=17),\n", - " Link(height=1839, left=1, right=16)),\n", - " (Link(height=1849, left=18, right=25),\n", - " Link(height=1850, left=4, right=18),\n", - " Link(height=1851, left=18, right=25)),\n", - " (Link(height=1856, left=6, right=13),\n", - " Link(height=1857, left=13, right=17),\n", - " Link(height=1858, left=6, right=13)),\n", - " (Link(height=1875, left=2, right=11),\n", - " Link(height=1876, left=11, right=15),\n", - " Link(height=1877, left=2, right=11)),\n", - " (Link(height=1970, left=6, right=24),\n", - " Link(height=1971, left=1, right=6),\n", - " Link(height=1972, left=6, right=24)),\n", - " (Link(height=2075, left=20, right=25),\n", - " Link(height=2076, left=5, right=20),\n", - " Link(height=2077, left=20, right=25)),\n", - " (Link(height=2081, left=4, right=19),\n", - " Link(height=2082, left=1, right=4),\n", - " Link(height=2083, left=4, right=19)),\n", - " (Link(height=2111, left=3, right=25),\n", - " Link(height=2112, left=1, right=3),\n", - " Link(height=2113, left=3, right=25)),\n", - " (Link(height=2225, left=3, right=12),\n", - " Link(height=2226, left=12, right=24),\n", - " Link(height=2227, left=3, right=12)),\n", - " (Link(height=2242, left=3, right=18),\n", - " Link(height=2243, left=18, right=23),\n", - " Link(height=2244, left=3, right=18))]" - ] - }, - "execution_count": 58, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "triple(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=316, left=8, right=17),\n", - " Link(height=317, left=8, right=21),\n", - " Link(height=318, left=8, right=17),\n", - " Link(height=319, left=8, right=21)),\n", - " (Link(height=867, left=4, right=11),\n", - " Link(height=868, left=5, right=11),\n", - " Link(height=869, left=4, right=11),\n", - " Link(height=870, left=5, right=11))]" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "triple_pair(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 60, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=316, left=8, right=17),\n", - " Link(height=317, left=8, right=21),\n", - " Link(height=318, left=8, right=17),\n", - " Link(height=319, left=8, right=21)),\n", - " (Link(height=867, left=4, right=11),\n", - " Link(height=868, left=5, right=11),\n", - " Link(height=869, left=4, right=11),\n", - " Link(height=870, left=5, right=11))]" - ] - }, - "execution_count": 60, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(elnet), lambda l: l.height)}\n", - "triple_pair_hg(height_groups)" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=1368, left=13, right=19),\n", - " Link(height=1368, left=14, right=16),\n", - " Link(height=1369, left=3, right=6)]" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[l for l in elnet if l.height >= 1367 if l.height <= 1370 if link_ends(l) & set((6, 16, 19))]" - ] - }, - { - "cell_type": "code", - "execution_count": 62, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 loop, best of 3: 21.3 s per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "triple_pair(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 63, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 105 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(elnet), lambda l: l.height)}\n", - "triple_pair_hg(height_groups)" - ] - }, - { - "cell_type": "code", - "execution_count": 64, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(elnet), lambda l: l.height)}\n", - "assert triple_pair_hg(height_groups) == triple_pair(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=242, left=8, right=9),\n", - " Link(height=242, left=15, right=21),\n", - " Link(height=243, left=1, right=9),\n", - " Link(height=243, left=8, right=14),\n", - " Link(height=243, left=11, right=15),\n", - " Link(height=244, left=1, right=18),\n", - " Link(height=244, left=6, right=8),\n", - " Link(height=244, left=9, right=20),\n", - " Link(height=244, left=15, right=25),\n", - " Link(height=245, left=0, right=15),\n", - " Link(height=245, left=1, right=16),\n", - " Link(height=245, left=9, right=12),\n", - " Link(height=245, left=18, right=21)]" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[l for l in elnet if l.height >= 242 if l.height <= 245 ] #if l.left in [13, 17, 20] or l.right in [13, 17, 20]]" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_triple_pairs_slow(net):\n", - " print(len(net))\n", - " new_net = eliminate_a_triple_pair_slow(net)\n", - " while new_net:\n", - " print(len(net))\n", - " net = new_net\n", - " new_net = eliminate_a_triple_pair_slow(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_triple_pairs(net):\n", - " print(len(net))\n", - " new_net = eliminate_a_triple_pair(net)\n", - " while new_net:\n", - " print(len(net))\n", - " net = new_net\n", - " new_net = eliminate_a_triple_pair(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 134, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9811\n", - "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", - "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=316, left=8, right=21) Link(height=317, left=8, right=17)\n", - "9811\n", - "eatp [(Link(height=866, left=4, right=11), Link(height=867, left=5, right=11), Link(height=868, left=4, right=11), Link(height=869, left=5, right=11))]\n", - "removing Link(height=866, left=4, right=11) Link(height=867, left=5, right=11) Link(height=868, left=4, right=11) Link(height=869, left=5, right=11) ; adding Link(height=866, left=5, right=11) Link(height=867, left=4, right=11)\n", - "9809\n", - "eatp []\n" - ] - } - ], - "source": [ - "etlnet = eliminate_triple_pairs(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 112, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", - "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=317, left=8, right=17) Link(height=318, left=8, right=21)\n" - ] - } - ], - "source": [ - "etlnet = eliminate_a_triple_pair(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 135, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 136, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=315, left=17, right=20),\n", - " Link(height=316, left=8, right=17),\n", - " Link(height=317, left=8, right=21),\n", - " Link(height=318, left=8, right=17),\n", - " Link(height=319, left=8, right=21),\n", - " Link(height=319, left=14, right=17),\n", - " Link(height=320, left=2, right=8),\n", - " Link(height=320, left=17, right=21)]" - ] - }, - "execution_count": 136, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "[l for l in elnet if l.height >= 315 if l.height <= 320 if link_ends(l) & set((8, 17, 21))] " - ] - }, - { - "cell_type": "code", - "execution_count": 137, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=17, right=20),\n", - " Link(height=1, left=8, right=17),\n", - " Link(height=2, left=8, right=21),\n", - " Link(height=3, left=8, right=17),\n", - " Link(height=4, left=8, right=21),\n", - " Link(height=4, left=14, right=17),\n", - " Link(height=5, left=2, right=8),\n", - " Link(height=5, left=17, right=21)]" - ] - }, - "execution_count": 137, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "nf = [l for l in elnet if l.height >= 315 if l.height <= 320 if link_ends(l) & set((8, 17, 21))]\n", - "pnf = pack(nf)\n", - "pnf" - ] - }, - { - "cell_type": "code", - "execution_count": 138, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "d: Link(height=3, left=8, right=17)\n", - "cs: [Link(height=2, left=8, right=21)]\n", - "c: ; lines: {8, 17, 21}\n", - "b: Link(height=1, left=8, right=17) ; bs: [Link(height=1, left=8, right=17)]\n", - "ah: 0 ; als: []\n", - "a: Link(height=0, left=8, right=21)\n", - "d: Link(height=4, left=8, right=21)\n", - "cs: [Link(height=3, left=8, right=17)]\n", - "c: ; lines: {8, 17, 21}\n", - "b: Link(height=2, left=8, right=21) ; bs: [Link(height=2, left=8, right=21)]\n", - "ah: 1 ; als: [Link(height=1, left=8, right=17)]\n", - "a: Link(height=1, left=8, right=17)\n", - "adding: Link(height=1, left=8, right=17) Link(height=2, left=8, right=21) Link(height=3, left=8, right=17) Link(height=4, left=8, right=21)\n", - "d: Link(height=4, left=14, right=17)\n", - "cs: [Link(height=3, left=8, right=17)]\n", - "c: ; lines: {8, 17, 14}\n", - "b: Link(height=2, left=14, right=17) ; bs: [Link(height=2, left=8, right=21)]\n" - ] - }, - { - "data": { - "text/plain": [ - "[(Link(height=1, left=8, right=17),\n", - " Link(height=2, left=8, right=21),\n", - " Link(height=3, left=8, right=17),\n", - " Link(height=4, left=8, right=21))]" - ] - }, - "execution_count": 138, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(pnf), lambda l: l.height)}\n", - "triple_pair_hg(height_groups, debug=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 139, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "9811\n", - "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", - "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=316, left=8, right=21) Link(height=317, left=8, right=17)\n", - "9811\n", - "eatp [(Link(height=866, left=4, right=11), Link(height=867, left=5, right=11), Link(height=868, left=4, right=11), Link(height=869, left=5, right=11))]\n", - "removing Link(height=866, left=4, right=11) Link(height=867, left=5, right=11) Link(height=868, left=4, right=11) Link(height=869, left=5, right=11) ; adding Link(height=866, left=5, right=11) Link(height=867, left=4, right=11)\n", - "9809\n", - "eatp []\n" - ] - } - ], - "source": [ - "setlnet = eliminate_triple_pairs_slow(elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 140, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9807" - ] - }, - "execution_count": 140, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(setlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 141, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 142, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zdunvslcfiqywjmkobhxtraegp'" - ] - }, - "execution_count": 142, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, etlnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 143, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zdunvslcfiqywjmkobhxtraegp'" - ] - }, - "execution_count": 143, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, setlnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 144, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zdunvslcfiqywjmkobhxtraegp'" - ] - }, - "execution_count": 144, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, elnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 145, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zdunvslcfiqywjmkobhxtraegp'" - ] - }, - "execution_count": 145, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 146, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 146, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eliminable_pairs(etlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 147, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(10207, 9807)" - ] - }, - "execution_count": 147, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(lnet), len(etlnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 148, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def simplify(net0):\n", - " netp = eliminate_pairs(net0)\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " while new_net:\n", - "# print('sipl', len(net0), len(netp), len(new_net))\n", - " netp = eliminate_pairs(new_net)\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " return netp" - ] - }, - { - "cell_type": "code", - "execution_count": 149, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", - "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=316, left=8, right=21) Link(height=317, left=8, right=17)\n", - "eatp [(Link(height=866, left=4, right=11), Link(height=867, left=5, right=11), Link(height=868, left=4, right=11), Link(height=869, left=5, right=11))]\n", - "removing Link(height=866, left=4, right=11) Link(height=867, left=5, right=11) Link(height=868, left=4, right=11) Link(height=869, left=5, right=11) ; adding Link(height=866, left=5, right=11) Link(height=867, left=4, right=11)\n", - "eatp []\n" - ] - } - ], - "source": [ - "simple_lnet = simplify(plnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 150, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 150, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, simple_lnet)) == ''.join(follow_many(string.ascii_lowercase, lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 151, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zdunvslcfiqywjmkobhxtraegp'" - ] - }, - "execution_count": 151, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, simple_lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 152, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'zdunvslcfiqywjmkobhxtraegp'" - ] - }, - "execution_count": 152, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, lnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 153, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9807" - ] - }, - "execution_count": 153, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(simple_lnet)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def add_triple_pair(net, max_lines=None):\n", - " if not max_lines:\n", - " max_lines = max(l.right for l in net)\n", - " a, b, c = 0, 0, 0\n", - " while len(set((a, b, c))) != 3:\n", - " a = random.randrange(max_lines)\n", - " b = random.randrange(max_lines)\n", - " c = random.randrange(max_lines)\n", - " tp = [(min(a, b), max(a, b)), (min(b, c), max(b, c))] * 2\n", - " \n", - " pairs = [(l.left, l.right) for l in sorted(net)]\n", - " i = random.randrange(len(pairs))\n", - " print(i, tp)\n", - " new_pairs = pairs[:i] + tp + pairs[i:]\n", - " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def add_pair(net, max_lines=None):\n", - " if not max_lines:\n", - " max_lines = max(l.right for l in net)\n", - "\n", - " a, b = 0, 0\n", - " while a == b:\n", - " a = random.randrange(max_lines)\n", - " b = random.randrange(max_lines)\n", - " p = [(min(a, b), max(a, b))] * 2\n", - " \n", - " pairs = [(l.left, l.right) for l in sorted(net)]\n", - " i = random.randrange(len(pairs))\n", - " \n", - " print(i, p)\n", - " new_pairs = pairs[:i] + p + pairs[i:]\n", - " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true, - "scrolled": true - }, - "outputs": [], - "source": [ - "lnettp = simple_lnet\n", - "for _ in range(10):\n", - " lnettp = add_pair(lnettp)\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true, - "scrolled": true - }, - "outputs": [], - "source": [ - "lnettp = simple_lnet\n", - "for _ in range(10):\n", - " lnettp = add_triple_pair(lnettp)\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true, - "scrolled": true - }, - "outputs": [], - "source": [ - "lnettp = simple_lnet\n", - "for _ in range(10):\n", - " lnettp = add_pair(lnettp)\n", - "for _ in range(10):\n", - " lnettp = add_triple_pair(lnettp)\n", - "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", - "tps = triple_pair_hg(height_groups)\n", - "tps" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "lnettp == pack(lnettp)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "lnettps = simplify(lnettp)\n", - "len(lnettps)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "len(simple_lnet), len(lnettp), len(lnettps)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2+" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/04-08-amidakuji/amidakuji-solution-1.ipynb b/04-08-amidakuji/amidakuji-solution-1.ipynb deleted file mode 100644 index 7f149b4..0000000 --- a/04-08-amidakuji/amidakuji-solution-1.ipynb +++ /dev/null @@ -1,431 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import collections\n", - "import string\n", - "import itertools\n", - "import re" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "Link = collections.namedtuple('Link', 'height left right')" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def extract_pairs(net_string):\n", - " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def read_net_string(net_string):\n", - " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def read_net(filename):\n", - " with open(filename) as f:\n", - " pairs = [re.split('\\D+', p.strip()) for p in f.readlines()]\n", - " lrs = [(int(lr[1]), int(lr[2])) for lr in pairs]\n", - " return [Link(h, l, r) \n", - " for h, (l, r) in enumerate(lrs)]" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=2, right=5),\n", - " Link(height=1, left=1, right=4),\n", - " Link(height=2, left=0, right=3),\n", - " Link(height=3, left=0, right=3),\n", - " Link(height=4, left=0, right=5),\n", - " Link(height=5, left=3, right=5),\n", - " Link(height=6, left=0, right=2),\n", - " Link(height=7, left=3, right=4),\n", - " Link(height=8, left=2, right=4),\n", - " Link(height=9, left=1, right=2),\n", - " Link(height=10, left=0, right=4),\n", - " Link(height=11, left=1, right=2),\n", - " Link(height=12, left=2, right=4),\n", - " Link(height=13, left=0, right=4),\n", - " Link(height=14, left=1, right=4)]" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "small_net = read_net('04-small.txt')\n", - "small_net" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10135" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "net = read_net('04-lines.txt')\n", - "len(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def show_net(links, pair_sep=', '):\n", - " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def link_ends(link):\n", - " return set((link.left, link.right))" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow(initial_line, links):\n", - " line = initial_line\n", - " heights = sorted(set(l.height for l in links))\n", - " for h in heights:\n", - " for l in [l for l in links if l.height == h]:\n", - " if line in link_ends(l):\n", - " line = [e for e in link_ends(l) if e != line][0]\n", - "# print(l, line)\n", - " return line" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def pack(net):\n", - " packed_links = []\n", - " line_heights = collections.defaultdict(lambda: -1)\n", - " for link in sorted(net):\n", - " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", - " line_heights[link.left] = link_height\n", - " line_heights[link.right] = link_height\n", - " packed_links += [Link(link_height, link.left, link.right)]\n", - " return sorted(packed_links)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "14" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in small_net)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in pack(small_net))" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10134" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in net)" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "pnet = pack(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2286" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def height_groups(net):\n", - " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow_many(in_sequence, net):\n", - " hgs = height_groups(net)\n", - " seq = list(in_sequence)\n", - " for h in hgs:\n", - " for link in hgs[h]:\n", - " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", - " return seq" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'acfbed'" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many('abcdef', small_net))" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10000 loops, best of 3: 39.5 µs per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many('abcdefghij', small_net)" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 47, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, net))" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 19.7 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many(string.ascii_lowercase, net)" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "100 loops, best of 3: 18.6 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many(string.ascii_lowercase, pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2+" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/04-08-amidakuji/amidakuji-solution-2.ipynb b/04-08-amidakuji/amidakuji-solution-2.ipynb deleted file mode 100644 index 3bc37db..0000000 --- a/04-08-amidakuji/amidakuji-solution-2.ipynb +++ /dev/null @@ -1,1452 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "import collections\n", - "import string\n", - "import itertools\n", - "import re" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "Link = collections.namedtuple('Link', 'height left right')" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def extract_pairs(net_string):\n", - " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def read_net_string(net_string):\n", - " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def read_net(filename):\n", - " with open(filename) as f:\n", - " pairs = [re.split('\\D+', p.strip()) for p in f.readlines()]\n", - " lrs = [(int(lr[1]), int(lr[2])) for lr in pairs]\n", - " return [Link(h, l, r) \n", - " for h, (l, r) in enumerate(lrs)]" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[Link(height=0, left=2, right=5),\n", - " Link(height=1, left=1, right=4),\n", - " Link(height=2, left=0, right=3),\n", - " Link(height=3, left=0, right=3),\n", - " Link(height=4, left=0, right=5),\n", - " Link(height=5, left=3, right=5),\n", - " Link(height=6, left=0, right=2),\n", - " Link(height=7, left=3, right=4),\n", - " Link(height=8, left=2, right=4),\n", - " Link(height=9, left=1, right=2),\n", - " Link(height=10, left=0, right=4),\n", - " Link(height=11, left=1, right=2),\n", - " Link(height=12, left=2, right=4),\n", - " Link(height=13, left=0, right=4),\n", - " Link(height=14, left=1, right=4)]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "small_net = read_net('04-small.txt')\n", - "small_net" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10135" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "net = read_net('04-lines.txt')\n", - "len(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def show_net(links, pair_sep=', '):\n", - " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def link_ends(link):\n", - " return set((link.left, link.right))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow(initial_line, links):\n", - " line = initial_line\n", - " heights = sorted(set(l.height for l in links))\n", - " for h in heights:\n", - " for l in [l for l in links if l.height == h]:\n", - " if line in link_ends(l):\n", - " line = [e for e in link_ends(l) if e != line][0]\n", - "# print(l, line)\n", - " return line" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def pack(net):\n", - " packed_links = []\n", - " line_heights = collections.defaultdict(lambda: -1)\n", - " for link in sorted(net):\n", - " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", - " line_heights[link.left] = link_height\n", - " line_heights[link.right] = link_height\n", - " packed_links += [Link(link_height, link.left, link.right)]\n", - " return sorted(packed_links)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "14" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in small_net)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in pack(small_net))" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10134" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in net)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "2286" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "max(l.height for l in pack(net))" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def height_groups(net):\n", - " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def follow_many(in_sequence, net):\n", - " hgs = height_groups(net)\n", - " seq = list(in_sequence)\n", - " for h in hgs:\n", - " for link in hgs[h]:\n", - " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", - " return seq" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'acfbedghij'" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many('abcdefghij', small_net))" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10000 loops, best of 3: 38.1 µs per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many('abcdefghij', small_net)" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, net))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "100 loops, best of 3: 19 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "follow_many(string.ascii_lowercase, net)" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "pnet = pack(net)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pairs(net):\n", - " hgs = height_groups(net)\n", - " eps = []\n", - " for h in range(1, max(hgs.keys())):\n", - " for l in hgs[h]:\n", - " o = Link(l.height - 1, l.left, l.right)\n", - " if o in hgs[h-1]:\n", - " eps += [(l, o)]\n", - " return eps" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=115, left=2, right=23), Link(height=114, left=2, right=23)),\n", - " (Link(height=149, left=15, right=23), Link(height=148, left=15, right=23)),\n", - " (Link(height=201, left=0, right=7), Link(height=200, left=0, right=7)),\n", - " (Link(height=207, left=22, right=23), Link(height=206, left=22, right=23)),\n", - " (Link(height=210, left=17, right=23), Link(height=209, left=17, right=23)),\n", - " (Link(height=247, left=16, right=20), Link(height=246, left=16, right=20)),\n", - " (Link(height=418, left=19, right=24), Link(height=417, left=19, right=24)),\n", - " (Link(height=424, left=9, right=21), Link(height=423, left=9, right=21)),\n", - " (Link(height=453, left=3, right=16), Link(height=452, left=3, right=16)),\n", - " (Link(height=456, left=2, right=22), Link(height=455, left=2, right=22)),\n", - " (Link(height=465, left=18, right=20), Link(height=464, left=18, right=20)),\n", - " (Link(height=491, left=14, right=18), Link(height=490, left=14, right=18)),\n", - " (Link(height=552, left=16, right=17), Link(height=551, left=16, right=17)),\n", - " (Link(height=772, left=0, right=7), Link(height=771, left=0, right=7)),\n", - " (Link(height=848, left=1, right=2), Link(height=847, left=1, right=2)),\n", - " (Link(height=895, left=6, right=21), Link(height=894, left=6, right=21)),\n", - " (Link(height=930, left=11, right=13), Link(height=929, left=11, right=13)),\n", - " (Link(height=987, left=8, right=17), Link(height=986, left=8, right=17)),\n", - " (Link(height=988, left=8, right=17), Link(height=987, left=8, right=17)),\n", - " (Link(height=1030, left=9, right=24), Link(height=1029, left=9, right=24)),\n", - " (Link(height=1134, left=4, right=23), Link(height=1133, left=4, right=23)),\n", - " (Link(height=1163, left=14, right=15), Link(height=1162, left=14, right=15)),\n", - " (Link(height=1164, left=14, right=15), Link(height=1163, left=14, right=15)),\n", - " (Link(height=1170, left=2, right=21), Link(height=1169, left=2, right=21)),\n", - " (Link(height=1232, left=6, right=22), Link(height=1231, left=6, right=22)),\n", - " (Link(height=1254, left=13, right=15), Link(height=1253, left=13, right=15)),\n", - " (Link(height=1255, left=1, right=24), Link(height=1254, left=1, right=24)),\n", - " (Link(height=1324, left=3, right=22), Link(height=1323, left=3, right=22)),\n", - " (Link(height=1370, left=15, right=19), Link(height=1369, left=15, right=19)),\n", - " (Link(height=1441, left=0, right=14), Link(height=1440, left=0, right=14)),\n", - " (Link(height=1441, left=11, right=24), Link(height=1440, left=11, right=24)),\n", - " (Link(height=1547, left=11, right=13), Link(height=1546, left=11, right=13)),\n", - " (Link(height=1578, left=14, right=23), Link(height=1577, left=14, right=23)),\n", - " (Link(height=1616, left=7, right=14), Link(height=1615, left=7, right=14)),\n", - " (Link(height=1671, left=8, right=20), Link(height=1670, left=8, right=20)),\n", - " (Link(height=1684, left=14, right=18), Link(height=1683, left=14, right=18)),\n", - " (Link(height=1717, left=0, right=17), Link(height=1716, left=0, right=17)),\n", - " (Link(height=1727, left=7, right=8), Link(height=1726, left=7, right=8)),\n", - " (Link(height=1866, left=8, right=16), Link(height=1865, left=8, right=16)),\n", - " (Link(height=1911, left=1, right=12), Link(height=1910, left=1, right=12)),\n", - " (Link(height=1966, left=20, right=23), Link(height=1965, left=20, right=23)),\n", - " (Link(height=1974, left=5, right=23), Link(height=1973, left=5, right=23)),\n", - " (Link(height=1994, left=18, right=19), Link(height=1993, left=18, right=19)),\n", - " (Link(height=2005, left=2, right=19), Link(height=2004, left=2, right=19)),\n", - " (Link(height=2031, left=12, right=17), Link(height=2030, left=12, right=17)),\n", - " (Link(height=2108, left=7, right=12), Link(height=2107, left=7, right=12)),\n", - " (Link(height=2137, left=7, right=16), Link(height=2136, left=7, right=16)),\n", - " (Link(height=2138, left=7, right=16), Link(height=2137, left=7, right=16)),\n", - " (Link(height=2229, left=10, right=11), Link(height=2228, left=10, right=11)),\n", - " (Link(height=2239, left=16, right=24), Link(height=2238, left=16, right=24)),\n", - " (Link(height=2240, left=16, right=24), Link(height=2239, left=16, right=24)),\n", - " (Link(height=2246, left=4, right=13), Link(height=2245, left=4, right=13)),\n", - " (Link(height=2247, left=4, right=13), Link(height=2246, left=4, right=13)),\n", - " (Link(height=2276, left=19, right=24), Link(height=2275, left=19, right=24)),\n", - " (Link(height=2277, left=4, right=18), Link(height=2276, left=4, right=18))]" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eliminable_pairs(pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10 loops, best of 3: 23.5 ms per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "eliminable_pairs(pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminable_pair(hgs):\n", - " for h in range(1, max(hgs.keys())):\n", - " for l in hgs[h]:\n", - " o = Link(l.height - 1, l.left, l.right)\n", - " if o in hgs[h-1]:\n", - " return l, o\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_pairs(net):\n", - " hgs = height_groups(pack(net))\n", - " eliminable_links = eliminable_pair(hgs)\n", - " while eliminable_links:\n", - " net = pack(l for l in net if l not in eliminable_links)\n", - " hgs = height_groups(pack(net))\n", - " eliminable_links = eliminable_pair(hgs)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "enet = eliminate_pairs(pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, net) == follow_many(string.ascii_lowercase, enet)\n", - "assert follow_many(string.ascii_lowercase, pnet) == follow_many(string.ascii_lowercase, enet)" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1 loop, best of 3: 2.35 s per loop\n" - ] - } - ], - "source": [ - "%%timeit\n", - "eliminate_pairs(pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def triple_pair(height_groups, debug=False):\n", - " ts = []\n", - " for h in range(3, max(height_groups.keys())):\n", - " for d in height_groups[h]:\n", - " if debug: print('d:', d)\n", - " ch = h - 1\n", - " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", - " if debug: print('cs:', cs)\n", - " while ch > 2 and not cs:\n", - " ch -= 1\n", - " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", - " if debug: print('cs:', cs)\n", - " if len(cs) == 1:\n", - " c = cs[0]\n", - " lines = set((d.left, d.right, c.left, c.right))\n", - " if debug: print('c:', '; lines:', lines)\n", - " bs = [l for l in height_groups[ch-1] if link_ends(l) & lines]\n", - " b = Link(ch - 1, d.left, d.right)\n", - " if debug: print('b:', b, '; bs:', bs)\n", - " if len(bs) == 1 and b in bs:\n", - " ah = b.height - 1\n", - " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", - " if debug: print('ah:', ah, '; als:', als)\n", - " while ah > 0 and not als:\n", - " ah -= 1\n", - " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", - " if debug: print('ah:', ah, '; als:', als)\n", - " a = Link(ah, c.left, c.right)\n", - " if debug: print('a:', a)\n", - " if a in als:\n", - " if debug: print('adding:', a, b, c, d)\n", - " ts += [(a, b, c, d)]\n", - " return ts" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_a_triple_pair(net, debug=False):\n", - " hgs = height_groups(net)\n", - "\n", - " tps = triple_pair(hgs)\n", - " if debug: print('eatp', tps)\n", - " if tps:\n", - " a, b, c, d = tps[0]\n", - " x = Link(b.height - 0.5, b.left, b.right)\n", - " y = Link(b.height, a.left, a.right)\n", - " if debug: print('removing', a, b, c, d, '; adding', x, y)\n", - " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", - " return None" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[(Link(height=8, left=1, right=5),\n", - " Link(height=9, left=1, right=21),\n", - " Link(height=10, left=1, right=5),\n", - " Link(height=11, left=1, right=21)),\n", - " (Link(height=40, left=16, right=23),\n", - " Link(height=41, left=16, right=19),\n", - " Link(height=42, left=16, right=23),\n", - " Link(height=43, left=16, right=19)),\n", - " (Link(height=62, left=0, right=10),\n", - " Link(height=63, left=10, right=13),\n", - " Link(height=64, left=0, right=10),\n", - " Link(height=65, left=10, right=13)),\n", - " (Link(height=137, left=23, right=24),\n", - " Link(height=139, left=0, right=24),\n", - " Link(height=140, left=23, right=24),\n", - " Link(height=141, left=0, right=24)),\n", - " (Link(height=138, left=10, right=21),\n", - " Link(height=139, left=2, right=10),\n", - " Link(height=140, left=10, right=21),\n", - " Link(height=141, left=2, right=10)),\n", - " (Link(height=139, left=2, right=10),\n", - " Link(height=140, left=10, right=21),\n", - " Link(height=141, left=2, right=10),\n", - " Link(height=142, left=10, right=21)),\n", - " (Link(height=156, left=6, right=11),\n", - " Link(height=157, left=3, right=6),\n", - " Link(height=158, left=6, right=11),\n", - " Link(height=159, left=3, right=6)),\n", - " (Link(height=184, left=2, right=21),\n", - " Link(height=185, left=5, right=21),\n", - " Link(height=186, left=2, right=21),\n", - " Link(height=187, left=5, right=21)),\n", - " (Link(height=272, left=7, right=13),\n", - " Link(height=273, left=7, right=11),\n", - " Link(height=274, left=7, right=13),\n", - " Link(height=275, left=7, right=11)),\n", - " (Link(height=290, left=14, right=15),\n", - " Link(height=291, left=5, right=15),\n", - " Link(height=292, left=14, right=15),\n", - " Link(height=293, left=5, right=15)),\n", - " (Link(height=387, left=1, right=8),\n", - " Link(height=389, left=8, right=15),\n", - " Link(height=390, left=1, right=8),\n", - " Link(height=391, left=8, right=15)),\n", - " (Link(height=420, left=14, right=22),\n", - " Link(height=422, left=14, right=18),\n", - " Link(height=423, left=14, right=22),\n", - " Link(height=424, left=14, right=18)),\n", - " (Link(height=432, left=5, right=19),\n", - " Link(height=433, left=1, right=19),\n", - " Link(height=434, left=5, right=19),\n", - " Link(height=435, left=1, right=19)),\n", - " (Link(height=454, left=0, right=15),\n", - " Link(height=455, left=14, right=15),\n", - " Link(height=456, left=0, right=15),\n", - " Link(height=457, left=14, right=15)),\n", - " (Link(height=546, left=13, right=21),\n", - " Link(height=547, left=6, right=21),\n", - " Link(height=548, left=13, right=21),\n", - " Link(height=549, left=6, right=21)),\n", - " (Link(height=620, left=17, right=23),\n", - " Link(height=621, left=1, right=23),\n", - " Link(height=622, left=17, right=23),\n", - " Link(height=623, left=1, right=23)),\n", - " (Link(height=699, left=8, right=15),\n", - " Link(height=700, left=3, right=15),\n", - " Link(height=701, left=8, right=15),\n", - " Link(height=702, left=3, right=15)),\n", - " (Link(height=789, left=7, right=24),\n", - " Link(height=790, left=8, right=24),\n", - " Link(height=791, left=7, right=24),\n", - " Link(height=792, left=8, right=24)),\n", - " (Link(height=795, left=8, right=13),\n", - " Link(height=796, left=4, right=8),\n", - " Link(height=797, left=8, right=13),\n", - " Link(height=798, left=4, right=8)),\n", - " (Link(height=809, left=16, right=17),\n", - " Link(height=810, left=3, right=16),\n", - " Link(height=811, left=16, right=17),\n", - " Link(height=812, left=3, right=16)),\n", - " (Link(height=900, left=2, right=15),\n", - " Link(height=901, left=13, right=15),\n", - " Link(height=902, left=2, right=15),\n", - " Link(height=903, left=13, right=15)),\n", - " (Link(height=921, left=2, right=15),\n", - " Link(height=922, left=15, right=16),\n", - " Link(height=923, left=2, right=15),\n", - " Link(height=924, left=15, right=16)),\n", - " (Link(height=961, left=2, right=15),\n", - " Link(height=962, left=2, right=14),\n", - " Link(height=963, left=2, right=15),\n", - " Link(height=964, left=2, right=14)),\n", - " (Link(height=976, left=13, right=18),\n", - " Link(height=979, left=18, right=19),\n", - " Link(height=980, left=13, right=18),\n", - " Link(height=981, left=18, right=19)),\n", - " (Link(height=985, left=5, right=16),\n", - " Link(height=986, left=2, right=5),\n", - " Link(height=987, left=5, right=16),\n", - " Link(height=988, left=2, right=5)),\n", - " (Link(height=1050, left=9, right=24),\n", - " Link(height=1054, left=9, right=18),\n", - " Link(height=1055, left=9, right=24),\n", - " Link(height=1056, left=9, right=18)),\n", - " (Link(height=1159, left=11, right=21),\n", - " Link(height=1160, left=11, right=14),\n", - " Link(height=1161, left=11, right=21),\n", - " Link(height=1162, left=11, right=14)),\n", - " (Link(height=1284, left=0, right=11),\n", - " Link(height=1285, left=0, right=14),\n", - " Link(height=1286, left=0, right=11),\n", - " Link(height=1287, left=0, right=14)),\n", - " (Link(height=1331, left=4, right=9),\n", - " Link(height=1333, left=4, right=10),\n", - " Link(height=1334, left=4, right=9),\n", - " Link(height=1335, left=4, right=10)),\n", - " (Link(height=1332, left=12, right=18),\n", - " Link(height=1333, left=12, right=24),\n", - " Link(height=1334, left=12, right=18),\n", - " Link(height=1335, left=12, right=24)),\n", - " (Link(height=1343, left=0, right=17),\n", - " Link(height=1344, left=0, right=23),\n", - " Link(height=1345, left=0, right=17),\n", - " Link(height=1346, left=0, right=23)),\n", - " (Link(height=1357, left=4, right=16),\n", - " Link(height=1358, left=16, right=17),\n", - " Link(height=1359, left=4, right=16),\n", - " Link(height=1360, left=16, right=17)),\n", - " (Link(height=1441, left=6, right=20),\n", - " Link(height=1443, left=16, right=20),\n", - " Link(height=1444, left=6, right=20),\n", - " Link(height=1445, left=16, right=20)),\n", - " (Link(height=1464, left=17, right=23),\n", - " Link(height=1465, left=3, right=17),\n", - " Link(height=1466, left=17, right=23),\n", - " Link(height=1467, left=3, right=17)),\n", - " (Link(height=1540, left=8, right=23),\n", - " Link(height=1541, left=7, right=23),\n", - " Link(height=1542, left=8, right=23),\n", - " Link(height=1543, left=7, right=23)),\n", - " (Link(height=1570, left=0, right=1),\n", - " Link(height=1571, left=1, right=21),\n", - " Link(height=1572, left=0, right=1),\n", - " Link(height=1573, left=1, right=21)),\n", - " (Link(height=1600, left=15, right=22),\n", - " Link(height=1603, left=7, right=15),\n", - " Link(height=1604, left=15, right=22),\n", - " Link(height=1605, left=7, right=15)),\n", - " (Link(height=1632, left=12, right=18),\n", - " Link(height=1634, left=12, right=20),\n", - " Link(height=1635, left=12, right=18),\n", - " Link(height=1636, left=12, right=20)),\n", - " (Link(height=1702, left=13, right=24),\n", - " Link(height=1705, left=14, right=24),\n", - " Link(height=1706, left=13, right=24),\n", - " Link(height=1707, left=14, right=24)),\n", - " (Link(height=1721, left=3, right=24),\n", - " Link(height=1722, left=3, right=21),\n", - " Link(height=1723, left=3, right=24),\n", - " Link(height=1724, left=3, right=21)),\n", - " (Link(height=1722, left=3, right=21),\n", - " Link(height=1723, left=3, right=24),\n", - " Link(height=1724, left=3, right=21),\n", - " Link(height=1725, left=3, right=24)),\n", - " (Link(height=1762, left=0, right=21),\n", - " Link(height=1763, left=13, right=21),\n", - " Link(height=1764, left=0, right=21),\n", - " Link(height=1765, left=13, right=21)),\n", - " (Link(height=1769, left=7, right=9),\n", - " Link(height=1770, left=7, right=12),\n", - " Link(height=1771, left=7, right=9),\n", - " Link(height=1772, left=7, right=12)),\n", - " (Link(height=1914, left=10, right=24),\n", - " Link(height=1915, left=8, right=24),\n", - " Link(height=1916, left=10, right=24),\n", - " Link(height=1917, left=8, right=24)),\n", - " (Link(height=1920, left=4, right=23),\n", - " Link(height=1921, left=3, right=4),\n", - " Link(height=1922, left=4, right=23),\n", - " Link(height=1923, left=3, right=4)),\n", - " (Link(height=2023, left=4, right=7),\n", - " Link(height=2024, left=7, right=15),\n", - " Link(height=2025, left=4, right=7),\n", - " Link(height=2026, left=7, right=15)),\n", - " (Link(height=2025, left=8, right=19),\n", - " Link(height=2031, left=8, right=15),\n", - " Link(height=2032, left=8, right=19),\n", - " Link(height=2033, left=8, right=15)),\n", - " (Link(height=2152, left=10, right=15),\n", - " Link(height=2153, left=10, right=16),\n", - " Link(height=2154, left=10, right=15),\n", - " Link(height=2155, left=10, right=16)),\n", - " (Link(height=2194, left=22, right=24),\n", - " Link(height=2195, left=7, right=22),\n", - " Link(height=2196, left=22, right=24),\n", - " Link(height=2197, left=7, right=22)),\n", - " (Link(height=2211, left=5, right=6),\n", - " Link(height=2212, left=6, right=14),\n", - " Link(height=2213, left=5, right=6),\n", - " Link(height=2214, left=6, right=14))]" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hgs = height_groups(enet)\n", - "triple_pair(hgs)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "etnet = eliminate_a_triple_pair(enet)" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, etnet) == follow_many(string.ascii_lowercase, enet)" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def eliminate_triple_pairs(net):\n", - " print(len(net))\n", - " new_net = eliminate_a_triple_pair(net)\n", - " while new_net:\n", - " print(len(net))\n", - " net = new_net\n", - " new_net = eliminate_a_triple_pair(net)\n", - " return net" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "10033\n", - "10033\n", - "10031\n", - "10029\n", - "10027\n", - "10025\n", - "10023\n", - "10021\n", - "10019\n", - "10017\n", - "10015\n", - "10013\n", - "10011\n", - "10009\n", - "10007\n", - "10005\n", - "10003\n", - "10001\n", - "9999\n", - "9997\n", - "9995\n", - "9993\n", - "9991\n", - "9989\n", - "9987\n", - "9985\n", - "9983\n", - "9981\n", - "9979\n", - "9977\n", - "9975\n", - "9973\n", - "9971\n", - "9969\n", - "9967\n", - "9965\n", - "9963\n", - "9961\n", - "9959\n", - "9957\n", - "9955\n", - "9953\n", - "9951\n", - "9949\n", - "9947\n", - "9945\n", - "9943\n", - "9941\n", - "9939\n" - ] - } - ], - "source": [ - "setnet = eliminate_triple_pairs(enet)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9937" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(setnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "assert follow_many(string.ascii_lowercase, etnet) == follow_many(string.ascii_lowercase, enet)" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, etnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, setnet))" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, enet))" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, net))" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "eliminable_pairs(etnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(10135, 10031)" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(net), len(etnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 46, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def simplify(net0):\n", - " netp = eliminate_pairs(net0)\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " while new_net:\n", - "# print('sipl', len(net0), len(netp), len(new_net))\n", - " netp = eliminate_pairs(new_net)\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " return netp" - ] - }, - { - "cell_type": "code", - "execution_count": 47, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "simple_net = simplify(pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 48, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, simple_net)) == ''.join(follow_many(string.ascii_lowercase, net))" - ] - }, - { - "cell_type": "code", - "execution_count": 49, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, simple_net))" - ] - }, - { - "cell_type": "code", - "execution_count": 50, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'doqzmbishkwunvltpcexyjgfra'" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, net))" - ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9931" - ] - }, - "execution_count": 51, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(simple_net)" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "def simplify_with_checks(net0):\n", - " netp = eliminate_pairs(net0)\n", - " if follow_many(string.ascii_lowercase, net0) != follow_many(string.ascii_lowercase, netp):\n", - " print('pairs', eliminable_pairs(net0))\n", - " return net0\n", - " else:\n", - " print('pairs ok')\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", - " hg = find_height_groups(netp)\n", - " print('triple', triple_pair_hg(hg))\n", - " return netp\n", - " else:\n", - " print('triple ok')\n", - " while new_net:\n", - "# print('sipl', len(net0), len(netp), len(new_net))\n", - " netp = eliminate_pairs(new_net)\n", - " if follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", - " print('pairs', eliminable_pairs(new_net))\n", - " return new_net\n", - " else:\n", - " print('pairs ok')\n", - " new_net = eliminate_a_triple_pair(netp)\n", - " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", - " hg = find_height_groups(netp)\n", - " print('triple', triple_pair_hg(hg))\n", - " return netp\n", - " else:\n", - " print('triple ok')\n", - " print('** done')\n", - " return netp" - ] - }, - { - "cell_type": "code", - "execution_count": 53, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "pairs ok\n", - "triple ok\n", - "** done\n" - ] - } - ], - "source": [ - "spnet = simplify_with_checks(pnet)" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "''.join(follow_many(string.ascii_lowercase, spnet)) == ''.join(follow_many(string.ascii_lowercase, net))" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9931" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len(spnet)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.5.2+" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/04-08-amidakuji/day4.clj b/04-08-amidakuji/day4.clj deleted file mode 100644 index 3c5d494..0000000 --- a/04-08-amidakuji/day4.clj +++ /dev/null @@ -1,70 +0,0 @@ -(ns day4 - (:require [clojure.string :as str])) - -(defstruct link :height :left :right) - -; (def network (str/split-lines (slurp "../04-small.txt"))) -(def network (str/split-lines (slurp "../04-lines.txt"))) - -(defn parse-link [l, h] - (let [endss (rest (str/split l #"\D+")) - ends (map #(Integer/parseInt %) endss)] - (struct-map link - :height h - :left (first ends) - :right (second ends)))) - -(defn parse-network [links] - (map-indexed - (fn [i l] (parse-link l i)) - links)) - -(def parsed-network - (parse-network network)) - - -(def initial - (str/split "abcdefghijklmnopqrstuvwxyz" #"")) - -(defn apply-link [items link] - (let [li (get link :left) - ri (get link :right) - le (nth items li) - re (nth items ri) - pre (subvec items 0 li) - mid (subvec items (inc li) ri) - suf (subvec items (inc ri))] - (into [] (concat pre (vector re) mid (vector le) suf)))) - -(defn follow [items links] - (reduce apply-link items links)) - - -(defn lane-count [links] - (inc (apply max (map (fn [l] (get l :right)) links)))) - -(defn initial-heights [links] - (vec (replicate (lane-count links) -1))) - -(defn pack-one [lane-heights link] - (let - [li (get link :left) - ri (get link :right) - new-height (inc (max (nth lane-heights li) - (nth lane-heights ri)))] - (assoc lane-heights li new-height ri new-height))) - -(defn pack [lane-heights links] - (reduce pack-one lane-heights links)) - - -(spit "day4.out" (prn-str - (str/join (follow initial parsed-network)))) - -(spit "day4.out" (prn-str - (apply max - (pack - (initial-heights parsed-network) - parsed-network))) - :append true) - diff --git a/04-08-amidakuji/small-expanded-trace.svg b/04-08-amidakuji/small-expanded-trace.svg deleted file mode 100644 index 3bed4a4..0000000 --- a/04-08-amidakuji/small-expanded-trace.svg +++ /dev/null @@ -1,555 +0,0 @@ - -image/svg+xml0 -1 -2 -3 -4 -5 - \ No newline at end of file diff --git a/04-08-amidakuji/small-expanded-trace.svg.png b/04-08-amidakuji/small-expanded-trace.svg.png deleted file mode 100644 index 7328878..0000000 Binary files a/04-08-amidakuji/small-expanded-trace.svg.png and /dev/null differ diff --git a/04-08-amidakuji/small-expanded.svg b/04-08-amidakuji/small-expanded.svg deleted file mode 100644 index 2c4b4be..0000000 --- a/04-08-amidakuji/small-expanded.svg +++ /dev/null @@ -1,520 +0,0 @@ - -image/svg+xml0 -1 -2 -3 -4 -5 - \ No newline at end of file diff --git a/04-08-amidakuji/small-expanded.svg.png b/04-08-amidakuji/small-expanded.svg.png deleted file mode 100644 index b720b61..0000000 Binary files a/04-08-amidakuji/small-expanded.svg.png and /dev/null differ diff --git a/04-08-amidakuji/small-packed.svg b/04-08-amidakuji/small-packed.svg deleted file mode 100644 index b5c3808..0000000 --- a/04-08-amidakuji/small-packed.svg +++ /dev/null @@ -1,522 +0,0 @@ - -image/svg+xml0 -1 -2 -3 -4 -5 - \ No newline at end of file diff --git a/04-08-amidakuji/small-packed.svg.png b/04-08-amidakuji/small-packed.svg.png deleted file mode 100644 index eff606c..0000000 Binary files a/04-08-amidakuji/small-packed.svg.png and /dev/null differ diff --git a/04-08-amidakuji/small-unpaired.svg b/04-08-amidakuji/small-unpaired.svg deleted file mode 100644 index 2dfe663..0000000 --- a/04-08-amidakuji/small-unpaired.svg +++ /dev/null @@ -1,405 +0,0 @@ - -image/svg+xml0 -1 -2 -3 -4 -5 - \ No newline at end of file diff --git a/04-08-amidakuji/small-untriple-1.svg b/04-08-amidakuji/small-untriple-1.svg deleted file mode 100644 index e7554c3..0000000 --- a/04-08-amidakuji/small-untriple-1.svg +++ /dev/null @@ -1,405 +0,0 @@ - -image/svg+xml0 -1 -2 -3 -4 -5 - \ No newline at end of file diff --git a/04-08-amidakuji/small-untriple-1.svg.png b/04-08-amidakuji/small-untriple-1.svg.png deleted file mode 100644 index 6203978..0000000 Binary files a/04-08-amidakuji/small-untriple-1.svg.png and /dev/null differ diff --git a/04-08-amidakuji/small-untriple-2.svg b/04-08-amidakuji/small-untriple-2.svg deleted file mode 100644 index 97413e4..0000000 --- a/04-08-amidakuji/small-untriple-2.svg +++ /dev/null @@ -1,373 +0,0 @@ - -image/svg+xml0 -1 -2 -3 -4 -5 - \ No newline at end of file diff --git a/04-08-amidakuji/untriple-general.svg b/04-08-amidakuji/untriple-general.svg deleted file mode 100644 index ced5c10..0000000 --- a/04-08-amidakuji/untriple-general.svg +++ /dev/null @@ -1,321 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/04-08-amidakuji/untriple-general.svg.png b/04-08-amidakuji/untriple-general.svg.png deleted file mode 100644 index 8b8fcd3..0000000 Binary files a/04-08-amidakuji/untriple-general.svg.png and /dev/null differ diff --git a/04-amidakuji/04-lines.txt b/04-amidakuji/04-lines.txt new file mode 100644 index 0000000..c859642 --- /dev/null +++ b/04-amidakuji/04-lines.txt @@ -0,0 +1,10135 @@ +(15, 25) +(5, 21) +(1, 19) +(7, 8) +(6, 14) +(2, 9) +(11, 16) +(1, 10) +(14, 22) +(2, 25) +(7, 9) +(8, 18) +(6, 23) +(4, 6) +(2, 13) +(9, 14) +(12, 18) +(0, 10) +(2, 3) +(6, 19) +(1, 10) +(8, 10) +(0, 19) +(10, 25) +(19, 20) +(2, 25) +(10, 23) +(3, 19) +(17, 20) +(3, 5) +(8, 25) +(19, 23) +(2, 21) +(16, 17) +(1, 10) +(2, 18) +(8, 13) +(3, 4) +(1, 5) +(1, 21) +(11, 13) +(4, 12) +(0, 8) +(3, 4) +(1, 5) +(4, 10) +(1, 21) +(5, 22) +(1, 12) +(10, 15) +(4, 9) +(5, 24) +(8, 21) +(3, 8) +(1, 14) +(14, 24) +(8, 13) +(1, 12) +(3, 22) +(13, 19) +(0, 3) +(1, 10) +(12, 18) +(5, 22) +(4, 19) +(5, 7) +(10, 16) +(0, 17) +(9, 13) +(3, 18) +(6, 13) +(0, 14) +(19, 25) +(2, 17) +(4, 21) +(3, 16) +(10, 15) +(11, 19) +(2, 22) +(3, 4) +(9, 15) +(11, 21) +(2, 18) +(8, 19) +(8, 23) +(2, 25) +(10, 18) +(2, 22) +(7, 25) +(6, 18) +(22, 25) +(7, 11) +(2, 12) +(0, 18) +(9, 11) +(12, 19) +(2, 10) +(22, 24) +(10, 15) +(24, 25) +(20, 22) +(19, 23) +(8, 10) +(0, 19) +(16, 22) +(15, 21) +(1, 21) +(13, 22) +(12, 16) +(15, 17) +(2, 10) +(0, 18) +(6, 10) +(21, 23) +(9, 15) +(2, 7) +(9, 23) +(0, 6) +(10, 24) +(7, 21) +(5, 23) +(14, 24) +(1, 10) +(6, 7) +(5, 21) +(4, 6) +(9, 10) +(1, 20) +(2, 23) +(1, 25) +(0, 20) +(9, 16) +(13, 20) +(2, 25) +(1, 17) +(16, 24) +(9, 10) +(19, 25) +(3, 16) +(20, 21) +(13, 18) +(14, 24) +(1, 23) +(0, 17) +(0, 10) +(17, 19) +(9, 23) +(1, 15) +(12, 25) +(13, 24) +(0, 3) +(2, 19) +(23, 24) +(4, 10) +(3, 8) +(4, 7) +(2, 9) +(20, 23) +(5, 7) +(2, 18) +(9, 11) +(0, 3) +(2, 12) +(7, 24) +(0, 16) +(3, 9) +(10, 18) +(6, 7) +(9, 20) +(3, 21) +(15, 16) +(16, 23) +(5, 7) +(3, 8) +(0, 9) +(8, 12) +(7, 15) +(5, 9) +(0, 6) +(16, 19) +(9, 18) +(12, 21) +(1, 6) +(16, 23) +(0, 3) +(16, 19) +(3, 14) +(0, 18) +(6, 20) +(21, 24) +(1, 17) +(2, 12) +(12, 13) +(2, 8) +(17, 24) +(5, 20) +(1, 16) +(3, 19) +(8, 22) +(19, 20) +(2, 10) +(12, 25) +(4, 8) +(2, 7) +(13, 25) +(9, 20) +(20, 21) +(5, 8) +(4, 10) +(0, 9) +(5, 14) +(6, 9) +(2, 20) +(0, 16) +(5, 10) +(14, 20) +(0, 11) +(1, 16) +(3, 9) +(3, 6) +(2, 16) +(0, 12) +(11, 22) +(2, 25) +(11, 23) +(0, 17) +(12, 18) +(3, 14) +(1, 22) +(8, 25) +(5, 12) +(0, 24) +(15, 23) +(3, 21) +(2, 22) +(0, 12) +(7, 23) +(1, 25) +(5, 18) +(11, 24) +(3, 6) +(12, 18) +(7, 19) +(5, 20) +(10, 23) +(3, 4) +(3, 21) +(4, 19) +(7, 15) +(0, 10) +(20, 22) +(14, 23) +(21, 24) +(3, 20) +(8, 14) +(6, 23) +(10, 18) +(4, 20) +(6, 9) +(8, 13) +(16, 23) +(11, 14) +(13, 17) +(8, 10) +(16, 19) +(11, 15) +(9, 10) +(13, 14) +(17, 25) +(9, 16) +(6, 17) +(0, 14) +(10, 23) +(11, 25) +(0, 4) +(3, 23) +(20, 25) +(14, 24) +(6, 8) +(10, 22) +(17, 23) +(5, 6) +(14, 16) +(0, 10) +(8, 12) +(10, 13) +(2, 12) +(4, 6) +(1, 17) +(14, 21) +(6, 15) +(2, 3) +(0, 10) +(2, 22) +(0, 8) +(3, 18) +(10, 13) +(2, 15) +(3, 19) +(8, 17) +(0, 18) +(10, 23) +(12, 13) +(17, 20) +(5, 13) +(3, 25) +(0, 9) +(6, 12) +(15, 16) +(14, 23) +(5, 14) +(15, 21) +(1, 23) +(6, 24) +(13, 18) +(10, 23) +(13, 22) +(4, 24) +(3, 14) +(1, 6) +(5, 6) +(13, 25) +(6, 15) +(5, 21) +(13, 19) +(9, 25) +(13, 16) +(9, 22) +(18, 25) +(6, 22) +(10, 25) +(9, 24) +(3, 13) +(6, 11) +(16, 22) +(10, 18) +(3, 17) +(15, 24) +(8, 25) +(9, 23) +(2, 23) +(10, 12) +(13, 17) +(8, 15) +(0, 25) +(19, 24) +(16, 24) +(12, 15) +(13, 25) +(7, 10) +(3, 17) +(0, 2) +(7, 11) +(16, 19) +(5, 10) +(12, 17) +(2, 24) +(14, 25) +(4, 10) +(2, 22) +(5, 8) +(1, 14) +(5, 18) +(12, 14) +(8, 20) +(4, 15) +(10, 21) +(18, 19) +(10, 23) +(8, 16) +(20, 22) +(5, 7) +(7, 9) +(0, 22) +(8, 11) +(19, 20) +(4, 16) +(11, 20) +(4, 17) +(9, 21) +(8, 15) +(6, 22) +(3, 16) +(1, 19) +(0, 19) +(5, 6) +(7, 16) +(1, 24) +(8, 10) +(8, 14) +(3, 10) +(7, 11) +(2, 5) +(12, 19) +(6, 18) +(13, 24) +(10, 13) +(1, 3) +(12, 16) +(6, 9) +(19, 23) +(14, 17) +(4, 24) +(3, 20) +(15, 16) +(1, 7) +(11, 12) +(0, 24) +(10, 18) +(2, 13) +(12, 22) +(0, 17) +(4, 10) +(15, 25) +(10, 23) +(13, 15) +(1, 25) +(4, 17) +(13, 18) +(2, 10) +(21, 25) +(4, 14) +(1, 11) +(0, 4) +(14, 19) +(8, 11) +(9, 18) +(1, 15) +(13, 18) +(5, 11) +(2, 8) +(3, 13) +(5, 16) +(15, 18) +(3, 23) +(7, 18) +(13, 17) +(0, 15) +(5, 9) +(5, 15) +(1, 23) +(18, 20) +(17, 24) +(6, 13) +(12, 15) +(5, 14) +(20, 23) +(1, 21) +(16, 17) +(20, 24) +(16, 23) +(10, 17) +(7, 14) +(11, 16) +(7, 23) +(24, 25) +(10, 21) +(22, 23) +(10, 18) +(4, 16) +(17, 21) +(15, 22) +(18, 19) +(13, 21) +(16, 20) +(15, 23) +(21, 24) +(14, 16) +(3, 13) +(5, 20) +(17, 19) +(7, 22) +(9, 21) +(7, 23) +(2, 13) +(14, 25) +(5, 24) +(3, 8) +(6, 16) +(0, 6) +(3, 7) +(13, 22) +(14, 18) +(3, 12) +(4, 6) +(0, 8) +(6, 9) +(7, 8) +(1, 3) +(4, 25) +(0, 20) +(17, 20) +(8, 18) +(5, 6) +(10, 25) +(8, 15) +(6, 23) +(10, 21) +(4, 5) +(14, 18) +(14, 20) +(11, 21) +(6, 24) +(4, 18) +(3, 4) +(7, 24) +(6, 17) +(17, 19) +(4, 25) +(18, 24) +(7, 10) +(6, 12) +(10, 18) +(5, 19) +(6, 23) +(12, 16) +(0, 17) +(4, 14) +(3, 19) +(9, 12) +(11, 23) +(6, 21) +(1, 17) +(16, 22) +(1, 24) +(5, 12) +(0, 9) +(19, 21) +(6, 8) +(17, 24) +(5, 9) +(2, 12) +(1, 15) +(17, 22) +(20, 24) +(2, 23) +(14, 15) +(1, 13) +(3, 20) +(4, 24) +(2, 23) +(0, 1) +(13, 25) +(10, 17) +(7, 10) +(20, 24) +(13, 22) +(1, 9) +(0, 3) +(0, 20) +(18, 24) +(22, 23) +(5, 7) +(10, 11) +(2, 11) +(8, 24) +(14, 20) +(7, 12) +(0, 25) +(4, 18) +(2, 3) +(23, 25) +(0, 15) +(14, 21) +(16, 18) +(13, 24) +(6, 12) +(0, 21) +(7, 23) +(2, 14) +(10, 24) +(6, 17) +(3, 22) +(9, 12) +(15, 22) +(11, 24) +(6, 21) +(3, 14) +(0, 9) +(10, 16) +(5, 17) +(6, 13) +(22, 25) +(2, 10) +(8, 15) +(4, 25) +(13, 19) +(8, 24) +(10, 13) +(4, 6) +(3, 25) +(0, 24) +(18, 19) +(8, 9) +(8, 19) +(18, 20) +(7, 13) +(5, 10) +(17, 25) +(6, 25) +(20, 24) +(16, 18) +(12, 16) +(2, 20) +(15, 18) +(5, 24) +(4, 25) +(9, 20) +(3, 18) +(8, 16) +(2, 22) +(2, 15) +(7, 16) +(11, 20) +(1, 7) +(0, 11) +(2, 6) +(11, 15) +(2, 22) +(0, 14) +(1, 16) +(1, 10) +(16, 20) +(14, 17) +(6, 15) +(4, 11) +(0, 15) +(5, 20) +(12, 17) +(1, 11) +(10, 20) +(5, 9) +(12, 18) +(17, 24) +(15, 20) +(4, 12) +(14, 18) +(5, 16) +(14, 19) +(5, 13) +(8, 16) +(1, 12) +(18, 23) +(10, 13) +(5, 11) +(9, 19) +(8, 21) +(14, 25) +(12, 17) +(0, 16) +(23, 24) +(15, 18) +(6, 18) +(16, 25) +(15, 19) +(10, 21) +(0, 13) +(5, 17) +(18, 22) +(11, 15) +(0, 24) +(7, 19) +(5, 8) +(2, 10) +(10, 21) +(23, 24) +(0, 24) +(11, 23) +(2, 10) +(0, 16) +(6, 11) +(2, 25) +(10, 21) +(12, 24) +(10, 22) +(1, 16) +(12, 13) +(4, 25) +(0, 9) +(12, 22) +(19, 25) +(10, 20) +(7, 13) +(1, 2) +(16, 19) +(2, 3) +(0, 25) +(4, 22) +(6, 13) +(13, 15) +(0, 5) +(6, 9) +(22, 24) +(1, 2) +(8, 16) +(12, 25) +(7, 16) +(8, 21) +(13, 24) +(3, 5) +(9, 23) +(3, 18) +(0, 8) +(9, 11) +(2, 5) +(10, 13) +(6, 21) +(15, 23) +(9, 13) +(15, 23) +(1, 11) +(8, 20) +(3, 10) +(4, 6) +(14, 18) +(8, 15) +(1, 2) +(0, 6) +(10, 19) +(20, 21) +(20, 24) +(21, 23) +(10, 16) +(6, 22) +(23, 25) +(5, 21) +(8, 20) +(14, 24) +(8, 21) +(6, 14) +(10, 23) +(4, 5) +(4, 20) +(6, 25) +(5, 19) +(10, 12) +(8, 9) +(1, 20) +(9, 18) +(11, 19) +(0, 6) +(8, 13) +(7, 13) +(17, 18) +(20, 21) +(3, 9) +(6, 11) +(2, 18) +(4, 20) +(7, 8) +(13, 22) +(12, 21) +(3, 6) +(6, 11) +(2, 24) +(12, 14) +(20, 23) +(5, 7) +(2, 17) +(5, 12) +(3, 6) +(0, 7) +(8, 24) +(18, 23) +(15, 23) +(7, 20) +(1, 2) +(8, 13) +(22, 24) +(17, 24) +(1, 25) +(16, 23) +(8, 19) +(17, 18) +(20, 25) +(14, 16) +(0, 1) +(9, 23) +(3, 19) +(22, 23) +(19, 20) +(24, 25) +(9, 12) +(6, 23) +(2, 22) +(17, 25) +(8, 23) +(1, 6) +(19, 25) +(2, 16) +(14, 22) +(0, 14) +(6, 16) +(4, 23) +(1, 13) +(21, 22) +(17, 25) +(8, 18) +(6, 15) +(1, 3) +(7, 22) +(14, 24) +(1, 23) +(7, 9) +(10, 22) +(19, 24) +(1, 2) +(3, 22) +(5, 10) +(3, 8) +(5, 12) +(11, 12) +(12, 15) +(10, 11) +(10, 15) +(0, 11) +(10, 14) +(5, 15) +(11, 21) +(0, 9) +(8, 14) +(6, 21) +(5, 18) +(11, 12) +(0, 5) +(4, 12) +(18, 22) +(11, 13) +(3, 8) +(3, 16) +(10, 13) +(12, 15) +(5, 20) +(12, 16) +(8, 15) +(20, 22) +(4, 5) +(1, 5) +(14, 20) +(6, 12) +(3, 8) +(4, 7) +(10, 22) +(5, 22) +(2, 6) +(9, 20) +(0, 12) +(8, 23) +(10, 21) +(1, 10) +(7, 20) +(7, 24) +(1, 14) +(14, 18) +(2, 24) +(1, 20) +(7, 22) +(9, 20) +(1, 8) +(2, 21) +(18, 19) +(7, 23) +(16, 22) +(1, 12) +(13, 23) +(9, 25) +(5, 21) +(12, 20) +(2, 21) +(13, 18) +(20, 23) +(5, 21) +(16, 21) +(5, 19) +(10, 23) +(16, 24) +(4, 21) +(5, 14) +(14, 18) +(22, 24) +(0, 16) +(7, 21) +(14, 16) +(8, 21) +(1, 24) +(0, 15) +(16, 23) +(2, 14) +(21, 22) +(15, 18) +(12, 18) +(3, 22) +(8, 14) +(5, 15) +(2, 4) +(3, 10) +(1, 14) +(4, 9) +(13, 22) +(6, 8) +(18, 21) +(11, 12) +(16, 18) +(12, 17) +(4, 21) +(0, 14) +(9, 23) +(10, 15) +(0, 11) +(14, 18) +(7, 16) +(12, 22) +(5, 23) +(3, 9) +(14, 24) +(10, 11) +(5, 7) +(6, 22) +(0, 19) +(16, 25) +(1, 9) +(5, 9) +(14, 23) +(6, 11) +(0, 15) +(1, 3) +(20, 24) +(1, 7) +(14, 18) +(20, 22) +(11, 12) +(0, 7) +(18, 25) +(9, 12) +(6, 22) +(2, 11) +(13, 18) +(16, 25) +(0, 7) +(1, 9) +(10, 11) +(18, 20) +(13, 25) +(11, 12) +(7, 17) +(0, 2) +(10, 19) +(7, 15) +(8, 13) +(0, 24) +(5, 19) +(22, 25) +(4, 22) +(18, 24) +(8, 9) +(2, 13) +(14, 15) +(7, 14) +(13, 23) +(16, 18) +(14, 15) +(2, 16) +(6, 7) +(22, 23) +(22, 23) +(1, 14) +(6, 8) +(15, 25) +(6, 24) +(17, 25) +(8, 11) +(15, 21) +(4, 15) +(10, 24) +(17, 23) +(7, 11) +(13, 15) +(6, 11) +(17, 23) +(7, 21) +(3, 21) +(4, 7) +(12, 15) +(4, 14) +(6, 21) +(9, 15) +(12, 13) +(3, 5) +(19, 21) +(4, 25) +(3, 24) +(6, 7) +(5, 18) +(9, 22) +(14, 23) +(5, 7) +(14, 15) +(16, 22) +(20, 24) +(2, 18) +(0, 3) +(0, 6) +(21, 22) +(18, 23) +(3, 12) +(9, 16) +(5, 17) +(14, 19) +(11, 23) +(14, 24) +(19, 20) +(12, 22) +(7, 20) +(5, 19) +(17, 24) +(0, 20) +(5, 6) +(4, 19) +(7, 25) +(10, 17) +(1, 10) +(4, 8) +(3, 25) +(7, 18) +(8, 14) +(5, 7) +(22, 25) +(3, 6) +(4, 10) +(3, 20) +(0, 7) +(4, 15) +(16, 25) +(2, 6) +(3, 8) +(0, 9) +(7, 24) +(16, 18) +(17, 20) +(17, 19) +(1, 20) +(22, 24) +(0, 12) +(12, 13) +(2, 17) +(3, 24) +(20, 22) +(0, 11) +(4, 24) +(10, 11) +(14, 20) +(1, 3) +(6, 17) +(3, 25) +(6, 16) +(1, 5) +(0, 20) +(2, 17) +(4, 8) +(19, 25) +(3, 9) +(2, 21) +(8, 18) +(0, 12) +(4, 21) +(2, 16) +(15, 19) +(3, 25) +(10, 15) +(8, 19) +(9, 25) +(11, 19) +(7, 8) +(10, 14) +(3, 8) +(2, 10) +(13, 14) +(5, 11) +(6, 7) +(6, 20) +(3, 9) +(11, 16) +(7, 14) +(5, 24) +(17, 24) +(0, 11) +(20, 22) +(10, 16) +(6, 18) +(11, 12) +(8, 18) +(14, 16) +(17, 22) +(1, 20) +(5, 6) +(8, 9) +(17, 18) +(10, 14) +(16, 21) +(6, 7) +(5, 7) +(4, 6) +(11, 16) +(2, 4) +(10, 11) +(6, 15) +(7, 22) +(15, 25) +(7, 24) +(13, 22) +(2, 5) +(5, 18) +(2, 19) +(1, 7) +(4, 25) +(2, 12) +(4, 21) +(7, 16) +(9, 18) +(1, 24) +(13, 24) +(7, 21) +(14, 16) +(21, 23) +(8, 14) +(6, 23) +(14, 17) +(8, 22) +(23, 25) +(6, 13) +(12, 14) +(11, 17) +(20, 25) +(16, 23) +(13, 21) +(11, 14) +(9, 11) +(16, 20) +(15, 25) +(0, 23) +(11, 18) +(0, 2) +(16, 20) +(9, 14) +(9, 18) +(2, 3) +(0, 19) +(8, 20) +(3, 4) +(0, 5) +(4, 24) +(3, 10) +(4, 23) +(3, 19) +(10, 21) +(1, 21) +(3, 6) +(2, 10) +(6, 21) +(2, 17) +(3, 22) +(1, 23) +(1, 2) +(3, 13) +(0, 22) +(14, 21) +(7, 17) +(21, 22) +(13, 16) +(14, 19) +(2, 4) +(1, 17) +(6, 19) +(21, 24) +(15, 16) +(1, 3) +(4, 25) +(8, 22) +(5, 22) +(19, 20) +(14, 21) +(13, 22) +(0, 14) +(11, 19) +(5, 15) +(13, 23) +(6, 15) +(19, 24) +(17, 22) +(10, 23) +(7, 15) +(13, 21) +(8, 15) +(10, 14) +(7, 25) +(4, 23) +(9, 21) +(13, 16) +(2, 21) +(5, 9) +(4, 18) +(15, 19) +(0, 8) +(15, 25) +(13, 21) +(5, 11) +(0, 19) +(4, 22) +(8, 11) +(7, 15) +(14, 22) +(5, 9) +(13, 24) +(6, 21) +(3, 14) +(4, 21) +(1, 5) +(20, 22) +(9, 24) +(5, 18) +(9, 17) +(0, 14) +(4, 13) +(1, 6) +(1, 23) +(3, 6) +(13, 22) +(5, 8) +(5, 7) +(13, 18) +(1, 9) +(3, 19) +(11, 23) +(13, 25) +(1, 2) +(0, 23) +(11, 14) +(0, 18) +(13, 24) +(8, 14) +(13, 17) +(0, 3) +(4, 18) +(6, 24) +(6, 25) +(12, 17) +(18, 21) +(4, 16) +(13, 19) +(15, 16) +(17, 20) +(0, 13) +(9, 18) +(4, 24) +(21, 25) +(5, 12) +(15, 24) +(18, 25) +(3, 16) +(1, 20) +(7, 13) +(4, 19) +(7, 11) +(4, 6) +(1, 10) +(10, 21) +(7, 13) +(1, 17) +(2, 4) +(10, 22) +(2, 5) +(7, 11) +(12, 21) +(7, 16) +(17, 21) +(10, 13) +(1, 22) +(1, 9) +(13, 16) +(3, 21) +(17, 23) +(1, 22) +(15, 21) +(10, 23) +(12, 17) +(5, 10) +(2, 15) +(11, 22) +(17, 19) +(0, 12) +(1, 25) +(9, 12) +(19, 24) +(2, 20) +(17, 19) +(2, 4) +(8, 24) +(3, 24) +(9, 17) +(19, 21) +(3, 20) +(16, 24) +(9, 18) +(9, 14) +(3, 13) +(1, 20) +(1, 6) +(14, 15) +(16, 20) +(8, 9) +(9, 19) +(16, 22) +(15, 24) +(12, 14) +(7, 20) +(8, 15) +(14, 19) +(3, 24) +(12, 21) +(16, 18) +(9, 10) +(6, 9) +(2, 16) +(12, 18) +(20, 24) +(11, 19) +(0, 8) +(5, 14) +(4, 15) +(14, 25) +(7, 8) +(5, 13) +(0, 19) +(0, 2) +(23, 25) +(14, 15) +(13, 18) +(19, 24) +(20, 24) +(5, 15) +(0, 9) +(12, 25) +(8, 13) +(3, 23) +(2, 17) +(1, 8) +(2, 11) +(14, 15) +(5, 15) +(2, 7) +(14, 16) +(5, 12) +(14, 25) +(15, 17) +(0, 5) +(15, 21) +(12, 20) +(17, 24) +(6, 21) +(12, 25) +(9, 15) +(15, 18) +(21, 22) +(6, 17) +(0, 9) +(20, 22) +(4, 21) +(6, 15) +(9, 24) +(0, 8) +(5, 17) +(7, 21) +(1, 4) +(17, 20) +(11, 15) +(1, 7) +(14, 20) +(12, 21) +(0, 11) +(2, 4) +(7, 13) +(2, 10) +(5, 12) +(1, 3) +(14, 15) +(12, 13) +(10, 19) +(2, 23) +(0, 5) +(1, 16) +(7, 20) +(15, 23) +(12, 18) +(10, 14) +(16, 24) +(6, 13) +(0, 8) +(17, 24) +(1, 8) +(3, 16) +(9, 23) +(12, 21) +(7, 13) +(15, 19) +(1, 19) +(12, 25) +(13, 15) +(18, 21) +(5, 8) +(4, 12) +(0, 18) +(1, 14) +(15, 17) +(5, 23) +(7, 17) +(8, 23) +(0, 6) +(13, 18) +(4, 22) +(14, 25) +(6, 22) +(13, 20) +(1, 23) +(11, 25) +(0, 24) +(5, 14) +(11, 13) +(2, 5) +(18, 23) +(6, 7) +(16, 24) +(16, 19) +(0, 13) +(2, 3) +(9, 24) +(4, 13) +(15, 16) +(17, 24) +(0, 21) +(19, 22) +(0, 6) +(4, 12) +(9, 19) +(13, 25) +(1, 4) +(15, 25) +(9, 23) +(12, 21) +(17, 23) +(3, 15) +(9, 20) +(2, 17) +(9, 13) +(15, 22) +(0, 20) +(14, 15) +(3, 17) +(15, 25) +(3, 5) +(14, 18) +(2, 17) +(10, 18) +(2, 4) +(0, 14) +(3, 24) +(15, 19) +(7, 19) +(22, 24) +(15, 25) +(5, 24) +(7, 16) +(12, 25) +(4, 25) +(16, 20) +(7, 18) +(1, 5) +(4, 21) +(7, 14) +(20, 23) +(8, 18) +(9, 16) +(3, 9) +(10, 18) +(8, 22) +(13, 23) +(7, 11) +(9, 20) +(7, 25) +(10, 11) +(3, 6) +(15, 23) +(2, 13) +(0, 11) +(21, 23) +(3, 13) +(8, 9) +(12, 20) +(15, 22) +(9, 22) +(15, 23) +(16, 21) +(7, 12) +(0, 8) +(1, 20) +(5, 21) +(7, 20) +(10, 15) +(23, 25) +(8, 11) +(5, 6) +(7, 15) +(23, 24) +(14, 25) +(8, 12) +(2, 5) +(0, 6) +(12, 13) +(8, 24) +(14, 17) +(3, 23) +(8, 14) +(4, 13) +(5, 10) +(24, 25) +(6, 21) +(0, 16) +(19, 21) +(10, 20) +(5, 22) +(1, 6) +(16, 18) +(9, 14) +(4, 15) +(2, 21) +(5, 12) +(6, 23) +(0, 20) +(1, 19) +(3, 22) +(2, 14) +(10, 22) +(0, 15) +(8, 21) +(1, 24) +(4, 22) +(6, 15) +(10, 11) +(18, 21) +(23, 24) +(10, 25) +(8, 22) +(1, 11) +(8, 18) +(1, 7) +(3, 11) +(1, 4) +(3, 16) +(7, 15) +(7, 8) +(1, 2) +(16, 19) +(3, 25) +(19, 24) +(6, 8) +(1, 9) +(3, 18) +(10, 16) +(3, 14) +(10, 15) +(12, 16) +(9, 13) +(18, 25) +(11, 24) +(0, 10) +(11, 14) +(3, 12) +(18, 21) +(16, 19) +(19, 23) +(0, 16) +(7, 14) +(8, 10) +(8, 20) +(14, 25) +(1, 23) +(10, 17) +(16, 19) +(1, 5) +(7, 19) +(13, 17) +(0, 16) +(2, 5) +(13, 19) +(1, 20) +(4, 5) +(1, 9) +(2, 23) +(15, 23) +(5, 22) +(5, 11) +(15, 22) +(0, 11) +(5, 23) +(20, 22) +(3, 22) +(8, 23) +(3, 6) +(4, 23) +(4, 7) +(17, 23) +(6, 9) +(7, 10) +(17, 22) +(12, 23) +(4, 6) +(1, 12) +(17, 24) +(5, 10) +(7, 11) +(16, 23) +(5, 8) +(1, 11) +(10, 13) +(3, 17) +(7, 18) +(8, 13) +(6, 11) +(0, 18) +(10, 22) +(3, 24) +(7, 21) +(5, 23) +(4, 22) +(8, 18) +(0, 9) +(3, 15) +(7, 20) +(10, 13) +(5, 19) +(10, 12) +(9, 25) +(2, 20) +(4, 7) +(1, 5) +(13, 22) +(5, 19) +(12, 20) +(1, 21) +(16, 21) +(1, 7) +(5, 23) +(14, 19) +(18, 21) +(11, 14) +(9, 18) +(8, 11) +(14, 21) +(11, 19) +(1, 21) +(0, 18) +(9, 23) +(7, 18) +(1, 3) +(2, 19) +(16, 23) +(3, 5) +(7, 15) +(9, 23) +(1, 8) +(6, 16) +(4, 15) +(13, 23) +(0, 3) +(4, 21) +(3, 22) +(0, 17) +(6, 23) +(15, 16) +(12, 22) +(8, 15) +(0, 13) +(14, 16) +(7, 23) +(2, 23) +(14, 24) +(3, 12) +(7, 25) +(16, 21) +(4, 7) +(1, 25) +(2, 10) +(0, 23) +(2, 20) +(7, 22) +(4, 9) +(13, 25) +(0, 14) +(0, 24) +(7, 18) +(4, 12) +(20, 21) +(9, 23) +(1, 14) +(0, 6) +(24, 25) +(9, 13) +(11, 20) +(16, 21) +(1, 22) +(0, 3) +(10, 11) +(20, 24) +(21, 23) +(7, 16) +(8, 13) +(1, 25) +(10, 18) +(3, 16) +(2, 11) +(5, 21) +(21, 24) +(10, 17) +(3, 4) +(11, 14) +(6, 18) +(12, 18) +(3, 22) +(6, 7) +(0, 14) +(15, 24) +(6, 9) +(12, 22) +(18, 19) +(0, 21) +(3, 7) +(14, 18) +(19, 20) +(3, 15) +(9, 22) +(5, 18) +(14, 23) +(2, 5) +(12, 18) +(9, 14) +(17, 23) +(5, 21) +(16, 17) +(9, 20) +(2, 6) +(19, 20) +(10, 16) +(18, 21) +(9, 25) +(5, 13) +(13, 14) +(7, 25) +(2, 16) +(11, 21) +(19, 22) +(12, 22) +(5, 19) +(0, 13) +(7, 21) +(10, 12) +(0, 18) +(13, 17) +(1, 19) +(22, 24) +(17, 19) +(18, 25) +(11, 12) +(10, 15) +(0, 21) +(1, 8) +(12, 13) +(17, 21) +(14, 25) +(5, 15) +(0, 12) +(7, 21) +(8, 15) +(14, 18) +(6, 25) +(20, 25) +(1, 8) +(0, 24) +(14, 16) +(8, 15) +(1, 17) +(5, 24) +(0, 10) +(10, 22) +(1, 25) +(8, 12) +(4, 17) +(12, 13) +(21, 25) +(2, 8) +(23, 25) +(0, 8) +(2, 6) +(13, 15) +(16, 21) +(15, 17) +(6, 11) +(21, 24) +(3, 13) +(16, 20) +(2, 5) +(3, 7) +(17, 20) +(6, 22) +(4, 13) +(14, 15) +(5, 9) +(2, 25) +(15, 19) +(9, 10) +(5, 24) +(14, 22) +(3, 20) +(0, 6) +(12, 15) +(0, 17) +(4, 14) +(3, 5) +(19, 24) +(2, 22) +(22, 25) +(16, 19) +(7, 12) +(13, 15) +(12, 20) +(8, 22) +(20, 23) +(8, 10) +(1, 22) +(4, 12) +(10, 20) +(3, 22) +(4, 11) +(4, 9) +(8, 20) +(2, 11) +(11, 18) +(5, 9) +(9, 23) +(5, 14) +(3, 11) +(5, 20) +(4, 11) +(23, 24) +(7, 23) +(21, 24) +(12, 23) +(7, 18) +(9, 24) +(0, 21) +(14, 24) +(20, 21) +(0, 2) +(18, 25) +(11, 14) +(0, 6) +(16, 24) +(6, 14) +(10, 11) +(6, 9) +(10, 19) +(7, 11) +(11, 18) +(2, 19) +(7, 12) +(10, 16) +(7, 25) +(5, 19) +(11, 17) +(10, 21) +(16, 18) +(4, 12) +(19, 24) +(4, 22) +(9, 17) +(19, 24) +(22, 25) +(3, 9) +(4, 14) +(8, 17) +(1, 8) +(7, 25) +(17, 23) +(11, 19) +(6, 23) +(15, 19) +(8, 18) +(12, 25) +(0, 11) +(8, 17) +(22, 25) +(9, 18) +(0, 10) +(19, 21) +(14, 22) +(1, 10) +(5, 19) +(4, 18) +(0, 2) +(9, 25) +(6, 18) +(3, 5) +(9, 21) +(7, 19) +(17, 25) +(0, 13) +(13, 24) +(3, 19) +(9, 21) +(2, 5) +(14, 18) +(14, 22) +(8, 13) +(2, 9) +(5, 23) +(0, 24) +(3, 4) +(5, 9) +(20, 24) +(14, 18) +(0, 15) +(13, 17) +(2, 13) +(12, 20) +(4, 14) +(15, 21) +(0, 8) +(16, 18) +(1, 16) +(4, 24) +(21, 25) +(0, 17) +(3, 20) +(11, 12) +(7, 18) +(17, 22) +(10, 18) +(4, 19) +(5, 21) +(7, 15) +(8, 25) +(14, 24) +(11, 23) +(0, 8) +(5, 10) +(12, 22) +(11, 21) +(9, 25) +(14, 18) +(4, 21) +(0, 6) +(7, 11) +(10, 16) +(14, 17) +(3, 12) +(7, 20) +(11, 24) +(2, 14) +(17, 23) +(4, 19) +(0, 23) +(2, 11) +(5, 14) +(9, 24) +(10, 17) +(3, 4) +(3, 12) +(5, 19) +(4, 18) +(8, 9) +(6, 24) +(2, 16) +(1, 19) +(4, 9) +(13, 18) +(12, 22) +(3, 25) +(8, 14) +(5, 19) +(3, 10) +(2, 5) +(1, 19) +(1, 20) +(0, 19) +(19, 22) +(9, 20) +(1, 21) +(9, 12) +(17, 19) +(0, 21) +(9, 22) +(0, 1) +(15, 21) +(13, 17) +(12, 20) +(11, 15) +(20, 24) +(0, 25) +(9, 12) +(22, 25) +(0, 8) +(11, 16) +(7, 8) +(2, 22) +(4, 25) +(11, 15) +(0, 23) +(1, 16) +(4, 6) +(1, 23) +(11, 14) +(0, 5) +(8, 14) +(0, 22) +(4, 19) +(11, 24) +(5, 18) +(8, 16) +(4, 12) +(5, 7) +(11, 21) +(3, 22) +(0, 2) +(14, 23) +(7, 20) +(5, 11) +(3, 15) +(11, 18) +(13, 20) +(3, 25) +(6, 7) +(0, 15) +(7, 23) +(3, 20) +(8, 25) +(13, 22) +(0, 7) +(3, 24) +(3, 16) +(4, 24) +(0, 6) +(0, 8) +(6, 23) +(22, 24) +(4, 17) +(3, 16) +(12, 24) +(16, 25) +(0, 17) +(4, 23) +(18, 22) +(2, 22) +(16, 21) +(4, 12) +(8, 24) +(0, 6) +(5, 25) +(4, 13) +(2, 22) +(10, 25) +(0, 15) +(16, 18) +(3, 21) +(22, 24) +(7, 21) +(14, 15) +(0, 15) +(14, 15) +(0, 3) +(3, 23) +(15, 25) +(15, 19) +(10, 25) +(7, 10) +(2, 19) +(1, 15) +(1, 24) +(2, 16) +(6, 19) +(7, 18) +(15, 21) +(8, 10) +(18, 20) +(9, 24) +(5, 16) +(15, 24) +(2, 16) +(18, 20) +(9, 25) +(18, 22) +(4, 24) +(11, 15) +(2, 8) +(16, 20) +(4, 12) +(6, 18) +(8, 11) +(13, 16) +(7, 22) +(24, 25) +(0, 8) +(2, 18) +(16, 24) +(7, 19) +(3, 11) +(6, 14) +(0, 22) +(3, 17) +(7, 23) +(7, 19) +(4, 17) +(0, 25) +(6, 22) +(12, 23) +(16, 19) +(20, 23) +(0, 1) +(9, 16) +(19, 24) +(10, 20) +(0, 8) +(0, 12) +(9, 11) +(18, 19) +(1, 8) +(10, 25) +(5, 10) +(0, 2) +(13, 19) +(12, 24) +(17, 25) +(9, 25) +(10, 19) +(13, 14) +(0, 11) +(15, 17) +(4, 5) +(4, 23) +(15, 22) +(14, 19) +(8, 13) +(5, 21) +(7, 23) +(18, 22) +(3, 19) +(13, 17) +(8, 20) +(4, 6) +(0, 15) +(8, 11) +(6, 16) +(12, 20) +(2, 3) +(19, 23) +(11, 13) +(2, 24) +(5, 20) +(14, 23) +(4, 11) +(2, 19) +(3, 14) +(3, 6) +(4, 5) +(17, 19) +(0, 6) +(3, 8) +(14, 19) +(7, 17) +(2, 17) +(14, 23) +(0, 1) +(3, 6) +(19, 25) +(1, 10) +(0, 21) +(6, 20) +(3, 24) +(13, 23) +(15, 19) +(0, 16) +(1, 9) +(6, 10) +(18, 23) +(2, 20) +(1, 12) +(4, 18) +(2, 3) +(8, 16) +(0, 22) +(10, 13) +(1, 23) +(4, 11) +(0, 8) +(18, 22) +(1, 4) +(16, 18) +(9, 23) +(0, 24) +(11, 13) +(2, 4) +(8, 9) +(14, 23) +(11, 17) +(1, 15) +(11, 20) +(1, 25) +(2, 19) +(4, 9) +(14, 18) +(12, 17) +(14, 18) +(11, 21) +(5, 21) +(13, 14) +(5, 17) +(6, 21) +(13, 23) +(11, 13) +(6, 12) +(10, 17) +(5, 25) +(6, 23) +(15, 17) +(13, 14) +(10, 19) +(0, 12) +(0, 23) +(9, 14) +(6, 7) +(3, 15) +(7, 16) +(1, 15) +(6, 8) +(17, 23) +(1, 25) +(0, 17) +(3, 7) +(4, 6) +(13, 25) +(0, 5) +(7, 23) +(4, 21) +(1, 14) +(2, 3) +(16, 25) +(11, 14) +(5, 6) +(1, 8) +(13, 17) +(8, 20) +(1, 13) +(0, 14) +(12, 25) +(4, 17) +(4, 5) +(11, 13) +(8, 10) +(2, 17) +(3, 14) +(1, 15) +(17, 23) +(0, 4) +(4, 16) +(15, 17) +(0, 24) +(4, 13) +(16, 19) +(23, 24) +(14, 15) +(11, 19) +(13, 22) +(0, 24) +(4, 21) +(3, 16) +(1, 4) +(0, 2) +(20, 22) +(16, 24) +(5, 13) +(10, 21) +(3, 9) +(4, 23) +(6, 20) +(8, 22) +(9, 25) +(23, 24) +(8, 14) +(2, 14) +(9, 23) +(6, 8) +(14, 22) +(5, 6) +(2, 15) +(7, 8) +(11, 22) +(2, 4) +(1, 7) +(14, 25) +(14, 22) +(0, 11) +(2, 3) +(6, 25) +(0, 9) +(23, 25) +(3, 10) +(14, 20) +(1, 6) +(1, 12) +(9, 22) +(0, 19) +(10, 25) +(9, 16) +(12, 20) +(17, 19) +(0, 7) +(6, 22) +(5, 20) +(12, 18) +(1, 9) +(16, 19) +(14, 22) +(6, 8) +(4, 6) +(18, 19) +(8, 13) +(1, 11) +(17, 22) +(9, 24) +(1, 17) +(2, 13) +(6, 20) +(7, 9) +(4, 21) +(15, 20) +(10, 21) +(4, 22) +(0, 13) +(0, 24) +(5, 10) +(13, 23) +(1, 4) +(2, 22) +(14, 21) +(16, 21) +(14, 18) +(0, 15) +(13, 19) +(8, 23) +(7, 23) +(8, 25) +(3, 16) +(6, 18) +(8, 14) +(3, 11) +(6, 12) +(12, 21) +(6, 16) +(13, 14) +(18, 21) +(1, 14) +(7, 13) +(10, 14) +(4, 13) +(0, 13) +(4, 6) +(3, 10) +(9, 13) +(3, 23) +(6, 20) +(17, 20) +(3, 7) +(2, 23) +(5, 6) +(12, 23) +(7, 19) +(14, 17) +(3, 24) +(1, 2) +(6, 9) +(11, 23) +(11, 22) +(17, 23) +(22, 25) +(11, 16) +(4, 22) +(4, 10) +(4, 18) +(10, 22) +(5, 18) +(4, 24) +(1, 10) +(12, 24) +(1, 13) +(0, 10) +(12, 25) +(7, 12) +(21, 25) +(14, 25) +(10, 12) +(20, 21) +(7, 11) +(12, 18) +(1, 20) +(16, 21) +(11, 17) +(8, 10) +(6, 8) +(12, 15) +(3, 20) +(1, 19) +(4, 8) +(12, 18) +(1, 23) +(13, 23) +(6, 8) +(4, 25) +(20, 25) +(4, 15) +(6, 9) +(1, 13) +(3, 13) +(1, 23) +(6, 10) +(11, 25) +(0, 20) +(3, 5) +(18, 25) +(22, 23) +(7, 13) +(3, 20) +(4, 22) +(7, 12) +(13, 21) +(9, 25) +(5, 17) +(11, 25) +(20, 24) +(16, 17) +(6, 21) +(9, 10) +(19, 25) +(13, 21) +(16, 17) +(5, 13) +(4, 16) +(1, 17) +(7, 19) +(6, 21) +(11, 21) +(5, 24) +(1, 14) +(2, 7) +(7, 14) +(11, 25) +(16, 21) +(1, 20) +(17, 24) +(5, 12) +(15, 25) +(5, 17) +(1, 22) +(3, 24) +(12, 23) +(1, 4) +(15, 16) +(18, 23) +(13, 17) +(0, 17) +(4, 21) +(1, 10) +(19, 23) +(6, 13) +(23, 25) +(4, 22) +(8, 19) +(3, 6) +(17, 24) +(1, 11) +(13, 19) +(20, 24) +(6, 18) +(3, 6) +(17, 24) +(5, 20) +(13, 14) +(1, 3) +(21, 24) +(16, 20) +(6, 9) +(8, 16) +(11, 21) +(7, 20) +(10, 21) +(7, 12) +(9, 11) +(5, 16) +(12, 20) +(17, 21) +(9, 24) +(8, 16) +(10, 15) +(12, 21) +(1, 10) +(6, 15) +(16, 21) +(1, 7) +(5, 15) +(6, 18) +(5, 7) +(14, 18) +(2, 6) +(5, 24) +(4, 6) +(0, 2) +(6, 13) +(0, 23) +(13, 22) +(0, 2) +(3, 23) +(2, 17) +(0, 4) +(11, 13) +(14, 23) +(2, 15) +(9, 11) +(4, 19) +(1, 13) +(6, 11) +(4, 25) +(9, 18) +(2, 12) +(15, 18) +(22, 25) +(3, 11) +(4, 10) +(0, 4) +(23, 25) +(10, 21) +(14, 22) +(6, 14) +(0, 15) +(17, 25) +(9, 14) +(17, 20) +(8, 15) +(6, 11) +(0, 18) +(2, 9) +(6, 21) +(10, 17) +(18, 24) +(14, 19) +(3, 18) +(10, 23) +(11, 24) +(2, 4) +(13, 14) +(5, 19) +(5, 18) +(19, 25) +(2, 23) +(4, 9) +(10, 17) +(7, 23) +(0, 9) +(1, 19) +(4, 12) +(2, 17) +(0, 23) +(1, 16) +(14, 19) +(2, 12) +(5, 16) +(7, 23) +(2, 9) +(7, 22) +(5, 17) +(16, 18) +(17, 21) +(7, 13) +(16, 24) +(6, 21) +(4, 7) +(13, 15) +(17, 19) +(19, 20) +(1, 21) +(20, 25) +(12, 21) +(14, 19) +(1, 23) +(10, 25) +(0, 12) +(18, 20) +(16, 21) +(0, 6) +(5, 10) +(16, 22) +(2, 20) +(8, 12) +(1, 16) +(8, 13) +(7, 10) +(17, 22) +(0, 4) +(8, 23) +(2, 17) +(5, 13) +(0, 19) +(7, 20) +(8, 20) +(15, 17) +(2, 23) +(9, 19) +(0, 1) +(1, 24) +(11, 15) +(18, 19) +(0, 16) +(10, 20) +(4, 24) +(0, 14) +(15, 22) +(0, 18) +(2, 15) +(13, 14) +(14, 16) +(5, 15) +(6, 13) +(3, 16) +(6, 8) +(0, 14) +(5, 17) +(17, 25) +(4, 8) +(3, 6) +(14, 24) +(16, 19) +(14, 18) +(7, 16) +(13, 19) +(3, 20) +(6, 10) +(18, 24) +(14, 22) +(2, 13) +(24, 25) +(13, 23) +(2, 17) +(6, 25) +(17, 21) +(16, 24) +(22, 25) +(11, 24) +(13, 16) +(8, 17) +(10, 13) +(7, 25) +(8, 15) +(9, 16) +(5, 22) +(18, 25) +(4, 9) +(16, 24) +(2, 7) +(4, 5) +(11, 24) +(18, 19) +(14, 16) +(18, 21) +(0, 14) +(5, 22) +(9, 11) +(16, 25) +(21, 23) +(6, 16) +(0, 24) +(13, 25) +(11, 19) +(17, 22) +(14, 20) +(0, 7) +(12, 21) +(13, 19) +(11, 18) +(1, 16) +(2, 21) +(1, 15) +(11, 23) +(12, 25) +(6, 11) +(16, 21) +(2, 18) +(16, 25) +(4, 18) +(21, 23) +(5, 16) +(18, 24) +(13, 25) +(17, 21) +(8, 25) +(2, 16) +(13, 20) +(1, 18) +(17, 22) +(13, 24) +(3, 8) +(15, 16) +(2, 19) +(20, 23) +(11, 23) +(6, 8) +(2, 12) +(7, 16) +(13, 18) +(2, 9) +(4, 18) +(12, 25) +(12, 23) +(22, 25) +(14, 18) +(9, 19) +(2, 14) +(18, 21) +(0, 22) +(5, 25) +(4, 23) +(17, 22) +(14, 16) +(12, 23) +(5, 18) +(2, 11) +(1, 17) +(9, 18) +(20, 23) +(0, 11) +(2, 19) +(9, 25) +(17, 23) +(0, 22) +(0, 7) +(14, 22) +(1, 23) +(7, 16) +(17, 23) +(6, 14) +(7, 24) +(10, 17) +(1, 23) +(5, 16) +(5, 9) +(11, 23) +(10, 15) +(17, 18) +(4, 17) +(10, 23) +(15, 20) +(11, 13) +(0, 4) +(11, 15) +(8, 13) +(3, 23) +(12, 17) +(19, 23) +(11, 24) +(2, 3) +(8, 25) +(12, 15) +(9, 13) +(13, 22) +(6, 9) +(7, 19) +(1, 2) +(18, 25) +(8, 16) +(1, 23) +(19, 20) +(2, 15) +(8, 10) +(5, 19) +(0, 10) +(2, 24) +(8, 22) +(19, 20) +(3, 10) +(7, 22) +(0, 17) +(3, 13) +(17, 19) +(7, 8) +(0, 23) +(4, 13) +(0, 19) +(7, 12) +(23, 25) +(7, 9) +(12, 16) +(16, 25) +(7, 15) +(6, 9) +(12, 18) +(7, 13) +(4, 6) +(15, 17) +(3, 25) +(14, 15) +(13, 23) +(7, 11) +(4, 9) +(15, 19) +(0, 23) +(11, 21) +(10, 14) +(4, 17) +(18, 23) +(1, 17) +(6, 15) +(5, 15) +(4, 6) +(10, 23) +(1, 20) +(4, 14) +(9, 15) +(23, 24) +(2, 6) +(10, 22) +(2, 18) +(5, 23) +(4, 12) +(7, 14) +(5, 6) +(12, 13) +(14, 19) +(16, 18) +(2, 15) +(0, 7) +(5, 7) +(4, 13) +(6, 23) +(2, 10) +(15, 17) +(8, 19) +(11, 18) +(4, 9) +(2, 25) +(16, 18) +(14, 19) +(10, 15) +(11, 24) +(4, 10) +(13, 19) +(23, 25) +(15, 18) +(8, 18) +(10, 24) +(15, 17) +(4, 21) +(13, 22) +(19, 21) +(14, 15) +(2, 4) +(18, 23) +(10, 11) +(0, 18) +(3, 19) +(2, 25) +(14, 17) +(6, 25) +(2, 20) +(1, 14) +(3, 18) +(5, 19) +(0, 11) +(20, 22) +(15, 19) +(4, 18) +(1, 24) +(2, 17) +(7, 11) +(0, 25) +(6, 11) +(21, 24) +(13, 22) +(7, 25) +(12, 15) +(8, 17) +(10, 17) +(23, 24) +(11, 13) +(15, 20) +(2, 22) +(17, 19) +(3, 10) +(24, 25) +(2, 7) +(16, 20) +(21, 22) +(1, 20) +(3, 8) +(0, 25) +(10, 23) +(7, 14) +(2, 4) +(3, 5) +(11, 20) +(2, 13) +(1, 22) +(1, 6) +(22, 24) +(2, 14) +(4, 22) +(1, 7) +(7, 15) +(1, 6) +(22, 25) +(19, 25) +(6, 17) +(7, 17) +(4, 25) +(6, 11) +(17, 21) +(6, 8) +(3, 11) +(0, 6) +(3, 16) +(15, 17) +(3, 23) +(6, 8) +(0, 21) +(14, 15) +(12, 16) +(12, 23) +(6, 11) +(7, 15) +(14, 16) +(2, 8) +(5, 23) +(8, 9) +(10, 11) +(14, 20) +(17, 20) +(5, 14) +(9, 13) +(5, 17) +(0, 20) +(1, 13) +(7, 9) +(20, 25) +(1, 15) +(9, 12) +(13, 24) +(7, 23) +(10, 17) +(5, 11) +(14, 24) +(1, 8) +(0, 12) +(3, 9) +(11, 22) +(3, 15) +(1, 13) +(17, 22) +(5, 14) +(2, 13) +(1, 15) +(11, 22) +(11, 21) +(8, 13) +(9, 22) +(4, 9) +(10, 13) +(20, 21) +(8, 23) +(2, 4) +(16, 20) +(19, 21) +(10, 24) +(13, 19) +(1, 16) +(3, 10) +(5, 20) +(12, 19) +(13, 14) +(5, 7) +(3, 8) +(20, 23) +(16, 18) +(20, 25) +(16, 17) +(6, 7) +(13, 23) +(5, 8) +(7, 15) +(6, 11) +(3, 11) +(5, 15) +(7, 18) +(14, 15) +(5, 24) +(1, 11) +(1, 7) +(5, 21) +(15, 18) +(8, 21) +(9, 18) +(9, 24) +(13, 21) +(8, 25) +(8, 15) +(14, 24) +(10, 21) +(3, 13) +(1, 3) +(4, 15) +(5, 21) +(11, 13) +(8, 20) +(11, 14) +(1, 9) +(15, 19) +(4, 23) +(20, 22) +(13, 17) +(2, 3) +(12, 19) +(11, 20) +(17, 25) +(1, 7) +(13, 21) +(6, 23) +(4, 20) +(13, 15) +(18, 19) +(1, 25) +(14, 17) +(7, 9) +(8, 23) +(3, 20) +(16, 19) +(6, 14) +(8, 9) +(18, 23) +(0, 13) +(7, 21) +(4, 19) +(5, 16) +(3, 6) +(8, 25) +(15, 20) +(11, 21) +(2, 16) +(5, 23) +(1, 4) +(6, 10) +(7, 19) +(21, 22) +(15, 25) +(0, 19) +(11, 25) +(15, 18) +(1, 20) +(20, 24) +(9, 25) +(1, 7) +(4, 18) +(6, 15) +(0, 10) +(11, 16) +(3, 4) +(12, 24) +(6, 11) +(5, 18) +(2, 10) +(8, 20) +(2, 13) +(5, 8) +(10, 21) +(1, 12) +(17, 24) +(0, 20) +(0, 16) +(10, 23) +(9, 24) +(7, 8) +(20, 22) +(6, 12) +(3, 5) +(16, 24) +(7, 20) +(6, 8) +(3, 23) +(7, 25) +(8, 15) +(3, 14) +(19, 25) +(3, 15) +(8, 15) +(21, 25) +(6, 21) +(3, 15) +(15, 20) +(12, 20) +(15, 18) +(17, 20) +(15, 16) +(0, 12) +(18, 22) +(18, 19) +(13, 15) +(17, 24) +(16, 22) +(16, 25) +(5, 22) +(12, 19) +(1, 16) +(21, 25) +(2, 5) +(10, 22) +(18, 21) +(5, 9) +(2, 20) +(7, 22) +(5, 22) +(9, 12) +(2, 4) +(11, 20) +(12, 14) +(2, 16) +(10, 20) +(22, 25) +(4, 13) +(9, 14) +(4, 7) +(2, 24) +(1, 25) +(3, 22) +(6, 10) +(2, 21) +(19, 22) +(3, 13) +(6, 15) +(0, 24) +(10, 18) +(11, 15) +(7, 18) +(19, 20) +(4, 21) +(2, 8) +(2, 4) +(15, 18) +(19, 23) +(12, 21) +(1, 7) +(0, 1) +(2, 25) +(5, 7) +(12, 20) +(2, 13) +(7, 11) +(22, 25) +(12, 25) +(15, 22) +(1, 7) +(13, 14) +(2, 17) +(9, 17) +(5, 15) +(22, 24) +(8, 9) +(13, 24) +(2, 22) +(5, 24) +(2, 11) +(3, 9) +(8, 21) +(9, 20) +(3, 18) +(2, 7) +(7, 24) +(3, 12) +(8, 20) +(18, 25) +(3, 25) +(8, 17) +(1, 12) +(10, 20) +(17, 20) +(10, 12) +(6, 25) +(3, 17) +(8, 20) +(10, 19) +(12, 21) +(0, 25) +(6, 7) +(0, 1) +(4, 19) +(22, 25) +(21, 24) +(6, 14) +(6, 20) +(15, 19) +(0, 23) +(9, 24) +(5, 14) +(21, 22) +(2, 15) +(0, 10) +(9, 20) +(3, 19) +(13, 23) +(18, 22) +(23, 25) +(10, 19) +(12, 15) +(3, 24) +(1, 24) +(10, 17) +(12, 16) +(2, 15) +(13, 15) +(2, 4) +(1, 3) +(20, 24) +(17, 25) +(15, 16) +(10, 13) +(1, 6) +(12, 24) +(3, 23) +(2, 11) +(1, 19) +(11, 20) +(3, 13) +(4, 15) +(16, 17) +(0, 2) +(6, 9) +(1, 15) +(11, 14) +(6, 8) +(4, 7) +(13, 25) +(16, 20) +(10, 15) +(18, 25) +(2, 4) +(6, 11) +(1, 24) +(1, 3) +(10, 23) +(19, 25) +(2, 10) +(1, 5) +(21, 25) +(3, 12) +(3, 4) +(10, 22) +(19, 25) +(2, 8) +(1, 14) +(13, 21) +(19, 20) +(7, 10) +(5, 21) +(11, 22) +(3, 8) +(19, 24) +(15, 20) +(0, 10) +(9, 22) +(3, 17) +(7, 20) +(4, 22) +(12, 17) +(10, 13) +(24, 25) +(2, 9) +(1, 15) +(17, 22) +(10, 18) +(11, 25) +(3, 12) +(0, 2) +(7, 13) +(2, 23) +(12, 24) +(0, 14) +(10, 16) +(9, 25) +(8, 17) +(2, 18) +(10, 15) +(6, 25) +(11, 17) +(14, 21) +(6, 18) +(2, 8) +(23, 25) +(11, 19) +(16, 21) +(15, 20) +(9, 15) +(0, 21) +(10, 25) +(14, 23) +(1, 16) +(16, 17) +(5, 16) +(0, 17) +(13, 17) +(5, 7) +(0, 19) +(16, 23) +(7, 22) +(2, 17) +(10, 16) +(12, 19) +(3, 5) +(15, 23) +(1, 22) +(7, 24) +(5, 8) +(3, 6) +(14, 22) +(6, 20) +(2, 24) +(2, 17) +(11, 22) +(4, 24) +(6, 8) +(3, 20) +(8, 9) +(19, 20) +(1, 22) +(0, 3) +(10, 22) +(9, 25) +(4, 19) +(18, 25) +(10, 13) +(8, 19) +(4, 24) +(0, 24) +(5, 19) +(2, 4) +(23, 25) +(0, 20) +(4, 12) +(17, 19) +(5, 8) +(1, 20) +(4, 11) +(5, 6) +(13, 20) +(5, 19) +(4, 17) +(1, 16) +(20, 22) +(9, 17) +(13, 24) +(15, 16) +(20, 25) +(13, 18) +(2, 22) +(16, 23) +(5, 13) +(9, 20) +(18, 24) +(1, 2) +(16, 25) +(18, 22) +(2, 6) +(1, 12) +(7, 12) +(3, 6) +(10, 22) +(1, 8) +(22, 23) +(0, 7) +(1, 12) +(18, 23) +(1, 24) +(0, 7) +(18, 19) +(7, 24) +(13, 23) +(0, 8) +(1, 6) +(8, 12) +(6, 16) +(7, 10) +(0, 15) +(0, 24) +(2, 12) +(7, 15) +(3, 6) +(2, 8) +(5, 24) +(4, 15) +(0, 16) +(8, 13) +(5, 7) +(4, 21) +(0, 25) +(14, 16) +(9, 24) +(8, 10) +(9, 25) +(0, 11) +(3, 14) +(21, 24) +(4, 17) +(7, 18) +(3, 22) +(0, 12) +(7, 8) +(4, 19) +(16, 24) +(18, 23) +(15, 17) +(1, 24) +(4, 7) +(20, 23) +(19, 22) +(16, 17) +(1, 15) +(18, 20) +(21, 23) +(10, 15) +(16, 18) +(14, 20) +(2, 23) +(7, 16) +(15, 24) +(1, 2) +(20, 25) +(14, 16) +(1, 6) +(7, 20) +(9, 24) +(14, 18) +(5, 9) +(2, 6) +(1, 4) +(4, 21) +(14, 25) +(1, 23) +(5, 11) +(9, 10) +(11, 16) +(9, 17) +(23, 24) +(10, 17) +(7, 11) +(0, 23) +(15, 24) +(9, 12) +(6, 24) +(15, 21) +(17, 19) +(4, 10) +(4, 22) +(20, 21) +(2, 15) +(7, 19) +(2, 3) +(15, 23) +(3, 6) +(0, 15) +(8, 23) +(2, 10) +(3, 4) +(6, 13) +(8, 15) +(0, 7) +(10, 21) +(2, 10) +(7, 24) +(12, 15) +(1, 15) +(8, 24) +(12, 19) +(1, 5) +(3, 19) +(7, 24) +(3, 18) +(8, 24) +(19, 21) +(5, 23) +(23, 25) +(5, 9) +(15, 24) +(8, 17) +(13, 17) +(9, 25) +(8, 11) +(0, 5) +(19, 23) +(15, 20) +(5, 9) +(6, 17) +(8, 13) +(1, 20) +(2, 6) +(10, 20) +(4, 8) +(14, 17) +(11, 20) +(8, 13) +(6, 24) +(4, 8) +(13, 25) +(2, 11) +(8, 14) +(4, 8) +(4, 22) +(8, 25) +(4, 15) +(3, 8) +(15, 18) +(4, 7) +(4, 16) +(12, 18) +(7, 19) +(15, 22) +(18, 22) +(6, 7) +(15, 17) +(4, 21) +(3, 12) +(5, 21) +(20, 22) +(3, 7) +(13, 17) +(16, 17) +(1, 22) +(7, 19) +(15, 20) +(10, 17) +(11, 15) +(2, 22) +(1, 2) +(4, 22) +(16, 17) +(11, 14) +(0, 15) +(3, 16) +(5, 11) +(21, 22) +(6, 14) +(0, 6) +(16, 17) +(3, 16) +(17, 20) +(9, 20) +(4, 17) +(9, 21) +(17, 24) +(4, 16) +(15, 24) +(17, 24) +(15, 23) +(8, 17) +(13, 23) +(11, 17) +(8, 16) +(4, 17) +(11, 13) +(8, 19) +(8, 10) +(11, 15) +(2, 17) +(19, 22) +(1, 22) +(19, 24) +(13, 17) +(2, 12) +(5, 13) +(6, 17) +(3, 12) +(2, 25) +(2, 10) +(11, 12) +(1, 6) +(5, 24) +(3, 16) +(11, 14) +(12, 22) +(8, 24) +(15, 16) +(9, 10) +(3, 21) +(6, 19) +(16, 23) +(15, 20) +(6, 17) +(11, 19) +(17, 22) +(9, 19) +(3, 11) +(6, 14) +(0, 17) +(19, 25) +(6, 10) +(11, 21) +(7, 14) +(4, 10) +(6, 9) +(13, 21) +(14, 16) +(3, 17) +(6, 24) +(7, 9) +(2, 16) +(20, 21) +(12, 14) +(11, 14) +(8, 20) +(9, 25) +(16, 22) +(2, 18) +(16, 20) +(6, 11) +(9, 21) +(16, 24) +(6, 12) +(6, 14) +(13, 24) +(16, 25) +(5, 12) +(14, 17) +(1, 13) +(10, 25) +(12, 23) +(6, 16) +(0, 10) +(3, 14) +(4, 16) +(22, 23) +(3, 7) +(2, 23) +(14, 20) +(16, 18) +(3, 24) +(6, 20) +(7, 12) +(17, 24) +(3, 8) +(6, 10) +(17, 19) +(11, 24) +(0, 6) +(10, 13) +(3, 20) +(9, 19) +(8, 20) +(0, 24) +(11, 16) +(17, 22) +(11, 15) +(12, 20) +(1, 22) +(3, 19) +(17, 22) +(1, 2) +(3, 13) +(1, 2) +(5, 22) +(3, 9) +(16, 17) +(4, 5) +(22, 24) +(1, 15) +(6, 22) +(0, 15) +(14, 24) +(3, 5) +(1, 13) +(8, 22) +(18, 24) +(3, 11) +(1, 16) +(17, 22) +(18, 19) +(7, 24) +(16, 23) +(0, 24) +(8, 16) +(13, 22) +(7, 19) +(9, 19) +(17, 22) +(13, 14) +(16, 23) +(24, 25) +(9, 18) +(12, 17) +(7, 14) +(21, 22) +(16, 19) +(2, 13) +(13, 24) +(1, 9) +(11, 14) +(7, 20) +(4, 24) +(11, 21) +(7, 23) +(1, 18) +(0, 20) +(14, 21) +(3, 20) +(11, 21) +(0, 3) +(12, 14) +(3, 22) +(12, 20) +(13, 21) +(10, 11) +(4, 14) +(4, 20) +(15, 21) +(3, 6) +(8, 13) +(0, 21) +(6, 22) +(1, 4) +(14, 15) +(3, 19) +(8, 9) +(0, 25) +(1, 24) +(9, 23) +(8, 15) +(2, 19) +(15, 20) +(0, 14) +(5, 23) +(3, 8) +(6, 19) +(9, 10) +(8, 9) +(6, 11) +(20, 24) +(10, 21) +(2, 23) +(10, 12) +(6, 13) +(1, 21) +(2, 14) +(17, 23) +(12, 13) +(18, 23) +(17, 25) +(0, 10) +(14, 24) +(6, 24) +(14, 16) +(5, 18) +(4, 10) +(9, 24) +(5, 12) +(6, 19) +(4, 18) +(10, 11) +(12, 17) +(3, 19) +(1, 18) +(4, 20) +(10, 23) +(6, 7) +(5, 17) +(10, 16) +(6, 22) +(1, 11) +(2, 12) +(12, 23) +(4, 17) +(2, 13) +(5, 8) +(5, 18) +(4, 7) +(11, 12) +(10, 13) +(0, 23) +(13, 15) +(1, 10) +(16, 23) +(5, 9) +(3, 7) +(1, 25) +(10, 20) +(15, 21) +(5, 6) +(2, 23) +(16, 18) +(9, 24) +(19, 21) +(2, 24) +(9, 20) +(12, 16) +(6, 25) +(0, 5) +(1, 14) +(18, 19) +(6, 8) +(7, 21) +(5, 14) +(13, 25) +(16, 23) +(0, 2) +(2, 8) +(1, 6) +(3, 14) +(5, 21) +(24, 25) +(12, 18) +(13, 17) +(12, 22) +(2, 16) +(14, 21) +(6, 9) +(8, 25) +(10, 17) +(8, 16) +(4, 6) +(10, 21) +(2, 5) +(14, 19) +(17, 18) +(0, 8) +(14, 22) +(16, 20) +(15, 19) +(3, 17) +(7, 18) +(7, 13) +(17, 23) +(15, 24) +(3, 22) +(18, 19) +(12, 13) +(4, 24) +(5, 23) +(19, 21) +(1, 17) +(12, 18) +(5, 14) +(15, 17) +(20, 23) +(8, 18) +(7, 17) +(14, 16) +(12, 15) +(18, 19) +(7, 25) +(11, 16) +(0, 15) +(1, 14) +(16, 21) +(17, 18) +(0, 11) +(13, 15) +(3, 15) +(0, 23) +(8, 23) +(0, 9) +(9, 11) +(0, 22) +(5, 8) +(1, 22) +(0, 23) +(6, 8) +(11, 14) +(14, 15) +(8, 20) +(1, 23) +(3, 22) +(3, 21) +(19, 23) +(8, 11) +(17, 20) +(6, 22) +(3, 16) +(6, 21) +(23, 25) +(4, 17) +(17, 25) +(6, 21) +(4, 15) +(11, 23) +(3, 9) +(6, 14) +(17, 21) +(3, 25) +(9, 23) +(5, 11) +(14, 18) +(4, 5) +(3, 10) +(9, 20) +(1, 23) +(6, 15) +(0, 25) +(2, 11) +(0, 7) +(15, 21) +(14, 19) +(4, 8) +(1, 2) +(22, 23) +(14, 20) +(4, 15) +(2, 9) +(16, 22) +(5, 23) +(0, 13) +(1, 3) +(6, 8) +(8, 19) +(5, 17) +(14, 23) +(6, 11) +(10, 14) +(2, 6) +(11, 21) +(5, 25) +(3, 17) +(8, 16) +(14, 20) +(6, 22) +(10, 17) +(16, 18) +(9, 11) +(7, 25) +(2, 24) +(1, 24) +(0, 10) +(18, 25) +(4, 9) +(14, 23) +(3, 22) +(2, 16) +(6, 15) +(11, 12) +(10, 23) +(3, 13) +(1, 15) +(6, 11) +(4, 8) +(0, 14) +(21, 25) +(3, 6) +(11, 16) +(23, 24) +(9, 25) +(2, 15) +(4, 18) +(7, 21) +(14, 25) +(6, 17) +(13, 15) +(11, 23) +(12, 25) +(2, 15) +(1, 14) +(14, 22) +(7, 12) +(1, 10) +(2, 3) +(13, 15) +(5, 15) +(4, 7) +(13, 18) +(1, 2) +(3, 25) +(7, 20) +(5, 6) +(4, 19) +(15, 22) +(11, 25) +(18, 20) +(8, 25) +(4, 24) +(9, 22) +(8, 16) +(9, 10) +(2, 20) +(24, 25) +(1, 22) +(7, 18) +(6, 10) +(4, 7) +(16, 22) +(12, 18) +(7, 24) +(11, 18) +(5, 12) +(8, 16) +(5, 21) +(15, 18) +(8, 9) +(6, 16) +(1, 11) +(7, 19) +(1, 6) +(18, 20) +(8, 21) +(15, 25) +(7, 17) +(1, 10) +(2, 20) +(12, 15) +(18, 24) +(23, 25) +(5, 23) +(15, 16) +(9, 24) +(16, 23) +(2, 24) +(14, 15) +(5, 7) +(5, 25) +(7, 17) +(4, 23) +(7, 22) +(4, 25) +(15, 23) +(14, 15) +(0, 7) +(19, 22) +(18, 25) +(4, 11) +(9, 23) +(15, 16) +(4, 18) +(8, 25) +(5, 23) +(3, 14) +(4, 24) +(11, 18) +(14, 17) +(1, 15) +(10, 25) +(5, 11) +(21, 25) +(6, 14) +(15, 19) +(8, 17) +(10, 17) +(7, 8) +(2, 15) +(6, 12) +(1, 5) +(0, 14) +(0, 22) +(17, 18) +(6, 13) +(7, 11) +(15, 16) +(3, 13) +(2, 15) +(0, 12) +(6, 9) +(1, 22) +(0, 18) +(4, 12) +(2, 5) +(15, 16) +(11, 13) +(1, 17) +(3, 20) +(4, 20) +(18, 22) +(5, 6) +(2, 8) +(11, 13) +(13, 14) +(1, 11) +(10, 18) +(4, 22) +(8, 12) +(1, 8) +(4, 9) +(14, 24) +(13, 15) +(3, 24) +(6, 15) +(9, 11) +(1, 5) +(13, 16) +(2, 13) +(4, 15) +(8, 16) +(4, 20) +(0, 13) +(2, 17) +(16, 19) +(13, 24) +(0, 22) +(2, 7) +(4, 14) +(5, 20) +(9, 17) +(0, 3) +(6, 17) +(10, 20) +(2, 8) +(14, 23) +(8, 20) +(2, 25) +(9, 23) +(6, 13) +(3, 24) +(10, 15) +(18, 20) +(22, 24) +(0, 10) +(4, 15) +(9, 25) +(1, 9) +(8, 22) +(2, 10) +(15, 17) +(14, 24) +(4, 12) +(7, 9) +(15, 20) +(4, 23) +(12, 16) +(16, 19) +(6, 20) +(7, 21) +(11, 12) +(8, 23) +(13, 15) +(4, 5) +(1, 4) +(10, 13) +(19, 25) +(9, 19) +(1, 3) +(4, 21) +(9, 17) +(1, 12) +(3, 22) +(12, 22) +(3, 15) +(1, 3) +(15, 23) +(23, 25) +(1, 2) +(3, 9) +(14, 25) +(2, 3) +(1, 15) +(16, 23) +(2, 20) +(8, 16) +(1, 4) +(13, 15) +(1, 5) +(15, 24) +(4, 23) +(10, 16) +(8, 21) +(8, 13) +(5, 19) +(4, 18) +(14, 21) +(10, 24) +(19, 23) +(17, 24) +(4, 6) +(5, 15) +(13, 20) +(4, 8) +(17, 18) +(2, 15) +(1, 19) +(5, 6) +(1, 12) +(4, 15) +(2, 11) +(7, 8) +(9, 19) +(5, 21) +(2, 25) +(8, 10) +(6, 7) +(5, 24) +(0, 12) +(16, 25) +(10, 21) +(2, 20) +(6, 8) +(7, 22) +(21, 24) +(5, 8) +(6, 19) +(4, 10) +(1, 22) +(16, 18) +(3, 8) +(12, 19) +(6, 24) +(5, 22) +(4, 7) +(1, 15) +(15, 23) +(8, 17) +(13, 19) +(6, 16) +(2, 23) +(14, 15) +(2, 9) +(14, 20) +(7, 23) +(2, 24) +(9, 21) +(13, 23) +(4, 20) +(7, 22) +(14, 25) +(4, 19) +(5, 9) +(6, 21) +(7, 20) +(10, 23) +(18, 25) +(1, 22) +(7, 21) +(13, 18) +(17, 22) +(1, 11) +(0, 5) +(15, 25) +(8, 17) +(23, 25) +(5, 12) +(3, 15) +(7, 17) +(3, 10) +(20, 25) +(6, 23) +(2, 15) +(8, 10) +(7, 18) +(2, 14) +(6, 11) +(2, 15) +(6, 19) +(11, 23) +(5, 8) +(4, 19) +(2, 14) +(5, 13) +(6, 8) +(0, 11) +(15, 16) +(14, 20) +(6, 10) +(0, 9) +(3, 16) +(2, 12) +(3, 11) +(14, 25) +(10, 13) +(1, 2) +(12, 21) +(6, 14) +(23, 25) +(0, 12) +(23, 24) +(15, 25) +(0, 2) +(4, 14) +(14, 16) +(4, 17) +(20, 25) +(8, 23) +(7, 15) +(7, 12) +(6, 23) +(8, 19) +(21, 23) +(5, 6) +(8, 18) +(19, 21) +(14, 18) +(22, 23) +(5, 15) +(12, 19) +(13, 22) +(8, 21) +(11, 18) +(5, 8) +(13, 23) +(18, 25) +(7, 22) +(4, 23) +(13, 15) +(21, 22) +(15, 16) +(13, 18) +(4, 11) +(15, 19) +(0, 16) +(15, 17) +(10, 16) +(6, 19) +(1, 10) +(2, 17) +(18, 19) +(6, 7) +(3, 15) +(2, 11) +(7, 12) +(13, 18) +(8, 17) +(15, 23) +(5, 10) +(6, 22) +(3, 14) +(18, 19) +(8, 17) +(5, 15) +(11, 22) +(8, 17) +(2, 19) +(15, 21) +(8, 10) +(1, 17) +(2, 14) +(10, 15) +(8, 22) +(13, 17) +(2, 3) +(3, 4) +(17, 24) +(5, 10) +(15, 25) +(9, 13) +(16, 17) +(20, 24) +(6, 9) +(7, 13) +(0, 25) +(7, 8) +(5, 16) +(0, 3) +(17, 19) +(6, 12) +(9, 12) +(8, 14) +(6, 24) +(2, 5) +(1, 7) +(17, 23) +(0, 23) +(7, 22) +(1, 6) +(9, 21) +(13, 14) +(8, 12) +(5, 16) +(4, 21) +(13, 19) +(8, 20) +(10, 12) +(9, 24) +(2, 5) +(1, 8) +(4, 10) +(15, 24) +(9, 18) +(11, 20) +(16, 21) +(5, 22) +(5, 7) +(22, 25) +(20, 21) +(6, 11) +(8, 10) +(14, 18) +(2, 11) +(3, 5) +(16, 25) +(13, 14) +(10, 25) +(2, 6) +(3, 4) +(11, 24) +(21, 24) +(5, 6) +(1, 2) +(5, 22) +(9, 24) +(2, 23) +(6, 17) +(1, 16) +(2, 14) +(21, 22) +(4, 9) +(1, 18) +(6, 19) +(5, 16) +(7, 24) +(0, 19) +(1, 2) +(13, 21) +(17, 22) +(14, 16) +(0, 3) +(17, 18) +(2, 6) +(20, 22) +(1, 8) +(16, 23) +(14, 21) +(9, 19) +(16, 25) +(0, 20) +(2, 15) +(9, 22) +(3, 17) +(19, 20) +(0, 3) +(9, 16) +(15, 22) +(2, 23) +(0, 1) +(12, 23) +(3, 5) +(13, 23) +(0, 5) +(3, 17) +(4, 12) +(1, 10) +(13, 14) +(6, 10) +(1, 4) +(4, 9) +(13, 19) +(1, 11) +(6, 15) +(14, 20) +(11, 24) +(7, 13) +(10, 14) +(15, 16) +(8, 19) +(6, 14) +(24, 25) +(11, 22) +(0, 22) +(1, 25) +(23, 24) +(11, 15) +(2, 6) +(0, 20) +(6, 10) +(1, 17) +(14, 15) +(9, 25) +(17, 24) +(9, 18) +(12, 20) +(3, 6) +(0, 16) +(1, 25) +(19, 20) +(3, 5) +(6, 21) +(9, 20) +(21, 22) +(6, 17) +(3, 11) +(5, 24) +(2, 19) +(20, 22) +(5, 6) +(8, 11) +(2, 7) +(15, 19) +(2, 24) +(5, 12) +(0, 11) +(6, 14) +(10, 15) +(0, 16) +(5, 7) +(14, 24) +(16, 19) +(0, 25) +(0, 18) +(16, 17) +(16, 25) +(17, 25) +(16, 19) +(18, 19) +(1, 17) +(24, 25) +(13, 16) +(15, 24) +(3, 16) +(17, 21) +(1, 9) +(0, 17) +(8, 24) +(2, 21) +(1, 15) +(10, 21) +(3, 17) +(9, 24) +(8, 22) +(9, 24) +(3, 15) +(16, 21) +(17, 18) +(8, 19) +(9, 17) +(12, 24) +(18, 23) +(18, 21) +(9, 20) +(16, 17) +(12, 15) +(13, 15) +(10, 20) +(0, 17) +(9, 14) +(14, 24) +(2, 13) +(6, 10) +(0, 3) +(20, 25) +(6, 17) +(7, 14) +(18, 25) +(19, 24) +(10, 22) +(11, 24) +(0, 22) +(16, 18) +(8, 19) +(15, 25) +(5, 6) +(12, 16) +(3, 5) +(4, 18) +(1, 6) +(14, 24) +(15, 20) +(2, 4) +(15, 18) +(13, 24) +(3, 22) +(2, 9) +(5, 24) +(13, 14) +(4, 19) +(18, 19) +(4, 8) +(9, 12) +(9, 22) +(3, 19) +(12, 23) +(4, 11) +(12, 24) +(10, 11) +(6, 23) +(10, 16) +(16, 21) +(10, 14) +(11, 16) +(20, 21) +(10, 20) +(8, 11) +(14, 21) +(15, 16) +(0, 16) +(14, 15) +(5, 10) +(8, 13) +(7, 11) +(13, 24) +(0, 20) +(2, 7) +(1, 11) +(0, 16) +(2, 18) +(5, 24) +(1, 6) +(7, 25) +(1, 17) +(16, 21) +(6, 8) +(5, 12) +(0, 11) +(19, 25) +(11, 24) +(6, 10) +(21, 22) +(12, 13) +(5, 11) +(12, 22) +(0, 24) +(13, 21) +(4, 10) +(2, 6) +(3, 6) +(18, 24) +(18, 23) +(6, 9) +(3, 19) +(11, 19) +(9, 16) +(6, 14) +(16, 24) +(2, 6) +(3, 14) +(9, 23) +(6, 7) +(9, 14) +(15, 16) +(2, 13) +(9, 24) +(13, 18) +(8, 16) +(4, 7) +(2, 10) +(0, 6) +(7, 21) +(1, 2) +(5, 18) +(13, 15) +(6, 20) +(0, 17) +(6, 15) +(1, 22) +(2, 16) +(3, 21) +(17, 19) +(14, 18) +(0, 4) +(0, 25) +(11, 16) +(18, 22) +(2, 19) +(12, 21) +(6, 20) +(8, 15) +(21, 25) +(9, 18) +(8, 13) +(0, 16) +(4, 20) +(5, 16) +(0, 19) +(13, 20) +(3, 21) +(12, 25) +(9, 24) +(10, 12) +(11, 16) +(2, 3) +(14, 21) +(8, 25) +(1, 20) +(9, 18) +(4, 25) +(21, 24) +(10, 23) +(11, 12) +(8, 17) +(17, 22) +(3, 8) +(2, 25) +(1, 21) +(10, 12) +(18, 23) +(7, 10) +(2, 3) +(18, 19) +(1, 25) +(16, 23) +(0, 22) +(4, 18) +(15, 19) +(0, 16) +(14, 22) +(3, 19) +(2, 14) +(14, 19) +(2, 13) +(14, 18) +(2, 21) +(19, 20) +(13, 15) +(4, 15) +(3, 21) +(2, 10) +(6, 19) +(11, 20) +(3, 13) +(15, 22) +(4, 20) +(0, 21) +(1, 22) +(21, 24) +(11, 15) +(4, 5) +(3, 16) +(9, 11) +(3, 19) +(5, 21) +(4, 12) +(8, 15) +(8, 11) +(3, 15) +(4, 25) +(2, 21) +(6, 8) +(12, 21) +(1, 25) +(13, 21) +(12, 23) +(18, 23) +(5, 13) +(4, 18) +(5, 21) +(12, 13) +(2, 23) +(17, 18) +(12, 20) +(3, 4) +(0, 2) +(21, 24) +(5, 19) +(15, 18) +(0, 17) +(6, 20) +(14, 24) +(2, 5) +(10, 20) +(0, 1) +(8, 14) +(15, 16) +(2, 9) +(5, 25) +(19, 24) +(12, 18) +(11, 17) +(7, 16) +(0, 5) +(1, 3) +(11, 25) +(4, 25) +(15, 16) +(7, 22) +(11, 20) +(15, 22) +(7, 12) +(0, 4) +(16, 17) +(12, 24) +(8, 17) +(7, 23) +(13, 16) +(3, 22) +(15, 25) +(12, 14) +(5, 8) +(22, 23) +(2, 16) +(9, 17) +(11, 12) +(16, 21) +(8, 10) +(16, 18) +(1, 8) +(10, 18) +(16, 19) +(1, 17) +(17, 25) +(0, 16) +(5, 18) +(13, 19) +(6, 18) +(3, 5) +(0, 15) +(2, 6) +(18, 24) +(2, 4) +(20, 24) +(2, 16) +(8, 20) +(10, 24) +(4, 20) +(2, 22) +(19, 24) +(8, 9) +(2, 9) +(13, 19) +(10, 24) +(13, 18) +(14, 19) +(2, 12) +(13, 20) +(18, 23) +(14, 22) +(9, 18) +(21, 23) +(6, 22) +(4, 20) +(18, 24) +(20, 21) +(4, 11) +(9, 20) +(3, 4) +(14, 24) +(11, 13) +(11, 22) +(9, 21) +(4, 25) +(3, 12) +(8, 20) +(9, 23) +(2, 25) +(3, 13) +(0, 8) +(22, 25) +(8, 16) +(2, 19) +(0, 15) +(10, 22) +(8, 13) +(6, 16) +(0, 21) +(16, 19) +(8, 11) +(6, 17) +(2, 8) +(4, 6) +(4, 8) +(6, 21) +(6, 16) +(4, 9) +(13, 21) +(1, 13) +(9, 14) +(6, 19) +(12, 16) +(3, 21) +(2, 12) +(6, 18) +(0, 14) +(7, 13) +(10, 14) +(0, 16) +(18, 23) +(8, 23) +(0, 3) +(16, 24) +(10, 16) +(8, 9) +(17, 23) +(1, 17) +(8, 25) +(2, 9) +(1, 11) +(2, 14) +(5, 9) +(8, 20) +(5, 6) +(14, 24) +(9, 19) +(11, 16) +(12, 20) +(8, 14) +(11, 22) +(10, 20) +(24, 25) +(6, 19) +(3, 5) +(3, 17) +(14, 20) +(5, 23) +(15, 24) +(16, 25) +(5, 21) +(3, 13) +(12, 15) +(19, 23) +(9, 24) +(22, 25) +(15, 18) +(5, 8) +(16, 21) +(9, 12) +(2, 21) +(7, 15) +(12, 20) +(0, 8) +(0, 1) +(8, 20) +(3, 15) +(7, 14) +(12, 19) +(7, 25) +(18, 19) +(2, 12) +(8, 14) +(3, 10) +(1, 12) +(5, 10) +(14, 23) +(24, 25) +(3, 9) +(12, 23) +(5, 13) +(9, 17) +(3, 25) +(9, 11) +(0, 25) +(8, 13) +(17, 20) +(9, 16) +(14, 17) +(20, 24) +(5, 16) +(20, 21) +(4, 9) +(9, 18) +(4, 13) +(1, 5) +(10, 16) +(2, 18) +(3, 5) +(16, 22) +(4, 23) +(2, 14) +(4, 23) +(11, 22) +(5, 6) +(16, 17) +(5, 17) +(2, 6) +(8, 16) +(9, 22) +(4, 5) +(16, 22) +(1, 9) +(19, 22) +(1, 15) +(10, 19) +(3, 22) +(7, 15) +(1, 14) +(3, 11) +(19, 24) +(1, 6) +(10, 16) +(12, 22) +(4, 19) +(3, 20) +(16, 23) +(11, 23) +(3, 13) +(16, 17) +(6, 13) +(3, 10) +(1, 23) +(12, 16) +(17, 18) +(9, 23) +(16, 24) +(0, 17) +(12, 25) +(6, 21) +(8, 18) +(2, 18) +(13, 25) +(5, 9) +(10, 23) +(12, 14) +(17, 20) +(6, 20) +(12, 15) +(1, 17) +(0, 15) +(6, 10) +(3, 20) +(4, 6) +(3, 12) +(11, 20) +(0, 19) +(8, 19) +(16, 20) +(3, 22) +(11, 12) +(6, 9) +(6, 23) +(4, 8) +(7, 19) +(5, 9) +(9, 10) +(8, 15) +(4, 17) +(0, 7) +(5, 11) +(0, 17) +(2, 11) +(4, 20) +(6, 9) +(11, 21) +(9, 10) +(6, 12) +(6, 16) +(8, 9) +(3, 10) +(3, 23) +(6, 22) +(0, 16) +(0, 7) +(12, 16) +(3, 9) +(7, 24) +(0, 19) +(15, 19) +(7, 8) +(22, 24) +(0, 24) +(19, 25) +(15, 23) +(3, 8) +(3, 13) +(10, 23) +(0, 25) +(9, 13) +(3, 11) +(6, 25) +(19, 23) +(16, 19) +(0, 25) +(11, 24) +(13, 21) +(10, 23) +(9, 15) +(3, 21) +(14, 15) +(3, 20) +(13, 21) +(14, 15) +(8, 13) +(14, 15) +(3, 25) +(21, 24) +(13, 24) +(4, 21) +(10, 15) +(8, 16) +(11, 14) +(6, 25) +(14, 20) +(5, 15) +(9, 11) +(12, 15) +(4, 9) +(11, 14) +(5, 16) +(0, 20) +(15, 22) +(8, 11) +(14, 20) +(3, 4) +(0, 23) +(2, 9) +(18, 20) +(4, 10) +(3, 25) +(14, 16) +(0, 24) +(1, 22) +(8, 19) +(2, 21) +(12, 19) +(7, 16) +(10, 17) +(4, 5) +(8, 25) +(9, 24) +(2, 21) +(12, 20) +(3, 4) +(15, 19) +(11, 21) +(4, 6) +(11, 14) +(12, 15) +(4, 25) +(3, 15) +(11, 21) +(5, 6) +(21, 22) +(0, 4) +(11, 14) +(6, 20) +(10, 14) +(1, 6) +(0, 2) +(11, 18) +(4, 23) +(22, 25) +(8, 21) +(3, 6) +(7, 10) +(17, 23) +(2, 15) +(12, 18) +(11, 16) +(9, 21) +(17, 25) +(11, 14) +(5, 23) +(18, 22) +(6, 19) +(4, 19) +(6, 15) +(14, 20) +(16, 23) +(0, 25) +(4, 13) +(5, 14) +(15, 22) +(0, 8) +(18, 19) +(4, 11) +(22, 25) +(12, 19) +(14, 18) +(16, 22) +(6, 25) +(15, 19) +(2, 18) +(19, 21) +(4, 6) +(15, 17) +(4, 12) +(11, 19) +(3, 17) +(14, 21) +(2, 15) +(15, 24) +(3, 9) +(13, 17) +(12, 21) +(2, 19) +(2, 14) +(5, 12) +(13, 18) +(6, 9) +(6, 8) +(13, 24) +(2, 3) +(18, 20) +(9, 24) +(8, 15) +(2, 7) +(6, 24) +(7, 25) +(8, 17) +(9, 11) +(1, 8) +(11, 16) +(14, 17) +(7, 10) +(6, 13) +(10, 11) +(8, 22) +(5, 13) +(17, 23) +(1, 24) +(8, 15) +(13, 16) +(14, 24) +(21, 22) +(17, 21) +(22, 23) +(16, 20) +(10, 15) +(23, 25) +(4, 21) +(13, 17) +(0, 22) +(9, 20) +(11, 16) +(13, 20) +(6, 9) +(3, 23) +(8, 16) +(0, 3) +(2, 9) +(22, 23) +(16, 19) +(1, 19) +(5, 16) +(3, 8) +(2, 6) +(12, 22) +(14, 23) +(8, 14) +(22, 25) +(17, 23) +(15, 16) +(1, 6) +(8, 20) +(0, 15) +(5, 16) +(14, 22) +(3, 25) +(9, 15) +(12, 25) +(14, 21) +(13, 20) +(0, 18) +(7, 15) +(20, 25) +(13, 24) +(17, 21) +(18, 20) +(3, 13) +(9, 21) +(14, 24) +(12, 25) +(10, 25) +(13, 22) +(3, 17) +(1, 24) +(7, 20) +(14, 23) +(12, 16) +(1, 13) +(12, 23) +(2, 3) +(6, 14) +(1, 15) +(2, 19) +(6, 20) +(12, 16) +(23, 24) +(2, 22) +(20, 23) +(16, 25) +(11, 19) +(13, 25) +(7, 16) +(0, 11) +(19, 23) +(14, 22) +(3, 22) +(17, 23) +(7, 24) +(12, 16) +(11, 14) +(5, 7) +(8, 12) +(4, 17) +(12, 23) +(4, 25) +(1, 7) +(8, 9) +(21, 23) +(2, 12) +(9, 19) +(8, 16) +(4, 13) +(15, 19) +(3, 4) +(11, 13) +(2, 5) +(15, 18) +(4, 20) +(13, 22) +(1, 19) +(3, 14) +(0, 5) +(22, 24) +(15, 17) +(14, 16) +(3, 11) +(24, 25) +(13, 14) +(10, 22) +(2, 15) +(12, 17) +(23, 25) +(1, 15) +(11, 14) +(8, 22) +(24, 25) +(0, 11) +(9, 14) +(15, 19) +(8, 16) +(2, 9) +(8, 19) +(1, 11) +(0, 13) +(9, 20) +(1, 4) +(2, 22) +(0, 10) +(0, 15) +(3, 9) +(4, 13) +(19, 20) +(10, 12) +(14, 15) +(5, 13) +(6, 12) +(10, 17) +(0, 21) +(3, 7) +(10, 14) +(6, 9) +(0, 13) +(15, 22) +(2, 3) +(1, 5) +(7, 16) +(3, 11) +(9, 14) +(0, 8) +(1, 12) +(5, 13) +(2, 10) +(4, 7) +(11, 20) +(6, 10) +(12, 22) +(3, 7) +(2, 21) +(5, 24) +(14, 19) +(4, 19) +(10, 13) +(3, 14) +(9, 11) +(18, 21) +(2, 17) +(0, 13) +(19, 20) +(12, 21) +(1, 4) +(2, 15) +(2, 16) +(20, 21) +(5, 19) +(13, 15) +(0, 14) +(12, 25) +(4, 25) +(9, 15) +(2, 6) +(5, 18) +(16, 19) +(3, 16) +(12, 19) +(4, 7) +(6, 10) +(10, 22) +(19, 21) +(16, 24) +(6, 20) +(10, 11) +(23, 24) +(9, 22) +(12, 20) +(2, 24) +(5, 9) +(10, 16) +(6, 22) +(11, 15) +(10, 20) +(8, 15) +(6, 22) +(1, 16) +(15, 22) +(16, 21) +(10, 13) +(8, 23) +(13, 15) +(17, 22) +(8, 25) +(3, 10) +(9, 15) +(23, 25) +(0, 8) +(6, 9) +(4, 8) +(20, 23) +(8, 11) +(2, 4) +(8, 22) +(11, 19) +(4, 25) +(5, 11) +(6, 8) +(2, 4) +(14, 19) +(5, 17) +(4, 21) +(11, 13) +(14, 22) +(18, 21) +(2, 5) +(1, 4) +(14, 23) +(16, 17) +(4, 21) +(2, 24) +(13, 18) +(1, 9) +(3, 17) +(5, 8) +(7, 16) +(17, 24) +(1, 7) +(18, 20) +(3, 22) +(3, 13) +(14, 22) +(24, 25) +(18, 21) +(4, 22) +(14, 15) +(23, 24) +(2, 25) +(18, 19) +(4, 23) +(12, 25) +(6, 24) +(2, 3) +(11, 23) +(10, 24) +(4, 8) +(20, 25) +(9, 25) +(3, 24) +(10, 16) +(6, 23) +(1, 20) +(7, 11) +(2, 8) +(4, 20) +(12, 24) +(11, 18) +(0, 7) +(13, 25) +(3, 15) +(10, 23) +(6, 18) +(2, 23) +(3, 14) +(16, 24) +(0, 5) +(7, 19) +(4, 8) +(1, 18) +(4, 15) +(7, 12) +(8, 13) +(11, 19) +(8, 23) +(7, 17) +(0, 11) +(5, 19) +(2, 15) +(4, 13) +(11, 19) +(13, 15) +(1, 17) +(7, 12) +(0, 6) +(5, 9) +(5, 21) +(13, 15) +(9, 25) +(1, 24) +(10, 19) +(1, 24) +(10, 22) +(3, 25) +(5, 7) +(5, 25) +(1, 20) +(12, 22) +(10, 18) +(12, 24) +(14, 22) +(10, 11) +(20, 21) +(11, 19) +(6, 20) +(4, 21) +(2, 24) +(15, 22) +(1, 10) +(7, 22) +(21, 24) +(12, 20) +(10, 17) +(10, 18) +(16, 20) +(22, 23) +(13, 17) +(12, 14) +(4, 7) +(10, 15) +(18, 21) +(5, 7) +(14, 24) +(0, 16) +(11, 12) +(16, 17) +(12, 20) +(13, 21) +(9, 24) +(6, 10) +(5, 14) +(17, 22) +(12, 15) +(9, 23) +(14, 25) +(10, 16) +(0, 16) +(8, 22) +(3, 23) +(1, 25) +(6, 10) +(3, 19) +(8, 11) +(6, 9) +(6, 19) +(8, 22) +(7, 11) +(5, 22) +(2, 11) +(7, 13) +(12, 19) +(8, 20) +(8, 17) +(7, 15) +(1, 20) +(18, 20) +(9, 15) +(17, 25) +(1, 20) +(24, 25) +(9, 10) +(15, 23) +(10, 17) +(3, 25) +(5, 23) +(9, 16) +(12, 15) +(1, 4) +(3, 7) +(4, 22) +(17, 21) +(13, 25) +(0, 9) +(8, 15) +(9, 10) +(3, 19) +(0, 21) +(13, 22) +(7, 13) +(21, 25) +(12, 22) +(7, 20) +(2, 13) +(5, 12) +(12, 22) +(8, 20) +(2, 18) +(13, 14) +(15, 18) +(1, 2) +(8, 21) +(12, 16) +(13, 22) +(7, 20) +(2, 4) +(22, 24) +(0, 20) +(1, 9) +(16, 23) +(1, 14) +(9, 17) +(15, 22) +(4, 5) +(6, 23) +(5, 7) +(1, 18) +(4, 9) +(11, 17) +(0, 6) +(4, 10) +(7, 18) +(9, 13) +(0, 23) +(5, 14) +(14, 17) +(5, 11) +(6, 7) +(13, 19) +(0, 2) +(10, 14) +(19, 21) +(4, 6) +(0, 8) +(13, 16) +(5, 17) +(6, 9) +(13, 18) +(5, 11) +(2, 16) +(1, 4) +(9, 20) +(6, 13) +(5, 7) +(3, 11) +(4, 10) +(18, 22) +(4, 9) +(6, 21) +(2, 5) +(7, 14) +(1, 20) +(3, 15) +(6, 22) +(7, 13) +(9, 20) +(4, 14) +(12, 15) +(6, 19) +(20, 22) +(7, 18) +(10, 12) +(13, 21) +(10, 15) +(11, 18) +(12, 24) +(7, 20) +(3, 24) +(15, 23) +(18, 25) +(2, 11) +(6, 23) +(12, 15) +(2, 13) +(8, 11) +(4, 24) +(1, 11) +(24, 25) +(12, 23) +(8, 9) +(3, 13) +(2, 5) +(8, 18) +(0, 25) +(9, 15) +(23, 24) +(5, 22) +(2, 12) +(1, 17) +(9, 25) +(0, 11) +(17, 21) +(12, 22) +(7, 18) +(5, 20) +(16, 18) +(13, 20) +(1, 7) +(12, 15) +(0, 14) +(4, 21) +(17, 21) +(4, 8) +(0, 11) +(1, 5) +(2, 21) +(0, 14) +(4, 18) +(17, 19) +(4, 20) +(6, 17) +(18, 25) +(14, 16) +(3, 19) +(13, 16) +(9, 25) +(0, 14) +(15, 18) +(0, 2) +(11, 25) +(13, 21) +(9, 21) +(12, 25) +(0, 24) +(8, 13) +(11, 22) +(10, 25) +(1, 12) +(8, 17) +(16, 22) +(15, 24) +(11, 15) +(8, 21) +(16, 23) +(1, 9) +(10, 19) +(8, 17) +(10, 25) +(18, 19) +(13, 23) +(21, 23) +(14, 17) +(1, 8) +(0, 25) +(10, 16) +(3, 18) +(16, 22) +(14, 24) +(3, 4) +(18, 25) +(3, 7) +(0, 4) +(11, 16) +(17, 25) +(15, 18) +(13, 16) +(0, 25) +(4, 22) +(5, 15) +(3, 23) +(4, 21) +(0, 17) +(2, 13) +(16, 19) +(5, 25) +(6, 17) +(13, 18) +(3, 16) +(0, 25) +(12, 21) +(2, 22) +(0, 10) +(12, 23) +(8, 22) +(15, 21) +(2, 25) +(12, 20) +(9, 10) +(2, 8) +(0, 24) +(4, 21) +(4, 13) +(1, 10) +(17, 24) +(7, 20) +(12, 14) +(9, 19) +(4, 7) +(9, 22) +(10, 11) +(20, 23) +(14, 17) +(23, 24) +(11, 12) +(17, 18) +(6, 14) +(10, 20) +(12, 22) +(2, 10) +(1, 20) +(24, 25) +(4, 23) +(14, 17) +(3, 20) +(0, 4) +(5, 24) +(6, 22) +(12, 25) +(4, 11) +(12, 23) +(6, 14) +(9, 22) +(1, 25) +(0, 16) +(5, 18) +(14, 15) +(1, 5) +(12, 17) +(16, 22) +(6, 7) +(18, 21) +(7, 10) +(18, 20) +(14, 24) +(18, 23) +(4, 10) +(3, 14) +(5, 24) +(1, 20) +(1, 17) +(0, 23) +(3, 16) +(13, 24) +(8, 10) +(3, 22) +(6, 16) +(18, 23) +(7, 8) +(17, 23) +(5, 7) +(8, 24) +(18, 25) +(3, 22) +(21, 23) +(3, 16) +(11, 25) +(4, 25) +(11, 19) +(0, 16) +(2, 25) +(11, 20) +(9, 19) +(20, 22) +(17, 19) +(23, 25) +(11, 18) +(1, 18) +(9, 20) +(4, 19) +(15, 22) +(17, 24) +(11, 16) +(18, 19) +(10, 11) +(1, 14) +(4, 21) +(5, 20) +(6, 15) +(8, 24) +(11, 23) +(0, 14) +(2, 10) +(17, 18) +(0, 10) +(5, 18) +(13, 17) +(11, 21) +(21, 22) +(0, 2) +(15, 18) +(5, 24) +(9, 18) +(24, 25) +(11, 21) +(8, 15) +(10, 22) +(2, 16) +(5, 14) +(15, 24) +(11, 14) +(13, 21) +(7, 9) +(17, 18) +(4, 8) +(6, 8) +(11, 23) +(1, 15) +(9, 20) +(7, 12) +(15, 16) +(9, 24) +(8, 25) +(12, 17) +(19, 20) +(2, 7) +(2, 19) +(1, 7) +(12, 21) +(16, 20) +(3, 9) +(5, 15) +(10, 20) +(9, 11) +(17, 21) +(15, 18) +(0, 7) +(10, 13) +(1, 20) +(9, 17) +(7, 12) +(3, 11) +(6, 21) +(12, 15) +(5, 20) +(10, 25) +(4, 9) +(0, 13) +(12, 18) +(13, 22) +(10, 23) +(1, 5) +(14, 25) +(4, 10) +(8, 13) +(21, 22) +(12, 24) +(3, 14) +(7, 8) +(6, 13) +(4, 9) +(12, 18) +(1, 3) +(8, 11) +(3, 19) +(4, 10) +(12, 24) +(13, 16) +(8, 20) +(9, 10) +(24, 25) +(6, 16) +(18, 19) +(10, 11) +(15, 25) +(9, 23) +(18, 20) +(6, 14) +(12, 16) +(8, 24) +(10, 23) +(13, 18) +(5, 11) +(17, 24) +(6, 21) +(4, 25) +(7, 15) +(7, 8) +(3, 17) +(11, 21) +(18, 23) +(13, 16) +(5, 20) +(4, 15) +(5, 23) +(1, 11) +(8, 24) +(9, 13) +(4, 19) +(15, 18) +(0, 21) +(7, 10) +(11, 24) +(6, 19) +(9, 25) +(5, 10) +(8, 14) +(21, 22) +(0, 22) +(7, 24) +(2, 9) +(3, 14) +(9, 18) +(2, 10) +(4, 22) +(7, 15) +(0, 17) +(4, 13) +(0, 23) +(12, 22) +(16, 18) +(3, 7) +(5, 18) +(6, 16) +(3, 24) +(7, 20) +(0, 17) +(8, 22) +(9, 22) +(0, 23) +(2, 20) +(8, 13) +(6, 17) +(10, 20) +(23, 25) +(0, 11) +(14, 17) +(6, 18) +(19, 23) +(0, 2) +(12, 17) +(1, 18) +(23, 25) +(2, 19) +(3, 18) +(1, 11) +(8, 17) +(1, 5) +(10, 23) +(11, 21) +(6, 17) +(7, 21) +(5, 16) +(1, 9) +(11, 15) +(2, 10) +(4, 7) +(15, 17) +(5, 25) +(11, 14) +(8, 10) +(11, 19) +(7, 9) +(20, 25) +(1, 7) +(0, 9) +(16, 20) +(1, 21) +(7, 20) +(4, 9) +(6, 16) +(7, 15) +(11, 20) +(8, 21) +(1, 6) +(9, 18) +(16, 25) +(8, 13) +(20, 22) +(7, 11) +(0, 6) +(4, 16) +(10, 15) +(16, 17) +(6, 19) +(2, 10) +(9, 22) +(15, 19) +(4, 16) +(15, 19) +(16, 17) +(4, 8) +(3, 8) +(4, 19) +(16, 23) +(6, 15) +(1, 3) +(5, 16) +(23, 24) +(3, 13) +(16, 18) +(12, 23) +(12, 24) +(1, 13) +(12, 17) +(0, 24) +(12, 14) +(0, 9) +(5, 24) +(12, 21) +(5, 20) +(14, 25) +(19, 24) +(20, 23) +(15, 24) +(17, 19) +(12, 16) +(18, 21) +(5, 16) +(4, 12) +(6, 18) +(20, 21) +(5, 21) +(4, 22) +(2, 16) +(1, 2) +(12, 16) +(5, 13) +(19, 21) +(10, 21) +(13, 19) +(5, 14) +(2, 4) +(16, 23) +(3, 16) +(0, 23) +(19, 20) +(13, 19) +(16, 22) +(20, 24) +(3, 6) +(4, 24) +(3, 21) +(7, 22) +(16, 23) +(6, 11) +(0, 13) +(13, 22) +(16, 18) +(3, 7) +(11, 20) +(2, 11) +(14, 22) +(12, 13) +(20, 21) +(3, 12) +(5, 20) +(11, 15) +(13, 14) +(2, 8) +(1, 8) +(3, 20) +(0, 15) +(13, 16) +(2, 19) +(10, 13) +(7, 19) +(6, 15) +(0, 25) +(11, 25) +(9, 15) +(6, 18) +(10, 16) +(4, 25) +(0, 15) +(10, 17) +(2, 16) +(7, 9) +(11, 13) +(16, 23) +(1, 15) +(10, 21) +(9, 12) +(0, 5) +(17, 19) +(13, 21) +(0, 25) +(3, 15) +(2, 19) +(16, 17) +(18, 21) +(19, 23) +(22, 25) +(0, 7) +(1, 15) +(18, 20) +(11, 25) +(17, 23) +(15, 19) +(1, 21) +(4, 19) +(10, 20) +(13, 23) +(1, 14) +(6, 21) +(4, 17) +(14, 25) +(21, 24) +(2, 24) +(5, 17) +(2, 25) +(3, 17) +(18, 24) +(4, 24) +(17, 21) +(0, 18) +(3, 22) +(10, 24) +(4, 11) +(1, 4) +(11, 20) +(0, 10) +(12, 20) +(0, 2) +(9, 11) +(8, 11) +(9, 25) +(6, 20) +(12, 24) +(8, 23) +(6, 13) +(7, 11) +(5, 8) +(7, 14) +(11, 13) +(7, 10) +(11, 17) +(1, 14) +(13, 20) +(1, 19) +(4, 20) +(13, 22) +(6, 13) +(4, 15) +(5, 22) +(15, 18) +(6, 8) +(13, 14) +(1, 4) +(20, 22) +(8, 25) +(7, 20) +(5, 22) +(13, 18) +(8, 10) +(2, 22) +(0, 5) +(13, 24) +(7, 14) +(5, 21) +(2, 7) +(15, 22) +(13, 17) +(5, 24) +(15, 23) +(18, 21) +(1, 2) +(11, 17) +(7, 8) +(5, 13) +(19, 23) +(21, 22) +(14, 15) +(10, 24) +(2, 25) +(12, 18) +(11, 14) +(0, 24) +(17, 21) +(4, 22) +(16, 18) +(6, 10) +(13, 20) +(5, 24) +(8, 17) +(1, 10) +(0, 9) +(13, 19) +(8, 23) +(0, 18) +(7, 9) +(3, 24) +(14, 17) +(8, 19) +(14, 20) +(7, 13) +(16, 17) +(8, 25) +(14, 21) +(16, 22) +(12, 13) +(3, 25) +(16, 21) +(8, 11) +(14, 24) +(2, 22) +(0, 25) +(13, 22) +(11, 19) +(6, 24) +(8, 16) +(8, 22) +(0, 18) +(9, 25) +(6, 15) +(20, 24) +(3, 19) +(12, 19) +(15, 24) +(0, 23) +(17, 23) +(0, 18) +(18, 23) +(1, 23) +(10, 18) +(0, 23) +(4, 18) +(0, 3) +(7, 23) +(5, 18) +(4, 13) +(3, 19) +(0, 1) +(14, 23) +(5, 16) +(13, 24) +(3, 21) +(0, 11) +(16, 18) +(23, 24) +(2, 5) +(6, 11) +(0, 19) +(5, 7) +(12, 16) +(4, 21) +(3, 18) +(2, 3) +(6, 13) +(4, 22) +(1, 7) +(11, 12) +(5, 9) +(0, 1) +(5, 14) +(11, 13) +(9, 20) +(20, 24) +(13, 25) +(7, 9) +(0, 10) +(14, 15) +(14, 16) +(0, 15) +(9, 19) +(21, 25) +(19, 21) +(12, 16) +(9, 17) +(0, 6) +(10, 15) +(6, 25) +(9, 22) +(2, 15) +(0, 24) +(3, 17) +(7, 10) +(12, 14) +(1, 10) +(3, 15) +(8, 9) +(22, 23) +(0, 14) +(11, 24) +(1, 4) +(11, 24) +(0, 14) +(14, 19) +(4, 25) +(18, 24) +(11, 24) +(4, 7) +(6, 19) +(5, 14) +(21, 25) +(14, 16) +(18, 24) +(6, 22) +(2, 5) +(0, 21) +(7, 15) +(17, 19) +(15, 25) +(1, 22) +(0, 16) +(4, 21) +(8, 18) +(13, 14) +(7, 17) +(0, 11) +(9, 16) +(4, 18) +(7, 10) +(3, 8) +(23, 25) +(5, 14) +(9, 18) +(3, 25) +(7, 17) +(8, 10) +(0, 24) +(14, 21) +(10, 23) +(9, 21) +(0, 1) +(3, 5) +(24, 25) +(6, 17) +(4, 24) +(3, 7) +(2, 17) +(21, 25) +(8, 10) +(5, 14) +(7, 23) +(4, 6) +(19, 24) +(12, 21) +(3, 15) +(0, 5) +(15, 24) +(4, 22) +(2, 3) +(5, 14) +(9, 12) +(6, 20) +(11, 23) +(19, 25) +(14, 21) +(3, 13) +(10, 12) +(2, 16) +(1, 4) +(5, 17) +(5, 10) +(21, 22) +(16, 20) +(1, 25) +(3, 8) +(6, 20) +(10, 21) +(5, 25) +(16, 20) +(9, 25) +(13, 25) +(7, 16) +(9, 10) +(4, 20) +(7, 18) +(2, 4) +(13, 24) +(15, 16) +(3, 10) +(4, 10) +(0, 18) +(11, 16) +(7, 14) +(15, 19) +(7, 23) +(8, 18) +(14, 17) +(11, 24) +(0, 3) +(22, 23) +(17, 25) +(6, 7) +(18, 21) +(19, 21) +(6, 15) +(10, 25) +(5, 22) +(7, 12) +(14, 18) +(14, 15) +(0, 5) +(9, 19) +(17, 18) +(16, 25) +(6, 21) +(6, 18) +(0, 7) +(12, 17) +(21, 25) +(14, 22) +(10, 15) +(2, 22) +(12, 13) +(4, 7) +(20, 25) +(10, 17) +(10, 12) +(4, 9) +(3, 13) +(7, 11) +(3, 23) +(11, 13) +(6, 7) +(6, 10) +(22, 23) +(12, 13) +(3, 19) +(5, 7) +(10, 14) +(7, 9) +(6, 24) +(17, 19) +(11, 23) +(5, 21) +(2, 19) +(11, 15) +(6, 25) +(3, 14) +(10, 20) +(19, 23) +(15, 16) +(1, 2) +(4, 6) +(11, 13) +(12, 20) +(6, 25) +(12, 22) +(0, 1) +(2, 18) +(3, 15) +(6, 14) +(1, 18) +(0, 8) +(2, 13) +(15, 17) +(8, 24) +(1, 19) +(13, 23) +(2, 20) +(0, 3) +(5, 6) +(17, 22) +(9, 18) +(4, 15) +(9, 21) +(4, 7) +(13, 22) +(17, 23) +(14, 15) +(5, 8) +(3, 17) +(2, 14) +(17, 23) +(2, 18) +(2, 4) +(3, 17) +(12, 18) +(16, 18) +(3, 21) +(10, 17) +(18, 23) +(10, 14) +(13, 17) +(2, 16) +(0, 2) +(8, 18) +(17, 21) +(10, 15) +(14, 23) +(16, 22) +(21, 25) +(20, 23) +(5, 10) +(2, 11) +(0, 9) +(6, 15) +(6, 7) +(0, 8) +(2, 19) +(3, 20) +(9, 11) +(23, 24) +(19, 25) +(3, 22) +(21, 23) +(1, 11) +(8, 9) +(9, 18) +(5, 25) +(0, 19) +(1, 6) +(0, 8) +(18, 25) +(9, 20) +(8, 16) +(9, 21) +(12, 20) +(0, 4) +(20, 25) +(0, 1) +(15, 16) +(1, 22) +(21, 25) +(20, 23) +(14, 15) +(9, 25) +(13, 14) +(4, 23) +(18, 23) +(17, 25) +(14, 23) +(17, 24) +(2, 18) +(11, 14) +(9, 24) +(16, 23) +(2, 4) +(1, 18) +(1, 7) +(0, 23) +(16, 22) +(16, 25) +(0, 21) +(1, 19) +(7, 23) +(1, 3) +(16, 17) +(0, 18) +(5, 25) +(7, 9) +(4, 19) +(7, 23) +(12, 16) +(19, 20) +(18, 24) +(13, 17) +(1, 15) +(5, 9) +(4, 20) +(13, 25) +(5, 15) +(12, 22) +(18, 21) +(16, 24) +(12, 13) +(3, 25) +(1, 24) +(0, 4) +(14, 22) +(8, 14) +(3, 17) +(6, 24) +(1, 10) +(7, 12) +(4, 18) +(1, 9) +(0, 10) +(21, 24) +(4, 13) +(18, 23) +(6, 11) +(12, 15) +(6, 20) +(18, 22) +(2, 11) +(8, 13) +(0, 21) +(10, 20) +(8, 23) +(11, 21) +(2, 3) +(9, 10) +(3, 24) +(4, 24) +(10, 25) +(9, 17) +(2, 3) +(2, 16) +(17, 24) +(22, 25) +(9, 13) +(3, 7) +(0, 2) +(17, 21) +(9, 16) +(6, 7) +(1, 2) +(10, 21) +(0, 20) +(6, 11) +(0, 8) +(21, 24) +(6, 25) +(1, 8) +(0, 13) +(0, 2) +(11, 13) +(1, 3) +(8, 20) +(3, 21) +(5, 8) +(13, 22) +(7, 20) +(8, 23) +(13, 25) +(5, 20) +(13, 18) +(23, 24) +(5, 22) +(19, 25) +(3, 8) +(10, 22) +(3, 9) +(12, 25) +(6, 18) +(4, 8) +(17, 23) +(8, 11) +(10, 20) +(2, 25) +(21, 23) +(7, 21) +(2, 12) +(4, 8) +(7, 25) +(9, 21) +(8, 17) +(8, 15) +(14, 21) +(17, 24) +(7, 16) +(9, 19) +(11, 16) +(19, 25) +(5, 9) +(3, 17) +(20, 21) +(7, 25) +(11, 18) +(20, 23) +(14, 21) +(2, 9) +(13, 19) +(6, 11) +(15, 21) +(17, 25) +(4, 18) +(16, 23) +(19, 20) +(10, 19) +(12, 17) +(0, 20) +(8, 11) +(3, 16) +(15, 25) +(0, 9) +(14, 19) +(2, 15) +(5, 10) +(17, 22) +(3, 21) +(7, 19) +(10, 23) +(2, 6) +(6, 25) +(7, 24) +(2, 4) +(0, 19) +(18, 23) +(23, 24) +(6, 21) +(0, 15) +(2, 5) +(4, 11) +(9, 19) +(0, 20) +(2, 10) +(19, 25) +(22, 24) +(3, 11) +(8, 9) +(5, 17) +(13, 24) +(17, 23) +(14, 20) +(0, 16) +(3, 4) +(14, 22) +(3, 9) +(0, 7) +(12, 20) +(4, 21) +(2, 7) +(6, 14) +(16, 20) +(0, 15) +(22, 23) +(9, 11) +(6, 8) +(0, 25) +(7, 18) +(3, 11) +(9, 13) +(16, 24) +(15, 20) +(1, 24) +(5, 15) +(11, 20) +(19, 25) +(4, 6) +(14, 19) +(4, 21) +(2, 20) +(11, 18) +(8, 15) +(5, 9) +(17, 21) +(15, 20) +(2, 13) +(4, 12) +(10, 18) +(0, 8) +(0, 11) +(2, 14) +(20, 25) +(3, 15) +(10, 24) +(16, 17) +(13, 23) +(21, 25) +(0, 4) +(5, 23) +(14, 24) +(15, 18) +(12, 20) +(3, 20) +(8, 21) +(13, 24) +(12, 25) +(15, 19) +(8, 10) +(16, 21) +(15, 25) +(3, 19) +(1, 13) +(14, 20) +(10, 20) +(6, 21) +(1, 3) +(7, 19) +(13, 17) +(17, 20) +(9, 21) +(7, 22) +(2, 6) +(6, 24) +(18, 22) +(7, 8) +(2, 11) +(10, 17) +(8, 20) +(17, 24) +(6, 16) +(17, 21) +(16, 23) +(2, 20) +(15, 21) +(10, 23) +(16, 22) +(7, 17) +(6, 20) +(6, 9) +(15, 16) +(13, 20) +(8, 17) +(14, 23) +(7, 25) +(6, 15) +(12, 23) +(10, 14) +(11, 13) +(8, 16) +(19, 25) +(5, 23) +(12, 18) +(4, 15) +(14, 17) +(11, 13) +(7, 10) +(13, 20) +(4, 5) +(6, 23) +(7, 11) +(2, 12) +(1, 18) +(15, 18) +(22, 23) +(4, 13) +(3, 6) +(6, 9) +(8, 23) +(22, 25) +(9, 10) +(7, 23) +(10, 21) +(8, 23) +(7, 23) +(0, 10) +(3, 8) +(0, 13) +(20, 23) +(6, 7) +(3, 11) +(10, 16) +(7, 24) +(10, 15) +(12, 23) +(9, 11) +(6, 21) +(7, 22) +(19, 24) +(6, 16) +(1, 10) +(0, 21) +(8, 10) +(3, 22) +(1, 15) +(18, 21) +(5, 19) +(20, 24) +(20, 23) +(3, 18) +(2, 15) +(9, 10) +(1, 11) +(14, 24) +(0, 22) +(12, 24) +(4, 20) +(23, 25) +(17, 18) +(11, 25) +(4, 16) +(2, 25) +(13, 16) +(9, 16) +(6, 13) +(2, 20) +(6, 18) +(9, 12) +(4, 16) +(13, 17) +(0, 18) +(7, 16) +(5, 12) +(9, 16) +(5, 23) +(0, 6) +(8, 12) +(0, 11) +(12, 17) +(8, 12) +(17, 23) +(2, 8) +(5, 12) +(20, 23) +(8, 24) +(4, 5) +(12, 17) +(20, 25) +(17, 18) +(12, 22) +(8, 21) +(1, 20) +(12, 20) +(11, 17) +(1, 7) +(2, 18) +(16, 22) +(5, 8) +(13, 18) +(1, 21) +(22, 23) +(7, 17) +(8, 10) +(18, 25) +(13, 14) +(6, 21) +(9, 22) +(13, 24) +(11, 18) +(4, 14) +(9, 25) +(0, 24) +(11, 15) +(14, 23) +(9, 16) +(12, 13) +(4, 14) +(11, 12) +(7, 16) +(15, 18) +(16, 24) +(4, 15) +(5, 11) +(14, 23) +(12, 13) +(14, 23) +(15, 18) +(0, 12) +(5, 10) +(4, 11) +(16, 17) +(7, 11) +(5, 25) +(2, 14) +(16, 24) +(19, 23) +(0, 10) +(4, 7) +(13, 14) +(0, 1) +(3, 23) +(19, 25) +(1, 21) +(18, 19) +(14, 22) +(0, 1) +(2, 14) +(12, 22) +(13, 14) +(2, 24) +(1, 21) +(17, 22) +(9, 24) +(4, 17) +(2, 10) +(8, 22) +(3, 14) +(10, 20) +(19, 22) +(2, 7) +(16, 24) +(13, 14) +(4, 23) +(4, 8) +(10, 14) +(5, 19) +(12, 13) +(15, 22) +(6, 7) +(6, 23) +(0, 12) +(19, 20) +(8, 11) +(15, 18) +(3, 5) +(11, 24) +(5, 20) +(8, 23) +(1, 3) +(6, 10) +(3, 22) +(1, 2) +(7, 8) +(0, 20) +(10, 21) +(3, 14) +(15, 20) +(18, 22) +(1, 5) +(2, 23) +(12, 18) +(1, 13) +(11, 20) +(5, 15) +(11, 17) +(0, 13) +(5, 16) +(4, 15) +(10, 17) +(16, 24) +(11, 20) +(5, 15) +(10, 14) +(8, 17) +(11, 25) +(5, 22) +(3, 11) +(17, 25) +(2, 3) +(11, 21) +(4, 17) +(11, 19) +(13, 21) +(3, 9) +(2, 10) +(1, 11) +(18, 19) +(7, 21) +(8, 19) +(18, 19) +(12, 19) +(13, 19) +(12, 24) +(19, 25) +(13, 16) +(20, 24) +(3, 12) +(16, 18) +(15, 25) +(17, 24) +(15, 19) +(12, 18) +(22, 25) +(11, 15) +(2, 25) +(0, 12) +(19, 23) +(4, 18) +(18, 22) +(4, 10) +(6, 15) +(0, 23) +(9, 12) +(11, 17) +(2, 19) +(1, 15) +(6, 7) +(9, 14) +(8, 18) +(12, 18) +(3, 15) +(0, 1) +(6, 20) +(3, 11) +(1, 10) +(6, 24) +(15, 22) +(6, 16) +(1, 19) +(4, 15) +(24, 25) +(15, 22) +(5, 24) +(5, 7) +(2, 24) +(4, 5) +(17, 24) +(2, 10) +(7, 8) +(1, 24) +(4, 17) +(8, 23) +(7, 14) +(9, 24) +(4, 5) +(7, 14) +(11, 17) +(7, 15) +(14, 23) +(9, 13) +(0, 11) +(15, 22) +(3, 9) +(0, 18) +(8, 11) +(13, 21) +(6, 14) +(9, 12) +(10, 14) +(3, 22) +(7, 15) +(3, 7) +(17, 22) +(1, 12) +(5, 12) +(2, 17) +(3, 4) +(15, 22) +(1, 5) +(19, 22) +(10, 15) +(7, 12) +(10, 17) +(15, 24) +(12, 14) +(1, 6) +(9, 17) +(1, 16) +(15, 21) +(8, 10) +(9, 13) +(17, 21) +(1, 19) +(8, 12) +(19, 23) +(9, 24) +(8, 25) +(13, 15) +(3, 17) +(4, 17) +(0, 23) +(8, 20) +(16, 24) +(2, 9) +(3, 11) +(4, 21) +(10, 24) +(9, 18) +(13, 20) +(0, 12) +(6, 23) +(16, 24) +(0, 15) +(11, 23) +(6, 17) +(5, 6) +(14, 16) +(9, 23) +(4, 11) +(2, 24) +(8, 16) +(2, 19) +(3, 23) +(1, 14) +(10, 24) +(6, 12) +(6, 23) +(2, 22) +(1, 4) +(14, 16) +(5, 19) +(15, 19) +(4, 24) +(2, 11) +(21, 24) +(2, 25) +(9, 19) +(7, 11) +(5, 15) +(5, 6) +(7, 18) +(2, 20) +(14, 18) +(8, 20) +(12, 14) +(20, 22) +(8, 15) +(8, 18) +(13, 15) +(14, 23) +(10, 20) +(8, 13) +(20, 25) +(10, 17) +(8, 12) +(11, 17) +(10, 24) +(13, 14) +(7, 11) +(23, 24) +(10, 21) +(3, 17) +(3, 5) +(6, 24) +(1, 10) +(11, 22) +(18, 21) +(4, 17) +(8, 17) +(10, 16) +(5, 18) +(19, 22) +(6, 9) +(0, 10) +(14, 22) +(12, 18) +(2, 8) +(9, 15) +(4, 15) +(14, 21) +(0, 11) +(20, 22) +(3, 9) +(10, 13) +(17, 22) +(5, 9) +(11, 13) +(12, 20) +(3, 16) +(15, 25) +(1, 4) +(12, 18) +(11, 14) +(4, 7) +(16, 21) +(1, 23) +(1, 22) +(6, 16) +(11, 13) +(7, 19) +(2, 23) +(3, 18) +(12, 20) +(12, 15) +(1, 17) +(5, 22) +(3, 20) +(9, 18) +(0, 7) +(7, 10) +(1, 23) +(3, 19) +(0, 15) +(9, 14) +(4, 7) +(19, 23) +(3, 6) +(4, 24) +(20, 23) +(2, 7) +(2, 11) +(21, 24) +(7, 22) +(16, 23) +(17, 21) +(8, 24) +(11, 18) +(13, 18) +(7, 21) +(14, 17) +(0, 21) +(10, 17) +(6, 18) +(14, 19) +(5, 6) +(13, 18) +(21, 23) +(10, 24) +(7, 17) +(3, 10) +(18, 22) +(5, 9) +(1, 5) +(0, 10) +(9, 12) +(14, 22) +(9, 18) +(1, 22) +(12, 15) +(12, 13) +(2, 18) +(14, 15) +(9, 20) +(12, 16) +(1, 2) +(18, 24) +(8, 20) +(4, 9) +(14, 22) +(13, 25) +(9, 13) +(14, 21) +(6, 22) +(16, 17) +(5, 8) +(7, 12) +(0, 5) +(7, 15) +(22, 25) +(6, 12) +(17, 18) +(14, 20) +(14, 22) +(5, 8) +(6, 13) +(4, 12) +(0, 9) +(9, 10) +(5, 21) +(1, 13) +(0, 23) +(3, 22) +(8, 17) +(20, 23) +(5, 12) +(3, 7) +(11, 21) +(12, 25) +(3, 16) +(0, 5) +(11, 24) +(18, 21) +(5, 24) +(11, 25) +(18, 22) +(17, 21) +(8, 12) +(7, 25) +(16, 21) +(18, 19) +(4, 12) +(11, 15) +(8, 20) +(7, 11) +(8, 20) +(13, 18) +(12, 15) +(1, 21) +(4, 6) +(8, 12) +(19, 20) +(20, 22) +(6, 12) +(8, 24) +(19, 20) +(11, 22) +(3, 24) +(15, 24) +(17, 24) +(15, 16) +(23, 24) +(8, 16) +(3, 17) +(1, 15) +(5, 16) +(1, 7) +(2, 17) +(3, 22) +(8, 15) +(10, 16) +(0, 5) +(0, 4) +(8, 16) +(5, 25) +(5, 15) +(1, 8) +(13, 25) +(14, 16) +(13, 17) +(4, 14) +(0, 16) +(18, 25) +(1, 7) +(1, 2) +(0, 25) +(14, 18) +(15, 16) +(17, 22) +(5, 25) +(14, 18) +(2, 10) +(11, 18) +(10, 25) +(2, 19) +(19, 22) +(3, 18) +(2, 13) +(18, 19) +(3, 21) +(11, 21) +(3, 9) +(11, 15) +(20, 21) +(9, 23) +(9, 22) +(10, 11) +(5, 15) +(18, 21) +(0, 20) +(3, 9) +(4, 10) +(22, 24) +(5, 17) +(16, 24) +(2, 3) +(5, 15) +(12, 22) +(13, 22) +(3, 12) +(15, 18) +(2, 7) +(16, 17) +(13, 16) +(1, 15) +(6, 17) +(22, 24) +(18, 19) +(4, 18) +(13, 19) +(1, 7) +(10, 17) +(6, 10) +(3, 17) +(4, 15) +(8, 15) +(10, 20) +(4, 9) +(6, 8) +(9, 11) +(3, 4) +(8, 20) +(11, 12) +(3, 7) +(0, 4) +(4, 5) +(12, 25) +(7, 14) +(8, 9) +(0, 21) +(11, 25) +(1, 9) +(10, 14) +(6, 21) +(4, 12) +(2, 8) +(0, 16) +(7, 18) +(12, 18) +(10, 19) +(6, 16) +(11, 13) +(5, 7) +(14, 15) +(16, 23) +(7, 9) +(6, 19) +(3, 11) +(13, 20) +(6, 14) +(13, 23) +(16, 17) +(4, 14) +(3, 13) +(5, 6) +(2, 17) +(16, 22) +(10, 23) +(1, 13) +(8, 16) +(2, 18) +(16, 21) +(8, 12) +(1, 11) +(7, 13) +(5, 21) +(11, 17) +(3, 13) +(1, 20) +(0, 8) +(16, 22) +(12, 24) +(0, 23) +(10, 12) +(3, 25) +(18, 24) +(1, 22) +(14, 24) +(9, 12) +(6, 23) +(10, 15) +(5, 22) +(11, 15) +(7, 14) +(0, 24) +(2, 23) +(12, 13) +(13, 24) +(5, 15) +(7, 19) +(1, 11) +(14, 18) +(22, 23) +(7, 16) +(15, 21) +(5, 14) +(8, 18) +(10, 24) +(15, 23) +(16, 17) +(3, 8) +(10, 25) +(22, 24) +(0, 14) +(1, 18) +(6, 16) +(5, 8) +(15, 18) +(1, 13) +(17, 20) +(8, 23) +(14, 16) +(5, 19) +(6, 7) +(13, 24) +(0, 17) +(14, 21) +(4, 23) +(3, 19) +(0, 17) +(7, 22) +(12, 21) +(0, 16) +(17, 18) +(6, 22) +(9, 23) +(4, 14) +(18, 19) +(0, 8) +(5, 16) +(2, 4) +(1, 23) +(14, 24) +(9, 22) +(13, 24) +(0, 2) +(10, 16) +(9, 17) +(4, 11) +(5, 12) +(14, 24) +(7, 12) +(4, 22) +(16, 18) +(1, 5) +(8, 13) +(1, 14) +(9, 18) +(0, 8) +(5, 24) +(9, 16) +(3, 8) +(1, 7) +(5, 21) +(6, 21) +(3, 20) +(5, 23) +(14, 21) +(6, 7) +(13, 23) +(5, 25) +(5, 15) +(2, 14) +(11, 25) +(10, 21) +(7, 8) +(0, 15) +(14, 24) +(1, 2) +(5, 19) +(7, 8) +(6, 25) +(4, 19) +(2, 18) +(1, 11) +(15, 23) +(5, 22) +(9, 14) +(2, 14) +(19, 25) +(4, 12) +(10, 15) +(5, 7) +(1, 12) +(0, 25) +(5, 18) +(15, 22) +(4, 20) +(7, 8) +(2, 11) +(15, 25) +(1, 13) +(5, 24) +(8, 21) +(11, 13) +(1, 23) +(17, 21) +(8, 9) +(11, 16) +(6, 23) +(2, 17) +(1, 21) +(9, 10) +(13, 24) +(3, 6) +(4, 9) +(8, 23) +(14, 21) +(3, 24) +(8, 19) +(4, 12) +(10, 14) +(9, 22) +(6, 23) +(11, 19) +(3, 21) +(8, 25) +(7, 22) +(11, 23) +(6, 8) +(7, 19) +(3, 24) +(8, 17) +(3, 21) +(0, 11) +(6, 19) +(3, 24) +(9, 21) +(3, 5) +(13, 24) +(20, 21) +(5, 13) +(15, 24) +(20, 22) +(1, 5) +(13, 18) +(2, 24) +(9, 22) +(4, 22) +(5, 20) +(3, 9) +(5, 23) +(4, 11) +(3, 25) +(0, 25) +(3, 15) +(4, 9) +(7, 25) +(9, 10) +(0, 8) +(21, 25) +(1, 9) +(1, 4) +(3, 9) +(8, 25) +(12, 21) +(1, 5) +(19, 25) +(20, 21) +(4, 17) +(8, 15) +(15, 25) +(14, 21) +(10, 20) +(10, 16) +(9, 21) +(2, 20) +(3, 20) +(2, 7) +(2, 13) +(7, 22) +(3, 12) +(14, 22) +(12, 18) +(0, 3) +(0, 5) +(3, 13) +(2, 22) +(12, 20) +(2, 21) +(13, 14) +(7, 12) +(17, 20) +(15, 20) +(10, 17) +(7, 16) +(1, 14) +(12, 25) +(1, 7) +(2, 16) +(3, 10) +(8, 15) +(9, 20) +(7, 21) +(4, 10) +(6, 8) +(9, 19) +(15, 23) +(3, 11) +(17, 23) +(3, 25) +(9, 24) +(8, 13) +(13, 21) +(12, 17) +(0, 25) +(5, 24) +(3, 11) +(6, 23) +(4, 24) +(12, 20) +(1, 5) +(16, 25) +(10, 17) +(2, 10) +(8, 16) +(4, 9) +(19, 24) +(20, 22) +(0, 12) +(17, 24) +(7, 9) +(6, 8) +(2, 15) +(18, 20) +(5, 19) +(11, 18) +(15, 23) +(7, 14) +(9, 21) +(2, 4) +(5, 25) +(17, 19) +(10, 19) +(1, 25) +(5, 16) +(11, 20) +(5, 13) +(10, 17) +(18, 25) +(13, 14) +(5, 23) +(17, 22) +(21, 22) +(3, 5) +(7, 23) +(14, 19) +(15, 23) +(8, 19) +(7, 12) +(4, 15) +(8, 24) +(12, 14) +(9, 19) +(15, 17) +(19, 25) +(2, 14) +(12, 21) +(18, 24) +(5, 24) +(12, 18) +(2, 16) +(10, 21) +(6, 25) +(4, 14) +(9, 21) +(0, 4) +(10, 17) +(2, 15) +(22, 25) +(2, 23) +(4, 7) +(8, 25) +(1, 15) +(0, 18) +(9, 19) +(7, 13) +(9, 16) +(0, 21) +(1, 11) +(7, 8) +(11, 25) +(13, 21) +(8, 20) +(0, 21) +(6, 7) +(13, 21) +(4, 20) +(8, 24) +(6, 23) +(1, 13) +(9, 20) +(21, 25) +(4, 19) +(3, 24) +(9, 16) +(1, 7) +(13, 19) +(15, 24) +(11, 21) +(3, 12) +(5, 25) +(1, 17) +(19, 20) +(15, 25) +(3, 16) +(0, 9) +(6, 13) +(13, 15) +(7, 9) +(19, 23) +(8, 17) +(1, 24) +(2, 19) +(8, 16) +(7, 12) +(1, 16) +(7, 9) +(8, 10) +(16, 23) +(7, 12) +(7, 20) +(12, 21) +(4, 20) +(9, 12) +(13, 21) +(12, 22) +(4, 21) +(9, 13) +(9, 17) +(12, 14) +(6, 22) +(4, 16) +(22, 24) +(14, 21) +(5, 17) +(2, 12) +(6, 19) +(7, 24) +(11, 14) +(0, 12) +(6, 13) +(21, 22) +(4, 6) +(13, 25) +(20, 22) +(17, 24) +(0, 21) +(19, 22) +(3, 24) +(0, 2) +(6, 22) +(0, 18) +(2, 5) +(8, 19) +(5, 15) +(11, 18) +(1, 11) +(0, 5) +(2, 15) +(7, 11) +(1, 25) +(5, 18) +(7, 9) +(18, 21) +(1, 3) +(3, 25) +(7, 15) +(19, 21) +(9, 11) +(11, 14) +(9, 18) +(2, 25) +(5, 25) +(9, 14) +(2, 6) +(9, 15) +(2, 22) +(24, 25) +(12, 24) +(21, 25) +(6, 22) +(8, 24) +(9, 12) +(13, 21) +(2, 25) +(11, 22) +(11, 16) +(5, 25) +(13, 17) +(8, 10) +(2, 9) +(1, 21) +(23, 24) +(12, 20) +(13, 15) +(9, 14) +(17, 25) +(19, 24) +(1, 7) +(11, 24) +(1, 15) +(0, 19) +(17, 22) +(1, 11) +(22, 25) +(7, 19) +(0, 3) +(13, 25) +(4, 19) +(7, 15) +(5, 11) +(0, 23) +(5, 8) +(3, 11) +(2, 19) +(4, 16) +(7, 18) +(3, 9) +(4, 25) +(0, 11) +(19, 23) +(10, 23) +(4, 13) +(19, 20) +(11, 16) +(9, 15) +(2, 25) +(14, 20) +(21, 23) +(6, 16) +(10, 12) +(10, 16) +(14, 23) +(6, 22) +(17, 20) +(16, 24) +(11, 22) +(7, 23) +(14, 18) +(6, 15) +(1, 10) +(4, 11) +(16, 22) +(0, 1) +(10, 14) +(6, 19) +(15, 16) +(19, 25) +(1, 5) +(12, 22) +(2, 10) +(7, 12) +(6, 15) +(3, 25) +(10, 21) +(22, 25) +(10, 20) +(2, 21) +(2, 23) +(17, 21) +(10, 18) +(8, 25) +(3, 22) +(0, 25) +(9, 22) +(2, 12) +(8, 24) +(0, 14) +(5, 8) +(2, 11) +(9, 21) +(4, 24) +(2, 3) +(7, 24) +(1, 14) +(0, 19) +(4, 24) +(2, 14) +(3, 19) +(7, 16) +(13, 24) +(7, 10) +(4, 22) +(22, 23) +(13, 21) +(4, 9) +(10, 11) +(13, 19) +(20, 22) +(2, 11) +(5, 23) +(6, 10) +(11, 16) +(13, 25) +(2, 18) +(10, 24) +(5, 17) +(21, 22) +(14, 16) +(5, 19) +(6, 11) +(9, 21) +(5, 23) +(6, 15) +(12, 21) +(14, 17) +(19, 25) +(8, 16) +(14, 23) +(7, 8) +(5, 16) +(2, 15) +(3, 17) +(0, 3) +(1, 8) +(17, 19) +(7, 25) +(19, 24) +(7, 22) +(1, 15) +(16, 24) +(7, 20) +(8, 15) +(5, 19) +(8, 13) +(7, 23) +(10, 24) +(20, 22) +(8, 25) +(2, 20) +(7, 18) +(7, 23) +(1, 18) +(1, 10) +(4, 7) +(22, 23) +(11, 23) +(7, 18) +(4, 25) +(8, 22) +(9, 18) +(8, 10) +(21, 22) +(5, 7) +(6, 11) +(3, 7) +(11, 15) +(6, 13) +(13, 24) +(11, 14) +(4, 15) +(7, 20) +(6, 16) +(0, 14) +(6, 23) +(10, 16) +(2, 24) +(6, 8) +(0, 17) +(14, 25) +(11, 25) +(0, 20) +(14, 15) +(19, 20) +(3, 25) +(11, 21) +(12, 14) +(14, 23) +(3, 12) +(19, 24) +(0, 25) +(2, 12) +(3, 22) +(7, 12) +(3, 24) +(1, 22) +(1, 17) +(0, 22) +(7, 20) +(8, 24) +(12, 22) +(11, 20) +(8, 18) +(7, 10) +(0, 13) +(21, 22) +(16, 18) +(11, 24) +(0, 20) +(10, 19) +(2, 13) +(10, 15) +(12, 19) +(4, 22) +(21, 23) +(9, 20) +(1, 13) +(3, 16) +(6, 10) +(17, 20) +(16, 23) +(1, 24) +(11, 15) +(3, 19) +(22, 25) +(5, 17) +(21, 25) +(1, 11) +(7, 22) +(8, 24) +(2, 24) +(6, 22) +(9, 21) +(7, 8) +(2, 18) +(0, 22) +(15, 21) +(7, 25) +(2, 20) +(0, 19) +(22, 23) +(11, 15) +(18, 19) +(2, 10) +(3, 20) +(16, 23) +(17, 22) +(3, 25) +(6, 16) +(2, 7) +(9, 10) +(4, 25) +(6, 23) +(7, 8) +(9, 15) +(1, 16) +(5, 8) +(9, 17) +(3, 7) +(14, 23) +(13, 25) +(6, 21) +(9, 14) +(0, 6) +(5, 12) +(8, 10) +(4, 13) +(14, 24) +(8, 16) +(4, 25) +(10, 17) +(13, 20) +(3, 4) +(20, 22) +(17, 21) +(8, 16) +(9, 24) +(3, 7) +(12, 24) +(4, 21) +(9, 18) +(14, 21) +(10, 12) +(4, 23) +(12, 19) +(7, 21) +(2, 23) +(4, 17) +(1, 14) +(7, 20) +(9, 17) +(16, 19) +(2, 14) +(1, 24) +(14, 25) +(15, 24) +(4, 19) +(1, 23) +(16, 20) +(17, 23) +(19, 20) +(8, 24) +(12, 15) +(1, 3) +(2, 15) +(0, 1) +(6, 8) +(3, 11) +(19, 24) +(7, 23) +(12, 13) +(6, 18) +(8, 20) +(22, 24) +(4, 13) +(1, 13) +(21, 24) +(2, 20) +(8, 15) +(3, 18) +(12, 22) +(2, 10) +(1, 8) +(6, 22) +(0, 3) +(16, 20) +(7, 15) +(1, 7) +(18, 22) +(5, 10) +(6, 12) +(3, 13) +(9, 20) +(10, 15) +(8, 22) +(2, 12) +(6, 16) +(13, 21) +(9, 22) +(0, 12) +(4, 13) +(8, 18) +(2, 5) +(6, 22) +(0, 7) +(6, 25) +(2, 22) +(4, 7) +(0, 11) +(2, 16) +(12, 22) +(11, 14) +(0, 4) +(5, 12) +(2, 17) +(20, 22) +(8, 12) +(5, 18) +(2, 15) +(8, 24) +(16, 18) +(12, 23) +(10, 12) +(9, 23) +(8, 25) +(6, 18) +(20, 23) +(10, 14) +(4, 8) +(9, 18) +(2, 8) +(3, 23) +(16, 20) +(1, 9) +(0, 10) +(5, 14) +(18, 25) +(6, 8) +(18, 24) +(22, 25) +(1, 13) +(6, 22) +(2, 8) +(21, 24) +(1, 14) +(9, 21) +(6, 19) +(1, 23) +(8, 25) +(17, 22) +(2, 3) +(5, 24) +(8, 20) +(3, 24) +(6, 18) +(2, 4) +(12, 21) +(6, 17) +(2, 18) +(9, 21) +(4, 13) +(21, 23) +(5, 17) +(2, 16) +(18, 25) +(7, 9) +(6, 11) +(11, 23) +(0, 2) +(8, 21) +(1, 17) +(15, 25) +(11, 20) +(6, 17) +(20, 22) +(6, 14) +(13, 17) +(20, 21) +(12, 17) +(2, 20) +(10, 17) +(12, 22) +(2, 16) +(0, 22) +(11, 17) +(1, 22) +(17, 23) +(0, 5) +(11, 13) +(13, 24) +(21, 23) +(5, 22) +(1, 8) +(11, 19) +(11, 25) +(3, 19) +(2, 23) +(14, 24) +(3, 17) +(6, 11) +(12, 24) +(18, 25) +(18, 23) +(8, 25) +(6, 12) +(3, 15) +(17, 21) +(10, 12) +(13, 25) +(6, 8) +(12, 25) +(8, 22) +(6, 14) +(13, 20) +(7, 10) +(5, 12) +(8, 25) +(0, 7) +(2, 14) +(10, 22) +(9, 13) +(2, 15) +(4, 13) +(12, 16) +(9, 17) +(3, 5) +(1, 12) +(0, 4) +(15, 23) +(11, 16) +(9, 25) +(13, 21) +(16, 18) +(19, 21) +(2, 9) +(14, 25) +(1, 12) +(1, 13) +(12, 19) +(11, 21) +(7, 12) +(1, 4) +(8, 13) +(16, 21) +(11, 14) +(8, 20) +(1, 19) +(16, 18) +(13, 24) +(4, 8) +(15, 20) +(1, 21) +(12, 13) +(9, 24) +(9, 15) +(2, 13) +(16, 24) +(4, 7) +(6, 8) +(6, 12) +(2, 18) +(7, 14) +(2, 6) +(13, 18) +(12, 17) +(7, 20) +(14, 19) +(10, 14) +(6, 20) +(13, 21) +(2, 8) +(9, 12) +(17, 22) +(4, 18) +(19, 24) +(7, 14) +(5, 6) +(18, 23) +(19, 20) +(1, 8) +(12, 17) +(22, 23) +(0, 5) +(1, 16) +(9, 17) +(8, 21) +(2, 18) +(7, 19) +(8, 25) +(2, 10) +(16, 24) +(7, 14) +(13, 22) +(2, 15) +(10, 18) +(16, 20) +(23, 24) +(10, 25) +(5, 15) +(1, 16) +(20, 23) +(1, 8) +(24, 25) +(5, 6) +(20, 21) +(22, 24) +(4, 21) +(2, 6) +(1, 25) +(8, 10) +(16, 22) +(2, 18) +(1, 15) +(10, 20) +(21, 24) +(6, 14) +(1, 23) +(15, 21) +(7, 16) +(17, 20) +(0, 10) +(10, 24) +(11, 20) +(23, 25) +(13, 17) +(0, 9) +(9, 25) +(8, 24) +(19, 23) +(13, 18) +(0, 14) +(1, 11) +(1, 17) +(13, 23) +(9, 11) +(14, 16) +(6, 18) +(10, 24) +(8, 24) +(11, 15) +(6, 19) +(5, 23) +(1, 22) +(9, 16) +(4, 17) +(22, 24) +(8, 25) +(4, 14) +(17, 21) +(0, 9) +(8, 19) +(13, 25) +(2, 4) +(0, 3) +(17, 23) +(13, 16) +(4, 23) +(15, 16) +(9, 13) +(3, 4) +(4, 23) +(12, 15) +(13, 18) +(8, 13) +(7, 15) +(3, 4) +(17, 18) +(5, 23) +(12, 24) +(12, 15) +(3, 14) +(20, 24) +(10, 14) +(9, 15) +(13, 24) +(3, 7) +(12, 25) +(5, 20) +(0, 3) +(12, 23) +(5, 21) +(4, 20) +(11, 24) +(8, 15) +(7, 18) +(6, 21) +(16, 18) +(5, 25) +(7, 24) +(4, 17) +(2, 6) +(21, 24) +(7, 11) +(19, 25) +(12, 21) +(2, 25) +(19, 23) +(3, 25) +(8, 21) +(13, 19) +(15, 23) +(8, 16) +(2, 19) +(9, 13) +(4, 23) +(2, 4) +(6, 13) +(17, 19) +(2, 25) +(3, 13) +(4, 23) +(17, 20) +(6, 24) +(19, 25) +(15, 20) +(18, 23) +(3, 5) +(9, 13) +(2, 10) +(12, 23) +(13, 21) +(0, 9) +(5, 24) +(18, 22) +(10, 20) +(4, 24) +(12, 15) +(19, 21) +(0, 14) +(7, 9) +(10, 16) +(0, 16) +(15, 25) +(8, 12) +(1, 14) +(20, 21) +(4, 22) +(7, 23) +(8, 11) +(14, 15) +(18, 25) +(19, 21) +(15, 19) +(8, 14) +(9, 11) +(5, 15) +(14, 18) +(2, 9) +(17, 19) +(11, 23) +(0, 15) +(11, 21) +(5, 18) +(9, 16) +(1, 2) +(7, 14) +(1, 23) +(18, 19) +(3, 21) +(4, 15) +(2, 14) +(7, 12) +(11, 13) +(1, 11) +(13, 20) +(2, 4) +(3, 7) +(21, 22) +(6, 22) +(3, 10) +(0, 21) +(16, 20) +(4, 25) +(6, 11) +(2, 21) +(24, 25) +(9, 10) +(12, 22) +(0, 14) +(16, 21) +(0, 17) +(22, 23) +(12, 13) +(8, 10) +(10, 14) +(9, 21) +(3, 23) +(15, 17) +(12, 20) +(0, 8) +(8, 10) +(1, 3) +(4, 15) +(19, 20) +(11, 21) +(4, 14) +(3, 19) +(6, 20) +(2, 19) +(4, 24) +(3, 12) +(14, 25) +(20, 23) +(7, 14) +(8, 12) +(20, 23) +(10, 23) +(10, 22) +(16, 23) +(15, 22) +(17, 23) +(4, 10) +(5, 17) +(10, 24) +(1, 23) +(6, 15) +(4, 20) +(11, 22) +(8, 17) +(3, 24) +(18, 22) +(10, 19) +(5, 21) +(18, 19) +(8, 13) +(5, 12) +(3, 21) +(7, 22) +(6, 12) +(5, 23) +(1, 3) +(2, 13) +(5, 23) +(1, 11) +(13, 20) +(3, 7) +(4, 6) +(5, 21) +(6, 13) +(4, 17) +(1, 20) +(11, 25) +(5, 24) +(16, 17) +(13, 15) +(9, 16) +(10, 13) +(5, 12) +(16, 20) +(6, 9) +(10, 18) +(12, 22) +(2, 5) +(0, 9) +(8, 12) +(22, 25) +(2, 7) +(16, 23) +(5, 21) +(13, 23) +(12, 17) +(16, 24) +(11, 22) +(7, 8) +(19, 25) +(11, 18) +(17, 21) +(14, 19) +(16, 18) +(9, 17) +(21, 25) +(19, 21) +(9, 13) +(12, 25) +(0, 17) +(12, 15) +(0, 3) +(14, 21) +(10, 13) +(1, 25) +(8, 9) +(3, 8) +(0, 23) +(9, 11) +(2, 14) +(6, 12) +(13, 17) +(5, 21) +(4, 23) +(11, 22) +(6, 25) +(6, 9) +(19, 22) +(21, 25) +(1, 4) +(18, 19) +(12, 22) +(1, 2) +(4, 7) +(1, 14) +(7, 13) +(22, 24) +(11, 13) +(1, 2) +(12, 14) +(7, 25) +(14, 19) +(2, 10) +(1, 9) +(7, 20) +(13, 25) +(11, 16) +(8, 16) +(13, 21) +(2, 23) +(17, 19) +(18, 20) +(4, 8) +(3, 23) +(17, 24) +(1, 20) +(18, 19) +(12, 13) +(10, 23) +(18, 19) +(3, 15) +(21, 24) +(7, 13) +(12, 14) +(5, 17) +(17, 22) +(9, 21) +(6, 14) +(6, 8) +(21, 22) +(5, 21) +(6, 15) +(8, 25) +(8, 12) +(14, 25) +(1, 6) +(23, 25) +(12, 21) +(1, 7) +(8, 15) +(8, 13) +(0, 7) +(9, 25) +(6, 15) +(1, 11) +(6, 8) +(9, 18) +(11, 23) +(24, 25) +(10, 13) +(7, 21) +(4, 9) +(6, 17) +(7, 12) +(14, 18) +(23, 25) +(13, 22) +(8, 19) +(0, 10) +(20, 22) +(14, 23) +(10, 19) +(2, 4) +(7, 25) +(8, 18) +(17, 23) +(14, 24) +(2, 19) +(15, 25) +(4, 14) +(2, 19) +(16, 17) +(23, 24) +(3, 24) +(10, 14) +(17, 20) +(4, 21) +(9, 16) +(10, 23) +(19, 20) +(3, 6) +(1, 16) +(4, 11) +(17, 21) +(1, 7) +(0, 17) +(9, 23) +(2, 10) +(10, 16) +(2, 14) +(9, 25) +(12, 23) +(10, 20) +(3, 12) +(2, 24) +(8, 16) +(14, 21) +(13, 23) +(1, 24) +(0, 21) +(8, 12) +(11, 13) +(2, 5) +(13, 15) +(1, 22) +(9, 11) +(12, 20) +(5, 25) +(2, 18) +(9, 13) +(14, 20) +(11, 24) +(15, 17) +(1, 3) +(23, 25) +(8, 23) +(1, 10) +(0, 20) +(17, 21) +(11, 19) +(14, 18) +(4, 25) +(2, 14) +(8, 16) +(11, 12) +(4, 10) +(1, 9) +(17, 25) +(4, 6) +(2, 19) +(14, 24) +(7, 8) +(3, 19) +(6, 22) +(2, 8) +(2, 12) +(3, 4) +(5, 6) +(8, 9) +(4, 13) +(3, 9) +(7, 8) +(5, 14) +(8, 15) +(0, 5) +(7, 11) +(3, 17) +(1, 14) +(13, 22) +(10, 13) +(14, 24) +(7, 12) +(1, 21) +(19, 22) +(1, 6) +(2, 13) +(3, 24) +(12, 15) +(18, 21) +(6, 14) +(1, 18) +(2, 3) +(0, 21) +(2, 4) +(1, 6) +(0, 9) +(19, 21) +(6, 25) +(1, 17) +(5, 21) +(0, 2) +(19, 22) +(22, 23) +(14, 19) +(5, 12) +(7, 14) +(6, 22) +(4, 23) +(13, 19) +(9, 19) +(14, 17) +(2, 23) +(6, 10) +(13, 18) +(3, 7) +(18, 20) +(0, 23) +(8, 13) +(3, 19) +(10, 16) +(7, 17) +(12, 17) +(20, 25) +(14, 16) +(3, 11) +(0, 10) +(4, 18) +(7, 15) +(5, 25) +(12, 17) +(4, 24) +(3, 15) +(9, 17) +(3, 11) +(8, 24) +(12, 18) +(13, 24) +(4, 9) +(12, 20) +(8, 21) +(3, 22) +(3, 14) +(18, 21) +(15, 20) +(2, 24) +(2, 17) +(8, 14) +(18, 19) +(1, 20) +(6, 15) +(1, 22) +(15, 25) +(2, 5) +(16, 17) +(19, 23) +(15, 21) +(5, 8) +(2, 8) +(5, 25) +(11, 15) +(11, 21) +(18, 25) +(2, 12) +(3, 5) +(3, 9) +(19, 25) +(2, 4) +(1, 11) +(15, 25) +(2, 20) +(5, 9) +(1, 24) +(4, 22) +(3, 7) +(7, 11) +(9, 13) +(17, 24) +(2, 3) +(4, 14) +(8, 24) +(17, 19) +(13, 21) +(4, 7) +(9, 23) +(18, 24) +(19, 23) +(7, 15) +(8, 19) +(4, 7) +(3, 24) +(3, 21) +(4, 18) +(7, 15) +(24, 25) +(3, 4) +(6, 7) +(3, 18) +(7, 12) +(0, 6) +(0, 2) +(7, 20) +(6, 18) +(3, 9) +(2, 18) +(0, 11) +(15, 20) +(1, 20) +(8, 15) +(4, 11) +(0, 16) +(3, 18) +(2, 7) +(8, 19) +(12, 18) +(7, 10) +(1, 11) +(20, 23) +(0, 22) +(0, 6) +(10, 16) +(8, 15) +(23, 24) +(11, 21) +(9, 11) +(21, 25) +(17, 24) +(6, 22) +(4, 15) +(3, 11) +(20, 25) +(14, 25) +(3, 12) +(11, 23) +(16, 20) +(7, 16) +(14, 19) +(4, 23) +(21, 23) +(8, 16) +(1, 19) +(2, 8) +(7, 19) +(3, 16) +(8, 11) +(17, 19) +(2, 10) +(7, 13) +(18, 19) +(1, 13) +(8, 10) +(11, 12) +(19, 20) +(5, 18) +(7, 8) +(2, 18) +(20, 23) +(5, 15) +(4, 19) +(15, 16) +(5, 7) +(2, 6) +(9, 18) +(9, 24) +(3, 18) +(10, 15) +(2, 23) +(2, 22) +(1, 9) +(16, 18) +(10, 20) +(17, 23) +(12, 15) +(8, 20) +(0, 16) +(1, 2) +(13, 15) +(12, 24) +(21, 23) +(16, 25) +(0, 18) +(3, 24) +(11, 13) +(15, 21) +(19, 24) +(4, 13) +(10, 11) +(3, 15) +(2, 21) +(6, 16) +(18, 25) +(11, 15) +(22, 24) +(12, 13) +(16, 19) +(18, 20) +(5, 6) +(4, 21) +(18, 25) +(14, 24) +(4, 10) +(6, 13) +(5, 15) +(4, 18) +(2, 14) +(10, 25) +(8, 14) +(10, 21) +(2, 8) +(9, 10) +(2, 23) +(10, 11) +(5, 8) +(5, 16) +(10, 12) +(21, 23) +(8, 11) +(5, 13) +(18, 23) +(9, 21) +(11, 19) +(0, 11) +(6, 19) +(14, 23) +(1, 21) +(9, 20) +(4, 11) +(0, 12) +(10, 21) +(3, 14) +(13, 19) +(1, 7) +(16, 19) +(1, 13) +(7, 8) +(14, 25) +(19, 22) +(6, 25) +(14, 18) +(8, 9) +(16, 24) +(17, 25) +(9, 21) +(16, 20) +(0, 24) +(3, 22) +(12, 16) +(10, 20) +(4, 22) +(8, 9) +(6, 10) +(22, 25) +(8, 12) +(7, 20) +(3, 16) +(2, 20) +(3, 19) +(7, 22) +(8, 15) +(4, 16) +(0, 6) +(4, 24) +(7, 18) +(2, 10) +(6, 17) +(11, 16) +(5, 7) +(10, 19) +(17, 18) +(6, 16) +(4, 21) +(22, 24) +(9, 19) +(8, 10) +(5, 14) +(3, 24) +(2, 19) +(6, 24) +(9, 11) +(8, 22) +(2, 13) +(1, 19) +(6, 25) +(2, 20) +(1, 16) +(19, 21) +(2, 10) +(13, 19) +(1, 4) +(9, 20) +(7, 21) +(12, 21) +(13, 15) +(0, 19) +(1, 9) +(7, 11) +(2, 24) +(23, 24) +(17, 21) +(4, 13) +(7, 19) +(13, 16) +(14, 17) +(21, 22) +(1, 24) +(17, 18) +(0, 24) +(21, 25) +(20, 22) +(10, 18) +(11, 17) +(3, 25) +(15, 21) +(1, 22) +(1, 7) +(12, 25) +(13, 21) +(5, 15) +(12, 16) +(0, 13) +(3, 5) +(11, 16) +(3, 4) +(10, 12) +(6, 16) +(11, 21) +(9, 10) +(4, 5) +(12, 23) +(6, 20) +(8, 16) +(7, 21) +(12, 19) +(16, 25) +(12, 14) +(2, 19) +(15, 25) +(0, 19) +(12, 24) +(16, 18) +(17, 24) +(5, 15) +(0, 1) +(2, 16) +(12, 21) +(3, 25) +(1, 24) +(3, 11) +(7, 25) +(0, 6) +(4, 5) +(8, 15) +(1, 5) +(19, 24) +(15, 20) +(7, 12) +(4, 14) +(10, 14) +(20, 22) +(7, 12) +(8, 19) +(15, 20) +(13, 22) +(4, 20) +(12, 15) +(2, 22) +(4, 12) +(20, 23) +(2, 21) +(6, 22) +(16, 20) +(2, 12) +(0, 23) +(9, 21) +(18, 23) +(1, 16) +(20, 25) +(11, 18) +(3, 23) +(5, 25) +(20, 22) +(0, 18) +(1, 3) +(5, 19) +(17, 23) +(8, 20) +(3, 25) +(0, 10) +(5, 18) +(1, 21) +(19, 21) +(0, 15) +(4, 10) +(10, 14) +(7, 19) +(4, 12) +(0, 21) +(12, 17) +(8, 14) +(0, 20) +(12, 24) +(5, 14) +(17, 23) +(7, 20) +(13, 14) +(17, 22) +(9, 23) +(17, 18) +(23, 24) +(16, 22) +(11, 13) +(0, 22) +(2, 18) +(17, 19) +(24, 25) +(5, 23) +(13, 14) +(21, 23) +(14, 24) +(6, 17) +(1, 19) +(11, 22) +(0, 7) +(12, 25) +(18, 23) +(6, 9) +(4, 25) +(20, 21) +(10, 12) +(17, 20) +(2, 4) +(12, 22) +(9, 13) +(6, 8) +(5, 23) +(2, 15) +(4, 10) +(5, 20) +(1, 6) +(17, 21) +(6, 13) +(0, 4) +(1, 12) +(15, 20) +(9, 13) +(11, 20) +(6, 22) +(12, 25) +(10, 15) +(1, 16) +(11, 14) +(1, 8) +(10, 16) +(13, 19) +(12, 23) +(5, 20) +(9, 21) +(12, 25) +(4, 9) +(19, 22) +(11, 13) +(19, 20) +(12, 21) +(7, 22) +(24, 25) +(11, 21) +(17, 19) +(0, 22) +(7, 18) +(23, 25) +(9, 12) +(14, 18) +(6, 12) +(19, 25) +(2, 9) +(7, 14) +(3, 6) +(18, 20) +(2, 23) +(7, 16) +(17, 20) +(14, 25) +(3, 13) +(7, 16) +(2, 20) +(5, 17) +(14, 18) +(20, 23) +(2, 6) +(14, 25) +(7, 16) +(5, 18) +(17, 21) +(6, 16) +(15, 23) +(2, 8) +(9, 21) +(5, 24) +(7, 20) +(17, 23) +(8, 14) +(10, 20) +(0, 7) +(14, 25) +(1, 17) +(18, 23) +(0, 4) +(10, 19) +(13, 18) +(7, 19) +(12, 23) +(0, 2) +(11, 19) +(13, 14) +(2, 15) +(6, 7) +(1, 7) +(4, 11) +(6, 16) +(19, 22) +(2, 9) +(1, 14) +(10, 16) +(3, 19) +(9, 15) +(6, 20) +(11, 22) +(2, 19) +(15, 21) +(5, 22) +(3, 17) +(0, 20) +(5, 17) +(19, 25) +(12, 21) +(0, 24) +(9, 12) +(18, 21) +(0, 4) +(0, 17) +(8, 21) +(10, 12) +(4, 7) +(6, 9) +(2, 17) +(9, 25) +(4, 22) +(10, 20) +(3, 6) +(2, 5) +(9, 13) +(0, 6) +(4, 20) +(3, 15) +(15, 24) +(3, 11) +(13, 17) +(0, 8) +(5, 18) +(16, 18) +(6, 15) +(11, 12) +(3, 7) +(8, 14) +(3, 13) +(11, 21) +(10, 12) +(1, 8) +(9, 18) +(6, 17) +(13, 16) +(5, 21) +(9, 19) +(6, 14) +(7, 10) +(17, 23) +(5, 20) +(16, 24) +(1, 7) +(15, 21) +(10, 12) +(4, 23) +(2, 20) +(16, 25) +(9, 12) +(5, 17) +(7, 17) +(0, 20) +(5, 11) +(1, 16) +(4, 16) +(11, 21) +(17, 24) +(0, 2) +(10, 20) +(0, 16) +(4, 7) +(6, 17) +(2, 20) +(10, 14) +(21, 23) +(7, 9) +(16, 22) +(14, 15) +(1, 6) +(4, 5) +(10, 17) +(15, 20) +(1, 2) +(6, 10) +(0, 4) +(14, 17) +(10, 16) +(4, 8) +(1, 13) +(15, 18) +(0, 24) +(2, 15) +(8, 18) +(3, 4) +(0, 1) +(1, 16) +(0, 19) +(15, 21) +(2, 15) +(19, 25) +(11, 21) +(15, 23) +(2, 10) +(4, 19) +(8, 25) +(19, 20) +(12, 25) +(2, 18) +(11, 12) +(8, 25) +(16, 19) +(2, 7) +(0, 16) +(13, 25) +(8, 14) +(10, 19) +(8, 9) +(7, 16) +(10, 24) +(3, 25) +(9, 25) +(10, 15) +(3, 8) +(10, 16) +(3, 13) +(6, 9) +(2, 8) +(1, 8) +(13, 23) +(0, 6) +(10, 15) +(10, 16) +(18, 23) +(1, 10) +(12, 23) +(3, 18) +(13, 16) +(3, 5) +(20, 23) +(12, 25) +(0, 13) +(3, 22) +(20, 25) +(15, 23) +(5, 19) +(1, 19) +(8, 23) +(3, 16) +(14, 22) +(5, 10) +(1, 9) +(10, 14) +(15, 22) +(2, 16) +(0, 3) +(14, 23) +(16, 21) +(0, 19) +(2, 25) +(3, 11) +(1, 17) +(3, 18) +(4, 25) +(6, 17) +(20, 21) +(2, 17) +(10, 18) +(3, 24) +(1, 4) +(6, 22) +(1, 9) +(14, 17) +(3, 7) +(4, 19) +(22, 24) +(10, 15) +(1, 16) +(2, 22) +(14, 24) +(7, 17) +(12, 15) +(10, 20) +(7, 23) +(11, 20) +(0, 10) +(3, 22) +(9, 14) +(1, 11) +(7, 16) +(20, 25) +(9, 17) +(10, 15) +(0, 8) +(14, 25) +(9, 13) +(17, 19) +(1, 12) +(9, 24) +(13, 19) +(14, 21) +(1, 3) +(11, 25) +(17, 23) +(0, 14) +(9, 10) +(3, 12) +(14, 22) +(10, 24) +(8, 9) +(0, 12) +(10, 20) +(2, 9) +(18, 24) +(11, 12) +(18, 22) +(3, 11) +(9, 24) +(5, 10) +(6, 12) +(12, 25) +(9, 20) +(6, 8) +(2, 24) +(11, 19) +(16, 18) +(3, 17) +(12, 19) +(7, 18) +(11, 17) +(1, 2) +(3, 23) +(24, 25) +(0, 9) +(17, 22) +(19, 25) +(2, 24) +(11, 20) +(5, 9) +(1, 16) +(0, 6) +(15, 20) +(5, 10) +(3, 9) +(14, 17) +(6, 22) +(5, 8) +(1, 15) +(2, 6) +(18, 20) +(9, 25) +(10, 21) +(3, 8) +(4, 5) +(6, 24) +(17, 18) +(11, 21) +(1, 19) +(10, 12) +(0, 11) +(12, 22) +(1, 6) +(0, 3) +(13, 22) +(5, 11) +(0, 1) +(5, 23) +(3, 14) +(10, 22) +(19, 23) +(10, 13) +(18, 22) +(3, 5) +(6, 23) +(5, 9) +(3, 16) +(19, 24) +(22, 25) +(5, 14) +(4, 19) +(7, 24) +(11, 16) +(7, 8) +(15, 16) +(6, 24) +(1, 14) +(3, 4) +(19, 22) +(5, 19) +(2, 24) +(7, 12) +(8, 23) +(3, 25) +(4, 10) +(4, 13) +(6, 8) +(23, 25) +(0, 10) +(12, 14) +(2, 9) +(10, 15) +(11, 13) +(18, 25) +(2, 20) +(6, 9) +(4, 16) +(0, 7) +(7, 25) +(1, 13) +(0, 8) +(9, 16) +(14, 18) +(2, 21) +(11, 17) +(1, 15) +(2, 20) +(18, 22) +(12, 17) +(21, 25) +(0, 17) +(1, 13) +(8, 12) +(14, 20) +(1, 10) +(13, 24) +(3, 20) +(14, 18) +(0, 22) +(22, 24) +(3, 17) +(20, 23) +(1, 4) +(10, 11) +(4, 6) +(10, 21) +(7, 22) +(22, 24) +(6, 9) +(9, 17) +(24, 25) +(7, 22) +(4, 7) +(1, 22) +(12, 17) +(10, 22) +(5, 12) +(7, 8) +(1, 25) +(7, 19) +(24, 25) +(8, 23) +(3, 19) +(5, 25) +(15, 23) +(6, 24) +(16, 19) +(3, 4) +(3, 21) +(7, 19) +(4, 22) +(13, 16) +(13, 17) +(2, 19) +(7, 18) +(1, 21) +(0, 4) +(4, 15) +(1, 24) +(7, 11) +(13, 21) +(2, 3) +(9, 18) +(18, 25) +(0, 11) +(16, 24) +(3, 12) +(2, 8) +(0, 14) +(2, 13) +(6, 8) +(15, 24) +(10, 18) +(8, 12) +(10, 11) +(19, 24) +(2, 23) +(13, 18) +(13, 25) +(1, 8) +(10, 11) +(2, 6) +(8, 14) +(11, 22) +(6, 21) +(1, 12) +(12, 20) +(15, 22) +(1, 23) +(5, 6) +(19, 21) +(7, 8) +(1, 4) +(12, 16) +(8, 24) +(17, 23) +(6, 14) +(4, 20) +(2, 24) +(5, 6) +(15, 16) +(21, 23) +(7, 20) +(11, 16) +(6, 14) +(3, 4) +(6, 10) +(16, 22) +(9, 14) +(5, 16) +(1, 10) +(6, 17) +(3, 9) +(14, 24) +(17, 25) +(10, 12) +(5, 21) +(6, 13) +(9, 24) +(16, 24) +(10, 15) +(4, 13) +(0, 12) +(2, 6) +(0, 11) +(16, 24) +(4, 6) +(3, 15) +(10, 23) +(12, 19) +(3, 22) +(2, 19) +(15, 18) +(1, 11) +(16, 24) +(0, 11) +(2, 25) +(12, 24) +(10, 16) +(8, 22) +(1, 17) +(14, 15) +(18, 20) +(17, 24) +(0, 22) +(2, 15) +(1, 23) +(18, 19) +(14, 21) +(3, 16) +(5, 10) +(0, 8) +(7, 19) +(3, 6) +(20, 23) +(1, 18) +(3, 14) +(6, 13) +(20, 21) +(8, 24) +(0, 7) +(1, 9) +(4, 13) +(21, 25) +(6, 19) +(9, 11) +(7, 15) +(1, 17) +(8, 23) +(8, 12) +(19, 22) +(9, 25) +(4, 13) +(1, 15) +(11, 18) +(7, 22) +(8, 17) +(4, 13) +(5, 25) +(4, 11) +(22, 23) +(15, 25) +(3, 17) +(2, 8) +(5, 8) +(2, 12) +(6, 11) +(7, 17) +(4, 16) +(10, 23) +(19, 23) +(0, 2) +(1, 6) +(9, 12) +(16, 21) +(9, 22) +(12, 19) +(0, 5) +(1, 11) +(2, 8) +(1, 24) +(4, 11) +(17, 19) +(1, 3) +(10, 24) +(11, 20) +(15, 24) +(20, 25) +(21, 25) +(15, 19) +(14, 20) +(17, 24) +(6, 25) +(14, 23) +(13, 21) +(4, 20) +(3, 13) +(12, 14) +(4, 22) +(4, 16) +(3, 5) +(7, 22) +(14, 25) +(16, 18) +(4, 6) +(5, 19) +(17, 18) +(4, 21) +(6, 11) +(11, 18) +(20, 21) +(16, 20) +(4, 16) +(4, 13) +(0, 16) +(4, 17) +(13, 14) +(7, 13) +(17, 23) +(5, 14) +(4, 25) +(2, 7) +(10, 17) +(11, 13) +(4, 24) +(14, 23) +(13, 15) +(2, 25) +(14, 17) +(21, 23) +(1, 4) +(12, 25) +(1, 15) +(16, 17) +(14, 23) +(8, 13) +(2, 22) +(16, 18) +(11, 14) +(2, 5) +(6, 12) +(4, 13) +(14, 22) +(13, 24) +(5, 15) +(6, 19) +(2, 25) +(9, 11) +(6, 21) +(10, 13) +(19, 25) +(6, 18) +(19, 22) +(13, 17) +(10, 16) +(2, 19) +(4, 13) +(10, 15) +(8, 18) +(6, 21) +(4, 17) +(18, 23) +(19, 24) +(3, 6) +(1, 13) +(19, 24) +(1, 21) +(6, 13) +(4, 18) +(3, 7) +(19, 22) +(1, 14) +(2, 3) +(4, 18) +(6, 25) +(0, 13) +(0, 2) +(4, 24) +(5, 14) +(18, 25) +(13, 15) +(15, 16) +(13, 19) +(5, 22) +(0, 3) +(4, 9) +(9, 10) +(19, 21) +(1, 22) +(16, 17) +(0, 5) +(4, 11) +(17, 23) +(4, 8) +(6, 9) +(10, 13) +(0, 7) +(2, 6) +(9, 11) +(20, 23) +(8, 16) +(10, 21) +(10, 22) +(1, 9) +(3, 11) +(5, 20) +(3, 21) +(1, 13) +(9, 22) +(10, 16) +(3, 19) +(15, 21) +(3, 19) \ No newline at end of file diff --git a/04-amidakuji/04-small.txt b/04-amidakuji/04-small.txt new file mode 100644 index 0000000..75e0d3d --- /dev/null +++ b/04-amidakuji/04-small.txt @@ -0,0 +1,15 @@ +(2, 5) +(1, 4) +(0, 3) +(0, 3) +(0, 5) +(3, 5) +(0, 2) +(3, 4) +(2, 4) +(1, 2) +(0, 4) +(1, 2) +(2, 4) +(0, 4) +(1, 4) \ No newline at end of file diff --git a/04-amidakuji/amidakuji-creation.ipynb b/04-amidakuji/amidakuji-creation.ipynb new file mode 100644 index 0000000..65d9751 --- /dev/null +++ b/04-amidakuji/amidakuji-creation.ipynb @@ -0,0 +1,2514 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import collections\n", + "import random\n", + "import string\n", + "import itertools" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "Link = collections.namedtuple('Link', 'height left right')" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def link_ends(link):\n", + " return set((link.left, link.right))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def can_add(link, links):\n", + " ends = link_ends(link)\n", + " same_height_links = [l for l in links if l.height == link.height]\n", + " return all(ends.isdisjoint(link_ends(l)) for l in same_height_links)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def make_net(num_links, lines=10, height=50):\n", + " links = set()\n", + " while len(links) < num_links:\n", + " a = random.randrange(lines)\n", + " b = random.randrange(lines)\n", + " if a != b:\n", + " l = min(a, b)\n", + " r = max(a, b)\n", + " h = random.randrange(height)\n", + " link = Link(h, l, r)\n", + " if can_add(link, links):\n", + " links.add(link)\n", + " return links" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{Link(height=4, left=0, right=3),\n", + " Link(height=8, left=1, right=5),\n", + " Link(height=16, left=0, right=4),\n", + " Link(height=17, left=1, right=5),\n", + " Link(height=18, left=3, right=5),\n", + " Link(height=20, left=0, right=1),\n", + " Link(height=25, left=0, right=3),\n", + " Link(height=30, left=1, right=4),\n", + " Link(height=33, left=0, right=4),\n", + " Link(height=34, left=4, right=5),\n", + " Link(height=35, left=0, right=3),\n", + " Link(height=36, left=1, right=4),\n", + " Link(height=37, left=2, right=5),\n", + " Link(height=45, left=4, right=5),\n", + " Link(height=46, left=2, right=5)}" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "net = make_net(15, lines=6)\n", + "net" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow(initial_line, links):\n", + " line = initial_line\n", + " heights = sorted(set(l.height for l in links))\n", + " for h in heights:\n", + " for l in [l for l in links if l.height == h]:\n", + " if line in link_ends(l):\n", + " line = [e for e in link_ends(l) if e != line][0]\n", + "# print(l, line)\n", + " return line" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "follow(4, net)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def pack(net):\n", + " packed_links = []\n", + " line_heights = collections.defaultdict(lambda: -1)\n", + " for link in sorted(net):\n", + " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", + " line_heights[link.left] = link_height\n", + " line_heights[link.right] = link_height\n", + " packed_links += [Link(link_height, link.left, link.right)]\n", + " return sorted(packed_links)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow_many_slow(in_sequence, links):\n", + " out_sequence = [(follow(i, links), term) \n", + " for i, term in enumerate(in_sequence)]\n", + " return [term for i, term in sorted(out_sequence)]" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow_many(in_sequence, net):\n", + " height_groups = [list(g) for _, g in itertools.groupby(pack(net), lambda l: l.height)]\n", + " seq = list(in_sequence)\n", + " for links in height_groups:\n", + " for link in links:\n", + "# l = seq[link.left]\n", + "# r = seq[link.right]\n", + "# seq[link.right] = l\n", + "# seq[link.left] = r\n", + " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", + " return seq" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10000 loops, best of 3: 39.2 µs per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many('abcdef', net)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# %%timeit\n", + "# follow_many_slow('abcdefghij', net)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_net(links, randomise=False, pair_sep=', '):\n", + " if randomise:\n", + " output = []\n", + " heights = sorted(set(l.height for l in links))\n", + " for h in heights:\n", + " ls = [l for l in links if l.height == h]\n", + " random.shuffle(ls)\n", + " output += ['({}, {})'.format(l.left, l.right) for l in ls]\n", + " return pair_sep.join(output)\n", + " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(0, 3), (1, 5), (0, 4), (1, 5), (3, 5), (0, 1), (0, 3), (1, 4), (0, 4), (4, 5), (0, 3), (1, 4), (2, 5), (4, 5), (2, 5)'" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_net(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(0, 3), (1, 5), (0, 4), (1, 5), (3, 5), (0, 1), (0, 3), (1, 4), (0, 4), (4, 5), (0, 3), (1, 4), (2, 5), (4, 5), (2, 5)'" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_net(net, randomise=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(0, 3) : (1, 5) : (0, 4) : (1, 5) : (3, 5) : (0, 1) : (0, 3) : (1, 4) : (0, 4) : (4, 5) : (0, 3) : (1, 4) : (2, 5) : (4, 5) : (2, 5)'" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_net(net, pair_sep=' : ')" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(0, 3)\\n(1, 5)\\n(0, 4)\\n(1, 5)\\n(3, 5)\\n(0, 1)\\n(0, 3)\\n(1, 4)\\n(0, 4)\\n(4, 5)\\n(0, 3)\\n(1, 4)\\n(2, 5)\\n(4, 5)\\n(2, 5)'" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_net(net, pair_sep='\\n')" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0, 3)\n", + "(1, 5)\n", + "(0, 4)\n", + "(1, 5)\n", + "(3, 5)\n", + "(0, 1)\n", + "(0, 3)\n", + "(1, 4)\n", + "(0, 4)\n", + "(4, 5)\n", + "(0, 3)\n", + "(1, 4)\n", + "(2, 5)\n", + "(4, 5)\n", + "(2, 5)\n" + ] + } + ], + "source": [ + "print(show_net(net, pair_sep='\\n'))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [], + "source": [ + "# open('04-small.txt', 'w').write(show_net(net))" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(0, 3), (1, 5), (0, 4), (1, 5), (3, 5), (0, 1), (0, 3), (1, 4), (0, 4), (4, 5), (0, 3), (1, 4), (2, 5), (4, 5), (2, 5)'" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_net(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ls = [l for l in net if l.height == 1]\n", + "ls" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "random.shuffle(ls)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_net(net_string):\n", + " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def extract_pairs(net_string):\n", + " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "net = read_net('(1, 5), (2, 4), (0, 2), (0, 4), (0, 1), (0, 2), (1, 5), (0, 3), (1, 2), (4, 5), (0, 5), (3, 5), (1, 4), (0, 1), (2, 3)')" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=1, right=5),\n", + " Link(height=1, left=2, right=4),\n", + " Link(height=2, left=0, right=2),\n", + " Link(height=3, left=0, right=4),\n", + " Link(height=4, left=0, right=1),\n", + " Link(height=5, left=0, right=2),\n", + " Link(height=6, left=1, right=5),\n", + " Link(height=7, left=0, right=3),\n", + " Link(height=8, left=1, right=2),\n", + " Link(height=9, left=4, right=5),\n", + " Link(height=10, left=0, right=5),\n", + " Link(height=11, left=3, right=5),\n", + " Link(height=12, left=1, right=4),\n", + " Link(height=13, left=0, right=1),\n", + " Link(height=14, left=2, right=3)]" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "read_net(show_net(net))" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=1, right=5),\n", + " Link(height=0, left=2, right=4),\n", + " Link(height=1, left=0, right=2),\n", + " Link(height=2, left=0, right=4),\n", + " Link(height=3, left=0, right=1),\n", + " Link(height=4, left=0, right=2),\n", + " Link(height=4, left=1, right=5),\n", + " Link(height=5, left=0, right=3),\n", + " Link(height=5, left=1, right=2),\n", + " Link(height=5, left=4, right=5),\n", + " Link(height=6, left=0, right=5),\n", + " Link(height=6, left=1, right=4),\n", + " Link(height=7, left=0, right=1),\n", + " Link(height=7, left=3, right=5),\n", + " Link(height=8, left=2, right=3)]" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pack(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=1, right=5),\n", + " Link(height=0, left=2, right=4),\n", + " Link(height=1, left=0, right=2),\n", + " Link(height=2, left=0, right=4),\n", + " Link(height=3, left=0, right=1),\n", + " Link(height=4, left=0, right=2),\n", + " Link(height=4, left=1, right=5),\n", + " Link(height=5, left=0, right=3),\n", + " Link(height=5, left=1, right=2),\n", + " Link(height=5, left=4, right=5),\n", + " Link(height=6, left=0, right=5),\n", + " Link(height=6, left=1, right=4),\n", + " Link(height=7, left=0, right=1),\n", + " Link(height=7, left=3, right=5),\n", + " Link(height=8, left=2, right=3)]" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pack(read_net(show_net(net)))" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, True)" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pnet = pack(net)\n", + "rrnet = read_net(show_net(net, randomise=True))\n", + "rnet = read_net(show_net(net))\n", + "rnet == rrnet, pack(rrnet) == pnet" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lnet = make_net(10207, 26, 100000)\n", + "plnet = pack(lnet)\n", + "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, plnet)\n", + "# for i in range(204):\n", + "# assert follow(i, lnet) == follow(i, plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "rlnet = read_net(show_net(lnet))\n", + "prlnet = pack(rlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2239" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "99989" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10206" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in rlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2239" + ] + }, + "execution_count": 71, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in prlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, prlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 25.9 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many(string.ascii_lowercase, lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# %%timeit\n", + "# follow_many_slow(string.ascii_lowercase, lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pairs_slow(net):\n", + " eps = []\n", + " for l in net:\n", + " o = Link(l.height + 1, l.left, l.right)\n", + " if o in net:\n", + " eps += [(l, o)]\n", + " return eps " + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pairs(net):\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + " eps = []\n", + " for h in range(1, max(height_groups.keys())):\n", + " for l in height_groups[h]:\n", + " o = Link(l.height - 1, l.left, l.right)\n", + " if o in height_groups[h-1]:\n", + " eps += [(l, o)]\n", + " return eps" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 24.1 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "eliminable_pairs(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pair(net):\n", + " for l in net:\n", + " o = Link(l.height + 1, l.left, l.right)\n", + " if o in net:\n", + " return l, o\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pair_hg(height_groups):\n", + " for h in range(1, max(height_groups.keys())):\n", + " for l in height_groups[h]:\n", + " o = Link(l.height - 1, l.left, l.right)\n", + " if o in height_groups[h-1]:\n", + " return l, o\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_pairs_slow(net):\n", + " eliminable_links = eliminable_pair(net)\n", + " while eliminable_links:\n", + " net = pack(l for l in net if l not in eliminable_links)\n", + " eliminable_links = eliminable_pair(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_pairs(net):\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + " eliminable_links = eliminable_pair_hg(height_groups)\n", + " while eliminable_links:\n", + " net = pack(l for l in net if l not in eliminable_links)\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + " eliminable_links = eliminable_pair_hg(height_groups)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10207\n" + ] + }, + { + "data": { + "text/plain": [ + "(10207, 9813)" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(len(plnet))\n", + "elnet = eliminate_pairs(plnet)\n", + "len(plnet), len(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eliminable_pairs(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, elnet)\n", + "assert follow_many(string.ascii_lowercase, plnet) == follow_many(string.ascii_lowercase, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 6.08 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "elnet = eliminate_pairs(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# for i in range(26):\n", + "# assert follow(i, plnet) == follow(i, elnet)\n", + "# assert follow(i, lnet) == follow(i, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# follow(0, plnet), follow(0, elnet), follow(0, lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple_slow(net):\n", + " x = None\n", + " y = None\n", + " ts = []\n", + " for a in net:\n", + " bs = [l for l in net if l.height == a.height + 1 \n", + " if l.left == a.right or l.right == a.left]\n", + " for b in bs:\n", + " c = Link(a.height + 2, a.left, a.right)\n", + " if c in net:\n", + " ts += [(a, b, c)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple_pair_slow(net):\n", + " ts = []\n", + " for a in net:\n", + " a_ends = link_ends(a)\n", + " bs = [l for l in net if l.height == a.height + 1 \n", + " if link_ends(l) & a_ends]\n", + " if len(bs) == 1:\n", + " b = bs[0]\n", + " lines = set((a.left, a.right, b.left, b.right))\n", + " cs = [l for l in net \n", + " if l.height == a.height + 2\n", + " if link_ends(l) & lines]\n", + " if len(cs) == 1:\n", + " c = Link(a.height + 2, a.left, a.right)\n", + " if c in cs:\n", + " ds = [l for l in net \n", + " if l.height == a.height + 3\n", + " if link_ends(l) & lines]\n", + " d = Link(a.height + 3, b.left, b.right)\n", + " if d in ds:\n", + " ts += [(a, b, c, d)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def find_height_groups(net):\n", + " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple_pair_hg(height_groups, debug=False):\n", + " ts = []\n", + " for h in range(3, max(height_groups.keys())):\n", + " for d in height_groups[h]:\n", + " if debug: print('d:', d)\n", + " ch = h - 1\n", + " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", + " if debug: print('cs:', cs)\n", + " while ch > 2 and not cs:\n", + " ch -= 1\n", + " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", + " if debug: print('cs:', cs)\n", + " if len(cs) == 1:\n", + " c = cs[0]\n", + " lines = set((d.left, d.right, c.left, c.right))\n", + " if debug: print('c:', '; lines:', lines)\n", + " bs = [l for l in height_groups[ch-1] if link_ends(l) & lines]\n", + " b = Link(ch - 1, d.left, d.right)\n", + " if debug: print('b:', b, '; bs:', bs)\n", + " if len(bs) == 1 and b in bs:\n", + " ah = b.height - 1\n", + " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", + " if debug: print('ah:', ah, '; als:', als)\n", + " while ah > 0 and not als:\n", + " ah -= 1\n", + " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", + " if debug: print('ah:', ah, '; als:', als)\n", + " a = Link(ah, c.left, c.right)\n", + " if debug: print('a:', a)\n", + " if a in als:\n", + " if debug: print('adding:', a, b, c, d)\n", + " ts += [(a, b, c, d)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_a_triple_pair_slow(net, debug=False):\n", + " tps = triple_pair_slow(net)\n", + " if debug: print('eatp', tps)\n", + "\n", + " if tps:\n", + " a, b, c, d = tps[0]\n", + "# x = Link(a.height, b.left, b.right)\n", + "# y = Link(b.height, a.left, a.right)\n", + " x = Link(b.height - 0.5, b.left, b.right)\n", + " y = Link(b.height, a.left, a.right)\n", + " if debug: print('removing', a, b, c, d, '; adding', x, y)\n", + " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_a_triple_pair(net, debug=False):\n", + " height_groups = find_height_groups(net)\n", + "\n", + " tps = triple_pair_hg(height_groups)\n", + " if debug: print('eatp', tps)\n", + " if tps:\n", + " a, b, c, d = tps[0]\n", + " x = Link(b.height - 0.5, b.left, b.right)\n", + " y = Link(b.height, a.left, a.right)\n", + " if debug: print('removing', a, b, c, d, '; adding', x, y)\n", + " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=1126, left=8, right=17),\n", + " Link(height=1127, left=1, right=8),\n", + " Link(height=1128, left=8, right=17),\n", + " Link(height=1129, left=1, right=8)),\n", + " (Link(height=1952, left=12, right=25),\n", + " Link(height=1953, left=10, right=12),\n", + " Link(height=1954, left=12, right=25),\n", + " Link(height=1955, left=10, right=12))]" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "height_groups = find_height_groups(elnet)\n", + "triple_pair_hg(height_groups)" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 98.7 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "height_groups = find_height_groups(elnet)\n", + "triple_pair_hg(height_groups)" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_triple_pairs_slow(net):\n", + " print(len(net))\n", + " new_net = eliminate_a_triple_pair_slow(net)\n", + " while new_net:\n", + " print(len(net))\n", + " net = new_net\n", + " new_net = eliminate_a_triple_pair_slow(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_triple_pairs(net):\n", + " print(len(net))\n", + " new_net = eliminate_a_triple_pair(net)\n", + " while new_net:\n", + " print(len(net))\n", + " net = new_net\n", + " new_net = eliminate_a_triple_pair(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "etlnet = eliminate_a_triple_pair(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9813\n", + "9813\n", + "9811\n" + ] + } + ], + "source": [ + "setlnet = eliminate_triple_pairs(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9809" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(setlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ypetfugkzdsacbvwjohqlnirmx'" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, etlnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ypetfugkzdsacbvwjohqlnirmx'" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, setlnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ypetfugkzdsacbvwjohqlnirmx'" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, elnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ypetfugkzdsacbvwjohqlnirmx'" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 107, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eliminable_pairs(etlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(10207, 9811)" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(lnet), len(etlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def simplify(net0):\n", + " netp = eliminate_pairs(net0)\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " while new_net:\n", + "# print('sipl', len(net0), len(netp), len(new_net))\n", + " netp = eliminate_pairs(new_net)\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " return netp" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "simple_lnet = simplify(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, simple_lnet)) == ''.join(follow_many(string.ascii_lowercase, lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ypetfugkzdsacbvwjohqlnirmx'" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, simple_lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'ypetfugkzdsacbvwjohqlnirmx'" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9809" + ] + }, + "execution_count": 114, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(simple_lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_triple_pair(net, max_lines=None, trace=False):\n", + " if not max_lines:\n", + " max_lines = max(l.right for l in net)\n", + " a, b, c = 0, 0, 0\n", + " while len(set((a, b, c))) != 3:\n", + " a = random.randrange(max_lines)\n", + " b = random.randrange(max_lines)\n", + " c = random.randrange(max_lines)\n", + " tp = [(min(a, b), max(a, b)), (min(b, c), max(b, c))] * 2\n", + " \n", + " pairs = [(l.left, l.right) for l in sorted(net)]\n", + " i = random.randrange(len(pairs))\n", + " if trace: print(i, tp)\n", + " new_pairs = pairs[:i] + tp + pairs[i:]\n", + " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_pair(net, max_lines=None, trace=False):\n", + " if not max_lines:\n", + " max_lines = max(l.right for l in net)\n", + "\n", + " a, b = 0, 0\n", + " while a == b:\n", + " a = random.randrange(max_lines)\n", + " b = random.randrange(max_lines)\n", + " p = [(min(a, b), max(a, b))] * 2\n", + " \n", + " pairs = [(l.left, l.right) for l in sorted(net)]\n", + " i = random.randrange(len(pairs))\n", + " \n", + " if trace: print(i, p)\n", + " new_pairs = pairs[:i] + p + pairs[i:]\n", + " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 117, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 118, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lnettp = simple_lnet\n", + "for _ in range(10):\n", + " lnettp = add_pair(lnettp)\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=301, left=7, right=23),\n", + " Link(height=302, left=16, right=23),\n", + " Link(height=303, left=7, right=23),\n", + " Link(height=304, left=16, right=23)),\n", + " (Link(height=362, left=11, right=23),\n", + " Link(height=363, left=3, right=23),\n", + " Link(height=364, left=11, right=23),\n", + " Link(height=365, left=3, right=23)),\n", + " (Link(height=363, left=3, right=23),\n", + " Link(height=364, left=11, right=23),\n", + " Link(height=365, left=3, right=23),\n", + " Link(height=366, left=11, right=23)),\n", + " (Link(height=595, left=12, right=15),\n", + " Link(height=596, left=10, right=15),\n", + " Link(height=597, left=12, right=15),\n", + " Link(height=598, left=10, right=15)),\n", + " (Link(height=796, left=12, right=21),\n", + " Link(height=797, left=4, right=12),\n", + " Link(height=798, left=12, right=21),\n", + " Link(height=799, left=4, right=12)),\n", + " (Link(height=879, left=0, right=18),\n", + " Link(height=880, left=0, right=8),\n", + " Link(height=881, left=0, right=18),\n", + " Link(height=882, left=0, right=8)),\n", + " (Link(height=930, left=3, right=17),\n", + " Link(height=931, left=3, right=21),\n", + " Link(height=932, left=3, right=17),\n", + " Link(height=933, left=3, right=21)),\n", + " (Link(height=1120, left=5, right=19),\n", + " Link(height=1121, left=18, right=19),\n", + " Link(height=1122, left=5, right=19),\n", + " Link(height=1123, left=18, right=19)),\n", + " (Link(height=2040, left=9, right=21),\n", + " Link(height=2041, left=9, right=15),\n", + " Link(height=2042, left=9, right=21),\n", + " Link(height=2043, left=9, right=15)),\n", + " (Link(height=2110, left=13, right=21),\n", + " Link(height=2111, left=13, right=24),\n", + " Link(height=2112, left=13, right=21),\n", + " Link(height=2113, left=13, right=24))]" + ] + }, + "execution_count": 119, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lnettp = simple_lnet\n", + "for _ in range(10):\n", + " lnettp = add_triple_pair(lnettp)\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=49, left=10, right=20),\n", + " Link(height=50, left=2, right=20),\n", + " Link(height=51, left=10, right=20),\n", + " Link(height=52, left=2, right=20)),\n", + " (Link(height=54, left=2, right=24),\n", + " Link(height=55, left=3, right=24),\n", + " Link(height=56, left=2, right=24),\n", + " Link(height=57, left=3, right=24)),\n", + " (Link(height=62, left=2, right=15),\n", + " Link(height=63, left=0, right=15),\n", + " Link(height=64, left=2, right=15),\n", + " Link(height=65, left=0, right=15)),\n", + " (Link(height=114, left=14, right=18),\n", + " Link(height=115, left=3, right=18),\n", + " Link(height=116, left=14, right=18),\n", + " Link(height=117, left=3, right=18)),\n", + " (Link(height=138, left=13, right=19),\n", + " Link(height=139, left=8, right=19),\n", + " Link(height=140, left=13, right=19),\n", + " Link(height=141, left=8, right=19)),\n", + " (Link(height=160, left=12, right=13),\n", + " Link(height=161, left=4, right=12),\n", + " Link(height=162, left=12, right=13),\n", + " Link(height=163, left=4, right=12)),\n", + " (Link(height=315, left=23, right=24),\n", + " Link(height=320, left=20, right=23),\n", + " Link(height=321, left=23, right=24),\n", + " Link(height=322, left=20, right=23)),\n", + " (Link(height=324, left=3, right=18),\n", + " Link(height=325, left=16, right=18),\n", + " Link(height=326, left=3, right=18),\n", + " Link(height=327, left=16, right=18)),\n", + " (Link(height=342, left=21, right=22),\n", + " Link(height=345, left=1, right=22),\n", + " Link(height=346, left=21, right=22),\n", + " Link(height=347, left=1, right=22)),\n", + " (Link(height=405, left=8, right=19),\n", + " Link(height=406, left=4, right=8),\n", + " Link(height=407, left=8, right=19),\n", + " Link(height=408, left=4, right=8)),\n", + " (Link(height=468, left=11, right=22),\n", + " Link(height=469, left=15, right=22),\n", + " Link(height=470, left=11, right=22),\n", + " Link(height=471, left=15, right=22)),\n", + " (Link(height=549, left=1, right=2),\n", + " Link(height=550, left=1, right=6),\n", + " Link(height=551, left=1, right=2),\n", + " Link(height=552, left=1, right=6)),\n", + " (Link(height=568, left=16, right=21),\n", + " Link(height=569, left=11, right=21),\n", + " Link(height=570, left=16, right=21),\n", + " Link(height=571, left=11, right=21)),\n", + " (Link(height=608, left=17, right=20),\n", + " Link(height=609, left=2, right=17),\n", + " Link(height=610, left=17, right=20),\n", + " Link(height=611, left=2, right=17)),\n", + " (Link(height=613, left=18, right=21),\n", + " Link(height=618, left=18, right=19),\n", + " Link(height=619, left=18, right=21),\n", + " Link(height=620, left=18, right=19)),\n", + " (Link(height=635, left=2, right=4),\n", + " Link(height=636, left=4, right=20),\n", + " Link(height=637, left=2, right=4),\n", + " Link(height=638, left=4, right=20)),\n", + " (Link(height=681, left=7, right=20),\n", + " Link(height=682, left=20, right=22),\n", + " Link(height=683, left=7, right=20),\n", + " Link(height=684, left=20, right=22)),\n", + " (Link(height=750, left=23, right=24),\n", + " Link(height=751, left=18, right=24),\n", + " Link(height=752, left=23, right=24),\n", + " Link(height=753, left=18, right=24)),\n", + " (Link(height=760, left=12, right=18),\n", + " Link(height=761, left=17, right=18),\n", + " Link(height=762, left=12, right=18),\n", + " Link(height=763, left=17, right=18)),\n", + " (Link(height=765, left=0, right=9),\n", + " Link(height=766, left=0, right=14),\n", + " Link(height=767, left=0, right=9),\n", + " Link(height=768, left=0, right=14)),\n", + " (Link(height=805, left=16, right=22),\n", + " Link(height=806, left=0, right=16),\n", + " Link(height=807, left=16, right=22),\n", + " Link(height=808, left=0, right=16)),\n", + " (Link(height=834, left=1, right=6),\n", + " Link(height=835, left=3, right=6),\n", + " Link(height=836, left=1, right=6),\n", + " Link(height=837, left=3, right=6)),\n", + " (Link(height=881, left=2, right=12),\n", + " Link(height=882, left=2, right=23),\n", + " Link(height=883, left=2, right=12),\n", + " Link(height=884, left=2, right=23)),\n", + " (Link(height=904, left=12, right=23),\n", + " Link(height=905, left=12, right=14),\n", + " Link(height=906, left=12, right=23),\n", + " Link(height=907, left=12, right=14)),\n", + " (Link(height=936, left=7, right=17),\n", + " Link(height=937, left=15, right=17),\n", + " Link(height=938, left=7, right=17),\n", + " Link(height=939, left=15, right=17)),\n", + " (Link(height=1010, left=4, right=6),\n", + " Link(height=1011, left=6, right=17),\n", + " Link(height=1012, left=4, right=6),\n", + " Link(height=1013, left=6, right=17)),\n", + " (Link(height=1030, left=1, right=12),\n", + " Link(height=1031, left=1, right=20),\n", + " Link(height=1032, left=1, right=12),\n", + " Link(height=1033, left=1, right=20)),\n", + " (Link(height=1197, left=2, right=9),\n", + " Link(height=1198, left=9, right=22),\n", + " Link(height=1199, left=2, right=9),\n", + " Link(height=1200, left=9, right=22)),\n", + " (Link(height=1222, left=2, right=3),\n", + " Link(height=1223, left=2, right=5),\n", + " Link(height=1224, left=2, right=3),\n", + " Link(height=1225, left=2, right=5)),\n", + " (Link(height=1318, left=12, right=23),\n", + " Link(height=1319, left=4, right=12),\n", + " Link(height=1320, left=12, right=23),\n", + " Link(height=1321, left=4, right=12)),\n", + " (Link(height=1341, left=17, right=22),\n", + " Link(height=1342, left=11, right=17),\n", + " Link(height=1343, left=17, right=22),\n", + " Link(height=1344, left=11, right=17)),\n", + " (Link(height=1396, left=4, right=9),\n", + " Link(height=1397, left=3, right=9),\n", + " Link(height=1398, left=4, right=9),\n", + " Link(height=1399, left=3, right=9)),\n", + " (Link(height=1426, left=18, right=24),\n", + " Link(height=1427, left=17, right=18),\n", + " Link(height=1428, left=18, right=24),\n", + " Link(height=1429, left=17, right=18)),\n", + " (Link(height=1456, left=2, right=15),\n", + " Link(height=1457, left=3, right=15),\n", + " Link(height=1458, left=2, right=15),\n", + " Link(height=1459, left=3, right=15)),\n", + " (Link(height=1505, left=13, right=18),\n", + " Link(height=1506, left=13, right=21),\n", + " Link(height=1507, left=13, right=18),\n", + " Link(height=1508, left=13, right=21)),\n", + " (Link(height=1551, left=10, right=12),\n", + " Link(height=1552, left=4, right=12),\n", + " Link(height=1553, left=10, right=12),\n", + " Link(height=1554, left=4, right=12)),\n", + " (Link(height=1622, left=4, right=11),\n", + " Link(height=1623, left=11, right=16),\n", + " Link(height=1624, left=4, right=11),\n", + " Link(height=1625, left=11, right=16)),\n", + " (Link(height=1653, left=8, right=24),\n", + " Link(height=1654, left=4, right=8),\n", + " Link(height=1655, left=8, right=24),\n", + " Link(height=1656, left=4, right=8)),\n", + " (Link(height=1688, left=0, right=5),\n", + " Link(height=1689, left=0, right=23),\n", + " Link(height=1690, left=0, right=5),\n", + " Link(height=1691, left=0, right=23)),\n", + " (Link(height=1724, left=10, right=23),\n", + " Link(height=1725, left=10, right=11),\n", + " Link(height=1726, left=10, right=23),\n", + " Link(height=1727, left=10, right=11)),\n", + " (Link(height=1863, left=1, right=12),\n", + " Link(height=1864, left=1, right=13),\n", + " Link(height=1865, left=1, right=12),\n", + " Link(height=1866, left=1, right=13)),\n", + " (Link(height=1873, left=10, right=22),\n", + " Link(height=1874, left=10, right=15),\n", + " Link(height=1875, left=10, right=22),\n", + " Link(height=1876, left=10, right=15)),\n", + " (Link(height=1879, left=18, right=20),\n", + " Link(height=1880, left=17, right=20),\n", + " Link(height=1881, left=18, right=20),\n", + " Link(height=1882, left=17, right=20)),\n", + " (Link(height=1916, left=18, right=19),\n", + " Link(height=1917, left=7, right=18),\n", + " Link(height=1918, left=18, right=19),\n", + " Link(height=1919, left=7, right=18)),\n", + " (Link(height=1961, left=11, right=20),\n", + " Link(height=1962, left=7, right=20),\n", + " Link(height=1963, left=11, right=20),\n", + " Link(height=1964, left=7, right=20)),\n", + " (Link(height=1962, left=9, right=18),\n", + " Link(height=1963, left=18, right=19),\n", + " Link(height=1964, left=9, right=18),\n", + " Link(height=1965, left=18, right=19)),\n", + " (Link(height=2031, left=3, right=6),\n", + " Link(height=2032, left=3, right=4),\n", + " Link(height=2033, left=3, right=6),\n", + " Link(height=2034, left=3, right=4)),\n", + " (Link(height=2077, left=2, right=9),\n", + " Link(height=2078, left=2, right=23),\n", + " Link(height=2079, left=2, right=9),\n", + " Link(height=2080, left=2, right=23)),\n", + " (Link(height=2165, left=1, right=8),\n", + " Link(height=2166, left=4, right=8),\n", + " Link(height=2167, left=1, right=8),\n", + " Link(height=2168, left=4, right=8)),\n", + " (Link(height=2185, left=6, right=21),\n", + " Link(height=2186, left=11, right=21),\n", + " Link(height=2187, left=6, right=21),\n", + " Link(height=2188, left=11, right=21))]" + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lnettp = simple_lnet\n", + "for _ in range(50):\n", + " lnettp = add_pair(lnettp)\n", + "for _ in range(50):\n", + " lnettp = add_triple_pair(lnettp)\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 121, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lnettp == pack(lnettp)" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9909" + ] + }, + "execution_count": 122, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lnettps = simplify(lnettp)\n", + "len(lnettps)" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(9809, 10109, 9909)" + ] + }, + "execution_count": 123, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(simple_lnet), len(lnettp), len(lnettps)" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 124, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnet)) == ''.join(follow_many(string.ascii_lowercase, simple_lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 125, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnettps)) == ''.join(follow_many(string.ascii_lowercase, lnettp))" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2285" + ] + }, + "execution_count": 126, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in lnettp)" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def simplify_with_checks(net0):\n", + " netp = eliminate_pairs(net0)\n", + " if follow_many(string.ascii_lowercase, net0) != follow_many(string.ascii_lowercase, netp):\n", + " print('pairs', eliminable_pairs(net0))\n", + " return net0\n", + " else:\n", + " print('pairs ok')\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", + " hg = find_height_groups(netp)\n", + " print('triple', triple_pair_hg(hg))\n", + " return netp\n", + " else:\n", + " print('triple ok')\n", + " while new_net:\n", + "# print('sipl', len(net0), len(netp), len(new_net))\n", + " netp = eliminate_pairs(new_net)\n", + " if follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", + " print('pairs', eliminable_pairs(new_net))\n", + " return new_net\n", + " else:\n", + " print('pairs ok')\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", + " hg = find_height_groups(netp)\n", + " print('triple', triple_pair_hg(hg))\n", + " return netp\n", + " else:\n", + " print('triple ok')\n", + " print('** done')\n", + " return netp" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "** done\n" + ] + } + ], + "source": [ + "lnettps = simplify_with_checks(lnettp)" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 129, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnettps)) == ''.join(follow_many(string.ascii_lowercase, lnettp))" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10109" + ] + }, + "execution_count": 130, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(lnettp)" + ] + }, + { + "cell_type": "code", + "execution_count": 131, + "metadata": {}, + "outputs": [], + "source": [ + "# open('04-lines.txt', 'w').write(show_net(lnettp, randomise=True, pair_sep='\\n'))" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "139" + ] + }, + "execution_count": 114, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# open('04-small.txt', 'w').write(show_net(make_net(20), randomise=True, pair_sep='\\n'))" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 [(2, 4), (0, 4), (2, 4), (0, 4)]\n", + "10 [(1, 2), (1, 2)]\n" + ] + }, + { + "data": { + "text/plain": [ + "[Link(height=0, left=2, right=5),\n", + " Link(height=1, left=1, right=4),\n", + " Link(height=2, left=0, right=3),\n", + " Link(height=3, left=0, right=3),\n", + " Link(height=4, left=0, right=5),\n", + " Link(height=5, left=3, right=5),\n", + " Link(height=6, left=0, right=2),\n", + " Link(height=7, left=3, right=4),\n", + " Link(height=8, left=2, right=4),\n", + " Link(height=9, left=1, right=2),\n", + " Link(height=10, left=0, right=4),\n", + " Link(height=11, left=1, right=2),\n", + " Link(height=12, left=2, right=4),\n", + " Link(height=13, left=1, right=2),\n", + " Link(height=14, left=0, right=4),\n", + " Link(height=15, left=1, right=4)]" + ] + }, + "execution_count": 143, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "net = make_net(10, lines=6)\n", + "net = add_triple_pair(net, trace=True)\n", + "net = add_pair(net, trace=True)\n", + "net = read_net(show_net(net, randomise=True))\n", + "net" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'(2, 5), (1, 4), (0, 3), (0, 3), (0, 5), (3, 5), (0, 2), (3, 4), (2, 4), (1, 2), (0, 4), (1, 2), (2, 4), (1, 2), (0, 4), (1, 4)'" + ] + }, + "execution_count": 147, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_net(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=2, right=5),\n", + " Link(height=1, left=1, right=4),\n", + " Link(height=2, left=0, right=3),\n", + " Link(height=3, left=0, right=3),\n", + " Link(height=4, left=0, right=5),\n", + " Link(height=5, left=3, right=5),\n", + " Link(height=6, left=0, right=2),\n", + " Link(height=7, left=3, right=4),\n", + " Link(height=8, left=2, right=4),\n", + " Link(height=9, left=1, right=2),\n", + " Link(height=10, left=0, right=4),\n", + " Link(height=11, left=1, right=2),\n", + " Link(height=12, left=2, right=4),\n", + " Link(height=13, left=0, right=4),\n", + " Link(height=14, left=1, right=4)]" + ] + }, + "execution_count": 149, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "net = read_net('(2, 5), (1, 4), (0, 3), (0, 3), (0, 5), (3, 5), (0, 2), (3, 4), (2, 4), (1, 2), (0, 4), (1, 2), (2, 4), (0, 4), (1, 4)')\n", + "net" + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=0, right=3),\n", + " Link(height=0, left=1, right=4),\n", + " Link(height=0, left=2, right=5),\n", + " Link(height=1, left=0, right=3),\n", + " Link(height=2, left=0, right=5),\n", + " Link(height=3, left=0, right=2),\n", + " Link(height=3, left=3, right=5),\n", + " Link(height=4, left=3, right=4),\n", + " Link(height=5, left=2, right=4),\n", + " Link(height=6, left=0, right=4),\n", + " Link(height=6, left=1, right=2),\n", + " Link(height=7, left=1, right=2),\n", + " Link(height=8, left=2, right=4),\n", + " Link(height=9, left=0, right=4),\n", + " Link(height=10, left=1, right=4)]" + ] + }, + "execution_count": 150, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pack(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=1, right=4),\n", + " Link(height=0, left=2, right=5),\n", + " Link(height=1, left=0, right=5),\n", + " Link(height=2, left=0, right=2),\n", + " Link(height=2, left=3, right=5),\n", + " Link(height=3, left=3, right=4),\n", + " Link(height=4, left=2, right=4),\n", + " Link(height=5, left=0, right=4),\n", + " Link(height=6, left=2, right=4),\n", + " Link(height=7, left=0, right=4),\n", + " Link(height=8, left=1, right=4)]" + ] + }, + "execution_count": 151, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "epnet = eliminate_pairs(net)\n", + "pack(epnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11\n", + "11\n" + ] + }, + { + "data": { + "text/plain": [ + "[Link(height=0, left=1, right=4),\n", + " Link(height=0, left=2, right=5),\n", + " Link(height=1, left=0, right=5),\n", + " Link(height=2, left=0, right=2),\n", + " Link(height=2, left=3, right=5),\n", + " Link(height=3, left=3, right=4),\n", + " Link(height=4, left=0, right=4),\n", + " Link(height=5, left=2, right=4),\n", + " Link(height=6, left=1, right=4)]" + ] + }, + "execution_count": 152, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eptnet = eliminate_triple_pairs(epnet)\n", + "pack(eptnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 153, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, net)) == ''.join(follow_many(string.ascii_lowercase, eptnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 155, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "104" + ] + }, + "execution_count": 155, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "open('04-small.txt', 'w').write(show_net(net, pair_sep='\\n'))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2+" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/04-amidakuji/amidakuji-solution-1-slow.ipynb b/04-amidakuji/amidakuji-solution-1-slow.ipynb new file mode 100644 index 0000000..345321d --- /dev/null +++ b/04-amidakuji/amidakuji-solution-1-slow.ipynb @@ -0,0 +1,1881 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import collections\n", + "import string\n", + "import itertools" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "Link = collections.namedtuple('Link', 'height left right')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def link_ends(link):\n", + " return set((link.left, link.right))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_net(net_string):\n", + " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow(initial_line, links):\n", + " line = initial_line\n", + " heights = sorted(set(l.height for l in links))\n", + " for h in heights:\n", + " for l in [l for l in links if l.height == h]:\n", + " if line in link_ends(l):\n", + " line = [e for e in link_ends(l) if e != line][0]\n", + "# print(l, line)\n", + " return line" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def pack(net):\n", + " packed_links = []\n", + " line_heights = collections.defaultdict(lambda: -1)\n", + " for link in sorted(net):\n", + " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", + " line_heights[link.left] = link_height\n", + " line_heights[link.right] = link_height\n", + " packed_links += [Link(link_height, link.left, link.right)]\n", + " return sorted(packed_links)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow_many_slow(in_sequence, links):\n", + " out_sequence = [(follow(i, links), term) \n", + " for i, term in enumerate(in_sequence)]\n", + " return [term for i, term in sorted(out_sequence)]" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow_many(in_sequence, net):\n", + " height_groups = [list(g) for _, g in itertools.groupby(pack(net), lambda l: l.height)]\n", + " seq = list(in_sequence)\n", + " for links in height_groups:\n", + " for link in links:\n", + " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", + " return seq" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10000 loops, best of 3: 47.5 µs per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many('abcdefghij', net)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# %%timeit\n", + "# follow_many_slow('abcdefghij', net)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_net(links, randomise=False):\n", + " if randomise:\n", + " output = []\n", + " heights = sorted(set(l.height for l in links))\n", + " for h in heights:\n", + " ls = [l for l in links if l.height == h]\n", + " random.shuffle(ls)\n", + " output += ['({}, {})'.format(l.left, l.right) for l in ls]\n", + " return ', '.join(output)\n", + " return ', '.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def extract_pairs(net_string):\n", + " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(True, True)" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rrnet = read_net(show_net(net, randomise=True))\n", + "rnet = read_net(show_net(net))\n", + "rnet == rrnet, pack(rrnet) == pnet" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lnet = make_net(10207, 26, 100000)\n", + "plnet = pack(lnet)\n", + "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, plnet)\n", + "# for i in range(204):\n", + "# assert follow(i, lnet) == follow(i, plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "rlnet = read_net(show_net(lnet))\n", + "prlnet = pack(rlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2251" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "99998" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10206" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in rlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2251" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(link.height for link in prlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, prlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 24.5 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many(string.ascii_lowercase, lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# %%timeit\n", + "# follow_many_slow(string.ascii_lowercase, lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pairs_slow(net):\n", + " eps = []\n", + " for l in net:\n", + " o = Link(l.height + 1, l.left, l.right)\n", + " if o in net:\n", + " eps += [(l, o)]\n", + " return eps " + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pairs(net):\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + " eps = []\n", + " for h in range(1, max(height_groups.keys())):\n", + " for l in height_groups[h]:\n", + " o = Link(l.height - 1, l.left, l.right)\n", + " if o in height_groups[h-1]:\n", + " eps += [(l, o)]\n", + " return eps" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 23.5 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "eliminable_pairs(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 2.33 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "eliminable_pairs_slow(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert sorted(sorted(p) for p in eliminable_pairs(plnet)) == sorted(sorted(p) for p in eliminable_pairs_slow(plnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pair(net):\n", + " for l in net:\n", + " o = Link(l.height + 1, l.left, l.right)\n", + " if o in net:\n", + " return l, o\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pair_hg(height_groups):\n", + " for h in range(1, max(height_groups.keys())):\n", + " for l in height_groups[h]:\n", + " o = Link(l.height - 1, l.left, l.right)\n", + " if o in height_groups[h-1]:\n", + " return l, o\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_pairs_slow(net):\n", + " eliminable_links = eliminable_pair(net)\n", + " while eliminable_links:\n", + " net = pack(l for l in net if l not in eliminable_links)\n", + " eliminable_links = eliminable_pair(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_pairs(net):\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + " eliminable_links = eliminable_pair_hg(height_groups)\n", + " while eliminable_links:\n", + " net = pack(l for l in net if l not in eliminable_links)\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + " eliminable_links = eliminable_pair_hg(height_groups)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10207\n" + ] + }, + { + "data": { + "text/plain": [ + "(10207, 9811)" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(len(plnet))\n", + "elnet = eliminate_pairs_slow(plnet)\n", + "len(plnet), len(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10207\n" + ] + }, + { + "data": { + "text/plain": [ + "(10207, 9811)" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(len(plnet))\n", + "elnet = eliminate_pairs(plnet)\n", + "len(plnet), len(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eliminable_pairs(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert eliminate_pairs_slow(plnet) == eliminate_pairs(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, lnet) == follow_many(string.ascii_lowercase, elnet)\n", + "assert follow_many(string.ascii_lowercase, plnet) == follow_many(string.ascii_lowercase, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 3min 30s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "elnet = eliminate_pairs_slow(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 6.27 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "elnet = eliminate_pairs(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# for i in range(26):\n", + "# assert follow(i, plnet) == follow(i, elnet)\n", + "# assert follow(i, lnet) == follow(i, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# follow(0, plnet), follow(0, elnet), follow(0, lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple(net):\n", + " x = None\n", + " y = None\n", + " ts = []\n", + " for a in net:\n", + " bs = [l for l in net if l.height == a.height + 1 \n", + " if l.left == a.right or l.right == a.left]\n", + " for b in bs:\n", + " c = Link(a.height + 2, a.left, a.right)\n", + " if c in net:\n", + " ts += [(a, b, c)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple_pair(net):\n", + " ts = []\n", + " for a in net:\n", + " a_ends = link_ends(a)\n", + " bs = [l for l in net if l.height == a.height + 1 \n", + " if link_ends(l) & a_ends]\n", + " if len(bs) == 1:\n", + " b = bs[0]\n", + " lines = set((a.left, a.right, b.left, b.right))\n", + " cs = [l for l in net \n", + " if l.height == a.height + 2\n", + " if link_ends(l) & lines]\n", + " if len(cs) == 1:\n", + " c = Link(a.height + 2, a.left, a.right)\n", + " if c in cs:\n", + " ds = [l for l in net \n", + " if l.height == a.height + 3\n", + " if link_ends(l) & lines]\n", + " d = Link(a.height + 3, b.left, b.right)\n", + " if d in ds:\n", + " ts += [(a, b, c, d)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple_pair_hg(height_groups, debug=False):\n", + " ts = []\n", + " for h in range(3, max(height_groups.keys())):\n", + " for d in height_groups[h]:\n", + " if debug: print('d:', d)\n", + " ch = h - 1\n", + " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", + " if debug: print('cs:', cs)\n", + " while ch > 2 and not cs:\n", + " ch -= 1\n", + " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", + " if debug: print('cs:', cs)\n", + " if len(cs) == 1:\n", + " c = cs[0]\n", + " lines = set((d.left, d.right, c.left, c.right))\n", + " if debug: print('c:', '; lines:', lines)\n", + " bs = [l for l in height_groups[ch-1] if link_ends(l) & lines]\n", + " b = Link(ch - 1, d.left, d.right)\n", + " if debug: print('b:', b, '; bs:', bs)\n", + " if len(bs) == 1 and b in bs:\n", + " ah = b.height - 1\n", + " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", + " if debug: print('ah:', ah, '; als:', als)\n", + " while ah > 0 and not als:\n", + " ah -= 1\n", + " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", + " if debug: print('ah:', ah, '; als:', als)\n", + " a = Link(ah, c.left, c.right)\n", + " if debug: print('a:', a)\n", + " if a in als:\n", + " if debug: print('adding:', a, b, c, d)\n", + " ts += [(a, b, c, d)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_a_triple_pair_slow(net):\n", + " tps = triple_pair(net)\n", + " print('eatp', tps)\n", + "\n", + " if tps:\n", + " a, b, c, d = tps[0]\n", + "# x = Link(a.height, b.left, b.right)\n", + "# y = Link(b.height, a.left, a.right)\n", + " x = Link(a.height, b.left, b.right)\n", + " y = Link(b.height, a.left, a.right)\n", + " print('removing', a, b, c, d, '; adding', x, y)\n", + " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_a_triple_pair(net):\n", + " height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + "\n", + " tps = triple_pair_hg(height_groups)\n", + " print('eatp', tps)\n", + " if tps:\n", + " a, b, c, d = tps[0]\n", + " x = Link(a.height, b.left, b.right)\n", + " y = Link(b.height, a.left, a.right)\n", + " print('removing', a, b, c, d, '; adding', x, y)\n", + " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=12, left=0, right=5),\n", + " Link(height=13, left=5, right=11),\n", + " Link(height=14, left=0, right=5)),\n", + " (Link(height=29, left=2, right=18),\n", + " Link(height=30, left=1, right=2),\n", + " Link(height=31, left=2, right=18)),\n", + " (Link(height=40, left=2, right=3),\n", + " Link(height=41, left=3, right=18),\n", + " Link(height=42, left=2, right=3)),\n", + " (Link(height=43, left=1, right=10),\n", + " Link(height=44, left=10, right=20),\n", + " Link(height=45, left=1, right=10)),\n", + " (Link(height=91, left=5, right=8),\n", + " Link(height=92, left=3, right=5),\n", + " Link(height=93, left=5, right=8)),\n", + " (Link(height=91, left=5, right=8),\n", + " Link(height=92, left=8, right=18),\n", + " Link(height=93, left=5, right=8)),\n", + " (Link(height=99, left=13, right=17),\n", + " Link(height=100, left=4, right=13),\n", + " Link(height=101, left=13, right=17)),\n", + " (Link(height=120, left=18, right=20),\n", + " Link(height=121, left=9, right=18),\n", + " Link(height=122, left=18, right=20)),\n", + " (Link(height=147, left=19, right=21),\n", + " Link(height=148, left=7, right=19),\n", + " Link(height=149, left=19, right=21)),\n", + " (Link(height=147, left=19, right=21),\n", + " Link(height=148, left=21, right=23),\n", + " Link(height=149, left=19, right=21)),\n", + " (Link(height=179, left=13, right=25),\n", + " Link(height=180, left=12, right=13),\n", + " Link(height=181, left=13, right=25)),\n", + " (Link(height=265, left=3, right=20),\n", + " Link(height=266, left=20, right=23),\n", + " Link(height=267, left=3, right=20)),\n", + " (Link(height=291, left=5, right=23),\n", + " Link(height=292, left=2, right=5),\n", + " Link(height=293, left=5, right=23)),\n", + " (Link(height=292, left=18, right=25),\n", + " Link(height=293, left=0, right=18),\n", + " Link(height=294, left=18, right=25)),\n", + " (Link(height=302, left=11, right=19),\n", + " Link(height=303, left=6, right=11),\n", + " Link(height=304, left=11, right=19)),\n", + " (Link(height=309, left=15, right=20),\n", + " Link(height=310, left=20, right=25),\n", + " Link(height=311, left=15, right=20)),\n", + " (Link(height=325, left=13, right=18),\n", + " Link(height=326, left=11, right=13),\n", + " Link(height=327, left=13, right=18)),\n", + " (Link(height=362, left=11, right=22),\n", + " Link(height=363, left=22, right=24),\n", + " Link(height=364, left=11, right=22)),\n", + " (Link(height=372, left=22, right=23),\n", + " Link(height=373, left=1, right=22),\n", + " Link(height=374, left=22, right=23)),\n", + " (Link(height=386, left=4, right=17),\n", + " Link(height=387, left=17, right=21),\n", + " Link(height=388, left=4, right=17)),\n", + " (Link(height=393, left=4, right=16),\n", + " Link(height=394, left=0, right=4),\n", + " Link(height=395, left=4, right=16)),\n", + " (Link(height=531, left=0, right=4),\n", + " Link(height=532, left=4, right=15),\n", + " Link(height=533, left=0, right=4)),\n", + " (Link(height=575, left=5, right=21),\n", + " Link(height=576, left=1, right=5),\n", + " Link(height=577, left=5, right=21)),\n", + " (Link(height=639, left=7, right=11),\n", + " Link(height=640, left=11, right=17),\n", + " Link(height=641, left=7, right=11)),\n", + " (Link(height=687, left=2, right=4),\n", + " Link(height=688, left=4, right=15),\n", + " Link(height=689, left=2, right=4)),\n", + " (Link(height=706, left=8, right=11),\n", + " Link(height=707, left=11, right=22),\n", + " Link(height=708, left=8, right=11)),\n", + " (Link(height=722, left=22, right=23),\n", + " Link(height=723, left=21, right=22),\n", + " Link(height=724, left=22, right=23)),\n", + " (Link(height=768, left=9, right=11),\n", + " Link(height=769, left=11, right=17),\n", + " Link(height=770, left=9, right=11)),\n", + " (Link(height=792, left=5, right=12),\n", + " Link(height=793, left=12, right=17),\n", + " Link(height=794, left=5, right=12)),\n", + " (Link(height=805, left=20, right=22),\n", + " Link(height=806, left=19, right=20),\n", + " Link(height=807, left=20, right=22)),\n", + " (Link(height=806, left=19, right=20),\n", + " Link(height=807, left=18, right=19),\n", + " Link(height=808, left=19, right=20)),\n", + " (Link(height=806, left=19, right=20),\n", + " Link(height=807, left=20, right=22),\n", + " Link(height=808, left=19, right=20)),\n", + " (Link(height=882, left=7, right=14),\n", + " Link(height=883, left=14, right=22),\n", + " Link(height=884, left=7, right=14)),\n", + " (Link(height=884, left=6, right=11),\n", + " Link(height=885, left=11, right=19),\n", + " Link(height=886, left=6, right=11)),\n", + " (Link(height=892, left=12, right=17),\n", + " Link(height=893, left=10, right=12),\n", + " Link(height=894, left=12, right=17)),\n", + " (Link(height=916, left=18, right=24),\n", + " Link(height=917, left=16, right=18),\n", + " Link(height=918, left=18, right=24)),\n", + " (Link(height=919, left=14, right=17),\n", + " Link(height=920, left=6, right=14),\n", + " Link(height=921, left=14, right=17)),\n", + " (Link(height=994, left=0, right=3),\n", + " Link(height=995, left=3, right=24),\n", + " Link(height=996, left=0, right=3)),\n", + " (Link(height=1012, left=9, right=12),\n", + " Link(height=1013, left=12, right=24),\n", + " Link(height=1014, left=9, right=12)),\n", + " (Link(height=1034, left=1, right=6),\n", + " Link(height=1035, left=6, right=12),\n", + " Link(height=1036, left=1, right=6)),\n", + " (Link(height=1035, left=7, right=21),\n", + " Link(height=1036, left=4, right=7),\n", + " Link(height=1037, left=7, right=21)),\n", + " (Link(height=1047, left=3, right=10),\n", + " Link(height=1048, left=10, right=11),\n", + " Link(height=1049, left=3, right=10)),\n", + " (Link(height=1088, left=7, right=8),\n", + " Link(height=1089, left=8, right=14),\n", + " Link(height=1090, left=7, right=8)),\n", + " (Link(height=1104, left=3, right=10),\n", + " Link(height=1105, left=10, right=11),\n", + " Link(height=1106, left=3, right=10)),\n", + " (Link(height=1135, left=5, right=8),\n", + " Link(height=1136, left=8, right=19),\n", + " Link(height=1137, left=5, right=8)),\n", + " (Link(height=1138, left=1, right=3),\n", + " Link(height=1139, left=3, right=23),\n", + " Link(height=1140, left=1, right=3)),\n", + " (Link(height=1146, left=5, right=7),\n", + " Link(height=1147, left=7, right=24),\n", + " Link(height=1148, left=5, right=7)),\n", + " (Link(height=1197, left=5, right=14),\n", + " Link(height=1198, left=14, right=15),\n", + " Link(height=1199, left=5, right=14)),\n", + " (Link(height=1205, left=7, right=23),\n", + " Link(height=1206, left=3, right=7),\n", + " Link(height=1207, left=7, right=23)),\n", + " (Link(height=1276, left=18, right=25),\n", + " Link(height=1277, left=17, right=18),\n", + " Link(height=1278, left=18, right=25)),\n", + " (Link(height=1319, left=14, right=20),\n", + " Link(height=1320, left=20, right=24),\n", + " Link(height=1321, left=14, right=20)),\n", + " (Link(height=1328, left=8, right=21),\n", + " Link(height=1329, left=1, right=8),\n", + " Link(height=1330, left=8, right=21)),\n", + " (Link(height=1329, left=2, right=14),\n", + " Link(height=1330, left=14, right=25),\n", + " Link(height=1331, left=2, right=14)),\n", + " (Link(height=1385, left=10, right=14),\n", + " Link(height=1386, left=14, right=15),\n", + " Link(height=1387, left=10, right=14)),\n", + " (Link(height=1419, left=2, right=8),\n", + " Link(height=1420, left=8, right=15),\n", + " Link(height=1421, left=2, right=8)),\n", + " (Link(height=1465, left=13, right=21),\n", + " Link(height=1466, left=21, right=24),\n", + " Link(height=1467, left=13, right=21)),\n", + " (Link(height=1514, left=11, right=15),\n", + " Link(height=1515, left=15, right=21),\n", + " Link(height=1516, left=11, right=15)),\n", + " (Link(height=1545, left=3, right=11),\n", + " Link(height=1546, left=11, right=25),\n", + " Link(height=1547, left=3, right=11)),\n", + " (Link(height=1561, left=7, right=18),\n", + " Link(height=1562, left=0, right=7),\n", + " Link(height=1563, left=7, right=18)),\n", + " (Link(height=1671, left=9, right=15),\n", + " Link(height=1672, left=15, right=23),\n", + " Link(height=1673, left=9, right=15)),\n", + " (Link(height=1701, left=13, right=21),\n", + " Link(height=1702, left=4, right=13),\n", + " Link(height=1703, left=13, right=21)),\n", + " (Link(height=1706, left=5, right=13),\n", + " Link(height=1707, left=13, right=23),\n", + " Link(height=1708, left=5, right=13)),\n", + " (Link(height=1730, left=7, right=16),\n", + " Link(height=1731, left=1, right=7),\n", + " Link(height=1732, left=7, right=16)),\n", + " (Link(height=1781, left=0, right=8),\n", + " Link(height=1782, left=8, right=17),\n", + " Link(height=1783, left=0, right=8)),\n", + " (Link(height=1784, left=8, right=18),\n", + " Link(height=1785, left=1, right=8),\n", + " Link(height=1786, left=8, right=18)),\n", + " (Link(height=1804, left=19, right=24),\n", + " Link(height=1805, left=7, right=19),\n", + " Link(height=1806, left=19, right=24)),\n", + " (Link(height=1827, left=3, right=23),\n", + " Link(height=1828, left=23, right=25),\n", + " Link(height=1829, left=3, right=23)),\n", + " (Link(height=1837, left=1, right=16),\n", + " Link(height=1838, left=16, right=17),\n", + " Link(height=1839, left=1, right=16)),\n", + " (Link(height=1849, left=18, right=25),\n", + " Link(height=1850, left=4, right=18),\n", + " Link(height=1851, left=18, right=25)),\n", + " (Link(height=1856, left=6, right=13),\n", + " Link(height=1857, left=13, right=17),\n", + " Link(height=1858, left=6, right=13)),\n", + " (Link(height=1875, left=2, right=11),\n", + " Link(height=1876, left=11, right=15),\n", + " Link(height=1877, left=2, right=11)),\n", + " (Link(height=1970, left=6, right=24),\n", + " Link(height=1971, left=1, right=6),\n", + " Link(height=1972, left=6, right=24)),\n", + " (Link(height=2075, left=20, right=25),\n", + " Link(height=2076, left=5, right=20),\n", + " Link(height=2077, left=20, right=25)),\n", + " (Link(height=2081, left=4, right=19),\n", + " Link(height=2082, left=1, right=4),\n", + " Link(height=2083, left=4, right=19)),\n", + " (Link(height=2111, left=3, right=25),\n", + " Link(height=2112, left=1, right=3),\n", + " Link(height=2113, left=3, right=25)),\n", + " (Link(height=2225, left=3, right=12),\n", + " Link(height=2226, left=12, right=24),\n", + " Link(height=2227, left=3, right=12)),\n", + " (Link(height=2242, left=3, right=18),\n", + " Link(height=2243, left=18, right=23),\n", + " Link(height=2244, left=3, right=18))]" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "triple(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=316, left=8, right=17),\n", + " Link(height=317, left=8, right=21),\n", + " Link(height=318, left=8, right=17),\n", + " Link(height=319, left=8, right=21)),\n", + " (Link(height=867, left=4, right=11),\n", + " Link(height=868, left=5, right=11),\n", + " Link(height=869, left=4, right=11),\n", + " Link(height=870, left=5, right=11))]" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "triple_pair(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=316, left=8, right=17),\n", + " Link(height=317, left=8, right=21),\n", + " Link(height=318, left=8, right=17),\n", + " Link(height=319, left=8, right=21)),\n", + " (Link(height=867, left=4, right=11),\n", + " Link(height=868, left=5, right=11),\n", + " Link(height=869, left=4, right=11),\n", + " Link(height=870, left=5, right=11))]" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(elnet), lambda l: l.height)}\n", + "triple_pair_hg(height_groups)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=1368, left=13, right=19),\n", + " Link(height=1368, left=14, right=16),\n", + " Link(height=1369, left=3, right=6)]" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[l for l in elnet if l.height >= 1367 if l.height <= 1370 if link_ends(l) & set((6, 16, 19))]" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 21.3 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "triple_pair(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 105 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(elnet), lambda l: l.height)}\n", + "triple_pair_hg(height_groups)" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(elnet), lambda l: l.height)}\n", + "assert triple_pair_hg(height_groups) == triple_pair(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=242, left=8, right=9),\n", + " Link(height=242, left=15, right=21),\n", + " Link(height=243, left=1, right=9),\n", + " Link(height=243, left=8, right=14),\n", + " Link(height=243, left=11, right=15),\n", + " Link(height=244, left=1, right=18),\n", + " Link(height=244, left=6, right=8),\n", + " Link(height=244, left=9, right=20),\n", + " Link(height=244, left=15, right=25),\n", + " Link(height=245, left=0, right=15),\n", + " Link(height=245, left=1, right=16),\n", + " Link(height=245, left=9, right=12),\n", + " Link(height=245, left=18, right=21)]" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[l for l in elnet if l.height >= 242 if l.height <= 245 ] #if l.left in [13, 17, 20] or l.right in [13, 17, 20]]" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_triple_pairs_slow(net):\n", + " print(len(net))\n", + " new_net = eliminate_a_triple_pair_slow(net)\n", + " while new_net:\n", + " print(len(net))\n", + " net = new_net\n", + " new_net = eliminate_a_triple_pair_slow(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_triple_pairs(net):\n", + " print(len(net))\n", + " new_net = eliminate_a_triple_pair(net)\n", + " while new_net:\n", + " print(len(net))\n", + " net = new_net\n", + " new_net = eliminate_a_triple_pair(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 134, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9811\n", + "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", + "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=316, left=8, right=21) Link(height=317, left=8, right=17)\n", + "9811\n", + "eatp [(Link(height=866, left=4, right=11), Link(height=867, left=5, right=11), Link(height=868, left=4, right=11), Link(height=869, left=5, right=11))]\n", + "removing Link(height=866, left=4, right=11) Link(height=867, left=5, right=11) Link(height=868, left=4, right=11) Link(height=869, left=5, right=11) ; adding Link(height=866, left=5, right=11) Link(height=867, left=4, right=11)\n", + "9809\n", + "eatp []\n" + ] + } + ], + "source": [ + "etlnet = eliminate_triple_pairs(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", + "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=317, left=8, right=17) Link(height=318, left=8, right=21)\n" + ] + } + ], + "source": [ + "etlnet = eliminate_a_triple_pair(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=315, left=17, right=20),\n", + " Link(height=316, left=8, right=17),\n", + " Link(height=317, left=8, right=21),\n", + " Link(height=318, left=8, right=17),\n", + " Link(height=319, left=8, right=21),\n", + " Link(height=319, left=14, right=17),\n", + " Link(height=320, left=2, right=8),\n", + " Link(height=320, left=17, right=21)]" + ] + }, + "execution_count": 136, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[l for l in elnet if l.height >= 315 if l.height <= 320 if link_ends(l) & set((8, 17, 21))] " + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=17, right=20),\n", + " Link(height=1, left=8, right=17),\n", + " Link(height=2, left=8, right=21),\n", + " Link(height=3, left=8, right=17),\n", + " Link(height=4, left=8, right=21),\n", + " Link(height=4, left=14, right=17),\n", + " Link(height=5, left=2, right=8),\n", + " Link(height=5, left=17, right=21)]" + ] + }, + "execution_count": 137, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "nf = [l for l in elnet if l.height >= 315 if l.height <= 320 if link_ends(l) & set((8, 17, 21))]\n", + "pnf = pack(nf)\n", + "pnf" + ] + }, + { + "cell_type": "code", + "execution_count": 138, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "d: Link(height=3, left=8, right=17)\n", + "cs: [Link(height=2, left=8, right=21)]\n", + "c: ; lines: {8, 17, 21}\n", + "b: Link(height=1, left=8, right=17) ; bs: [Link(height=1, left=8, right=17)]\n", + "ah: 0 ; als: []\n", + "a: Link(height=0, left=8, right=21)\n", + "d: Link(height=4, left=8, right=21)\n", + "cs: [Link(height=3, left=8, right=17)]\n", + "c: ; lines: {8, 17, 21}\n", + "b: Link(height=2, left=8, right=21) ; bs: [Link(height=2, left=8, right=21)]\n", + "ah: 1 ; als: [Link(height=1, left=8, right=17)]\n", + "a: Link(height=1, left=8, right=17)\n", + "adding: Link(height=1, left=8, right=17) Link(height=2, left=8, right=21) Link(height=3, left=8, right=17) Link(height=4, left=8, right=21)\n", + "d: Link(height=4, left=14, right=17)\n", + "cs: [Link(height=3, left=8, right=17)]\n", + "c: ; lines: {8, 17, 14}\n", + "b: Link(height=2, left=14, right=17) ; bs: [Link(height=2, left=8, right=21)]\n" + ] + }, + { + "data": { + "text/plain": [ + "[(Link(height=1, left=8, right=17),\n", + " Link(height=2, left=8, right=21),\n", + " Link(height=3, left=8, right=17),\n", + " Link(height=4, left=8, right=21))]" + ] + }, + "execution_count": 138, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(pnf), lambda l: l.height)}\n", + "triple_pair_hg(height_groups, debug=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 139, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9811\n", + "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", + "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=316, left=8, right=21) Link(height=317, left=8, right=17)\n", + "9811\n", + "eatp [(Link(height=866, left=4, right=11), Link(height=867, left=5, right=11), Link(height=868, left=4, right=11), Link(height=869, left=5, right=11))]\n", + "removing Link(height=866, left=4, right=11) Link(height=867, left=5, right=11) Link(height=868, left=4, right=11) Link(height=869, left=5, right=11) ; adding Link(height=866, left=5, right=11) Link(height=867, left=4, right=11)\n", + "9809\n", + "eatp []\n" + ] + } + ], + "source": [ + "setlnet = eliminate_triple_pairs_slow(elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 140, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9807" + ] + }, + "execution_count": 140, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(setlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 141, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, etlnet) == follow_many(string.ascii_lowercase, elnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 142, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zdunvslcfiqywjmkobhxtraegp'" + ] + }, + "execution_count": 142, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, etlnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 143, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zdunvslcfiqywjmkobhxtraegp'" + ] + }, + "execution_count": 143, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, setlnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 144, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zdunvslcfiqywjmkobhxtraegp'" + ] + }, + "execution_count": 144, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, elnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 145, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zdunvslcfiqywjmkobhxtraegp'" + ] + }, + "execution_count": 145, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 146, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 146, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eliminable_pairs(etlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 147, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(10207, 9807)" + ] + }, + "execution_count": 147, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(lnet), len(etlnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 148, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def simplify(net0):\n", + " netp = eliminate_pairs(net0)\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " while new_net:\n", + "# print('sipl', len(net0), len(netp), len(new_net))\n", + " netp = eliminate_pairs(new_net)\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " return netp" + ] + }, + { + "cell_type": "code", + "execution_count": 149, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "eatp [(Link(height=316, left=8, right=17), Link(height=317, left=8, right=21), Link(height=318, left=8, right=17), Link(height=319, left=8, right=21)), (Link(height=867, left=4, right=11), Link(height=868, left=5, right=11), Link(height=869, left=4, right=11), Link(height=870, left=5, right=11))]\n", + "removing Link(height=316, left=8, right=17) Link(height=317, left=8, right=21) Link(height=318, left=8, right=17) Link(height=319, left=8, right=21) ; adding Link(height=316, left=8, right=21) Link(height=317, left=8, right=17)\n", + "eatp [(Link(height=866, left=4, right=11), Link(height=867, left=5, right=11), Link(height=868, left=4, right=11), Link(height=869, left=5, right=11))]\n", + "removing Link(height=866, left=4, right=11) Link(height=867, left=5, right=11) Link(height=868, left=4, right=11) Link(height=869, left=5, right=11) ; adding Link(height=866, left=5, right=11) Link(height=867, left=4, right=11)\n", + "eatp []\n" + ] + } + ], + "source": [ + "simple_lnet = simplify(plnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 150, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 150, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, simple_lnet)) == ''.join(follow_many(string.ascii_lowercase, lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 151, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zdunvslcfiqywjmkobhxtraegp'" + ] + }, + "execution_count": 151, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, simple_lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 152, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zdunvslcfiqywjmkobhxtraegp'" + ] + }, + "execution_count": 152, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, lnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 153, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9807" + ] + }, + "execution_count": 153, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(simple_lnet)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_triple_pair(net, max_lines=None):\n", + " if not max_lines:\n", + " max_lines = max(l.right for l in net)\n", + " a, b, c = 0, 0, 0\n", + " while len(set((a, b, c))) != 3:\n", + " a = random.randrange(max_lines)\n", + " b = random.randrange(max_lines)\n", + " c = random.randrange(max_lines)\n", + " tp = [(min(a, b), max(a, b)), (min(b, c), max(b, c))] * 2\n", + " \n", + " pairs = [(l.left, l.right) for l in sorted(net)]\n", + " i = random.randrange(len(pairs))\n", + " print(i, tp)\n", + " new_pairs = pairs[:i] + tp + pairs[i:]\n", + " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def add_pair(net, max_lines=None):\n", + " if not max_lines:\n", + " max_lines = max(l.right for l in net)\n", + "\n", + " a, b = 0, 0\n", + " while a == b:\n", + " a = random.randrange(max_lines)\n", + " b = random.randrange(max_lines)\n", + " p = [(min(a, b), max(a, b))] * 2\n", + " \n", + " pairs = [(l.left, l.right) for l in sorted(net)]\n", + " i = random.randrange(len(pairs))\n", + " \n", + " print(i, p)\n", + " new_pairs = pairs[:i] + p + pairs[i:]\n", + " return pack([Link(h, l, r) for h, (l, r) in enumerate(new_pairs)]) " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "lnettp = simple_lnet\n", + "for _ in range(10):\n", + " lnettp = add_pair(lnettp)\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "lnettp = simple_lnet\n", + "for _ in range(10):\n", + " lnettp = add_triple_pair(lnettp)\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true, + "scrolled": true + }, + "outputs": [], + "source": [ + "lnettp = simple_lnet\n", + "for _ in range(10):\n", + " lnettp = add_pair(lnettp)\n", + "for _ in range(10):\n", + " lnettp = add_triple_pair(lnettp)\n", + "height_groups = {h: list(g) for h, g in itertools.groupby(pack(lnettp), lambda l: l.height)}\n", + "tps = triple_pair_hg(height_groups)\n", + "tps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lnettp == pack(lnettp)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "lnettps = simplify(lnettp)\n", + "len(lnettps)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "len(simple_lnet), len(lnettp), len(lnettps)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2+" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/04-amidakuji/amidakuji-solution-1.ipynb b/04-amidakuji/amidakuji-solution-1.ipynb new file mode 100644 index 0000000..df69a1f --- /dev/null +++ b/04-amidakuji/amidakuji-solution-1.ipynb @@ -0,0 +1,613 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import collections\n", + "import string\n", + "import itertools\n", + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "Link = collections.namedtuple('Link', 'height left right')" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def extract_pairs(net_string):\n", + " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_net_string(net_string):\n", + " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_net(filename, rev=False):\n", + " with open(filename) as f:\n", + " pairs = [re.split('\\D+', p.strip()) for p in f.readlines()]\n", + " if rev:\n", + " lrs = [(int(lr[1]), int(lr[2])) for lr in reversed(pairs)]\n", + " else:\n", + " lrs = [(int(lr[1]), int(lr[2])) for lr in pairs]\n", + " return [Link(h, l, r) \n", + " for h, (l, r) in enumerate(lrs)]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=2, right=5),\n", + " Link(height=1, left=1, right=4),\n", + " Link(height=2, left=0, right=3),\n", + " Link(height=3, left=0, right=3),\n", + " Link(height=4, left=0, right=5),\n", + " Link(height=5, left=3, right=5),\n", + " Link(height=6, left=0, right=2),\n", + " Link(height=7, left=3, right=4),\n", + " Link(height=8, left=2, right=4),\n", + " Link(height=9, left=1, right=2),\n", + " Link(height=10, left=0, right=4),\n", + " Link(height=11, left=1, right=2),\n", + " Link(height=12, left=2, right=4),\n", + " Link(height=13, left=0, right=4),\n", + " Link(height=14, left=1, right=4)]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "small_net = read_net('04-small.txt')\n", + "small_net" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10135" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "net = read_net('04-lines.txt')\n", + "len(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "23" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "permnet = read_net('permutations.txt')\n", + "len(permnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "23" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rpermnet = read_net('permutations.txt', rev=True)\n", + "len(rpermnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_net(links, pair_sep=', '):\n", + " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def link_ends(link):\n", + " return set((link.left, link.right))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow(initial_line, links):\n", + " line = initial_line\n", + " heights = sorted(set(l.height for l in links))\n", + " for h in heights:\n", + " for l in [l for l in links if l.height == h]:\n", + " if line in link_ends(l):\n", + " line = [e for e in link_ends(l) if e != line][0]\n", + "# print(l, line)\n", + " return line" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def pack(net):\n", + " packed_links = []\n", + " line_heights = collections.defaultdict(lambda: -1)\n", + " for link in sorted(net):\n", + " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", + " line_heights[link.left] = link_height\n", + " line_heights[link.right] = link_height\n", + " packed_links += [Link(link_height, link.left, link.right)]\n", + " return sorted(packed_links)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "14" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in small_net)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in pack(small_net))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10134" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in net)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "pnet = pack(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2286" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def height_groups(net):\n", + " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow_many(in_sequence, net):\n", + " hgs = height_groups(net)\n", + " seq = list(in_sequence)\n", + " for h in hgs:\n", + " for link in hgs[h]:\n", + " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", + " return seq" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'acfbed'" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many('abcdef', small_net))" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " 0 ['0', '1', '2', '3', '4', '5']\n", + " 1 (2, 5) ['0', '1', '5', '3', '4', '2']\n", + " 2 (1, 4) ['0', '4', '5', '3', '1', '2']\n", + " 3 (0, 3) ['3', '4', '5', '0', '1', '2']\n", + " 4 (0, 3) ['0', '4', '5', '3', '1', '2']\n", + " 5 (0, 5) ['2', '4', '5', '3', '1', '0']\n", + " 6 (3, 5) ['2', '4', '5', '0', '1', '3']\n", + " 7 (0, 2) ['5', '4', '2', '0', '1', '3']\n", + " 8 (3, 4) ['5', '4', '2', '1', '0', '3']\n", + " 9 (2, 4) ['5', '4', '0', '1', '2', '3']\n", + "10 (1, 2) ['5', '0', '4', '1', '2', '3']\n", + "11 (0, 4) ['2', '0', '4', '1', '5', '3']\n", + "12 (1, 2) ['2', '4', '0', '1', '5', '3']\n", + "13 (2, 4) ['2', '4', '5', '1', '0', '3']\n", + "14 (0, 4) ['0', '4', '5', '1', '2', '3']\n", + "15 (1, 4) ['0', '2', '5', '1', '4', '3']\n" + ] + } + ], + "source": [ + "for i in range(len(small_net)+1):\n", + " pre_net = small_net[:i]\n", + " if i == 0:\n", + " print('{:2}'.format(i), \n", + " \" \".format(small_net[i-1].left, small_net[i-1].right),\n", + " follow_many(\"012345\", pre_net))\n", + " else:\n", + " print('{:2}'.format(i), \n", + " \"({}, {})\".format(small_net[i-1].left, small_net[i-1].right),\n", + " follow_many(\"012345\", pre_net))\n", + "\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=2, right=5),\n", + " Link(height=1, left=1, right=4),\n", + " Link(height=2, left=0, right=3),\n", + " Link(height=3, left=0, right=3),\n", + " Link(height=4, left=0, right=5),\n", + " Link(height=5, left=3, right=5),\n", + " Link(height=6, left=0, right=2),\n", + " Link(height=7, left=3, right=4),\n", + " Link(height=8, left=2, right=4),\n", + " Link(height=9, left=1, right=2),\n", + " Link(height=10, left=0, right=4),\n", + " Link(height=11, left=1, right=2),\n", + " Link(height=12, left=2, right=4),\n", + " Link(height=13, left=0, right=4),\n", + " Link(height=14, left=1, right=4)]" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "small_net[:15]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10000 loops, best of 3: 42 µs per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many('abcdefghij', small_net)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, net))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zfrasxwigvjoembqcyhplnktud'" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, permnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, rpermnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "follow_many(string.ascii_lowercase, net) == follow_many(string.ascii_lowercase, rpermnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 19.3 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many(string.ascii_lowercase, net)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 loops, best of 3: 18.7 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many(string.ascii_lowercase, pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2+" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/04-amidakuji/amidakuji-solution-2.ipynb b/04-amidakuji/amidakuji-solution-2.ipynb new file mode 100644 index 0000000..3745c3c --- /dev/null +++ b/04-amidakuji/amidakuji-solution-2.ipynb @@ -0,0 +1,1553 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import collections\n", + "import string\n", + "import itertools\n", + "import re" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "Link = collections.namedtuple('Link', 'height left right')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def extract_pairs(net_string):\n", + " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_net_string(net_string):\n", + " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# def read_net(filename):\n", + "# with open(filename) as f:\n", + "# pairs = [re.split('\\D+', p.strip()) for p in f.readlines()]\n", + "# lrs = [(int(lr[1]), int(lr[2])) for lr in pairs]\n", + "# return [Link(h, l, r) \n", + "# for h, (l, r) in enumerate(lrs)]" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_net(filename, rev=False):\n", + " with open(filename) as f:\n", + " pairs = [re.split('\\D+', p.strip()) for p in f.readlines()]\n", + " if rev:\n", + " lrs = [(int(lr[1]), int(lr[2])) for lr in reversed(pairs)]\n", + " else:\n", + " lrs = [(int(lr[1]), int(lr[2])) for lr in pairs]\n", + " return [Link(h, l, r) \n", + " for h, (l, r) in enumerate(lrs)]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[Link(height=0, left=2, right=5),\n", + " Link(height=1, left=1, right=4),\n", + " Link(height=2, left=0, right=3),\n", + " Link(height=3, left=0, right=3),\n", + " Link(height=4, left=0, right=5),\n", + " Link(height=5, left=3, right=5),\n", + " Link(height=6, left=0, right=2),\n", + " Link(height=7, left=3, right=4),\n", + " Link(height=8, left=2, right=4),\n", + " Link(height=9, left=1, right=2),\n", + " Link(height=10, left=0, right=4),\n", + " Link(height=11, left=1, right=2),\n", + " Link(height=12, left=2, right=4),\n", + " Link(height=13, left=0, right=4),\n", + " Link(height=14, left=1, right=4)]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "small_net = read_net('04-small.txt')\n", + "small_net" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10135" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "net = read_net('04-lines.txt')\n", + "len(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "23" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "permnet = read_net('permutations.txt')\n", + "len(permnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "23" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rpermnet = read_net('permutations.txt', rev=True)\n", + "len(rpermnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_net(links, pair_sep=', '):\n", + " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def link_ends(link):\n", + " return set((link.left, link.right))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow(initial_line, links):\n", + " line = initial_line\n", + " heights = sorted(set(l.height for l in links))\n", + " for h in heights:\n", + " for l in [l for l in links if l.height == h]:\n", + " if line in link_ends(l):\n", + " line = [e for e in link_ends(l) if e != line][0]\n", + "# print(l, line)\n", + " return line" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def pack(net):\n", + " packed_links = []\n", + " line_heights = collections.defaultdict(lambda: -1)\n", + " for link in sorted(net):\n", + " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n", + " line_heights[link.left] = link_height\n", + " line_heights[link.right] = link_height\n", + " packed_links += [Link(link_height, link.left, link.right)]\n", + " return sorted(packed_links)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "14" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in small_net)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in pack(small_net))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10134" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in net)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "2286" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max(l.height for l in pack(net))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def height_groups(net):\n", + " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def follow_many(in_sequence, net):\n", + " hgs = height_groups(net)\n", + " seq = list(in_sequence)\n", + " for h in hgs:\n", + " for link in hgs[h]:\n", + " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n", + " return seq" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'acfbedghij'" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many('abcdefghij', small_net))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10000 loops, best of 3: 40.1 µs per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many('abcdefghij', small_net)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, net))" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'zfrasxwigvjoembqcyhplnktud'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, permnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, rpermnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100 loops, best of 3: 19 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "follow_many(string.ascii_lowercase, net)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "pnet = pack(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pairs(net):\n", + " hgs = height_groups(net)\n", + " eps = []\n", + " for h in range(1, max(hgs.keys())):\n", + " for l in hgs[h]:\n", + " o = Link(l.height - 1, l.left, l.right)\n", + " if o in hgs[h-1]:\n", + " eps += [(l, o)]\n", + " return eps" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=115, left=2, right=23), Link(height=114, left=2, right=23)),\n", + " (Link(height=149, left=15, right=23), Link(height=148, left=15, right=23)),\n", + " (Link(height=201, left=0, right=7), Link(height=200, left=0, right=7)),\n", + " (Link(height=207, left=22, right=23), Link(height=206, left=22, right=23)),\n", + " (Link(height=210, left=17, right=23), Link(height=209, left=17, right=23)),\n", + " (Link(height=247, left=16, right=20), Link(height=246, left=16, right=20)),\n", + " (Link(height=418, left=19, right=24), Link(height=417, left=19, right=24)),\n", + " (Link(height=424, left=9, right=21), Link(height=423, left=9, right=21)),\n", + " (Link(height=453, left=3, right=16), Link(height=452, left=3, right=16)),\n", + " (Link(height=456, left=2, right=22), Link(height=455, left=2, right=22)),\n", + " (Link(height=465, left=18, right=20), Link(height=464, left=18, right=20)),\n", + " (Link(height=491, left=14, right=18), Link(height=490, left=14, right=18)),\n", + " (Link(height=552, left=16, right=17), Link(height=551, left=16, right=17)),\n", + " (Link(height=772, left=0, right=7), Link(height=771, left=0, right=7)),\n", + " (Link(height=848, left=1, right=2), Link(height=847, left=1, right=2)),\n", + " (Link(height=895, left=6, right=21), Link(height=894, left=6, right=21)),\n", + " (Link(height=930, left=11, right=13), Link(height=929, left=11, right=13)),\n", + " (Link(height=987, left=8, right=17), Link(height=986, left=8, right=17)),\n", + " (Link(height=988, left=8, right=17), Link(height=987, left=8, right=17)),\n", + " (Link(height=1030, left=9, right=24), Link(height=1029, left=9, right=24)),\n", + " (Link(height=1134, left=4, right=23), Link(height=1133, left=4, right=23)),\n", + " (Link(height=1163, left=14, right=15), Link(height=1162, left=14, right=15)),\n", + " (Link(height=1164, left=14, right=15), Link(height=1163, left=14, right=15)),\n", + " (Link(height=1170, left=2, right=21), Link(height=1169, left=2, right=21)),\n", + " (Link(height=1232, left=6, right=22), Link(height=1231, left=6, right=22)),\n", + " (Link(height=1254, left=13, right=15), Link(height=1253, left=13, right=15)),\n", + " (Link(height=1255, left=1, right=24), Link(height=1254, left=1, right=24)),\n", + " (Link(height=1324, left=3, right=22), Link(height=1323, left=3, right=22)),\n", + " (Link(height=1370, left=15, right=19), Link(height=1369, left=15, right=19)),\n", + " (Link(height=1441, left=0, right=14), Link(height=1440, left=0, right=14)),\n", + " (Link(height=1441, left=11, right=24), Link(height=1440, left=11, right=24)),\n", + " (Link(height=1547, left=11, right=13), Link(height=1546, left=11, right=13)),\n", + " (Link(height=1578, left=14, right=23), Link(height=1577, left=14, right=23)),\n", + " (Link(height=1616, left=7, right=14), Link(height=1615, left=7, right=14)),\n", + " (Link(height=1671, left=8, right=20), Link(height=1670, left=8, right=20)),\n", + " (Link(height=1684, left=14, right=18), Link(height=1683, left=14, right=18)),\n", + " (Link(height=1717, left=0, right=17), Link(height=1716, left=0, right=17)),\n", + " (Link(height=1727, left=7, right=8), Link(height=1726, left=7, right=8)),\n", + " (Link(height=1866, left=8, right=16), Link(height=1865, left=8, right=16)),\n", + " (Link(height=1911, left=1, right=12), Link(height=1910, left=1, right=12)),\n", + " (Link(height=1966, left=20, right=23), Link(height=1965, left=20, right=23)),\n", + " (Link(height=1974, left=5, right=23), Link(height=1973, left=5, right=23)),\n", + " (Link(height=1994, left=18, right=19), Link(height=1993, left=18, right=19)),\n", + " (Link(height=2005, left=2, right=19), Link(height=2004, left=2, right=19)),\n", + " (Link(height=2031, left=12, right=17), Link(height=2030, left=12, right=17)),\n", + " (Link(height=2108, left=7, right=12), Link(height=2107, left=7, right=12)),\n", + " (Link(height=2137, left=7, right=16), Link(height=2136, left=7, right=16)),\n", + " (Link(height=2138, left=7, right=16), Link(height=2137, left=7, right=16)),\n", + " (Link(height=2229, left=10, right=11), Link(height=2228, left=10, right=11)),\n", + " (Link(height=2239, left=16, right=24), Link(height=2238, left=16, right=24)),\n", + " (Link(height=2240, left=16, right=24), Link(height=2239, left=16, right=24)),\n", + " (Link(height=2246, left=4, right=13), Link(height=2245, left=4, right=13)),\n", + " (Link(height=2247, left=4, right=13), Link(height=2246, left=4, right=13)),\n", + " (Link(height=2276, left=19, right=24), Link(height=2275, left=19, right=24)),\n", + " (Link(height=2277, left=4, right=18), Link(height=2276, left=4, right=18))]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eliminable_pairs(pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10 loops, best of 3: 23.5 ms per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "eliminable_pairs(pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminable_pair(hgs):\n", + " for h in range(1, max(hgs.keys())):\n", + " for l in hgs[h]:\n", + " o = Link(l.height - 1, l.left, l.right)\n", + " if o in hgs[h-1]:\n", + " return l, o\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_pairs(net):\n", + " hgs = height_groups(pack(net))\n", + " eliminable_links = eliminable_pair(hgs)\n", + " while eliminable_links:\n", + " net = pack(l for l in net if l not in eliminable_links)\n", + " hgs = height_groups(pack(net))\n", + " eliminable_links = eliminable_pair(hgs)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "enet = eliminate_pairs(pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, net) == follow_many(string.ascii_lowercase, enet)\n", + "assert follow_many(string.ascii_lowercase, pnet) == follow_many(string.ascii_lowercase, enet)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 loop, best of 3: 2.35 s per loop\n" + ] + } + ], + "source": [ + "%%timeit\n", + "eliminate_pairs(pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def triple_pair(height_groups, debug=False):\n", + " ts = []\n", + " for h in range(3, max(height_groups.keys())):\n", + " for d in height_groups[h]:\n", + " if debug: print('d:', d)\n", + " ch = h - 1\n", + " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", + " if debug: print('cs:', cs)\n", + " while ch > 2 and not cs:\n", + " ch -= 1\n", + " cs = [l for l in height_groups[ch] if link_ends(l) & link_ends(d)]\n", + " if debug: print('cs:', cs)\n", + " if len(cs) == 1:\n", + " c = cs[0]\n", + " lines = set((d.left, d.right, c.left, c.right))\n", + " if debug: print('c:', '; lines:', lines)\n", + " bs = [l for l in height_groups[ch-1] if link_ends(l) & lines]\n", + " b = Link(ch - 1, d.left, d.right)\n", + " if debug: print('b:', b, '; bs:', bs)\n", + " if len(bs) == 1 and b in bs:\n", + " ah = b.height - 1\n", + " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", + " if debug: print('ah:', ah, '; als:', als)\n", + " while ah > 0 and not als:\n", + " ah -= 1\n", + " als = [l for l in height_groups[ah] if link_ends(l) & link_ends(c)]\n", + " if debug: print('ah:', ah, '; als:', als)\n", + " a = Link(ah, c.left, c.right)\n", + " if debug: print('a:', a)\n", + " if a in als:\n", + " if debug: print('adding:', a, b, c, d)\n", + " ts += [(a, b, c, d)]\n", + " return ts" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_a_triple_pair(net, debug=False):\n", + " hgs = height_groups(net)\n", + "\n", + " tps = triple_pair(hgs)\n", + " if debug: print('eatp', tps)\n", + " if tps:\n", + " a, b, c, d = tps[0]\n", + " x = Link(b.height - 0.5, b.left, b.right)\n", + " y = Link(b.height, a.left, a.right)\n", + " if debug: print('removing', a, b, c, d, '; adding', x, y)\n", + " return pack([l for l in net if l not in [a, b, c, d]] + [x, y])\n", + " return None" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[(Link(height=8, left=1, right=5),\n", + " Link(height=9, left=1, right=21),\n", + " Link(height=10, left=1, right=5),\n", + " Link(height=11, left=1, right=21)),\n", + " (Link(height=40, left=16, right=23),\n", + " Link(height=41, left=16, right=19),\n", + " Link(height=42, left=16, right=23),\n", + " Link(height=43, left=16, right=19)),\n", + " (Link(height=62, left=0, right=10),\n", + " Link(height=63, left=10, right=13),\n", + " Link(height=64, left=0, right=10),\n", + " Link(height=65, left=10, right=13)),\n", + " (Link(height=137, left=23, right=24),\n", + " Link(height=139, left=0, right=24),\n", + " Link(height=140, left=23, right=24),\n", + " Link(height=141, left=0, right=24)),\n", + " (Link(height=138, left=10, right=21),\n", + " Link(height=139, left=2, right=10),\n", + " Link(height=140, left=10, right=21),\n", + " Link(height=141, left=2, right=10)),\n", + " (Link(height=139, left=2, right=10),\n", + " Link(height=140, left=10, right=21),\n", + " Link(height=141, left=2, right=10),\n", + " Link(height=142, left=10, right=21)),\n", + " (Link(height=156, left=6, right=11),\n", + " Link(height=157, left=3, right=6),\n", + " Link(height=158, left=6, right=11),\n", + " Link(height=159, left=3, right=6)),\n", + " (Link(height=184, left=2, right=21),\n", + " Link(height=185, left=5, right=21),\n", + " Link(height=186, left=2, right=21),\n", + " Link(height=187, left=5, right=21)),\n", + " (Link(height=272, left=7, right=13),\n", + " Link(height=273, left=7, right=11),\n", + " Link(height=274, left=7, right=13),\n", + " Link(height=275, left=7, right=11)),\n", + " (Link(height=290, left=14, right=15),\n", + " Link(height=291, left=5, right=15),\n", + " Link(height=292, left=14, right=15),\n", + " Link(height=293, left=5, right=15)),\n", + " (Link(height=387, left=1, right=8),\n", + " Link(height=389, left=8, right=15),\n", + " Link(height=390, left=1, right=8),\n", + " Link(height=391, left=8, right=15)),\n", + " (Link(height=420, left=14, right=22),\n", + " Link(height=422, left=14, right=18),\n", + " Link(height=423, left=14, right=22),\n", + " Link(height=424, left=14, right=18)),\n", + " (Link(height=432, left=5, right=19),\n", + " Link(height=433, left=1, right=19),\n", + " Link(height=434, left=5, right=19),\n", + " Link(height=435, left=1, right=19)),\n", + " (Link(height=454, left=0, right=15),\n", + " Link(height=455, left=14, right=15),\n", + " Link(height=456, left=0, right=15),\n", + " Link(height=457, left=14, right=15)),\n", + " (Link(height=546, left=13, right=21),\n", + " Link(height=547, left=6, right=21),\n", + " Link(height=548, left=13, right=21),\n", + " Link(height=549, left=6, right=21)),\n", + " (Link(height=620, left=17, right=23),\n", + " Link(height=621, left=1, right=23),\n", + " Link(height=622, left=17, right=23),\n", + " Link(height=623, left=1, right=23)),\n", + " (Link(height=699, left=8, right=15),\n", + " Link(height=700, left=3, right=15),\n", + " Link(height=701, left=8, right=15),\n", + " Link(height=702, left=3, right=15)),\n", + " (Link(height=789, left=7, right=24),\n", + " Link(height=790, left=8, right=24),\n", + " Link(height=791, left=7, right=24),\n", + " Link(height=792, left=8, right=24)),\n", + " (Link(height=795, left=8, right=13),\n", + " Link(height=796, left=4, right=8),\n", + " Link(height=797, left=8, right=13),\n", + " Link(height=798, left=4, right=8)),\n", + " (Link(height=809, left=16, right=17),\n", + " Link(height=810, left=3, right=16),\n", + " Link(height=811, left=16, right=17),\n", + " Link(height=812, left=3, right=16)),\n", + " (Link(height=900, left=2, right=15),\n", + " Link(height=901, left=13, right=15),\n", + " Link(height=902, left=2, right=15),\n", + " Link(height=903, left=13, right=15)),\n", + " (Link(height=921, left=2, right=15),\n", + " Link(height=922, left=15, right=16),\n", + " Link(height=923, left=2, right=15),\n", + " Link(height=924, left=15, right=16)),\n", + " (Link(height=961, left=2, right=15),\n", + " Link(height=962, left=2, right=14),\n", + " Link(height=963, left=2, right=15),\n", + " Link(height=964, left=2, right=14)),\n", + " (Link(height=976, left=13, right=18),\n", + " Link(height=979, left=18, right=19),\n", + " Link(height=980, left=13, right=18),\n", + " Link(height=981, left=18, right=19)),\n", + " (Link(height=985, left=5, right=16),\n", + " Link(height=986, left=2, right=5),\n", + " Link(height=987, left=5, right=16),\n", + " Link(height=988, left=2, right=5)),\n", + " (Link(height=1050, left=9, right=24),\n", + " Link(height=1054, left=9, right=18),\n", + " Link(height=1055, left=9, right=24),\n", + " Link(height=1056, left=9, right=18)),\n", + " (Link(height=1159, left=11, right=21),\n", + " Link(height=1160, left=11, right=14),\n", + " Link(height=1161, left=11, right=21),\n", + " Link(height=1162, left=11, right=14)),\n", + " (Link(height=1284, left=0, right=11),\n", + " Link(height=1285, left=0, right=14),\n", + " Link(height=1286, left=0, right=11),\n", + " Link(height=1287, left=0, right=14)),\n", + " (Link(height=1331, left=4, right=9),\n", + " Link(height=1333, left=4, right=10),\n", + " Link(height=1334, left=4, right=9),\n", + " Link(height=1335, left=4, right=10)),\n", + " (Link(height=1332, left=12, right=18),\n", + " Link(height=1333, left=12, right=24),\n", + " Link(height=1334, left=12, right=18),\n", + " Link(height=1335, left=12, right=24)),\n", + " (Link(height=1343, left=0, right=17),\n", + " Link(height=1344, left=0, right=23),\n", + " Link(height=1345, left=0, right=17),\n", + " Link(height=1346, left=0, right=23)),\n", + " (Link(height=1357, left=4, right=16),\n", + " Link(height=1358, left=16, right=17),\n", + " Link(height=1359, left=4, right=16),\n", + " Link(height=1360, left=16, right=17)),\n", + " (Link(height=1441, left=6, right=20),\n", + " Link(height=1443, left=16, right=20),\n", + " Link(height=1444, left=6, right=20),\n", + " Link(height=1445, left=16, right=20)),\n", + " (Link(height=1464, left=17, right=23),\n", + " Link(height=1465, left=3, right=17),\n", + " Link(height=1466, left=17, right=23),\n", + " Link(height=1467, left=3, right=17)),\n", + " (Link(height=1540, left=8, right=23),\n", + " Link(height=1541, left=7, right=23),\n", + " Link(height=1542, left=8, right=23),\n", + " Link(height=1543, left=7, right=23)),\n", + " (Link(height=1570, left=0, right=1),\n", + " Link(height=1571, left=1, right=21),\n", + " Link(height=1572, left=0, right=1),\n", + " Link(height=1573, left=1, right=21)),\n", + " (Link(height=1600, left=15, right=22),\n", + " Link(height=1603, left=7, right=15),\n", + " Link(height=1604, left=15, right=22),\n", + " Link(height=1605, left=7, right=15)),\n", + " (Link(height=1632, left=12, right=18),\n", + " Link(height=1634, left=12, right=20),\n", + " Link(height=1635, left=12, right=18),\n", + " Link(height=1636, left=12, right=20)),\n", + " (Link(height=1702, left=13, right=24),\n", + " Link(height=1705, left=14, right=24),\n", + " Link(height=1706, left=13, right=24),\n", + " Link(height=1707, left=14, right=24)),\n", + " (Link(height=1721, left=3, right=24),\n", + " Link(height=1722, left=3, right=21),\n", + " Link(height=1723, left=3, right=24),\n", + " Link(height=1724, left=3, right=21)),\n", + " (Link(height=1722, left=3, right=21),\n", + " Link(height=1723, left=3, right=24),\n", + " Link(height=1724, left=3, right=21),\n", + " Link(height=1725, left=3, right=24)),\n", + " (Link(height=1762, left=0, right=21),\n", + " Link(height=1763, left=13, right=21),\n", + " Link(height=1764, left=0, right=21),\n", + " Link(height=1765, left=13, right=21)),\n", + " (Link(height=1769, left=7, right=9),\n", + " Link(height=1770, left=7, right=12),\n", + " Link(height=1771, left=7, right=9),\n", + " Link(height=1772, left=7, right=12)),\n", + " (Link(height=1914, left=10, right=24),\n", + " Link(height=1915, left=8, right=24),\n", + " Link(height=1916, left=10, right=24),\n", + " Link(height=1917, left=8, right=24)),\n", + " (Link(height=1920, left=4, right=23),\n", + " Link(height=1921, left=3, right=4),\n", + " Link(height=1922, left=4, right=23),\n", + " Link(height=1923, left=3, right=4)),\n", + " (Link(height=2023, left=4, right=7),\n", + " Link(height=2024, left=7, right=15),\n", + " Link(height=2025, left=4, right=7),\n", + " Link(height=2026, left=7, right=15)),\n", + " (Link(height=2025, left=8, right=19),\n", + " Link(height=2031, left=8, right=15),\n", + " Link(height=2032, left=8, right=19),\n", + " Link(height=2033, left=8, right=15)),\n", + " (Link(height=2152, left=10, right=15),\n", + " Link(height=2153, left=10, right=16),\n", + " Link(height=2154, left=10, right=15),\n", + " Link(height=2155, left=10, right=16)),\n", + " (Link(height=2194, left=22, right=24),\n", + " Link(height=2195, left=7, right=22),\n", + " Link(height=2196, left=22, right=24),\n", + " Link(height=2197, left=7, right=22)),\n", + " (Link(height=2211, left=5, right=6),\n", + " Link(height=2212, left=6, right=14),\n", + " Link(height=2213, left=5, right=6),\n", + " Link(height=2214, left=6, right=14))]" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hgs = height_groups(enet)\n", + "triple_pair(hgs)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "etnet = eliminate_a_triple_pair(enet)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, etnet) == follow_many(string.ascii_lowercase, enet)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def eliminate_triple_pairs(net):\n", + " print(len(net))\n", + " new_net = eliminate_a_triple_pair(net)\n", + " while new_net:\n", + " print(len(net))\n", + " net = new_net\n", + " new_net = eliminate_a_triple_pair(net)\n", + " return net" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10033\n", + "10033\n", + "10031\n", + "10029\n", + "10027\n", + "10025\n", + "10023\n", + "10021\n", + "10019\n", + "10017\n", + "10015\n", + "10013\n", + "10011\n", + "10009\n", + "10007\n", + "10005\n", + "10003\n", + "10001\n", + "9999\n", + "9997\n", + "9995\n", + "9993\n", + "9991\n", + "9989\n", + "9987\n", + "9985\n", + "9983\n", + "9981\n", + "9979\n", + "9977\n", + "9975\n", + "9973\n", + "9971\n", + "9969\n", + "9967\n", + "9965\n", + "9963\n", + "9961\n", + "9959\n", + "9957\n", + "9955\n", + "9953\n", + "9951\n", + "9949\n", + "9947\n", + "9945\n", + "9943\n", + "9941\n", + "9939\n" + ] + } + ], + "source": [ + "setnet = eliminate_triple_pairs(enet)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9937" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(setnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "assert follow_many(string.ascii_lowercase, etnet) == follow_many(string.ascii_lowercase, enet)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, etnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, setnet))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, enet))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, net))" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eliminable_pairs(etnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(10135, 10031)" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(net), len(etnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def simplify(net0):\n", + " netp = eliminate_pairs(net0)\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " while new_net:\n", + "# print('sipl', len(net0), len(netp), len(new_net))\n", + " netp = eliminate_pairs(new_net)\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " return netp" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "simple_net = simplify(pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, simple_net)) == ''.join(follow_many(string.ascii_lowercase, net))" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, simple_net))" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'doqzmbishkwunvltpcexyjgfra'" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, net))" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9931" + ] + }, + "execution_count": 51, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(simple_net)" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def simplify_with_checks(net0):\n", + " netp = eliminate_pairs(net0)\n", + " if follow_many(string.ascii_lowercase, net0) != follow_many(string.ascii_lowercase, netp):\n", + " print('pairs', eliminable_pairs(net0))\n", + " return net0\n", + " else:\n", + " print('pairs ok')\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", + " hg = find_height_groups(netp)\n", + " print('triple', triple_pair_hg(hg))\n", + " return netp\n", + " else:\n", + " print('triple ok')\n", + " while new_net:\n", + "# print('sipl', len(net0), len(netp), len(new_net))\n", + " netp = eliminate_pairs(new_net)\n", + " if follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", + " print('pairs', eliminable_pairs(new_net))\n", + " return new_net\n", + " else:\n", + " print('pairs ok')\n", + " new_net = eliminate_a_triple_pair(netp)\n", + " if new_net and follow_many(string.ascii_lowercase, new_net) != follow_many(string.ascii_lowercase, netp):\n", + " hg = find_height_groups(netp)\n", + " print('triple', triple_pair_hg(hg))\n", + " return netp\n", + " else:\n", + " print('triple ok')\n", + " print('** done')\n", + " return netp" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "pairs ok\n", + "triple ok\n", + "** done\n" + ] + } + ], + "source": [ + "spnet = simplify_with_checks(pnet)" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "''.join(follow_many(string.ascii_lowercase, spnet)) == ''.join(follow_many(string.ascii_lowercase, net))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9931" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "len(spnet)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.2+" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/04-amidakuji/day4.clj b/04-amidakuji/day4.clj new file mode 100644 index 0000000..3c5d494 --- /dev/null +++ b/04-amidakuji/day4.clj @@ -0,0 +1,70 @@ +(ns day4 + (:require [clojure.string :as str])) + +(defstruct link :height :left :right) + +; (def network (str/split-lines (slurp "../04-small.txt"))) +(def network (str/split-lines (slurp "../04-lines.txt"))) + +(defn parse-link [l, h] + (let [endss (rest (str/split l #"\D+")) + ends (map #(Integer/parseInt %) endss)] + (struct-map link + :height h + :left (first ends) + :right (second ends)))) + +(defn parse-network [links] + (map-indexed + (fn [i l] (parse-link l i)) + links)) + +(def parsed-network + (parse-network network)) + + +(def initial + (str/split "abcdefghijklmnopqrstuvwxyz" #"")) + +(defn apply-link [items link] + (let [li (get link :left) + ri (get link :right) + le (nth items li) + re (nth items ri) + pre (subvec items 0 li) + mid (subvec items (inc li) ri) + suf (subvec items (inc ri))] + (into [] (concat pre (vector re) mid (vector le) suf)))) + +(defn follow [items links] + (reduce apply-link items links)) + + +(defn lane-count [links] + (inc (apply max (map (fn [l] (get l :right)) links)))) + +(defn initial-heights [links] + (vec (replicate (lane-count links) -1))) + +(defn pack-one [lane-heights link] + (let + [li (get link :left) + ri (get link :right) + new-height (inc (max (nth lane-heights li) + (nth lane-heights ri)))] + (assoc lane-heights li new-height ri new-height))) + +(defn pack [lane-heights links] + (reduce pack-one lane-heights links)) + + +(spit "day4.out" (prn-str + (str/join (follow initial parsed-network)))) + +(spit "day4.out" (prn-str + (apply max + (pack + (initial-heights parsed-network) + parsed-network))) + :append true) + diff --git a/04-amidakuji/packing-variants.svg b/04-amidakuji/packing-variants.svg new file mode 100644 index 0000000..07c4963 --- /dev/null +++ b/04-amidakuji/packing-variants.svg @@ -0,0 +1,675 @@ + +image/svg+xml1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/packing-variants.svg.png b/04-amidakuji/packing-variants.svg.png new file mode 100644 index 0000000..a696960 Binary files /dev/null and b/04-amidakuji/packing-variants.svg.png differ diff --git a/04-amidakuji/permutations.txt b/04-amidakuji/permutations.txt new file mode 100644 index 0000000..576ae5d --- /dev/null +++ b/04-amidakuji/permutations.txt @@ -0,0 +1,23 @@ +(0, 3) +(0, 25) +(1, 14) +(1, 11) +(1, 20) +(1, 24) +(1, 17) +(1, 2) +(1, 16) +(1, 15) +(1, 19) +(1, 23) +(1, 5) +(4, 12) +(4, 13) +(4, 21) +(4, 9) +(4, 10) +(4, 22) +(4, 6) +(4, 8) +(4, 7) +(4, 18) diff --git a/04-amidakuji/small-expanded-trace.svg b/04-amidakuji/small-expanded-trace.svg new file mode 100644 index 0000000..3bed4a4 --- /dev/null +++ b/04-amidakuji/small-expanded-trace.svg @@ -0,0 +1,555 @@ + +image/svg+xml0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/small-expanded-trace.svg.png b/04-amidakuji/small-expanded-trace.svg.png new file mode 100644 index 0000000..7328878 Binary files /dev/null and b/04-amidakuji/small-expanded-trace.svg.png differ diff --git a/04-amidakuji/small-expanded.svg b/04-amidakuji/small-expanded.svg new file mode 100644 index 0000000..2c4b4be --- /dev/null +++ b/04-amidakuji/small-expanded.svg @@ -0,0 +1,520 @@ + +image/svg+xml0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/small-expanded.svg.png b/04-amidakuji/small-expanded.svg.png new file mode 100644 index 0000000..b720b61 Binary files /dev/null and b/04-amidakuji/small-expanded.svg.png differ diff --git a/04-amidakuji/small-packed.svg b/04-amidakuji/small-packed.svg new file mode 100644 index 0000000..b5c3808 --- /dev/null +++ b/04-amidakuji/small-packed.svg @@ -0,0 +1,522 @@ + +image/svg+xml0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/small-packed.svg.png b/04-amidakuji/small-packed.svg.png new file mode 100644 index 0000000..eff606c Binary files /dev/null and b/04-amidakuji/small-packed.svg.png differ diff --git a/04-amidakuji/small-unpaired.svg b/04-amidakuji/small-unpaired.svg new file mode 100644 index 0000000..2dfe663 --- /dev/null +++ b/04-amidakuji/small-unpaired.svg @@ -0,0 +1,405 @@ + +image/svg+xml0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/small-untriple-1.svg b/04-amidakuji/small-untriple-1.svg new file mode 100644 index 0000000..e7554c3 --- /dev/null +++ b/04-amidakuji/small-untriple-1.svg @@ -0,0 +1,405 @@ + +image/svg+xml0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/small-untriple-1.svg.png b/04-amidakuji/small-untriple-1.svg.png new file mode 100644 index 0000000..6203978 Binary files /dev/null and b/04-amidakuji/small-untriple-1.svg.png differ diff --git a/04-amidakuji/small-untriple-2.svg b/04-amidakuji/small-untriple-2.svg new file mode 100644 index 0000000..97413e4 --- /dev/null +++ b/04-amidakuji/small-untriple-2.svg @@ -0,0 +1,373 @@ + +image/svg+xml0 +1 +2 +3 +4 +5 + \ No newline at end of file diff --git a/04-amidakuji/untriple-general.svg b/04-amidakuji/untriple-general.svg new file mode 100644 index 0000000..ced5c10 --- /dev/null +++ b/04-amidakuji/untriple-general.svg @@ -0,0 +1,321 @@ + +image/svg+xml \ No newline at end of file diff --git a/04-amidakuji/untriple-general.svg.png b/04-amidakuji/untriple-general.svg.png new file mode 100644 index 0000000..8b8fcd3 Binary files /dev/null and b/04-amidakuji/untriple-general.svg.png differ