Trick or Treat: A Halloween Kata

Learn how to use Eclipse Collections APIs in a fun Java code kata.

Image for post
Image for post
Is a Cup a Bag?

Kata Time

More simply:

  1. Do
  2. Teach

So here I am now, practicing what I preach. The rest of this blog will include code for a Halloween Kata using Java 8 with Eclipse Collections. I just developed the kata this evening. There’s perhaps no better way to see how sweet the APIs of Eclipse Collections are than with a cup or Bag of candy. You might also get to see how sweet some of the Java Time APIs are along the way.

Getting Started

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.util.Random;
import java.util.stream.IntStream;

import org.eclipse.collections.api.bag.Bag;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.set.MutableSet;
import org.eclipse.collections.api.tuple.primitive.ObjectIntPair;
import org.eclipse.collections.impl.collector.Collectors2;
import org.eclipse.collections.impl.factory.Lists;
import org.eclipse.collections.impl.factory.Sets;
import org.junit.Assert;
import org.junit.Test;
public class HalloweenKata
{
....
}

Trick or Treat

enum Candy
{
SNICKERS,
MILKYWAY,
REESES_PIECES,
REESES_PEANUT_BUTTER_CUPS,
M_AND_M_S,
TWIZZLERS,
WHOPPERS,
ONE_HUNDRED_GRAND,
SKITTLES,
TWIX,
CANDY_CORN,
JOLLY_RANCHERS,
NERDS,
ALMOND_JOY,
MOUNDS,
BABY_RUTH,
THREE_MUSKETEERS,
HERSHEYS,
CRUNCH,
HERSHEYS_KISSES,
MIKE_AND_IKE,
MILK_DUDS,
SWEDISH_FISH,
YORK_PEPPERMINT_PATTY
}

Time to send the kids out trick or treating

private MutableList<Bag<Candy>> collectBagsOfCandy()
{
LocalDate halloween =
LocalDate.of(2018, Month.OCTOBER, 31);
LocalTime elementarySchoolStart =
LocalTime.NOON.plus(Duration.ofHours(3));
LocalTime middleSchoolStart =
elementarySchoolStart.plus(Duration.ofHours(2));
LocalTime highSchoolStart =
middleSchoolStart.plus(Duration.ofHours(2));
long candyCount = 250L;

Bag<Candy> elementarySchoolBag = this.trickOrTreat(
halloween.atTime(elementarySchoolStart),
candyCount);
Bag<Candy> middleSchoolBag = this.trickOrTreat(
halloween.atTime(middleSchoolStart),
candyCount);
Bag<Candy> highSchoolBag = this.trickOrTreat(
halloween.atTime(highSchoolStart),
candyCount);

return Lists.mutable.with(
elementarySchoolBag,
middleSchoolBag,
highSchoolBag);
}

When each group goes trick or treating, they get a random collection of candy in their bags, seeded by their start time.

public Bag<Candy> trickOrTreat(LocalDateTime time, long candyCount)
{
ZoneId newYork = ZoneId.of("America/New_York");
IntStream limit = new Random(
time.atZone(newYork).toEpochSecond())
.ints(0, Candy.values().length - 1)
.limit(candyCount);
Bag<Candy> bagOfCandy = limit.mapToObj(i -> Candy.values()[i])
.collect(Collectors2.toBag());
System.out.println(bagOfCandy.topOccurrences(10));
return bagOfCandy;
}

A fix the test style kata

@Test
public void topCandy()
{
MutableList<Bag<Candy>> bagsOfCandy =
this.collectBagsOfCandy();

// Hint: Flatten the Bags of Candy into a single Bag
Bag<Candy> bigBagOfCandy = null;

// Hint: Find the top occurrence in the bag and convert that
// to a set of Candy.
MutableSet<Candy> mostCommon = null;
Assert.assertEquals(
Sets.mutable.with(Candy.CRUNCH),
mostCommon);

// Hint: Find the top 10 occurrences of Candy in each of the
// bags and intersect them to see which are the common ones
// between all of the bags.
MutableSet<Candy> commonInTop10 = null;
Assert.assertEquals(
Sets.mutable.with(Candy.REESES_PIECES, Candy.CRUNCH),
commonInTop10);
}

Note: I have tried running these tests on a Mac Book Pro and Windows 10 Machine with Java 8. The results are consistent between runs, but I have not verified if they are consistent on any other platforms and Java versions.

Kata to learn, Kata to teach

I have posted my solutions to the kata.

Happy Halloween!

Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.

Written by

Java Champion. Creator of the Eclipse Collections OSS Java library (http://www.eclipse.org/collections/). Inspired by Smalltalk. Opinions are my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store