Created
February 20, 2013 11:23
-
-
Save sazzer/4994891 to your computer and use it in GitHub Desktop.
Solution for the pat-the-unicorns problem at http://zeroturnaround.com/fun/magical-java-puzzle-pat-the-unicorns/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.junit.Test; | |
import java.util.Arrays; | |
import java.util.HashSet; | |
import java.util.List; | |
import java.util.Set; | |
public class Unicorns { | |
@Test | |
public void patUnicorns() { | |
for (int i = 0; i < (Math.random() * 500) + 2; i++) { | |
if (Unicorn.pat()) { | |
System.out.println("UNICORN #1: PAT THIS UNICORN ONCE"); | |
} | |
} | |
for (int i = 0; i < (Math.random() * 500) + 2; i++) { | |
if (Unicorn.pat()) { | |
System.out.println("UNICORN #2: PAT THIS UNICORN ONCE"); | |
} | |
} | |
System.out.println("END OF PROGRAM"); | |
} | |
public static class Unicorn { | |
/** The set of stack traces that we've seen */ | |
private static Set<List<StackTraceElement>> stacks = new HashSet<List<StackTraceElement>>(); | |
/** | |
* Pat the unicorn. Return true if the caller has never patted us before. This includes the exact line of code | |
* as the caller and not just the class/method. | |
* Note that this implementation is truly horrific, and uses the fact that an Exception knows its stack trace | |
* and the stack trace knows the calling line numbers of every method in the stack above us. We then remember | |
* the stack trace of every caller, and we return true only if the stack trace is one we've never seen before. | |
* @return true if the line number has never patted us before. False if they have | |
*/ | |
public static boolean pat() { | |
try { | |
throw new Exception(); | |
} | |
catch (Exception e) { | |
e.fillInStackTrace(); | |
List<StackTraceElement> ste = Arrays.asList(e.getStackTrace()); | |
boolean result = true; | |
if (stacks.contains(ste)) { | |
result = false; | |
} | |
stacks.add(ste); | |
return result; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment