Task: Most frequent k chars distance




Go: package main

import (
    "fmt"
    "sort"
)

type cf struct {
    c rune
    f int
}

func reverseStr(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

func indexOfCf(cfs []cf, r rune) int {
    for i, cf := range cfs {
        if cf.c == r {
            return i
        }
    }
    return -1
}

func minOf(i, j int) int {
    if i < j {
        return i
    }
    return j
}

func mostFreqKHashing(input string, k int) string {
    var cfs []cf
    for _, r := range input {
        ix := indexOfCf(cfs, r)
        if ix >= 0 {
            cfs[ix].f++
        } else {
            cfs = append(cfs, cf{r, 1})
        }
    }
    sort.SliceStable(cfs, func(i, j int) bool {
        return cfs[i].f > cfs[j].f 
    })
    acc := ""
    min := minOf(len(cfs), k)
    for _, cf := range cfs[:min] {
        acc += fmt.Sprintf("%c%c", cf.c, cf.f)
    }
    return acc
}

func mostFreqKSimilarity(input1, input2 string) int {
    similarity := 0
    runes1, runes2 := []rune(input1), []rune(input2)
    for i := 0; i < len(runes1); i += 2 {
        for j := 0; j < len(runes2); j += 2 {
            if runes1[i] == runes2[j] {
                freq1, freq2 := runes1[i+1], runes2[j+1]
                if freq1 != freq2 {
                    continue 
                }
                similarity += int(freq1)
            }
        }
    }
    return similarity
}

func mostFreqKSDF(input1, input2 string, k, maxDistance int) {
    fmt.Println("input1 :", input1)
    fmt.Println("input2 :", input2)
    s1 := mostFreqKHashing(input1, k)
    s2 := mostFreqKHashing(input2, k)
    fmt.Printf("mfkh(input1, %d) = ", k)
    for i, c := range s1 {
        if i%2 == 0 {
            fmt.Printf("%c", c)
        } else {
            fmt.Printf("%d", c)
        }
    }
    fmt.Printf("\nmfkh(input2, %d) = ", k)
    for i, c := range s2 {
        if i%2 == 0 {
            fmt.Printf("%c", c)
        } else {
            fmt.Printf("%d", c)
        }
    }
    result := maxDistance - mostFreqKSimilarity(s1, s2)
    fmt.Printf("\nSDF(input1, input2, %d, %d) = %d\n\n", k, maxDistance, result)
}

func main() {
    pairs := [][2]string{
        {"research", "seeking"},
        {"night", "nacht"},
        {"my", "a"},
        {"research", "research"},
        {"aaaaabbbb", "ababababa"},
        {"significant", "capabilities"},
    }
    for _, pair := range pairs {
        mostFreqKSDF(pair[0], pair[1], 2, 10)
    }

    s1 := "LCLYTHIGRNIYYGSYLYSETWNTGIMLLLITMATAFMGYVLPWGQMSFWGATVITNLFSAIPYIGTNLV"
    s2 := "EWIWGGFSVDKATLNRFFAFHFILPFTMVALAGVHLTFLHETGSNNPLGLTSDSDKIPFHPYYTIKDFLG"
    mostFreqKSDF(s1, s2, 2, 100)
    s1 = "abracadabra12121212121abracadabra12121212121"
    s2 = reverseStr(s1)
    mostFreqKSDF(s1, s2, 2, 100)
}




Python: import collections
def MostFreqKHashing(inputString, K):
    occuDict = collections.defaultdict(int)
    for c in inputString:
        occuDict[c] += 1
    occuList = sorted(occuDict.items(), key = lambda x: x[1], reverse = True)
    outputStr = ''.join(c + str(cnt) for c, cnt in occuList[:K])
    return outputStr 


def MostFreqKSimilarity(inputStr1, inputStr2):
    similarity = 0
    for i in range(0, len(inputStr1), 2):
        c = inputStr1[i]
        cnt1 = int(inputStr1[i + 1])
        for j in range(0, len(inputStr2), 2):
            if inputStr2[j] == c:
                cnt2 = int(inputStr2[j + 1])
                similarity += cnt1 + cnt2
                break
    return similarity

def MostFreqKSDF(inputStr1, inputStr2, K, maxDistance):
    return maxDistance - MostFreqKSimilarity(MostFreqKHashing(inputStr1,K), MostFreqKHashing(inputStr2,K))