Skip to content

Instantly share code, notes, and snippets.

@Mihonarium
Last active August 9, 2021 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mihonarium/b386e113f5206710207c248cd352a6ff to your computer and use it in GitHub Desktop.
Save Mihonarium/b386e113f5206710207c248cd352a6ff to your computer and use it in GitHub Desktop.
An evil and time-based way to check whether an array is permutation, as an answer to https://t.me/oleg_log/4809
package main
import (
"fmt"
"sync"
"time"
)
type BetterObject struct {
ID int
}
func CheckWhetherAllTheObjectsAreActuallyHaveUniqIDsFrom1toLenArr(arrayLen int, objects chan BetterObject) bool {
wg, mu := sync.WaitGroup{}, sync.Mutex{}
sleepBetweenIDs := arrayLen / 1000 + 10 // Add a second for every 1000 elements of the array
gotCollision, gotImpossibleSleepTime, avoidChanCollisions := make(chan bool, 5), make(chan bool, 5), sync.Mutex{}
startCycleTime := time.Now()
for o := range objects { // check if there are any collisions
wg.Add(1)
go func(o BetterObject) {
defer wg.Done()
sleepTime := time.Second * time.Duration(o.ID * sleepBetweenIDs)
if sleepTime <= 0 {
avoidChanCollisions.Lock()
if len(gotImpossibleSleepTime) == 0 {
gotImpossibleSleepTime <- true
}
avoidChanCollisions.Unlock()
}
time.Sleep(sleepTime)
timeBeforeLock := time.Now()
mu.Lock()
time.Sleep(3 * time.Second)
mu.Unlock()
timeAfterLock := time.Now()
if timeAfterLock.Sub(timeBeforeLock) > 5 * time.Second {
avoidChanCollisions.Lock()
if len(gotCollision) == 0 {
gotCollision <- true
}
avoidChanCollisions.Unlock()
return
}
}(o)
}
wg.Wait()
endCycleTime := time.Now()
maxAllowedTimeToCompleteIfTheIDsAreUpToLen := arrayLen * (sleepBetweenIDs) + 3 + 1
if endCycleTime.Sub(startCycleTime) > time.Duration(maxAllowedTimeToCompleteIfTheIDsAreUpToLen) * time.Second {
return false // there are IDs larger than len(array)
}
if len(gotCollision) > 0 || len(gotImpossibleSleepTime) > 0 {
return false // there are collisions or Ds <= 0
}
return true
}
func CheckWhetherAllTheObjectsAreActuallyHaveUniqIDsFrom1toLenArrFromSlice(objectsInKindOfArray []BetterObject) bool {
c := make(chan BetterObject, len(objectsInKindOfArray))
go func() {
for _, o := range objectsInKindOfArray {
c <- o
}
close(c)
}()
return CheckWhetherAllTheObjectsAreActuallyHaveUniqIDsFrom1toLenArr(len(objectsInKindOfArray), c)
}
func main() {
test := make([]BetterObject, 0)
for i := 1; i < 3; i++ {
test = append(test, BetterObject{i})
}
fmt.Println(CheckWhetherAllTheObjectsAreActuallyHaveUniqIDsFrom1toLenArrFromSlice(test))
}
@Mihonarium
Copy link
Author

You can use this under any license you want for the purpose of including this in the Golang standard library

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