Recently in response to 
[https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching](https://www.reddit.com/r/dailyprogrammer/comments/ffxabb/20200309_challenge_383_easy_necklace_matching)/
 I came up with my nim solution which was pretty identical to that of a Go code 
someone else posted. Seeing Go executing the same algorithm faster I translated 
almost 1:1 from Go but Go still wins:
    
    
    import os, tables
    
    # My original
    # func smallestRepr(arg: string): string =
    #   let repeated = arg & arg
    #   result = arg
    #   var i = 0
    #   while i + high(arg) <= repeated.high():
    #     let slice = repeated[i .. i + arg.high()]
    #     if slice < result:
    #       result = slice
    #     inc i
    
    # Translation
    func smallestRepr(arg: string): string =
      let repeated = arg & arg
      result = arg
      for i in 1 .. arg.len():
        let slice = repeated[i .. i + arg.high()]
        if slice < result:
          result = slice
    
    when isMainModule:
      var wordTable = initTable[string, seq[string]]()
      for word in paramStr(1).lines():
        let key = word.smallestRepr()
        if unlikely wordTable.hasKey(key):
          wordTable[key] &= word
          if wordTable[key].len() == 4:
            echo(wordTable[key])
            break
        else:
          wordTable[key] = @[word]
    
    
    Run

Go:
    
    
    package main
    
    import (
            "bufio"
            "fmt"
            "os"
    )
    
    func canonicalize(s string) string {
            c := s + s[:len(s)-1]
            best := s
            for i := 1; i < len(s); i++ {
                    if c[i:i+len(s)] < best {
                            best = c[i : i+len(s)]
                    }
            }
            return best
    }
    
    func main() {
            seen := make(map[string][]string)
            
            inputFile, err := os.Open(os.Args[1])
            defer inputFile.Close()
            
            if err != nil {
                    os.Exit(1)
            }
            
            scanner := bufio.NewScanner(inputFile)
            
            for scanner.Scan() {
                    word := scanner.Text()
                    n := canonicalize(word)
                    seen[n] = append(seen[n], word)
            
            }
            
            for _, words := range seen {
                    if len(words) == 4 {
                            fmt.Printf("%v\n", words)
                            break
                    }
            
            }
    }
    
    
    Run

In my machine, Nim version compiled with -d:release executes in 0.274 seconds 
while the Go version takes only 0.120 seconds. I'm looking for places where I 
didn't notice any performance pitfall. 

Reply via email to