Advertisement
sci4me

AllTheCollatzs

Dec 30th, 2017
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.57 KB | None | 0 0
  1.  package main
  2.  
  3. import (
  4.     "strconv"
  5.     "strings"
  6.     "fmt"
  7.     "os"
  8.     "os/signal"
  9.     "syscall"
  10.     "runtime"
  11.     "time"
  12.     "flag"
  13. )
  14.  
  15. func comma(v uint64) string {
  16.     sign := ""
  17.     if v < 0 {
  18.         sign = "-"
  19.         v = 0 - v
  20.     }
  21.  
  22.     parts := []string{"", "", "", "", "", "", ""}
  23.     j := len(parts) - 1
  24.  
  25.     for v > 999 {
  26.         parts[j] = strconv.FormatUint(v%1000, 10)
  27.         switch len(parts[j]) {
  28.         case 2:
  29.             parts[j] = "0" + parts[j]
  30.         case 1:
  31.             parts[j] = "00" + parts[j]
  32.         }
  33.         v = v / 1000
  34.         j--
  35.     }
  36.     parts[j] = strconv.Itoa(int(v))
  37.     return sign + strings.Join(parts[j:len(parts)], ",")
  38. }
  39.  
  40. func formatRate(rate float64) string {
  41.     if(rate >= 1000000000) {
  42.         return fmt.Sprintf("%.2f gC/s", rate / 1000000000)
  43.     } else if(rate >= 1000000) {
  44.         return fmt.Sprintf("%.2f mC/s", rate / 1000000)
  45.     } else if(rate >= 1000) {
  46.         return fmt.Sprintf("%.2f kC/s", rate / 1000)
  47.     } else {
  48.         return fmt.Sprintf("%.2f C/s", rate)
  49.     }
  50. }
  51.  
  52. func steps(n uint64) uint64 {
  53.     if n <= 0 { return 0; }
  54.     if n == 1 { return 0; }
  55.  
  56.     var steps uint64
  57.  
  58.     i := n
  59.     for i != 1 {
  60.         for (i & 1) == 1 {
  61.             i = ((3 * i) + 1) / 2
  62.             steps += 2
  63.         }
  64.  
  65.         for (i & 1) == 0 {
  66.             i /= 2
  67.             steps++
  68.         }
  69.     }
  70.  
  71.     return steps
  72. }
  73.  
  74. type work struct {
  75.     start uint64
  76.     end uint64
  77. }
  78.  
  79. func worker(req chan work, resp chan uint64) {
  80.     for {
  81.         w := <- req
  82.  
  83.         var total uint64
  84.         for i := w.start; i < w.end; i++ {
  85.             total += steps(i)
  86.         }
  87.         resp <- total
  88.     }
  89. }
  90.  
  91. func main() {
  92.     var nthreads int
  93.     var blockSize uint64
  94.  
  95.     flag.IntVar(&nthreads, "threads", runtime.NumCPU(), "number of worker threads")
  96.     flag.Uint64Var(&blockSize, "work", 1000000, "work unit size")
  97.     flag.Parse()
  98.  
  99.     if(nthreads <= 0) {
  100.         fmt.Printf("Must have > 0 threads")
  101.         return
  102.     }
  103.  
  104.     fmt.Printf("Running with %d threads, work size %s\n", nthreads, comma(blockSize))
  105.  
  106.     reqs  := make([]chan work, nthreads)
  107.     resps := make([]chan uint64, nthreads)
  108.  
  109.     for i := 0; i < nthreads; i++ {
  110.         reqs[i] = make(chan work)
  111.         resps[i] = make(chan uint64)
  112.         go worker(reqs[i], resps[i])
  113.     }
  114.  
  115.     stop := make(chan os.Signal, 2)
  116.     signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
  117.     go func() {
  118.         <-stop
  119.         os.Exit(0)
  120.     }()
  121.  
  122.     startTime := time.Now()
  123.  
  124.     var current uint64
  125.     for {
  126.         for _, req := range reqs {
  127.             var w work
  128.             w.start = current
  129.             w.end = current + blockSize
  130.             req <- w
  131.             current += blockSize
  132.         }
  133.  
  134.         var total uint64
  135.         for _, resp := range resps {
  136.             total += <-resp
  137.         }
  138.  
  139.         elapsed := time.Since(startTime)
  140.  
  141.         fmt.Printf("%s | %s | %s\n", elapsed, comma(current), formatRate(float64(current) / float64(elapsed) * float64(time.Second)))
  142.     }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement