/** * builds an adjacency graph as a dictionary: {character: [adjacent_characters]}. * adjacent characters occur in a clockwise order. * for example: * on qwerty layout, 'g' maps to ['fF', 'tT', 'yY', 'hH', 'bB', 'vV'] * on keypad layout, '7' maps to [None, None, None, '=', '8', '5', '4', None] * */ public Map<Character, List<String>> build() { final Map<Position, String> positionTable = buildPositionTable(layout); final Map<Character, List<String>> adjacencyGraph = new HashMap<>(); for (Map.Entry<Position, String> entry : positionTable.entrySet()) { for (final char key : entry.getValue().toCharArray()) { final List<String> adjacencies = new ArrayList<>(); final Position position = entry.getKey(); for (final Position coord : getAdjacentCoords(position)) { adjacencies.add(positionTable.get(coord)); } adjacencyGraph.put(key, adjacencies); } } return adjacencyGraph; }
private Map<Position, String> buildPositionTable(final String layout) { final Map<Position, String> positionTable = new HashMap<>(); final List<String> tokens = split(layout, WHITESPACE_SPLIT_MATCHER); final int tokenSize = tokens.get(0).length(); final int xUnit = tokenSize + 1; for (String token : tokens) { assert token.length() == tokenSize : String.format("token [%s] length mismatch:\n%s", token, layout); } int y = 1; for (final String line : split(layout, NEW_LINE_SPLIT_MATCHER)) { // the way I illustrated keys above, each qwerty row is indented one space in from the last int slant = calcSlant(y); for (final String token : split(line, WHITESPACE_SPLIT_MATCHER)) { int index = line.indexOf(token) - slant; int x = index / xUnit; final int remainder = index % xUnit; assert remainder == 0 : String.format("unexpected x offset [%d] for %s in:\n%s", x, token, layout); positionTable.put(Position.of(x, y), token); } y++; } return positionTable; }
/** * builds an adjacency graph as a dictionary: {character: [adjacent_characters]}. * adjacent characters occur in a clockwise order. * for example: * on qwerty layout, 'g' maps to ['fF', 'tT', 'yY', 'hH', 'bB', 'vV'] * on keypad layout, '7' maps to [None, None, None, '=', '8', '5', '4', None] * */ public Map<Character, List<String>> build() { final Map<Position, String> positionTable = buildPositionTable(layout); final Map<Character, List<String>> adjacencyGraph = new HashMap<>(); for (Map.Entry<Position, String> entry : positionTable.entrySet()) { for (final char key : entry.getValue().toCharArray()) { final List<String> adjacencies = new ArrayList<>(); final Position position = entry.getKey(); for (final Position coord : getAdjacentCoords(position)) { adjacencies.add(positionTable.get(coord)); } adjacencyGraph.put(key, adjacencies); } } return adjacencyGraph; }
private Map<Position, String> buildPositionTable(final String layout) { final Map<Position, String> positionTable = new HashMap<>(); final List<String> tokens = split(layout, WHITESPACE_SPLIT_MATCHER); final int tokenSize = tokens.get(0).length(); final int xUnit = tokenSize + 1; for (String token : tokens) { assert token.length() == tokenSize : String.format("token [%s] length mismatch:\n%s", token, layout); } int y = 1; for (final String line : split(layout, NEW_LINE_SPLIT_MATCHER)) { // the way I illustrated keys above, each qwerty row is indented one space in from the last int slant = calcSlant(y); for (final String token : split(line, WHITESPACE_SPLIT_MATCHER)) { int index = line.indexOf(token) - slant; int x = index / xUnit; final int remainder = index % xUnit; assert remainder == 0 : String.format("unexpected x offset [%d] for %s in:\n%s", x, token, layout); positionTable.put(Position.of(x, y), token); } y++; } return positionTable; }
private Keyboard(final String name, final AdjacentGraphBuilder adjacentGraphBuilder) { this.name = name; this.adjacencyGraph = adjacentGraphBuilder.build(); this.slanted = adjacentGraphBuilder.isSlanted(); this.startingPositions = adjacencyGraph.size(); this.averageDegree = calcAverageDegree(adjacencyGraph); }
private Keyboard(final String name, final AdjacentGraphBuilder adjacentGraphBuilder) { this.name = name; this.adjacencyGraph = adjacentGraphBuilder.build(); this.slanted = adjacentGraphBuilder.isSlanted(); this.startingPositions = adjacencyGraph.size(); this.averageDegree = calcAverageDegree(adjacencyGraph); }