Java 8 Lambdas - programming challenge

216 views
Skip to first unread message

Adrian O'Sullivan

unread,
Aug 11, 2014, 9:49:53 AM8/11/14
to java...@googlegroups.com
I set myself a programming challenge using Java 8 lambda expressions and, well, I was unable to solve it!  So I am turning here to see if anyone can figure out the solution.

The Problem

Generate an array of arrays containing all permutations of integers, 0 - 4, starting with single values 0 - 4, then pairs of values 00,01,02 etc, then triples, then quadruples, as follows:

Results

int[][] results;

result[0] = {0} 
result[1] = {1} 
result[2] = {2} 
result[3] = {3} 
result[4] = {4} 
result[5] = {0,0} 
result[6] = {0,1} 
result[7] = {0,2} 
result[8] = {0,3} 
result[9] = {0,4} 
result[10] = {1,0} 
result[11] = {1,1} 
result[12] = {1,2} 
result[13] = {1,3} 
result[14] = {1,4} 
... 
{4,3} 
{4,4} 
{0,0,0} 
{0,0,1} 
{0,0,2} 
... 
{4,4,4} 
{0,0,0,0} 
{0,0,0,1} 
... 
{4,4,4,4} 

The constraint

You must use only Java 8 lambda expressions. This might be quite easy to do with for loops, but try doing it with lambda expressions.

The best I have been able to do so far is to generate all pairs:

 Integer[][] result = IntStream.rangeClosed(0, 4)
 
.boxed()
 
.flatMap(x -> IntStream.rangeClosed(0, 4).mapToObj(y -> new Integer{}{x,y}))
 
.toArray(Integer[][]::new);


If you can, write the code to generate all the required arrays.

clay

unread,
Aug 18, 2014, 5:52:48 PM8/18/14
to java...@googlegroups.com
I did permutations of two [0..4] values. Extending to three/four should be straight forward.

Haskell, do notation version:
do { a <- [0..4]; b <- [0..4]; [(a, b)] }

Haskell, bind version:
[0..4] >>= (\a -> [0..4] >>= (\b -> [(a, b)]))

Scala, for comprehension (just like Haskell's do notation):
for (a <- 0 until 4; b <- 0 until 4) yield (a,b)

Java 8 Stream/Lambda version:
Stream<AbstractMap.SimpleImmutableEntry<Integer, Integer>> s1 = IntStream.rangeClosed(0, 4).boxed().flatMap(a -> IntStream.rangeClosed(0, 4).mapToObj(b -> new AbstractMap.SimpleImmutableEntry<Integer, Integer>(a, b)));
List<AbstractMap.SimpleImmutableEntry<Integer, Integer>> l1 = s1.collect(Collectors.toList());

Clearly, the Java 8 version is far clumsier than the others. The biggest hold ups with Java are the lack of tuples, the primitive/object divide, and then the lack of flatMap syntactic sugar like Haskell's do or Scala's for.

With this type of functional programming exercise, Java 8 is a big step up from Java 7, but far short of Scala or Haskell.

Also, as much as I like this group, I'd recommend stackexchange as a better alternative for this type of focused question with a direct answer.


Josh Berry

unread,
Aug 18, 2014, 11:47:26 PM8/18/14
to javaposse
Probably not what you were looking for, but the following feels like a more direct usage of lambdas.  Apologies for not trying it in Java 8, I embarrassingly do not have an install of that handy at the moment.  (This is Scala.)

    List.range(0, math.pow(5,4).intValue).map(x => Integer.toString(x, 5)).map(_.toCharArray)

To get the exact order of the answers you showed would take a little fiddling, of course, but the idea should translate easily enough.  (Unless, of course, I made a mistake.  Very likely.)





--
You received this message because you are subscribed to the Google Groups "Java Posse" group.
To unsubscribe from this group and stop receiving emails from it, send an email to javaposse+...@googlegroups.com.
To post to this group, send email to java...@googlegroups.com.
Visit this group at http://groups.google.com/group/javaposse.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages