Odin SolutionsOdin Solutions

↔️

Anagrams

Week 37, 2026

All Solutions

Prepare word list, Iterate and find anagrams | greenya | Odin Solutions

// https://program52.com/en/challenge/2026/571490F44 package main import "core:fmt" import "core:slice" import "core:strings" main :: proc () { state: State // state_init(&state, #load("words-example.txt", string)) state_init(&state, #load("words-strict.txt", string)) defer state_destroy(&state) for w in state.known_words { state_gen_anagrams_of(&state, w) } state_print(state) } State :: struct { known_words : [] string, sets : map [string] [dynamic] string, seen : map [string] struct {}, } state_init :: proc (this: ^State, known_words_text: string) { projected_word_count := 1 + strings.count(known_words_text, "\n") known_words := make([dynamic] string, 0, projected_word_count) text := known_words_text for s in strings.split_lines_iterator(&text) { w := strings.trim_space(s) append(&known_words, w) } shrink(&known_words) slice.sort(known_words[:]) this.known_words = known_words[:] } state_destroy :: proc (this: ^State) { delete(this.known_words) for _, list in this.sets do delete(list) delete(this.sets) delete(this.seen) } state_gen_anagrams_of :: proc (this: ^State, word: string) { if word in this.seen do return for known_word in this.known_words { if words_are_anagrams(known_word, word) { if word not_in this.sets do this.sets[word] = {} list := &this.sets[word] append(list, known_word) this.seen[known_word] = {} } } } state_print :: proc (this: State) { order, _ := slice.map_keys(this.sets) defer delete(order) sets := this.sets context.user_ptr = &sets slice.sort_by(order[:], less=proc (a, b: string) -> bool { sets := cast (^map [string] [dynamic] string) context.user_ptr len_a := len(sets[a]) len_b := len(sets[b]) return len_a==len_b ? a<b : len_a>len_b }) total, alone: int for o in order { list := this.sets[o] slice.sort(list[:]) count := len(list) total += count if count==1 do alone += 1 fmt.printf("%i: ", count) for w, i in list { if i>0 do fmt.print(", ") fmt.print(w) } fmt.println() } fmt.printfln("--- %i of %i words are anagrams of other words ---", total-alone, total) } words_are_anagrams :: proc (a, b: string) -> bool { if len(a) != len(b) do return false counts: [256] int for c in a { counts[c] += 1 } for c in b { if counts[c] == 0 do return false counts[c] -= 1 } return true }