Skip to content

Instantly share code, notes, and snippets.

@shantanoo-desai
Last active October 13, 2023 17:29
Show Gist options
  • Save shantanoo-desai/1067caba681bfbe6036387e6ffa04cd1 to your computer and use it in GitHub Desktop.
Save shantanoo-desai/1067caba681bfbe6036387e6ffa04cd1 to your computer and use it in GitHub Desktop.
AoC-2015-Day4
package main
import (
"crypto/md5"
"fmt"
"math"
"sort"
"strconv"
"sync"
"time"
)
func AdventCoinMiner(secretKey, goal string, ind, bound int, ch chan int, wg *sync.WaitGroup) {
// fmt.Printf("Goroutine: %d\n", ind)
defer wg.Done()
min := ind * bound
max := bound + min
length := len(goal)
// fmt.Printf("min: %d, max: %d\n", min, max)
for i := min; i <= max; i++ {
hashInput := []byte(secretKey + strconv.Itoa(i)) //"abcdef1000000"
md5Sum := md5.Sum(hashInput)
if fmt.Sprintf("%x", md5Sum)[:length] == goal {
ch <- i
return
}
}
ch <- 0
return
}
func main() {
start := time.Now()
secretKey := "iwrupvqb"
zeros := "00000"
bound := int(math.Pow10(len(secretKey) - 1))
bin := int(bound/len(secretKey))
ch := make(chan int, len(secretKey))
wg := new(sync.WaitGroup)
wg.Add(len(secretKey))
fmt.Println("bound: ", bound)
fmt.Println("bin: ", bin)
for i := 0; i < len(secretKey); i++ {
go AdventCoinMiner(secretKey, zeros, i , bin, ch, wg)
}
defer close(ch)
returnedValues := make([]int,0)
for i := 0; i < len(secretKey); i++ {
val := <- ch
if val > 0 {
returnedValues = append(returnedValues, val)
}
}
sort.Ints(returnedValues)
fmt.Println("Value: ", returnedValues[0])
elapsed := time.Since(start)
fmt.Println("Elapsed Time: ", elapsed)
}
// Brute Force linear Search over 10^(len(secretKey) - 1))
package main
import (
"crypto/md5"
"fmt"
"math"
"strconv"
"time"
)
func AdventCoinMiner(secretKey, goal string) int {
bound := int(math.Pow10(len(secretKey) - 1))
length := len(goal)
fmt.Println("bound: ", bound)
for i := 0; i < bound; i++ {
hashInput := []byte(secretKey + strconv.Itoa(i)) //"abcdef1000000"
md5Sum := md5.Sum(hashInput)
if fmt.Sprintf("%x", md5Sum)[:length] == goal {
return i
}
}
return -1
}
func main() {
start := time.Now()
secretKey := "iwrupvqb"
zeros := "000000"
value := AdventCoinMiner(secretKey, zeros)
fmt.Println("Value: ", value)
elapsed := time.Since(start)
fmt.Println("Elapsed Time: ", elapsed)
}
@shantanoo-desai
Copy link
Author

shantanoo-desai commented Oct 13, 2023

Go Versions / Machines

  • Window 10 with WSL2 go version go1.20.2 linux/amd64

Outputs

WSL2 / Go v1.20.2 Ubuntu20.04

For:

  • secretKey: iwrupvqb
  • zeros : 000000 (6 zeros)

NOTE: produces the correct value of 9958218

go run main.go

bound:  10000000
bin:  1250000
min: 8750000, max: 10000000
min: 2500000, max: 3750000
min: 0, max: 1250000
min: 5000000, max: 6250000
min: 6250000, max: 7500000
min: 1250000, max: 2500000
min: 3750000, max: 5000000
min: 7500000, max: 8750000
Value:  9958218
Elapsed Time:  763.685002ms
go run main3.go
bound:  10000000
Value:  9958218
Elapsed Time:  3.64900318s

For:

  • secretKey: iwrupvqb
  • zeros : 00000 (5 zeros)

Answer should be 346386

go run main.go
bound:  10000000
bin:  1250000
min: 8750000, max: 10000000
min: 2500000, max: 3750000
min: 5000000, max: 6250000
min: 0, max: 1250000
min: 6250000, max: 7500000
min: 1250000, max: 2500000
min: 3750000, max: 5000000
min: 7500000, max: 8750000
Value:  6251728
Elapsed Time:  1.744401ms
go run main3.go

bound:  10000000
Value:  346386
Elapsed Time:  129.878792ms

@shantanoo-desai
Copy link
Author

Updated

using sync.WaitGroup for the Miner task will be able to provide either the actual iteration value (if found) or 0 if not found.

Using the same amount of listeners on the channels as goroutines + waitgroups one can determine the iteration value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment