Cryptanalysis Word Patterns in Java

The challenge

In cryptanalysis, words patterns can be a useful tool in cracking simple ciphers.

A word pattern is a description of the patterns of letters occurring in a word, where each letter is given an integer code in order of appearance. So the first letter is given the code 0, and second is then assigned 1 if it is different to the first letter or 0 otherwise, and so on.

As an example, the word “hello” would become “0.1.2.2.3”. For this task case-sensitivity is ignored, so “hello”, “helLo” and “heLlo” will all return the same word pattern.

Your task is to return the word pattern for a given word. All words provided will be non-empty strings of alphabetic characters only, i.e. matching the regex “[a-zA-Z]+”.

Test cases

import org.junit.Test; import static org.junit.Assert.assertEquals; import org.junit.runners.JUnit4; public class SolutionTest { @Test public void exampleTests() { String[][] tests = { {"hello", "0.1.2.2.3"}, {"heLlo", "0.1.2.2.3"}, {"helLo", "0.1.2.2.3"}, {"Hippopotomonstrosesquippedaliophobia", "0.1.2.2.3.2.3.4.3.5.3.6.7.4.8.3.7.9.7.10.11.1.2.2.9.12.13.14.1.3.2.0.3.15.1.13"}, }; for(String[] arr: tests) assertEquals(arr[1],Crypto.wordPattern(arr[0])); } }
Code language: Java (java)

The solution in Java

Option 1:

import java.util.*; class Crypto { public static String wordPattern(final String word){ var h = new HashMap<Integer,Integer>(); String[] arr = word.toLowerCase().chars() .mapToObj( c-> "" + h.computeIfAbsent(c,k->h.size()) ) .toArray(String[]::new); return String.join(".", arr); } }
Code language: Java (java)

Option 2 (using streams):

import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; class Crypto { static String wordPattern(String word) { AtomicInteger nextCode = new AtomicInteger(); Map<Integer, Integer> codes = new HashMap<>(); return word.chars() .map(Character::toLowerCase) .map(ch -> codes.computeIfAbsent(ch, $ -> nextCode.getAndIncrement())) .mapToObj(String::valueOf) .collect(Collectors.joining(".")); } }
Code language: Java (java)

Option 3:

import java.util.ArrayList; import java.util.List; class Crypto { public static String wordPattern(final String word){ String newword = word.toLowerCase(); List<Character> characterList = new ArrayList<>(); String result = ""; for (int i = 0; i < newword.length(); i++) { if (!characterList.contains( newword.charAt( i ) )) { characterList.add( newword.charAt( i ) ); } if (i != 0) { result += "."; } result += characterList.indexOf( newword.charAt( i ) ); } return result; } }
Code language: Java (java)
Tags:
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments