Facebook Hacker Cup 2012: Billboards Solution | Programming Logic


Facebook Hacker Cup 2012: Billboards Solution | Programming Logic
We are starting preparations for Hacker Cup 2013 really early. Our first step is to prepare billboards to advertise the contest. We have text for hundreds of billboards, but we need your help to design them.
The billboards are of different sizes, but are all rectangular. The billboard widths and heights are all integers. We will supply you with the size in inches and the text we want printed. We want you to tell us how large we can print the text, such that it fits on the billboard without splitting any words across lines. Since this is to attract hackers like yourself, we will use a monospace font, meaning that all characters are of the same width (e.g.. 'l' and 'm' take up the same horizontal space, as do space characters). The characters in our font are of equal width and height, and there will be no additional spacing between adjacent characters or adjacent rows.
Let's say we want to print the text "Facebook Hacker Cup 2013″ on a 350×100″ billboard. If we use a font size of 33″ per character, then we can print "Facebook" on the first line, "Hacker Cup" on the second and "2013" on the third. The widest of the three lines is "Hacker Cup", which is 330″ wide. There are three lines, so the total height is 99″. We cannot go any larger.
Input
The first line of the input file contains a single integer T: the number of test cases. T lines follow, each representing a single test case in the form "W H S". W and H are the width and height in inches of the available space. S is the text to be written.
Output
Output T lines, one for each test case. For each case, output "Case #t: s", where t is the test case number (starting from 1) and s is the maximum font size, in inches per character, we can use. The size must be an integral number of inches. If the text does not fit when printed at a size of 1″, then output 0.
Constraints
1 ≤ T ≤ 20
1 ≤ W, H ≤ 1000
The text will contain only lower-case letters a-z, upper-case letters A-Z, digits 0-9 and the space character
The text will not start or end with the space character, and will never contain two adjacent space characters
The text in each case contains at most 1000 characters

Why the correct approach to a problem is important
As one can see, the problem consists in maximizing the font size that can be used for a given message on a particular billboard size. Where it gets tricky is that it seems that you need to determine the optimum layout of the text to maximize the possible font size, I did this while Peter solved the problem in a more clever way. While my experience with programming contests hinted at my solution being too complicated, I went ahead and did it anyway without stepping back and re-analyzing the problem, this proved to be a mistake.
The issue here is that determining the optimum layout is NOT a trivial problem and it is the main source of the high runtime complexity in my solution; basically I made a solution for something that did not need to be solved in this particular problem.
eter, on the other hand, decided to do a binary search on the possible font sizes and see whether a particular size can be fit onto the billboard. To do this he just used up space on the billboard at a given size until he ran out of words or ran out of space. In the first case it means the text did fit and went on to try larger font sizes while the second case means it did not fit and went on to try smaller sizes.
In retrospective, this makes much more sense because the limitations of the problem allow for far fewer font sizes than text distributions and ultimately this takes care of the problem at hand without having to go through the tricky part of arranging the words. His solution is roughly O(n*logm) where n is the number of characters that need to be printed and m is the billboard size on its smallest side.
As one can see, the main lesson to be learned here is that approaching a problem from the correct angle allows you to come up with a solution that avoids having to bother with solving things that are not really relevant to that particular problem. “Billboards” requires you to maximize a font size and my solution did much more than that; while those other thing that were solved can be useful in other situations, it is not really relevant for the purpose of the contest.
This is why in contests and many other programming challenges, one has to take a step back and really figure out what needs to be solved and what doesn’t.
   private static Scanner in = new Scanner(System.in);

    public static void main(String[] args) {
        int cases = in.nextInt();
        int caseNumber = 1;
        in.nextLine(); // Discards the remaining input line
        while (cases-- > 0) {
            int width = in.nextInt();
            int height = in.nextInt();
            String[] message = in.nextLine().trim().split(" ");

            int minSize = 1;
            int maxSize = Math.min(height, width);
            int bestSize = -1;

            // Does a binary search on the possible font sizes to see which fits
            while (minSize <= maxSize) {
                // The font size that will be attempted
                int currentTargetSize = (minSize + maxSize) / 2;

                // See if the given font size fits
                if (sizeIsDoable(currentTargetSize, width, height, message)) {
                    // It fits, save as largest so far and try even larger
                    minSize = currentTargetSize + 1;
                    bestSize = currentTargetSize;
                } else {
                    // Doesn't fit, try smaller sizes
                    maxSize = currentTargetSize - 1;
                }
            }
            System.out.println("Case #" + caseNumber + ": " + bestSize);
            caseNumber++;
        }
    }
    private static boolean sizeIsDoable(int targetSize, int width, int height,
            String[] message) {
        int currentWidth = 0;
        int currentHeight = 0;
        int currentMessagePosition = 0;

        // While it can keep adding lines
        while (currentHeight + targetSize <= height) {
            // If the entire message has been fitted in, return true
            if (currentMessagePosition == message.length) {
                return true;
            }
            int nextWordLength = message[currentMessagePosition].length();

            // If the next word will still fit in the current line
            while (currentWidth + nextWordLength * targetSize <= width) {
                currentWidth += nextWordLength * targetSize;
                currentMessagePosition++; // Accounts for the space
                
                // If the entire message has been fitted in, return true
                if (currentMessagePosition == message.length) {
                    return true;
                }
                nextWordLength = message[currentMessagePosition].length() + 1;
            }
            currentWidth = 0;
            currentHeight += targetSize;
        }
        
        // Did not fit, return false
        return false;
    }
http://notes.tweakblogs.net/blog/7524/facebook-hacker-cup-qualification-round-problem-analysis.html
That leaves the question of how to determine whether a certain text fits on the billboard. A nice trick is to not scale up the text, but to scale down the billboard and pretend our font always needs exactly 1 unit of length per letter. Then, we simply try to put as many words on each line as possible, truncating lines if necessary to end on a word boundary.
def fits(W, H, L):
    'Returns whether text L fits on a W by H billboard.'
    pos = 0
    for line in range(H):
        pos += W
        if pos >= len(L):
            return True
        pos = L.rfind(' ', 0, pos + 1) + 1
    return False

def solve(W, H, L):
    size = 0
    while fits(W//(size + 1), H//(size + 1), L):
        size = size + 1
    return size

http://www.programminglogic.com/facebook-hacker-cup-2012-billboards-solution/
https://www.facebook.com/notes/facebook-hacker-cup/2012-qualification-round-solutions/371108282905079
Read full article from Facebook Hacker Cup 2012: Billboards Solution | Programming Logic

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts