Last active
August 3, 2020 13:08
-
-
Save chidiwilliams/620be628a06e428f291e6047c76bce70 to your computer and use it in GitHub Desktop.
My Solution to Find Treasure App (Ileya Game)
This file contains hidden or 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 | |
import ( | |
"encoding/json" | |
"fmt" | |
"log" | |
"math" | |
"net/http" | |
"os" | |
"time" | |
) | |
const ( | |
maxCallsPerMin = 11 | |
numNodes = 50000 | |
startURL = "https://findtreasure.app/api/v1/games/ileya/start" | |
) | |
var ( | |
mobile = os.Getenv("mobile") | |
token = os.Getenv("token") | |
) | |
type response struct { | |
Paths []string `json:"paths"` | |
Treasures struct { | |
Total int `json:"total"` | |
Found int `json:"found"` | |
} `json:"treasures"` | |
} | |
func main() { | |
ticker := time.NewTicker(time.Duration(math.Round(float64(60)/maxCallsPerMin)) * time.Second) | |
urls := make([]string, 0, numNodes) | |
urls = append(urls, startURL) | |
checked := make(map[string]bool, numNodes) | |
newURLs, found := make(chan string), make(chan int) | |
foundCount := 0 | |
go func() { | |
for range found { | |
foundCount++ | |
} | |
}() | |
go func() { | |
for newURL := range newURLs { | |
if checked[newURL] { | |
fmt.Println("url already exists, skipping") | |
} else { | |
urls = append(urls, newURL) | |
fmt.Printf("urls left to check: %v, found: %v, checked: %v\n", len(urls), foundCount, len(checked)) | |
} | |
} | |
}() | |
for { | |
select { | |
case <-ticker.C: | |
log.Println("Making new request") | |
if len(urls) > 0 { | |
url := urls[0] | |
urls = urls[1:] | |
checked[url] = true | |
go func() { | |
if err := makeReq(url, found, newURLs); err != nil { | |
log.Print(err) | |
} | |
}() | |
} | |
} | |
} | |
} | |
func makeReq(url string, found chan<- int, newURLs chan<- string) error { | |
req, err := http.NewRequest("GET", url, nil) | |
if err != nil { | |
return err | |
} | |
req.Header.Set("gomoney", mobile) | |
req.Header.Set("Authorization", "Bearer "+token) | |
resp, err := http.DefaultClient.Do(req) | |
if err != nil { | |
return err | |
} | |
log.Printf("Received response: %+v\n", resp) | |
if resp.StatusCode == 302 { | |
found <- 1 | |
} | |
var result response | |
if err = json.NewDecoder(resp.Body).Decode(&result); err != nil { | |
return err | |
} | |
log.Printf("Result: %+v\n", result) | |
for _, path := range result.Paths { | |
newURLs <- path | |
} | |
return nil | |
} |
Would a map[string]bool be a bad idea for checked?
Would a map[string]bool be a bad idea for checked?
@ajizanci You're very right, it wouldn't. I actually updated my implementation previously. Will update the gist now ๐๐
Oh, ok๐
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice!