Skip to content

Instantly share code, notes, and snippets.

@mendelgusmao
Last active August 29, 2015 14:11
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 mendelgusmao/f16d1301a2c214f77569 to your computer and use it in GitHub Desktop.
Save mendelgusmao/f16d1301a2c214f77569 to your computer and use it in GitHub Desktop.
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