Last active
October 17, 2018 07:44
-
-
Save biniama/f517aa87ba7aeb8e2a5c1c6a8af149ff to your computer and use it in GitHub Desktop.
"Find Unique Numbers of Length n" using Java
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 java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
public class PhonePadExercise { | |
public static void main(String[] args) { | |
Integer selectedDigit = 4; | |
Integer maxIteration = 4; | |
PhonePadNumberGenerator generator = new PhonePadNumberGenerator(); | |
List<List<Integer>> result = generator.findUniqueNumberFromPhonePad(selectedDigit, maxIteration); | |
System.out.println(result); | |
} | |
} | |
class PhonePadNumberGenerator { | |
private List<List<Integer>> result = new ArrayList<>(); | |
private List<Integer> subresult = new ArrayList<>(); | |
private Map<DirectionEnum, DirectionEnum> opposites = new HashMap<>(); | |
private List<PhonePadWithDirection> phonePadWithDirectionList = new ArrayList<>(); | |
public PhonePadNumberGenerator() { | |
initPad(); | |
initOpposites(); | |
} | |
private static Map<DirectionEnum, Integer> createMap(Integer up, Integer down, Integer left, Integer right) { | |
return new HashMap<DirectionEnum, Integer>() { | |
{ | |
put(DirectionEnum.UP, up); | |
put(DirectionEnum.DOWN, down); | |
put(DirectionEnum.LEFT, left); | |
put(DirectionEnum.RIGHT, right); | |
} | |
}; | |
} | |
private void initPad() { | |
phonePadWithDirectionList.add(new PhonePadWithDirection(0, createMap(8, null, null, null))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(1, createMap(null, 4, null, 2))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(2, createMap(null, 5, 1, 3))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(3, createMap(null, 6, 2, null))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(4, createMap(1, 7, null, 5))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(5, createMap(2, 8, 4, 6))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(6, createMap(3, 5, 9, null))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(7, createMap(4, null, null, 8))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(8, createMap(5, 0, 7, 9))); | |
phonePadWithDirectionList.add(new PhonePadWithDirection(9, createMap(6, null, 8, null))); | |
} | |
private void initOpposites() { | |
opposites.put(DirectionEnum.UP, DirectionEnum.DOWN); | |
opposites.put(DirectionEnum.DOWN, DirectionEnum.UP); | |
opposites.put(DirectionEnum.LEFT, DirectionEnum.RIGHT); | |
opposites.put(DirectionEnum.RIGHT, DirectionEnum.LEFT); | |
} | |
public List<List<Integer>> findUniqueNumberFromPhonePad(Integer selectedDigit, Integer maxIteration) { | |
PhonePadWithDirection pad = phonePadWithDirectionList.get(selectedDigit); | |
for (DirectionEnum direction : DirectionEnum.values()) { | |
subresult.add(pad.getNumber()); | |
recursivelyFindPath(pad, direction, maxIteration); | |
result.add(subresult); | |
subresult = new ArrayList<>(); | |
} | |
// remove subresult which doesn't fulfil max iteration (which contains less elements) //java 8 solution | |
result.removeIf(r -> r.size() < maxIteration); | |
return result; | |
} | |
private void recursivelyFindPath(PhonePadWithDirection pad, DirectionEnum directionEnum, Integer maxIteration) { | |
if (subresult.size() < maxIteration) { | |
System.out.printf("With Number %d and New Direction %s%n", pad.getNumber(), directionEnum.name()); | |
Integer valueAtNewDirection = pad.getValue(directionEnum); | |
if (valueAtNewDirection != null) { | |
PhonePadWithDirection newPad = phonePadWithDirectionList.get(valueAtNewDirection); | |
// should not go back to the same number again | |
if (subresult.indexOf(newPad.getNumber()) == -1) { | |
subresult.add(valueAtNewDirection); printPretty(newPad); | |
for (DirectionEnum direction : DirectionEnum.values()) { | |
if (direction != opposites.get(directionEnum)) | |
recursivelyFindPath(newPad, direction, maxIteration); | |
} | |
} | |
} | |
} | |
} | |
private void printPretty(PhonePadWithDirection pad) { | |
System.out.printf("For Number = %d : Up = %d, Down = %d, Left = %d, Right = %d%n", | |
pad.getNumber(), | |
pad.getValue(DirectionEnum.UP), | |
pad.getValue(DirectionEnum.DOWN), | |
pad.getValue(DirectionEnum.LEFT), | |
pad.getValue(DirectionEnum.RIGHT) | |
); | |
} | |
} | |
class PhonePadWithDirection { | |
private Integer number; | |
private Map<DirectionEnum, Integer> directionWithValue = new HashMap<>(); | |
public PhonePadWithDirection(Integer number, Map<DirectionEnum, Integer> directionWithValue) { | |
this.number = number; | |
this.directionWithValue = directionWithValue; | |
} | |
public Integer getNumber() { | |
return number; | |
} | |
public Map<DirectionEnum, Integer> getDirectionWithValue() { | |
return directionWithValue; | |
} | |
public Integer getValue(DirectionEnum directionEnum) { | |
return this.getDirectionWithValue().get(directionEnum); | |
} | |
} | |
enum DirectionEnum { | |
UP, | |
DOWN, | |
LEFT, | |
RIGHT | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment