aboutsummaryrefslogtreecommitdiff
path: root/cmd/seq-stat
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cmd/seq-stat/main.go115
1 files changed, 115 insertions, 0 deletions
diff --git a/cmd/seq-stat/main.go b/cmd/seq-stat/main.go
new file mode 100644
index 0000000..75bb0a3
--- /dev/null
+++ b/cmd/seq-stat/main.go
@@ -0,0 +1,115 @@
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+)
+
+var ticks = []rune{'▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'}
+
+func histogram(sequence []float64) []rune {
+ if len(sequence) == 0 {
+ return []rune{}
+ }
+
+ minVal := sequence[0]
+ maxVal := sequence[0]
+
+ for _, v := range sequence {
+ if v < minVal {
+ minVal = v
+ }
+ if v > maxVal {
+ maxVal = v
+ }
+ }
+
+ scale := (maxVal - minVal) * 256 / float64(len(ticks)-1)
+ if scale < 1 {
+ scale = 1
+ }
+
+ result := make([]rune, len(sequence))
+ for i, v := range sequence {
+ index := int(((v - minVal) * 256) / scale)
+ if index >= len(ticks) {
+ index = len(ticks) - 1
+ }
+ result[i] = ticks[index]
+ }
+
+ return result
+}
+
+func parseNumbers(input string) ([]float64, error) {
+ fields := strings.Fields(input)
+ numbers := make([]float64, 0, len(fields))
+
+ for _, field := range fields {
+ num, err := strconv.ParseFloat(field, 64)
+ if err != nil {
+ return nil, fmt.Errorf("invalid number: %s", field)
+ }
+ numbers = append(numbers, num)
+ }
+
+ return numbers, nil
+}
+
+func readFromStdin() ([]float64, error) {
+ var numbers []float64
+ scanner := bufio.NewScanner(os.Stdin)
+
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if line == "" {
+ continue
+ }
+
+ lineNumbers, err := parseNumbers(line)
+ if err != nil {
+ return nil, err
+ }
+ numbers = append(numbers, lineNumbers...)
+ }
+
+ if err := scanner.Err(); err != nil {
+ return nil, fmt.Errorf("error reading from stdin: %v", err)
+ }
+
+ return numbers, nil
+}
+
+func main() {
+ var numbers []float64
+ var err error
+
+ if len(os.Args) > 1 {
+ numbers = make([]float64, 0, len(os.Args)-1)
+ for _, arg := range os.Args[1:] {
+ num, parseErr := strconv.ParseFloat(arg, 64)
+ if parseErr != nil {
+ fmt.Fprintf(os.Stderr, "Invalid number: %s\n", arg)
+ os.Exit(1)
+ }
+ numbers = append(numbers, num)
+ }
+ } else {
+ numbers, err = readFromStdin()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error: %v\n", err)
+ os.Exit(1)
+ }
+
+ if len(numbers) == 0 {
+ fmt.Fprintln(os.Stderr, "No numbers provided")
+ os.Exit(1)
+ }
+ }
+
+ h := histogram(numbers)
+ fmt.Println(string(h))
+}