Skip to content

Code kata to figure out efficient permutation generation and transformation (Colloquially, brute forcing 🕵️)

License

Notifications You must be signed in to change notification settings

MrGraversen/Arrow

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Arrow

Code kata to figure out efficient permutation generation and transformation (Colloquially, brute forcing 🕵️)

Goals

  • Generate permutations of an ideograph (the english alphabet, numbers, emojis, whatever!)
  • Non-recursive computation (space complexity of semi-infinite resources punishes the stack)
  • Expose permutations as an infinite resource (A java.util Stream<String> in this case)
  • Work on a continous flow of computed permutations in a chain of operations, allowing a "lifecycle" for the infinite resource
  • Allow async computation
  • Use JMH to measure results

Examples

Simply getting started

final CombinationsService combinationsService = CombinationsService.usingEnglishAlphabet();

combinationsService.computeNext();  // => a
combinationsService.computeNext();  // => b
combinationsService.computeNext();  // => c

Work on permutations as a Stream

final CombinationsService combinationsService = CombinationsService.usingEnglishAlphabet();

// Discard all elements which are shorter than 3 characters
combinationsService.computeCombinations().dropWhile(s -> s.length() < 3).forEach(System.out::println);  // => 'aaa' and onwards

Locking onto a target

final CombinationsService combinationsService = CombinationsService.usingEnglishAlphabet();

// Construct the (no lifecycle hooks) Arrow instance
final Arrow arrow = Arrow.using(combinationsService).build();

try (arrow)
{
    final Future<ArrowResult> result = arrow.tryFind("HELLO");
    final ArrowResult arrowResult = result.get(); 
    // => [result=HELLO, attempts=305223758, duration=15674 ms, performance=19473252.39 op/s]
}

We may add additional lifecycle hooks with "loggers" and "transformers". For example, tranform combinations to MD5 and print to System.out

final Arrow arrow = Arrow.using(combinationsService)
        .withLoggers(System.out::println)
        .withTransformers(HashingTransformers.md5())
        .build();

Of course, adding multiple steps (especially printing to standard out) severely slows down the Stream.

Using the previous setup and the following method call:

arrow.tryFind("02c425157ecd32f259548b33402ff6d3");  // => MD5("zzzz")

The runtime performance is about 0.8% compared to the previous result. If System.out is skipped, it becomes much faster.

[result=zzzz, attempts=3727490, duration=23101 ms, performance=161356.22 op/s]

About

Code kata to figure out efficient permutation generation and transformation (Colloquially, brute forcing 🕵️)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages