Thursday, October 31, 2013

How to Solve Max Volume Problem

My solution for max volume problem.
package main

import (
    "fmt"
)

func maxVolume(a []int) int {
    left := 0
    right := len(a) - 1
    volume := 0
    total := 0
    for left != right {
        if a[left] <= a[right] {
            for i := left + 1; i < len(a); i++ {
                if a[left] > a[i] {
                    volume += a[left] - a[i]
                } else {
                    left = i
                    total += volume
                    volume = 0
                    break
                }
            }
        } else {
            for i := right - 1; i >= left; i-- {
                if a[right] > a[i] {
                    volume += a[right] - a[i]
                } else {
                    right = i
                    total += volume
                    volume = 0
                    break
                }
            }
        }
    }
    return total
}

func main() {
    fmt.Println(maxVolume([]int{2, 5, 1, 2, 3, 4, 7, 7, 6}) == 10)
    fmt.Println(maxVolume([]int{2, 5, 1, 3, 1, 2, 1, 7, 7, 6}) == 17)
    fmt.Println(maxVolume([]int{2, 3, 1, 2, 3, 1, 3}) == 5)
    fmt.Println(maxVolume([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}) == 0)
    fmt.Println(maxVolume([]int{9, 8, 7, 6, 5, 4, 3, 2, 1}) == 0)
    fmt.Println(maxVolume([]int{1, 1, 1, 1, 1}) == 0)
    fmt.Println(maxVolume([]int{1, 0, 1}) == 1)
    fmt.Println(maxVolume([]int{5, 0, 5}) == 5)
    fmt.Println(maxVolume([]int{5, 0, 4}) == 4)
    fmt.Println(maxVolume([]int{4, 0, 5}) == 4)
    fmt.Println(maxVolume([]int{4, 0, 5, 0, 2}) == 6)
    fmt.Println(maxVolume([]int{0, 1, 0, 1, 0}) == 1)
    fmt.Println(maxVolume([]int{0, 1, 0, 0, 1, 0}) == 2)
    fmt.Println(maxVolume([]int{4, 2, 2, 1, 1, 1, 3}) == 8)
    fmt.Println(maxVolume([]int{0, 3, 2, 1, 4}) == 3)
    fmt.Println(maxVolume([]int{1, 0, 1, 0}) == 1)
    fmt.Println(maxVolume([]int{1, 0, 1, 2, 0, 2}) == 3)
    fmt.Println(maxVolume([]int{2, 5, 1, 2, 3, 4, 7, 7, 6}) == 10)
    fmt.Println(maxVolume([]int{5, 1, 0, 1}) == 1)
    fmt.Println(maxVolume([]int{2, 5, 1, 2, 3, 4, 7, 7, 6, 3, 5}) == 12)
    fmt.Println(maxVolume([]int{3, 0, 1, 0, 2}) == 5)
}

How to Solve Spiral Problem

My solution for spiral problem.
package main

import (
    "fmt"
)

func spiral(height, width, row, col int) []int {
    a := createSlice(height, width)
    result := []int{}
    r := row - 1
    c := col - 1
    result = append(result, a[r][c])
    x := 1
    for z := 0; (height * width) != len(result); z++ {
        for i := 0; i < x; i++ {
            r, c = up(r, c)
            if !outOfBoundary(height, width, r, c) {
                result = append(result, a[r][c])
            }
        }
        for i := 0; i < x; i++ {
            r, c = left(r, c)
            if !outOfBoundary(height, width, r, c) {
                result = append(result, a[r][c])
            }
        }
        x += 1
        for i := 0; i < x; i++ {
            r, c = down(r, c)
            if !outOfBoundary(height, width, r, c) {
                result = append(result, a[r][c])
            }
        }
        for i := 0; i < x; i++ {
            r, c = right(r, c)
            if !outOfBoundary(height, width, r, c) {
                result = append(result, a[r][c])
            }
        }
        x += 1
    }
    return result
}

func outOfBoundary(height, width, row, col int) bool {
    return !((row >= 0 && row < height) && (col >= 0 && col < width))
}

func left(row, col int) (int, int) {
    return row, col - 1
}

func right(row, col int) (int, int) {
    return row, col + 1
}

func up(row, col int) (int, int) {
    return row - 1, col
}

func down(row, col int) (int, int) {
    return row + 1, col
}

func createSlice(height, width int) [][]int {
    a := make([][]int, height)
    n := 1
    for i := 0; i < height; i++ {
        a[i] = make([]int, width)
        for j := 0; j < width; j++ {
            a[i][j] = n
            n += 1
        }
    }
    return a
}

func main() {
    fmt.Println(spiral(5, 5, 3, 3))
    fmt.Println(spiral(2, 4, 1, 2))
    fmt.Println(spiral(5, 5, 4, 2))
}

Sunday, October 27, 2013

How to Call C++ from Go

.
└── src
    └── cgotest
        ├── hello
        │   ├── cpp
        │   │   └── hellocpp.cpp
        │   ├── hello.go
        │   ├── include
        │   │   └── hellocpp.h
        │   └── lib
        │       └── libhellocpp.so
        └── main.go
hellocpp.h
#ifndef _HELLOCPP_H_
#define _HELLOCPP_H_

#ifdef __cplusplus
extern "C" {
#endif
    void SayHello();
#ifdef __cplusplus
}
#endif

#endif
hellocpp.cpp
#include <iostream>
#include "hellocpp.h"
using namespace std;

void SayHello() {
    cout << "Hello from C++" << endl;
}
Let's now create a C++ shared library.
cd $GOPATH/src/cgotest/hello
mkdir lib
g++ -Wall -shared -fpic cpp/hellocpp.cpp -Iinclude -o lib/hellocpp.so
hello.go
package hello

// #cgo CFLAGS: -Iinclude
// #cgo LDFLAGS: -Llib -lhellocpp
// #include "hellocpp.h"
import "C"

func HelloFromCpp() {
    C.SayHello()
}
main.go
package main

import "cgotest/hello"

func main() {
    hello.HelloFromCpp()
}
There seems to be a bug that makes setting relative paths in LDFLAGS not to work. The workaround is to set LIBRARY_PATH env variable using absolute path.
cd $GOPATH
export LIBRARY_PATH=$GOPATH/src/cgotest/hello/lib
export LD_LIBRARY_PATH=$LIBRARY_PATH
go build cgotest
./cgotest
Output:
Hello from C++

Wednesday, October 23, 2013

How to Create a Self-Extracting Installer in Bash

The basic idea of creating a self-extracting installer in Bash is really straightforward. We just need to append the binary package, e.g. an archive file in our installer script. Here's a simple example on how to do that.
  1. Create an installer script
  2. #!/bin/bash
    
    echo "Running self-extracting installer"
    
    ARCHIVE=`awk '/^__START_HERE__/ {print NR + 1; exit 0; }' $0`
    echo $ARCHIVE
    tail -n+$ARCHIVE $0 | tar xzv
    
    exit 0
    
    __START_HERE__
    
  3. Append an archive file into an installer script
  4. cat myproject.tar.gz >> installer
    
  5. Give an executable permission
  6. chmod +x installer
    
  7. Execute the installer script
  8. ./installer
    

Tuesday, October 15, 2013

How to Programmatically Download Dependencies using Ivy

Below is an example how to programmatically download dependencies using Ivy.
apply plugin: "java"
apply plugin: "eclipse"

repositories {
    mavenCentral()
}

dependencies {
    compile "org.apache.ivy:ivy:2.3.0"
    testCompile "junit:junit:4.10"
}
import java.util.ArrayList;
import java.util.List;

import org.apache.ivy.Main;

public class Test {
    public static void main(String[] args) throws Exception {
        List<String> list = new ArrayList<>();
        list.add("-settings");
        list.add("ivysettings.xml");
        list.add("-dependency");
        list.add("testgroup");
        list.add("testartifact");
        list.add("1.0.0");
        list.add("-retrieve");
        list.add("lib/[artifact]-[revision].[ext]");
        String[] newArgs = new String[list.size()];
        Main.main(list.toArray(newArgs));
    }
}
<ivysettings>
  <settings defaultResolver="myResolver"/>
  <property name="ivy.checksums" value="" />
  <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
  <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
  <resolvers>
    <url name="testivy">
      <ivy pattern="http://myivyserver/[organisation]/[module]/[revision]/ivy-[revision].xml" /> -->
      <artifact pattern="http://myivyserver/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
    </url>
    <ibiblio name="testmaven" m2compatible="true" root="http://mymavenserver/maven" />
    <chain name="myResolver">
      <resolver ref="default" />
      <resolver ref="testivy" />
      <resolver ref="testmaven" />
    </chain>
  </resolvers>
</ivysettings>