Skip to content

Instantly share code, notes, and snippets.

@mi11y
Last active September 1, 2020 20:07
Show Gist options
  • Save mi11y/9724f4e96670842a83a2b2eb22e63736 to your computer and use it in GitHub Desktop.
Save mi11y/9724f4e96670842a83a2b2eb22e63736 to your computer and use it in GitHub Desktop.
golang mission
package main
// See comments in main(), this is written in Go.
import (
"log"
"sort"
)
func makeMap(items []string) map[string]int {
itemsToTheirCount := make(map[string]int)
for _, item := range items {
if value, mapContainsItem := itemsToTheirCount[item]; mapContainsItem {
itemsToTheirCount[item] = value + 1
} else {
itemsToTheirCount[item] = 1
}
}
return itemsToTheirCount
}
func makeCustomerMaps(shoppers map[string][]string) map[string]map[string]int {
itemCounts := make(map[string]map[string]int)
for shopperName, itemsList := range shoppers {
itemsMap := makeMap(itemsList)
itemCounts[shopperName] = itemsMap
}
return itemCounts
}
func alikeness(s1items map[string]int, s2items map[string]int) int {
score := 0
for s1ItemName, s1ItemCount := range s1items {
if s2itemCount, mapContainsItem := s2items[s1ItemName]; mapContainsItem {
score = score + s1ItemCount + s2itemCount
}
}
return score
}
func updateRelationsMap(relationsMap *map[string]map[string]int, s1 string, s2 string, score int) {
if _, mapContainsKey := (*relationsMap)[s1]; !mapContainsKey {
(*relationsMap)[s1] = make(map[string]int)
}
if _, mapContainsKey := (*relationsMap)[s2]; !mapContainsKey {
(*relationsMap)[s2] = make(map[string]int)
}
(*relationsMap)[s1][s2] = score
(*relationsMap)[s2][s1] = score
}
func main() {
testShoppers := map[string][]string{
"fred": []string{"Banana", "Coffee", "Coffee", "Energy Drink"},
"ralph": []string{"Cup Cakes", "Cigarettes", "Wine", "Lighter"},
"jeff": []string{"Coffee", "Fountain Drink", "Gum", "Lighter", "Propane"},
"jake": []string{"Candy Bar", "Energy Drink"},
"brian": []string{"Coffee", "Toy Robot"},
}
// Map a customer to the items in their basket and its count.
// We will use this map to calculate a "distance" between
// a customer and every other customer given their items.
// For fred, this would be:
// "fred" : {
// "Banana":1,
// "Coffee",2
// ...
// }
itemCounts := makeCustomerMaps(testShoppers)
// This map will map a customer to a list of other customers
// who are mapped to their "alikness".
// For example, fred:
// "fred": [
// { "brian", 3},
// { "jake", 2 },
// { "jeff", 3 }
// ]
// This means fred is most alike to brian and jeff equally.
relationsMap := make(map[string]map[string]int)
customerNames := make([]string, 0)
for key := range itemCounts {
customerNames = append(customerNames, key)
}
sort.Strings(customerNames)
// Compare each customer to every other customer,
// starting the inner loop one ahead to avoid doing duplicate
// work.
for index, shopperName := range customerNames {
for i := index + 1; i < len(customerNames)-1; i++ {
score := alikeness(itemCounts[shopperName], itemCounts[customerNames[i]])
updateRelationsMap(&relationsMap, shopperName, customerNames[i], score)
}
}
log.Print("Alikness between customers (higher score means more alike)")
for key, value := range relationsMap {
log.Printf("Customer: %s\n", key)
for key2, value2 := range value {
log.Printf("\t=> Alikeness with %s\tScore: %d\n", key2, value2)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment