Use edit distance for transposing correction

+1      73
-1       4
+2       0
-2       0
+3       0
-3       0
+4      11
-4      19
+5       9
-5       3
+6       2
-6      63
+7       2
-7       8

Change-Id: I269cd2386f451f8932e4e0ae66223e794fdfa862
diff --git a/native/src/correction.cpp b/native/src/correction.cpp
index 75831b6..5dc6f87 100644
--- a/native/src/correction.cpp
+++ b/native/src/correction.cpp
@@ -653,9 +653,10 @@
     int finalFreq = freq;
 
     // TODO: Optimize this.
-    // TODO: Ignoring edit distance for transposed char, for now
-    if (transposedCount == 0 && (proximityMatchedCount > 0 || skipped || excessiveCount > 0)) {
-        ed = getCurrentEditDistance(editDistanceTable, inputLength, outputIndex + 1);
+    if (transposedCount > 0 || proximityMatchedCount > 0 || skipped || excessiveCount > 0) {
+        ed = getCurrentEditDistance(editDistanceTable, inputLength, outputIndex + 1)
+                - transposedCount;
+
         const int matchWeight = powerIntCapped(typedLetterMultiplier,
                 max(inputLength, outputIndex + 1) - ed);
         multiplyIntCapped(matchWeight, &finalFreq);
@@ -667,21 +668,22 @@
 
         ed = max(0, ed - quoteDiffCount);
 
-        if (ed == 1 && (inputLength == outputIndex || inputLength == outputIndex + 2)) {
-            // Promote a word with just one skipped or excessive char
-            if (sameLength) {
-                multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE, &finalFreq);
-            } else {
+        if (transposedCount < 1) {
+            if (ed == 1 && (inputLength == outputIndex || inputLength == outputIndex + 2)) {
+                // Promote a word with just one skipped or excessive char
+                if (sameLength) {
+                    multiplyRate(WORDS_WITH_JUST_ONE_CORRECTION_PROMOTION_RATE, &finalFreq);
+                } else {
+                    multiplyIntCapped(typedLetterMultiplier, &finalFreq);
+                }
+            } else if (ed == 0) {
                 multiplyIntCapped(typedLetterMultiplier, &finalFreq);
+                sameLength = true;
             }
-        } else if (ed == 0) {
-            multiplyIntCapped(typedLetterMultiplier, &finalFreq);
-            sameLength = true;
         }
         adjustedProximityMatchedCount = min(max(0, ed - (outputIndex + 1 - inputLength)),
                 proximityMatchedCount);
     } else {
-        // TODO: Calculate the edit distance for transposed char
         const int matchWeight = powerIntCapped(typedLetterMultiplier, matchCount);
         multiplyIntCapped(matchWeight, &finalFreq);
     }
diff --git a/native/src/defines.h b/native/src/defines.h
index ce3f85a..31175c3 100644
--- a/native/src/defines.h
+++ b/native/src/defines.h
@@ -190,7 +190,7 @@
 #define WORDS_WITH_MISSING_SPACE_CHARACTER_DEMOTION_RATE 67
 #define WORDS_WITH_EXCESSIVE_CHARACTER_DEMOTION_RATE 75
 #define WORDS_WITH_EXCESSIVE_CHARACTER_OUT_OF_PROXIMITY_DEMOTION_RATE 75
-#define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 60
+#define WORDS_WITH_TRANSPOSED_CHARACTERS_DEMOTION_RATE 70
 #define FULL_MATCHED_WORDS_PROMOTION_RATE 120
 #define WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE 90
 #define WORDS_WITH_MATCH_SKIP_PROMOTION_RATE 105