Up to Exercise 1-4
authorwatkinsr <ryanwatkins54@gmail.com>
Thu, 21 May 2020 02:45:43 +0000 (03:45 +0100)
committerwatkinsr <ryanwatkins54@gmail.com>
Thu, 21 May 2020 02:45:43 +0000 (03:45 +0100)
dup1.go [new file with mode: 0644]
dup2.go [new file with mode: 0644]
dup3.go [new file with mode: 0644]

diff --git a/dup1.go b/dup1.go
new file mode 100644 (file)
index 0000000..edbb60b
--- /dev/null
+++ b/dup1.go
@@ -0,0 +1,25 @@
+// Dup1 prints the text of each line that appear more than
+// once in the standard input, preceded by it's count
+
+package main
+
+import (
+       "bufio"
+       "fmt"
+       "os"
+)
+
+func main() {
+       counts := make(map[string]int)
+       input := bufio.NewScanner(os.Stdin)
+       for input.Scan() {
+               counts[input.Text()]++
+       }
+       // NOTE: ignoring potential errors from input.Err()
+       for line, n := range counts {
+       // fmt.Println(line, n);
+               if n > 1 {
+                       fmt.Printf("%d\t%s\n", n, line)
+               }
+       }
+}
diff --git a/dup2.go b/dup2.go
new file mode 100644 (file)
index 0000000..5ab6e88
--- /dev/null
+++ b/dup2.go
@@ -0,0 +1,61 @@
+// Dup2 prints the count and text of lines that appear more than once
+//in the input. It reads from stdin or from a list of named files.
+package main
+
+import (
+       "bufio"
+       "fmt"
+       "os"
+)
+
+type val struct {
+       amount int
+       files  []string
+}
+
+func main() {
+       counts := make(map[string]val)
+       files := os.Args[1:]
+       if len(files) == 0 {
+               countLines(os.Stdin, counts)
+       } else {
+               for _, arg := range files {
+                       f, err := os.Open(arg)
+                       if err != nil {
+                               fmt.Fprintf(os.Stderr, "dup2: %v\n", err)
+                       }
+                       countLines(f, counts)
+                       f.Close()
+               }
+       }
+       for line, v := range counts {
+               if v.amount > 1 {
+                       fs := unique(v.files)
+                       fmt.Printf("%d\t%s\t%s\n", v.amount, line, fs)
+               }
+       }
+}
+
+func unique(strSlice []string) []string {
+       keys := make(map[string]bool)
+       list := []string{}
+       for _, entry := range strSlice {
+               if _, value := keys[entry]; !value {
+                       keys[entry] = true
+                       list = append(list, entry)
+               }
+       }
+       return list
+}
+
+func countLines(f *os.File, counts map[string]val) {
+       input := bufio.NewScanner(f)
+       for input.Scan() {
+               t := input.Text()
+               pair := counts[t]
+               pair.amount++
+               pair.files = append(pair.files, f.Name())
+               // fmt.Printf("%s %d %s\n", input.Text(), pair.amount, pair.files)
+               counts[t] = pair
+       }
+}
diff --git a/dup3.go b/dup3.go
new file mode 100644 (file)
index 0000000..1c8319e
--- /dev/null
+++ b/dup3.go
@@ -0,0 +1,27 @@
+package main
+
+import (
+    "fmt"
+    "io/ioutil"
+    "os"
+    "strings"
+)
+
+func main() {
+       counts := make(map[string]int)
+       for _, filename := range os.Args[1:] {
+       data, err := ioutil.ReadFile(filename)
+       if err != nil {
+               fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
+               continue
+       }
+       for _, line := range strings.Split(string(data), "\n") {
+               counts[line]++
+       }
+       }
+       for line, n := range counts {
+               if n > 1 {
+               fmt.Printf("%d\t%s\n", n, line)
+               }
+       }
+}