Ocado coding task for intern position.
Java Version: 17
Tested with:
openjdk 17.0.9 2023-10-17
OpenJDK Runtime Environment (Red_Hat-17.0.9.0.9-4) (build 17.0.9+9)
OpenJDK 64-Bit Server VM (Red_Hat-17.0.9.0.9-4) (build 17.0.9+9, mixed mode, sharing)
The task is to split user's basket in such a way that:
- Most items can be delivered using a single delivery method;
- The number of delivery methods (groups of items that can be delivered using different shipping methods) should be minimal.
In order to solve this problem we should notice, that one item can belong to multiple groups. That is,
is the item Qux
simultaneously belongs to the groups Foo
and Bar
, it can be shipped using only
one delivery method (either Foo
or Bar
).
So, to satisfy both requirements we can construct the following algorithm:
- Build the map of candidate shipping methods:
DeliveryMethodId
is a key, the list of items that can be shipped using this method is a value; - Generate an
i
-element combination of delivery method candidates ids (order is not important, repetition is not allowed). There are2^i
such combinations that can be generated using bitwise operations, but to improve readability and simplify code, the library was used; - Check, if the corresponding groups contain all the items
- If so, check if it is the current best solution, and if it is, remember the results (solution is considered the best if its largest group contains more items than the previous one)
- Otherwise, continue
- If the solution has been already found, both requirements were satisfied. Create the resulting map by
subtracting
i
th set items from thei+1
th set items. Note: the largest group is located at the index0
. - Otherwise, continue
Approx. complexity: O(2^(f(n)))
, where n
is the total number of available delivery methods,
f
- some polynomial function.
The project has the following dependencies:
org.json
- JSON parsercombinatoricslib3
- combinations generatororg.jetbrains.annotations
- to improve code readability (and improve null safety)
In order to build jar
file (with all included dependencies, so-called fat-jar
or uber-jar
)
execute the following command:
./gradlew jar
The resulting jar
file will appear in build/libs
directory.
Additionally, the app can also be launched from the console:
./gradlew run --args="<path to the config file> <path to the basket file>"
or (in case of already built jar
):
java -jar build/libs/ocado-basket-1.0-SNAPSHOT.jar
The result will be print as JSON.
Some tests were written in order to test the main functionality. JUnit 5 framework was used.