{"id":416,"date":"2011-06-25T18:27:45","date_gmt":"2011-06-25T18:27:45","guid":{"rendered":"http:\/\/www.themissingdocs.net\/wordpress\/?p=416"},"modified":"2011-06-25T18:27:45","modified_gmt":"2011-06-25T18:27:45","slug":"tco11-r2","status":"publish","type":"post","link":"https:\/\/www.themissingdocs.net\/?p=416","title":{"rendered":"TCO11 R2"},"content":{"rendered":"<p>No t-shirts for me this year&#8230;<\/p>\n<p>Only 760 out of 850 potential contestants turned up, and I came 443rd, short of the required top 350 which advance to shirt round.\u00a0 I think 7 Aussies qualified for this round, but only 6 registered.\u00a0 Out of those 6, 3 failed to get any points (possibly fell asleep!), 2 of us around the 440th place, and John Dethridge advances 315th place.<\/p>\n<p>I could have made it through to get a t-shirt, but I took too long to realise I had an overflow bug in my count number of powers of k less than or equal to n loop.\u00a0 I really should have implemented it using a divide, but also I should stop using 32bit integers &#8211; except where absolutely needed.\u00a0 One day I will learn!<\/p>\n<p>I had time enough to do question 2, but it was not easy and I was very tired.\u00a0 I looked for corner cases for Q1 hoping to get the single challenge I needed to get through, but the given examples covered all of them, so there was basically no one to challenge.<\/p>\n<p><strong>Q1) How many boolean sequences of length n are are plausible, if the ith entry is the answer to whether a number is divisible by i.\u00a0 Return answer mod 1000000007 since input can be up to 1000000.<\/strong><\/p>\n<p>A1) I was a bit slow in realizing the correct approach here, but it wasn&#8217;t too long before I realized the answer was related purely based on the primes less than or equal to n.\u00a0 Specifically each prime doubled the answer at a minimum, more if different powers of that prime were less than n as well.\u00a0 More specifically if the maximum power of a prime p less than or equal to n is p^k then the prime independently contributes (k+1) ways to build the final sequence.\u00a0 So, multiply all these factors mod 1 billion and 7 and you have your answer.<\/p>\n<p>What kept me too slow to advance was it took a long time to realize that my loop for determining max power was potentially squaring numbers just less than 1 million, which doesn&#8217;t fit into 32bit integer.\u00a0 I had correctly identified that I needed to use 64bit integers for the result as small powers go more than squared and so mod 1 billion and 7 is not sufficient to keep you under 32bit limit, but I should have used them more liberally from the start.<\/p>\n<p><strong>Q2) Given an square array of strings which are built up by concatenating the smallest of the vertically and horizontally previous cells in front of the largest, where the first row and column are provided (and each have a single character in each cell), return up to 50 characters starting at a specific index of the string in the far bottom right corner (the largest string).\u00a0 Note: no character will be repeated in the first row or column.<\/strong><\/p>\n<p>A2) Pascals triangle gives the length of each cell &#8211; and with a worst case of 30&#215;30 the length of the largest string can be very large!<\/p>\n<p>Having built up pascals triangle, all that is really needed is to know for each cell, which of the two vertically and horizontally previous cells is lexically smallest.\u00a0 As usual, &#8216;all&#8217; is of course the whole actual problem.\u00a0 I thought I was on the right track for this, but I suspect its performance is too slow, the trick being to define a memotizable recursion which doesn&#8217;t require an offset and length for comparison for both cells involved.<\/p>\n<p>Edit: Before I managed to fall asleep I think I solved this.\u00a0 The memotizable recursion is &#8216;which is smaller for 2 cells on a common diagonal?&#8217;.\u00a0 If the 2 cells are neighbours on a diagonal, they are built out of the 3 cells on the previous diagonal. From there it can be seen that the middle cell can be ignored as it is either the common start, the common end or transitive property applies and you can just compare the outside pair.\u00a0 If they are not neighbours, you get 4 cells which are in neighbouring pairs.\u00a0 By using the memotized recursion on each neighbouring pair you can then reapply the recursion on the smallest of each pair.\u00a0 Memotization ensures that the algorithm runs in O(n^3), both in space and time.<\/p>\n<p>Now if you can read between the lines there you&#8217;ll notice that I have failed to take in to account an important special case.\u00a0 Once the recursion hits an edge we need to compare that edge value to a cell on the same diagonal.\u00a0 Unless that other cell is on the opposite edge of the diagonal, this doesn&#8217;t appear trivial.\u00a0 However the original problem was &#8216;determine the nth character in the bottom right hand corner&#8217;, we can trivially expand that to also &#8216;determine the first character in every cell&#8217;.\u00a0 Since the answer to these new questions depends on the which is smaller question, it might seem we are at an impasse &#8211; but because each question is entirely answered by considering the previous diagonal alone, we can invoke mutual memotized recursion safely.<\/p>\n<p>All that remains is to prove that this method works.\u00a0 Something which is obvious is that each cell is only made up of characters which appear on the edge in the same or lesser row, or same or lesser column.\u00a0 Thus since every comparison in the algorithm involves two different cells on the same diagonal, it can be seen that the termination comparison is never equal, as an edge on a diagonal compared to a different cell in the diagonal cannot be equal as the cells on the diagonal cannot be made out of that edges character and all edge characters are distinct.<\/p>\n<p><strong>Q3) Given 2 arrays of positions, and a set of &#8216;connections&#8217; from one array to another, determine the number of orderings of the two arrays such that no connections cross. (Return mod 1000000007 as with arrays of length 50, the answer might be very large.)<\/strong><\/p>\n<p>A3) Edit: Also solved this one before going to sleep.\u00a0 I think it is easier than Q2 even.<\/p>\n<p>First step, DFS the connections to form them into groups.\u00a0 If you discover a loop, return 0.\u00a0 Now we have our first factor in the answer, n! where n is the number of groups.\u00a0 Each group is going to be independent, since there is no way they can cross each other without causing a crossed connection so the n! comes from the orderings of the n groups.<\/p>\n<p>Each group now contributes an independent factor.\u00a0 There are 2 scenarios, either every edge in the group joins at a common endpoint, or there are 2 or more locations in the group where 2 or more edges join.\u00a0 If it is a single common endpoint the answer is k! where k is the number of edges in the group.\u00a0 If it is more than two common endpoints we can either arrange said endpoints left to right, or right to left &#8211; so that gives a factor of 2.\u00a0 Then for each endpoint we also get a factor of (m-2)! where m is the number of edges which join to that endpoint.<\/p>\n<p>Finally we have additional factors for the array locations which do not participate in a connection.\u00a0 These can be added in any place in any order, so if there are n spots in the array and k of them are endpoints of 1 or more connections, the additional factor is n!\/k!.\u00a0 Since there are 2 arrays, this gives 2 more factors total.\u00a0 Multiply everything together using repeated modulo and 64 bit integers&#8230; and we should be done.<\/p>\n<p>All in all it makes me wish I was less tired when I did the competition.\u00a0 I think I could have solved that second question during the competition if I had of been able to concentrate at all.\u00a0 Third one, well I&#8217;m pretty sure I would have run out of time having only opened it with a few minutes to go.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No t-shirts for me this year&#8230; Only 760 out of 850 potential contestants turned up, and I came 443rd, short of the required top 350 which advance to shirt round.\u00a0 I think 7 Aussies qualified for this round, but only 6 registered.\u00a0 Out of those 6, 3 failed to get any points (possibly fell asleep!), &hellip; <a href=\"https:\/\/www.themissingdocs.net\/?p=416\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">TCO11 R2<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-416","post","type-post","status-publish","format-standard","hentry","category-code-competitions"],"_links":{"self":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/posts\/416","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=416"}],"version-history":[{"count":0,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=\/wp\/v2\/posts\/416\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=416"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=416"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.themissingdocs.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}