Task: Wordle comparison




Go: package main

import (
    "bytes"
    "fmt"
    "log"
)

func wordle(answer, guess string) []int {
    n := len(guess)
    if n != len(answer) {
        log.Fatal("The words must be of the same length.")
    }
    answerBytes := []byte(answer)
    result := make([]int, n) 
    for i := 0; i < n; i++ {
        if guess[i] == answerBytes[i] {
            answerBytes[i] = '\000'
            result[i] = 2
        }
    }
    for i := 0; i < n; i++ {
        ix := bytes.IndexByte(answerBytes, guess[i])
        if ix >= 0 {
            answerBytes[ix] = '\000'
            result[i] = 1
        }
    }
    return result
}

func main() {
    colors := []string{"grey", "yellow", "green"}
    pairs := [][]string{
        {"ALLOW", "LOLLY"},
        {"BULLY", "LOLLY"},
        {"ROBIN", "ALERT"},
        {"ROBIN", "SONIC"},
        {"ROBIN", "ROBIN"},
    }
    for _, pair := range pairs {
        res := wordle(pair[0], pair[1])
        res2 := make([]string, len(res))
        for i := 0; i < len(res); i++ {
            res2[i] = colors[res[i]]
        }
        fmt.Printf("%s v %s => %v => %v\n", pair[0], pair[1], res, res2)
    }
}




Python: 

from functools import reduce
from operator import add



def wordleScore(target, guess):
    
    return mapAccumL(amber)(
        *first(charCounts)(
            mapAccumL(green)(
                [], zip(target, guess)
            )
        )
    )[1]



def green(residue, tg):
    
    t, g = tg
    return (residue, (g, 2)) if t == g else (
        [t] + residue, (g, 0)
    )



def amber(tally, cn):
    
    c, n = cn
    return (tally, 2) if 2 == n else (
        adjust(
            lambda x: x - 1,
            c, tally
        ),
        1
    ) if 0 < tally.get(c, 0) else (tally, 0)




def main():
    
    print(' -> '.join(['Target', 'Guess', 'Scores']))
    print()
    print(
        '\n'.join([
            wordleReport(*tg) for tg in [
                ("ALLOW", "LOLLY"),
                ("CHANT", "LATTE"),
                ("ROBIN", "ALERT"),
                ("ROBIN", "SONIC"),
                ("ROBIN", "ROBIN"),
                ("BULLY", "LOLLY"),
                ("ADAPT", "SÅLÅD"),
                ("Ukraine", "Ukraíne"),
                ("BBAAB", "BBBBBAA"),
                ("BBAABBB", "AABBBAA")
            ]
        ])
    )



def wordleReport(target, guess):
    
    scoreName = {2: 'green', 1: 'amber', 0: 'gray'}

    if 5 != len(target):
        return f'{target}: Expected 5 character target.'
    elif 5 != len(guess):
        return f'{guess}: Expected 5 character guess.'
    else:
        scores = wordleScore(target, guess)
        return ' -> '.join([
            target, guess, repr(scores),
            ' '.join([
                scoreName[n] for n in scores
            ])
        ])





def adjust(f, k, dct):
    
    return dict(
        dct,
        **{k: f(dct[k]) if k in dct else None}
    )



def charCounts(s):
    
    return reduce(
        lambda a, c: insertWith(add)(c)(1)(a),
        list(s),
        {}
    )



def first(f):
    
    return lambda xy: (f(xy[0]), xy[1])




def insertWith(f):
    
    return lambda k: lambda x: lambda dct: dict(
        dct,
        **{k: f(dct[k], x) if k in dct else x}
    )




def mapAccumL(f):
    
    def nxt(a, x):
        return second(lambda v: a[1] + [v])(
            f(a[0], x)
        )
    return lambda acc, xs: reduce(
        nxt, xs, (acc, [])
    )



def second(f):
    
    return lambda xy: (xy[0], f(xy[1]))



if __name__ == '__main__':
    main()