Last active
September 1, 2020 20:07
-
-
Save mi11y/9724f4e96670842a83a2b2eb22e63736 to your computer and use it in GitHub Desktop.
golang mission
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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