Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package main
- import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "os"
- "strings"
- "sync"
- "sync/atomic"
- )
- func main() {
- f, err := os.Open(filename)
- if err != nil {
- panic(err)
- }
- defer f.Close()
- candidates := make(chan string)
- done := make(chan struct{})
- var twos, threes int64
- wg := &sync.WaitGroup{}
- r := bufio.NewReader(f)
- go worker(candidates, done)
- for {
- wg.Add(1)
- line, err := r.ReadSlice('\n')
- if err != nil && err != io.EOF {
- panic(err)
- }
- if err == io.EOF { // this one has no trailing '\n'
- go checkCandidate(string(line), &threes, &twos, wg)
- go sendCandidate(string(line), candidates)
- break
- }
- go checkCandidate(string(line)[:len(line)-1], &threes, &twos, wg)
- go sendCandidate(string(line[:len(line)-1]), candidates)
- }
- printChecksum(&threes, &twos, wg)
- <-done
- }
- func printChecksum(threes, twos *int64, wg *sync.WaitGroup) {
- wg.Wait()
- fmt.Printf("\n Checksum: %d\n", atomic.LoadInt64(threes)*atomic.LoadInt64(twos))
- }
- func sendCandidate(s string, ch chan<- string) {
- ch <- s
- }
- func checkCandidate(s string, threes, twos *int64, wg *sync.WaitGroup) {
- defer wg.Done()
- var foundThree, foundTwo bool
- for _, r := range s {
- c := strings.Count(s, string(r))
- if c == 2 {
- if !foundTwo {
- foundTwo = true
- atomic.AddInt64(twos, 1)
- if foundThree {
- break
- }
- }
- } else {
- if c == 3 {
- if !foundThree {
- foundThree = true
- atomic.AddInt64(threes, 1)
- }
- if foundTwo {
- break
- }
- }
- }
- }
- }
- func worker(in chan string, done chan struct{}) {
- previous := make([]string, 0, 50000)
- for s := range in {
- go doWork(s, previous[:len(previous)], done)
- previous = append(previous, s)
- }
- }
- func doWork(s string, previous []string, done chan struct{}) {
- for _, p := range previous {
- if res := compare(s, p); res != "" {
- fmt.Printf("\nResult is: %s\n", res)
- close(done)
- return
- }
- }
- }
- func compare(a, b string) string {
- diffIndex := -1
- for i := 0; i < len(a); i++ {
- if a[i] != b[i] {
- if diffIndex != -1 {
- return ""
- }
- diffIndex = i
- }
- }
- return a[:diffIndex] + a[diffIndex+1:]
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement