Advertisement
Guest User

Untitled

a guest
Dec 2nd, 2018
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 2.15 KB | None | 0 0
  1. package main
  2. import (
  3.     "bufio"
  4.     "bytes"
  5.     "fmt"
  6.     "io"
  7.     "os"
  8.     "strings"
  9.     "sync"
  10.     "sync/atomic"
  11. )
  12.  
  13. func main() {
  14.     f, err := os.Open(filename)
  15.     if err != nil {
  16.         panic(err)
  17.     }
  18.     defer f.Close()
  19.     candidates := make(chan string)
  20.     done := make(chan struct{})
  21.     var twos, threes int64
  22.     wg := &sync.WaitGroup{}
  23.     r := bufio.NewReader(f)
  24.     go worker(candidates, done)
  25.     for {
  26.         wg.Add(1)
  27.         line, err := r.ReadSlice('\n')
  28.         if err != nil && err != io.EOF {
  29.             panic(err)
  30.         }
  31.         if err == io.EOF { // this one has no trailing '\n'
  32.             go checkCandidate(string(line), &threes, &twos, wg)
  33.             go sendCandidate(string(line), candidates)
  34.             break
  35.         }
  36.         go checkCandidate(string(line)[:len(line)-1], &threes, &twos, wg)
  37.         go sendCandidate(string(line[:len(line)-1]), candidates)
  38.     }
  39.     printChecksum(&threes, &twos, wg)
  40.     <-done
  41. }
  42.  
  43. func printChecksum(threes, twos *int64, wg *sync.WaitGroup) {
  44.     wg.Wait()
  45.     fmt.Printf("\n Checksum: %d\n", atomic.LoadInt64(threes)*atomic.LoadInt64(twos))
  46. }
  47.  
  48. func sendCandidate(s string, ch chan<- string) {
  49.     ch <- s
  50. }
  51. func checkCandidate(s string, threes, twos *int64, wg *sync.WaitGroup) {
  52.     defer wg.Done()
  53.     var foundThree, foundTwo bool
  54.     for _, r := range s {
  55.         c := strings.Count(s, string(r))
  56.         if c == 2 {
  57.             if !foundTwo {
  58.                 foundTwo = true
  59.                 atomic.AddInt64(twos, 1)
  60.                 if foundThree {
  61.                     break
  62.                 }
  63.             }
  64.         } else {
  65.             if c == 3 {
  66.                 if !foundThree {
  67.                     foundThree = true
  68.                     atomic.AddInt64(threes, 1)
  69.                 }
  70.                 if foundTwo {
  71.                     break
  72.                 }
  73.             }
  74.         }
  75.     }
  76. }
  77.  
  78. func worker(in chan string, done chan struct{}) {
  79.     previous := make([]string, 0, 50000)
  80.     for s := range in {
  81.         go doWork(s, previous[:len(previous)], done)
  82.         previous = append(previous, s)
  83.     }
  84. }
  85.  
  86. func doWork(s string, previous []string, done chan struct{}) {
  87.     for _, p := range previous {
  88.         if res := compare(s, p); res != "" {
  89.             fmt.Printf("\nResult is: %s\n", res)
  90.             close(done)
  91.             return
  92.         }
  93.     }
  94. }
  95.  
  96. func compare(a, b string) string {
  97.     diffIndex := -1
  98.     for i := 0; i < len(a); i++ {
  99.         if a[i] != b[i] {
  100.             if diffIndex != -1 {
  101.                 return ""
  102.             }
  103.             diffIndex = i
  104.         }
  105.     }
  106.     return a[:diffIndex] + a[diffIndex+1:]
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement