Showing posts with label go. Show all posts
Showing posts with label go. Show all posts

Wednesday, March 28, 2012

go run go

Go version 1 is released today.

Wednesday, March 7, 2012

Go Snail Go

I came across a post which solves what it calls the "snail" problem in Go. We've seen some very pretty examples of the same thing in Python here.

This is the output of my version in Go for S = 9.

 1  2  3  4  5  6  7  8  9
32 33 34 35 36 37 38 39 10
31 56 57 58 59 60 61 40 11
30 55 72 73 74 75 62 41 12
29 54 71 80 81 76 63 42 13
28 53 70 79 78 77 64 43 14
27 52 69 68 67 66 65 44 15
26 51 50 49 48 47 46 45 16
25 24 23 22 21 20 19 18 17

You can see why he called it the snail. Anyway, I noticed a chance to use a goroutine for this problem. In any cycle starting with [left] followed by [down] we go n steps in each direction, then n+1 steps in the [right,up] directions. In the code below, we obtain these step values from a Go channel.

A couple of other Go-like things about this code. We stash the 2D array (as a 1D array with a shape parameter) in a struct, and then attach a func to that struct to pretty print it. The details of the pprint function could doubtless be improved---I'm not too swift with formatting. The other Goish thing is to modify both the row and column indices at once, returning what we'd call in Python a tuple value from the step function.

Fun.

package main

import (
    "fmt"
    "os"
    "strings"
)

func dist(ch chan int) {
    var a int = 1
    for { 
        ch <- a
        ch <-a
        a++ 
    }
}

var m = map[string]string{"L":"D","D":"R","R":"U","U":"L"}

func step(r, c int, dir string)(rn, cn int) {
    switch dir {
        case "L": { c-- }
        case "D": { r++ } 
        case "R": { c++ }
        case "U": { r-- }
    }
    return r,c
}

type A struct { arr []int;  SZ int }
func (a *A) pprint() {
    d := a.SZ
    for i:= 0; i < len(a.arr); i += d {
        S := []string{}
        for _,f := range a.arr[i:i+d] {
            S = append(S,fmt.Sprintf("%2d", f))
        }
        fmt.Println(strings.Join(S," "))
    }
}

func main() {
    S := 9
    if S%2 != 1 { os.Exit(1) }
    N := S*S
    a := A{make([]int,N), S}
    ch := make(chan int)
    go dist(ch)
    dir := "L"
    var r, c int;  r = S/2 + 1;  c = r
    n := <- ch
    for {
        for i := 0; i < n; i++ {
            //fmt.Println(r, c, N)
            a.arr[(r-1)*S + (c-1)] = N
            N--
            if N == 0 { break }
            r,c = step(r, c, dir)
        }
        n = <- ch
        dir = m[dir]
        if N == 0 { break }
    }
    a.pprint()
}

Sunday, March 4, 2012

Go, again

This is a brief, updated report on my exploration of the Go language. (First post here). For an idea about what Go can do I encourage you to check out another video with Rob Pike (and Russ Cox). Not to disrespect Russ, but as a great example, check out the segment starting about 21:25. It's amazing.

The source of that program is here.

In order to play with this stuff, you will have to download the compiler source and build it. I assume you can do that, if not, drop me a line.

I've spent a total of about 40 hours on Go over the last week, and I can say that I believe this is all quite correct:

The Go programming language is an open source project to make programmers more productive. Go is expressive, concise, clean, and efficient. Its concurrency mechanisms make it easy to write programs that get the most out of multicore and networked machines, while its novel type system enables flexible and modular program construction. Go compiles quickly to machine code yet has the convenience of garbage collection and the power of run-time reflection. It’s a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language.

The more I explore, the better I like it. Go does "feel like a dynamically typed, interpreted language." Exactly. And using TextMate I can just do CMD-R and the build, linking and execution happen painlessly.

I wrote about 30 or so short programs to explore simple tasks in Go. I also wrote two different versions of the PSSM code discussed here, and in subsequent posts. And I played with Bruce Eckel's code from here. A zipped folder of all this stuff is on Dropbox. It's not very well documented but only the intrepid will follow this lead anyway.

I'm hooked. I have a lot of work to do figuring out the interface and concurrency stuff. And it is great fun!

Thursday, March 1, 2012

Go fib

I've been having fun with a new programming language called Go, developed by Rob Pike and friends at Google (video). Somehow I missed hearing about it until now. I'm not leaving my true love, Python, but there's a lot to like about Go as a replacement for C and C++.

Go has

  • garbage collection, so there are no worries about managing memory
  • no classes, but simply attaches methods to types
  • a simple syntax compared to C---eliminating most semicolons
  • much less complexity than C++
  • goroutines to launch parallel processes that communicate using channels
  • maps and string support, and slices as a kind of resizable array
  • multiple return values from a function
  • combined var declaration and assignment with type of rhs
  • pointers but no pointer arithmetic
  • the ability to construct and return a local variable from a function.
  • great docs, is compiled, and fast.

    Go has interfaces, which I don't understand very well, but they can be used to give polymorphic behavior.

    Here is a simple, familiar Go program using a goroutine and a channel. Notice that the type declaration comes after the variable name, and the arrow symbol for flow into and out of the channel, c.

    package main
    
    import "fmt"
    
    func fib(c chan int) {
        var a, b int = 1, 0
        for {
            c <- a
            a, b = a + b, a
        }
    }
    
    func main() {
        c := make(chan int)
        go fib(c)
        for i := 1; i < 12; i++ {
            f := <- c
            fmt.Println(f)
        }
    }
    fib() will generate values as long as we want, similar to a Python generator. Output:
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55
    89
    I found a Go "bundle" for TextMate here.