## The challenge

Suppose you have 4 numbers: `'0', '9', '6', '4'` and 3 strings composed with them:

 ``````1 2 3 `````` ``````s1 = "6900690040" s2 = "4690606946" s3 = "9990494604" ``````

Compare `s1` and `s2` to see how many positions they have in common: `` at index 3, `6` at index 4, `4` at index 8 ie 3 common positions out of ten.

Compare `s1` and `s3` to see how many positions they have in common: `9` at index 1, `` at index 3, `9` at index 5 ie 3 common positions out of ten.

Compare `s2` and `s3`. We find 2 common positions out of ten.

So for the 3 strings we have 8 common positions out of 30 ie 0.2666… or 26.666…%

Given `n` substrings (n >= 2) in a string `s` our function `pos_average` will calculate the average percentage of positions that are the same between the `(n * (n-1)) / 2` sets of substrings taken amongst the given `n` substrings. It can happen that some substrings are duplicate but since their ranks are not the same in `s` they are considered as different substrings.

The function returns the percentage formatted as a float with 10 decimals but the result is tested at 1e.-9 (see function assertFuzzy in the tests).

### Example:

Given string s = “444996, 699990, 666690, 096904, 600644, 640646, 606469, 409694, 666094, 606490” composing a set of n = 10 substrings (hence 45 combinations), `pos_average` returns `29.2592592593`.

In a set the `n` substrings will have the same length ( > 0 ).

## The solution in Java code

Option 1:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 `````` ``````public class PositionAverage { public static double posAverage(String s) { String[] strings = s.split(","); int matchs = 0; double of = 0; for (int i = 0; i < strings.length; i++) strings[i] = strings[i].trim(); for (int i = 0; i < strings.length; i++) { for (int j = i + 1; j < strings.length; j++) for (int k = 0; k < strings[i].length(); k++) { matchs += (strings[i].charAt(k) == strings[j].charAt(k)) ? 1 : 0; of++; } } return matchs * 100 / of; } } ``````

Option 2:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 `````` ``````class PositionAverage { private static double pairPercentage(String s1, String s2) { int lg = s1.length(); int count = 0; for (int pos = 0; pos < lg; pos++) { if (s1.charAt(pos) == s2.charAt(pos)) count += 1; } return (double)count / lg; } public static double posAverage(String s) { String[] strings = s.split(", "); double result = 0.0; int cnt = 0; int lg = strings.length; for (int k = 0; k < lg; k++) { for (int i = k + 1; i < lg; i++) { result += pairPercentage(strings[k], strings[i]); cnt += 1; } } result = 100.0 * result / cnt; return Math.floor(result * Math.pow(10.0, 10)) / Math.pow(10.0, 10); } } ``````

Option 3:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 `````` ``````public class PositionAverage { public static double posAverage(String s) { long posCount = 0; long matchCount = 0; String[] parts = s.split(", "); for(int i=0; i

## Test cases to validate our solution

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 `````` ``````import org.junit.Test; import org.junit.runners.JUnit4; import static org.junit.Assert.*; import org.junit.Test; public class PositionAverageTest { private static void assertFuzzy(String s, double exp){ System.out.println("Testing " + s); boolean inrange; double merr = 1e-9; double actual = PositionAverage.posAverage(s); inrange = Math.abs(actual - exp) <= merr; if (inrange == false) { System.out.println("Expected mean must be near " + exp +", got " + actual); } assertEquals(true, inrange); } @Test public void test() { assertFuzzy("466960, 069060, 494940, 060069, 060090, 640009, 496464, 606900, 004000, 944096", 26.6666666667); assertFuzzy("444996, 699990, 666690, 096904, 600644, 640646, 606469, 409694, 666094, 606490", 29.2592592593); assertFuzzy("4444444, 4444444, 4444444, 4444444, 4444444, 4444444, 4444444, 4444444", 100); assertFuzzy("0, 0, 0, 0, 0, 0, 0, 0", 100); } } ``````