combo-guesser.odin
· 2.0 KiB · Odin
Raw
package main
import "core:mem/virtual"
import "core:time"
import "core:strings"
import "core:unicode/utf8"
import "core:math/rand"
import "core:fmt"
import "core:math"
import "core:mem"
main :: proc() {
arena: virtual.Arena
arena_err := virtual.arena_init_growing(&arena)
assert(arena_err == .None)
arena_allocator := virtual.arena_allocator(&arena)
context.allocator = arena_allocator
NUM_LETTERS :: 26
NUM_COMBOS :: 4
LETTERS :: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#assert(len(LETTERS) == NUM_LETTERS)
total_number_of_combinations := int(math.pow_f32(NUM_LETTERS, NUM_COMBOS))
fmt.println("Max Amount of combinations:", total_number_of_combinations)
runes := utf8.string_to_runes(LETTERS)
used_combos, err := make(map[string]bool, total_number_of_combinations)
if err != .None {
return
}
guessing_start := time.now()
guessing_attempts := 0
for len(used_combos) < total_number_of_combinations {
free_all(context.temp_allocator)
guessing_attempts += 1
builder := strings.builder_make(context.temp_allocator)
for _ in 0..<NUM_COMBOS {
pos := rand.int63_max(NUM_LETTERS)
letter := runes[pos]
strings.write_rune(&builder, letter)
}
code := strings.to_string(builder)
assert(len(code) == NUM_COMBOS)
ok := code in used_combos
if !ok { // good path. unused means we can insert now
insertable_code := strings.clone(code)
used_combos[insertable_code] = true // set dummy to insert key, a hashmap needs a value. but the value is of no value to us
remaining_combos := total_number_of_combinations - len(used_combos)
// because printing to console is expensive, only enable for debug / informative
// fmt.printfln("Code %s inserted. Amount of insertion attempts: %v . %v unoccupied Codes Remain of %v total possibilities.", insertable_code, guessing_attempts, remaining_combos, total_number_of_combinations )
guessing_attempts = 0
}
}
guessing_end := time.now()
diff := time.diff(guessing_start, guessing_end)
dur_seconds := time.duration_seconds(diff)
fmt.println("Took", dur_seconds, "seconds.")
}
| 1 | package main |
| 2 | |
| 3 | import "core:mem/virtual" |
| 4 | import "core:time" |
| 5 | import "core:strings" |
| 6 | import "core:unicode/utf8" |
| 7 | import "core:math/rand" |
| 8 | import "core:fmt" |
| 9 | import "core:math" |
| 10 | import "core:mem" |
| 11 | |
| 12 | main :: proc() { |
| 13 | |
| 14 | arena: virtual.Arena |
| 15 | arena_err := virtual.arena_init_growing(&arena) |
| 16 | assert(arena_err == .None) |
| 17 | arena_allocator := virtual.arena_allocator(&arena) |
| 18 | |
| 19 | context.allocator = arena_allocator |
| 20 | |
| 21 | NUM_LETTERS :: 26 |
| 22 | NUM_COMBOS :: 4 |
| 23 | |
| 24 | LETTERS :: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 25 | #assert(len(LETTERS) == NUM_LETTERS) |
| 26 | |
| 27 | total_number_of_combinations := int(math.pow_f32(NUM_LETTERS, NUM_COMBOS)) |
| 28 | fmt.println("Max Amount of combinations:", total_number_of_combinations) |
| 29 | |
| 30 | runes := utf8.string_to_runes(LETTERS) |
| 31 | |
| 32 | used_combos, err := make(map[string]bool, total_number_of_combinations) |
| 33 | if err != .None { |
| 34 | return |
| 35 | } |
| 36 | |
| 37 | guessing_start := time.now() |
| 38 | guessing_attempts := 0 |
| 39 | |
| 40 | for len(used_combos) < total_number_of_combinations { |
| 41 | free_all(context.temp_allocator) |
| 42 | guessing_attempts += 1 |
| 43 | |
| 44 | builder := strings.builder_make(context.temp_allocator) |
| 45 | for _ in 0..<NUM_COMBOS { |
| 46 | pos := rand.int63_max(NUM_LETTERS) |
| 47 | letter := runes[pos] |
| 48 | strings.write_rune(&builder, letter) |
| 49 | } |
| 50 | code := strings.to_string(builder) |
| 51 | assert(len(code) == NUM_COMBOS) |
| 52 | |
| 53 | ok := code in used_combos |
| 54 | if !ok { // good path. unused means we can insert now |
| 55 | insertable_code := strings.clone(code) |
| 56 | used_combos[insertable_code] = true // set dummy to insert key, a hashmap needs a value. but the value is of no value to us |
| 57 | remaining_combos := total_number_of_combinations - len(used_combos) |
| 58 | |
| 59 | // because printing to console is expensive, only enable for debug / informative |
| 60 | // fmt.printfln("Code %s inserted. Amount of insertion attempts: %v . %v unoccupied Codes Remain of %v total possibilities.", insertable_code, guessing_attempts, remaining_combos, total_number_of_combinations ) |
| 61 | |
| 62 | guessing_attempts = 0 |
| 63 | } |
| 64 | |
| 65 | } |
| 66 | |
| 67 | guessing_end := time.now() |
| 68 | diff := time.diff(guessing_start, guessing_end) |
| 69 | dur_seconds := time.duration_seconds(diff) |
| 70 | |
| 71 | fmt.println("Took", dur_seconds, "seconds.") |
| 72 | } |
| 73 |