how many valid CPFs are there?
package main | |
import ( | |
"fmt" | |
"runtime" | |
) | |
type CPF []int | |
func NewCPF(cpf int64) CPF { | |
digits := make([]int, 11) | |
index := 10 | |
for cpf > 0 { | |
digits[index] = int(cpf % 10) | |
cpf = cpf / 10 | |
index-- | |
} | |
return digits | |
} | |
func (cpf CPF) Valid() bool { | |
add := 0 | |
if cpf.allDigitsAreEqual() { | |
return false | |
} | |
for i := 0; i < 9; i++ { | |
add += cpf[i] * (10 - i) | |
} | |
rev := 11 - (add % 11) | |
if rev > 9 { | |
rev = 0 | |
} | |
if rev != cpf[9] { | |
return false | |
} | |
add = 0 | |
for i := 0; i < 10; i++ { | |
add += cpf[i] * (11 - i) | |
} | |
rev = 11 - (add % 11) | |
if rev > 9 { | |
rev = 0 | |
} | |
if rev != cpf[10] { | |
return false | |
} | |
return true | |
} | |
func (cpf CPF) allDigitsAreEqual() bool { | |
for i := 1; i < 11; i++ { | |
if cpf[i] != cpf[0] { | |
return false | |
} | |
} | |
return true | |
} | |
func main() { | |
runtime.GOMAXPROCS(2) | |
jobs := make(chan CPF, 1024) | |
results := make(chan bool, 1024) | |
done := make(chan bool) | |
numberOfWorkers := 8 | |
numberOfJobs := 99999999999 | |
for i := 0; i < numberOfWorkers; i++ { | |
go func(cpfs chan CPF, result chan bool, done chan bool) { | |
for { | |
select { | |
case cpf := <-cpfs: | |
result <- cpf.Valid() | |
case <-done: | |
return | |
} | |
} | |
}(jobs, results, done) | |
} | |
go func() { | |
for i := 0; i < numberOfJobs; i++ { | |
jobs <- NewCPF(int64(i)) | |
} | |
}() | |
go func() { | |
count := 0 | |
valids := 0 | |
invalids := 0 | |
for { | |
if <-results { | |
valids++ | |
} else { | |
invalids++ | |
} | |
count++ | |
if count%1000000 == 0 { | |
fmt.Printf("@ %d (valids: %d, invalids: %d)\n", count, valids, invalids) | |
} | |
if count >= numberOfJobs { | |
fmt.Println("valids:", valids) | |
fmt.Println("invalids:", invalids) | |
done <- true | |
return | |
} | |
} | |
}() | |
<-done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment