WeixiangYan/CodeTransOcean huggingface dataset:
Task: Update a configuration file




Go: package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strings"
	"unicode"
)


type line struct {
	kind     lineKind
	option   string
	value    string
	disabled bool
}


type lineKind int

const (
	_ lineKind = iota
	ignore
	parseError
	comment
	blank
	value
)

func (l line) String() string {
	switch l.kind {
	case ignore, parseError, comment, blank:
		return l.value
	case value:
		s := l.option
		if l.disabled {
			s = "; " + s
		}
		if l.value != "" {
			s += " " + l.value
		}
		return s
	}
	panic("unexpected line kind")
}

func removeDross(s string) string {
	return strings.Map(func(r rune) rune {
		if r < 32 || r > 0x7f || unicode.IsControl(r) {
			return -1
		}
		return r
	}, s)
}

func parseLine(s string) line {
	if s == "" {
		return line{kind: blank}
	}
	if s[0] == '#' {
		return line{kind: comment, value: s}
	}
	s = removeDross(s)
	fields := strings.Fields(s)
	if len(fields) == 0 {
		return line{kind: blank}
	}
	
	semi := false
	for len(fields[0]) > 0 && fields[0][0] == ';' {
		semi = true
		fields[0] = fields[0][1:]
	}
	
	if fields[0] == "" {
		fields = fields[1:]
	}
	switch len(fields) {
	case 0:
		
		
		return line{kind: ignore}
	case 1:
		return line{
			kind:     value,
			option:   strings.ToUpper(fields[0]),
			disabled: semi,
		}
	case 2:
		return line{
			kind:     value,
			option:   strings.ToUpper(fields[0]),
			value:    fields[1],
			disabled: semi,
		}
	}
	return line{kind: parseError, value: s}
}


type Config struct {
	options map[string]int		
	lines   []line
}



func (c *Config) index(option string) int {
	if i, ok := c.options[option]; ok {
		return i
	}
	return -1
}



func (c *Config) addLine(l line) {
	switch l.kind {
	case ignore:
		return
	case value:
		if c.index(l.option) >= 0 {
			return
		}
		c.options[l.option] = len(c.lines)
		c.lines = append(c.lines, l)
	default:
		c.lines = append(c.lines, l)
	}
}


func ReadConfig(path string) (*Config, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	r := bufio.NewReader(f)
	c := &Config{options: make(map[string]int)}
	for {
		s, err := r.ReadString('\n')
		if s != "" {
			if err == nil {
				
				s = s[:len(s)-1]
			}
			c.addLine(parseLine(s))
		}
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, err
		}
	}
	return c, nil
}



func (c *Config) Set(option string, val string) {
	if i := c.index(option); i >= 0 {
		line := &c.lines[i]
		line.disabled = false
		line.value = val
		return
	}
	c.addLine(line{
		kind:   value,
		option: option,
		value:  val,
	})
}



func (c *Config) Enable(option string, enabled bool) {
	if i := c.index(option); i >= 0 {
		c.lines[i].disabled = !enabled
	}
}


func (c *Config) Write(w io.Writer) {
	for _, line := range c.lines {
		fmt.Println(line)
	}
}

func main() {
	c, err := ReadConfig("/tmp/cfg")
	if err != nil {
		log.Fatalln(err)
	}
	c.Enable("NEEDSPEELING", false)
	c.Set("SEEDSREMOVED", "")
	c.Set("NUMBEROFBANANAS", "1024")
	c.Set("NUMBEROFSTRAWBERRIES", "62000")
	c.Write(os.Stdout)
}
Task: Straddling checkerboard




Go: package main

import (
    "fmt"
    "strings"
)

func main() {
    key := `
 8752390146
 ET AON RIS
5BC/FGHJKLM
0PQD.VWXYZU`
    p := "you have put on 7.5 pounds since I saw you."
    fmt.Println(p)
    c := enc(key, p)
    fmt.Println(c)
    fmt.Println(dec(key, c))
}

func enc(bd, pt string) (ct string) {
    enc := make(map[byte]string)
    row := strings.Split(bd, "\n")[1:]
    r2d := row[2][:1]
    r3d := row[3][:1]
    for col := 1; col <= 10; col++ {
        d := string(row[0][col])
        enc[row[1][col]] = d
        enc[row[2][col]] = r2d+d
        enc[row[3][col]] = r3d+d
    }
    num := enc['/']
    delete(enc, '/')
    delete(enc, ' ')
    for i := 0; i < len(pt); i++ {
        if c := pt[i]; c <= '9' && c >= '0' {
            ct += num + string(c)
        } else {
            if c <= 'z' && c >= 'a' {
                c -= 'a'-'A'
            }
            ct += enc[c]
        }
    }
    return
}

func dec(bd, ct string) (pt string) {
    row := strings.Split(bd, "\n")[1:]
    var cx [10]int
    for i := 1; i <= 10; i++ {
        cx[row[0][i]-'0'] = i
    }
    r2d := row[2][0]-'0'
    r3d := row[3][0]-'0'
    for i := 0; i < len(ct); i++ {
        var r int
        switch d := ct[i]-'0'; d {
        case r2d:
            r = 2
        case r3d:
            r = 3
        default:
            pt += string(row[1][cx[d]])
            continue
        }
        i++
        if b := row[r][cx[ct[i]-'0']]; b == '/' {
            i++
            pt += string(ct[i])
        } else {
            pt += string(b)
        }
    }
    return
}
Task: I before E except after C




Go: package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"regexp"
	"strings"
)

func main() {
	f, err := os.Open("unixdict.txt")
	if err != nil {
		log.Fatalln(err)
	}
	defer f.Close()

	s := bufio.NewScanner(f)
	rie := regexp.MustCompile("^ie|[^c]ie")
	rei := regexp.MustCompile("^ei|[^c]ei")
	var cie, ie int
	var cei, ei int
	for s.Scan() {
		line := s.Text()
		if strings.Contains(line, "cie") {
			cie++
		}
		if strings.Contains(line, "cei") {
			cei++
		}
		if rie.MatchString(line) {
			ie++
		}
		if rei.MatchString(line) {
			ei++
		}
	}
	err = s.Err()
	if err != nil {
		log.Fatalln(err)
	}

	if check(ie, ei, "I before E when not preceded by C") &&
		check(cei, cie, "E before I when preceded by C") {
		fmt.Println("Both plausable.")
		fmt.Println(`"I before E, except after C" is plausable.`)
	} else {
		fmt.Println("One or both implausable.")
		fmt.Println(`"I before E, except after C" is implausable.`)
	}
}



func check(a, b int, s string) bool {
	switch {
	case a > b*2:
		fmt.Printf("%q is plausible (%d vs %d).\n", s, a, b)
		return true
	case a >= b:
		fmt.Printf("%q is implausible (%d vs %d).\n", s, a, b)
	default:
		fmt.Printf("%q is implausible and contra-indicated (%d vs %d).\n",
			s, a, b)
	}
	return false
}
Task: Abelian sandpile model




Go: package main

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

const dim = 16 

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}


func drawPile(pile [][]uint) {
    chars:= []rune(" ░▓█")
    for _, row := range pile {
        line := make([]rune, len(row))
        for i, elem := range row {
            if elem > 3 { 
                elem = 3
            }
            line[i] = chars[elem]
        }
        fmt.Println(string(line))
    }
}



func writePile(pile [][]uint) {
    file, err := os.Create("output.ppm")
    check(err)
    defer file.Close()
    
    fmt.Fprintf(file, "P3\n%d %d\n255\n", dim, dim)
    bcolors := []string{"125 0 25 ", "125 80 0 ", "186 118 0 ", "224 142 0 "}
    var line strings.Builder
    for _, row := range pile {        
        for _, elem := range row {
            line.WriteString(bcolors[elem])
        }
        file.WriteString(line.String() + "\n")
        line.Reset() 
    }
}


func handlePile(x, y uint, pile [][]uint) {
    if pile[y][x] >= 4 {
        pile[y][x] -= 4
        
        
        if y > 0 {
            pile[y-1][x]++
            if pile[y-1][x] >= 4 {
                handlePile(x, y-1, pile)
            }
        }
        if x > 0 {
            pile[y][x-1]++
            if pile[y][x-1] >= 4 {
                handlePile(x-1, y, pile)
            }
        }
        if y < dim-1 {
            pile[y+1][x]++
            if pile[y+1][x] >= 4 {
                handlePile(x, y+1, pile)
            }
        }
        if x < dim-1 {
            pile[y][x+1]++
            if pile[y][x+1] >= 4 {
                handlePile(x+1, y, pile)
            }
        }

        
        
        

        
        
        handlePile(x, y, pile)
    }
}

func main() {
    
    pile := make([][]uint, dim)
    for i := 0; i < dim; i++ {
        pile[i] = make([]uint, dim)
    }

    
    hdim := uint(dim/2 - 1)
    pile[hdim][hdim] = 16
    handlePile(hdim, hdim, pile)
    drawPile(pile)

    
    
    
}
Task: Xiaolin Wu's line algorithm




Go: package raster

import "math"

func ipart(x float64) float64 {
    return math.Floor(x)
}

func round(x float64) float64 {
    return ipart(x + .5)
}

func fpart(x float64) float64 {
    return x - ipart(x)
}

func rfpart(x float64) float64 {
    return 1 - fpart(x)
}


func (g *Grmap) AaLine(x1, y1, x2, y2 float64) {
    
    dx := x2 - x1
    dy := y2 - y1
    ax := dx
    if ax < 0 {
        ax = -ax
    }
    ay := dy
    if ay < 0 {
        ay = -ay
    }
    
    var plot func(int, int, float64)
    if ax < ay {
        x1, y1 = y1, x1
        x2, y2 = y2, x2
        dx, dy = dy, dx
        plot = func(x, y int, c float64) {
            g.SetPx(y, x, uint16(c*math.MaxUint16))
        }
    } else {
        plot = func(x, y int, c float64) {
            g.SetPx(x, y, uint16(c*math.MaxUint16))
        }
    }
    if x2 < x1 {
        x1, x2 = x2, x1
        y1, y2 = y2, y1
    }
    gradient := dy / dx

    
    xend := round(x1)
    yend := y1 + gradient*(xend-x1)
    xgap := rfpart(x1 + .5)
    xpxl1 := int(xend) 
    ypxl1 := int(ipart(yend))
    plot(xpxl1, ypxl1, rfpart(yend)*xgap)
    plot(xpxl1, ypxl1+1, fpart(yend)*xgap)
    intery := yend + gradient 

    
    xend = round(x2)
    yend = y2 + gradient*(xend-x2)
    xgap = fpart(x2 + 0.5)
    xpxl2 := int(xend) 
    ypxl2 := int(ipart(yend))
    plot(xpxl2, ypxl2, rfpart(yend)*xgap)
    plot(xpxl2, ypxl2+1, fpart(yend)*xgap)

    
    for x := xpxl1 + 1; x <= xpxl2-1; x++ {
        plot(x, int(ipart(intery)), rfpart(intery))
        plot(x, int(ipart(intery))+1, fpart(intery))
        intery = intery + gradient
    }
}
Task: Next highest int from digits




Go: package main

import (
    "fmt"
    "sort"
)

func permute(s string) []string {
    var res []string
    if len(s) == 0 {
        return res
    }
    b := []byte(s)
    var rc func(int) 
    rc = func(np int) {
        if np == 1 {
            res = append(res, string(b))
            return
        }
        np1 := np - 1
        pp := len(b) - np1
        rc(np1)
        for i := pp; i > 0; i-- {
            b[i], b[i-1] = b[i-1], b[i]
            rc(np1)
        }
        w := b[0]
        copy(b, b[1:pp+1])
        b[pp] = w
    }
    rc(len(b))
    return res
}

func algorithm1(nums []string) {
    fmt.Println("Algorithm 1")
    fmt.Println("-----------")
    for _, num := range nums {
        perms := permute(num)
        le := len(perms)
        if le == 0 { 
            continue
        }
        sort.Strings(perms)
        ix := sort.SearchStrings(perms, num)
        next := ""
        if ix < le-1 {
            for i := ix + 1; i < le; i++ {
                if perms[i] > num {
                    next = perms[i]
                    break
                }
            }
        }
        if len(next) > 0 {
            fmt.Printf("%29s -> %s\n", commatize(num), commatize(next))
        } else {
            fmt.Printf("%29s -> 0\n", commatize(num))
        }
    }
    fmt.Println()
}

func algorithm2(nums []string) {
    fmt.Println("Algorithm 2")
    fmt.Println("-----------")
outer:
    for _, num := range nums {
        b := []byte(num)
        le := len(b)
        if le == 0 { 
            continue
        }
        max := num[le-1]
        mi := le - 1
        for i := le - 2; i >= 0; i-- {
            if b[i] < max {
                min := max - b[i]
                for j := mi + 1; j < le; j++ {
                    min2 := b[j] - b[i]
                    if min2 > 0 && min2 < min {
                        min = min2
                        mi = j
                    }
                }
                b[i], b[mi] = b[mi], b[i]
                c := (b[i+1:])
                sort.Slice(c, func(i, j int) bool {
                    return c[i] < c[j]
                })
                next := string(b[0:i+1]) + string(c)
                fmt.Printf("%29s -> %s\n", commatize(num), commatize(next))
                continue outer
            } else if b[i] > max {
                max = num[i]
                mi = i
            }
        }
        fmt.Printf("%29s -> 0\n", commatize(num))
    }
}

func commatize(s string) string {
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    return s
}

func main() {
    nums := []string{"0", "9", "12", "21", "12453", "738440", "45072010", "95322020", "9589776899767587796600"}
    algorithm1(nums[:len(nums)-1]) 
    algorithm2(nums)               
}
Task: Four is magic




Go: package main

import (
	"fmt"
	"math"
	"strings"
)

func main() {
	for _, n := range [...]int64{
		0, 4, 6, 11, 13, 75, 100, 337, -164,
		math.MaxInt64,
	} {
		fmt.Println(fourIsMagic(n))
	}
}

func fourIsMagic(n int64) string {
	s := say(n)
	s = strings.ToUpper(s[:1]) + s[1:]
	t := s
	for n != 4 {
		n = int64(len(s))
		s = say(n)
		t += " is " + s + ", " + s
	}
	t += " is magic."
	return t
}
 


var small = [...]string{"zero", "one", "two", "three", "four", "five", "six",
	"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
	"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
var tens = [...]string{"", "", "twenty", "thirty", "forty",
	"fifty", "sixty", "seventy", "eighty", "ninety"}
var illions = [...]string{"", " thousand", " million", " billion",
	" trillion", " quadrillion", " quintillion"}

func say(n int64) string {
	var t string
	if n < 0 {
		t = "negative "
		
		n = -n
	}
	switch {
	case n < 20:
		t += small[n]
	case n < 100:
		t += tens[n/10]
		s := n % 10
		if s > 0 {
			t += "-" + small[s]
		}
	case n < 1000:
		t += small[n/100] + " hundred"
		s := n % 100
		if s > 0 {
			t += " " + say(s)
		}
	default:
		
		sx := ""
		for i := 0; n > 0; i++ {
			p := n % 1000
			n /= 1000
			if p > 0 {
				ix := say(p) + illions[i]
				if sx != "" {
					ix += " " + sx
				}
				sx = ix
			}
		}
		t += sx
	}
	return t
}
Task: Two bullet roulette




Go: package main

import (
    "fmt"
    "math/rand"
    "strings"
    "time"
)

var cylinder = [6]bool{}

func rshift() {
    t := cylinder[5]
    for i := 4; i >= 0; i-- {
        cylinder[i+1] = cylinder[i]
    }
    cylinder[0] = t
}

func unload() {
    for i := 0; i < 6; i++ {
        cylinder[i] = false
    }
}

func load() {
    for cylinder[0] {
        rshift()
    }
    cylinder[0] = true
    rshift()
}

func spin() {
    var lim = 1 + rand.Intn(6)
    for i := 1; i < lim; i++ {
        rshift()
    }
}

func fire() bool {
    shot := cylinder[0]
    rshift()
    return shot
}

func method(s string) int {
    unload()
    for _, c := range s {
        switch c {
        case 'L':
            load()
        case 'S':
            spin()
        case 'F':
            if fire() {
                return 1
            }
        }
    }
    return 0
}

func mstring(s string) string {
    var l []string
    for _, c := range s {
        switch c {
        case 'L':
            l = append(l, "load")
        case 'S':
            l = append(l, "spin")
        case 'F':
            l = append(l, "fire")
        }
    }
    return strings.Join(l, ", ")
}

func main() {
    rand.Seed(time.Now().UnixNano())
    tests := 100000
    for _, m := range []string{"LSLSFSF", "LSLSFF", "LLSFSF", "LLSFF"} {
        sum := 0
        for t := 1; t <= tests; t++ {
            sum += method(m)
        }
        pc := float64(sum) * 100 / float64(tests)
        fmt.Printf("%-40s produces %6.3f%% deaths.\n", mstring(m), pc)
    }
}
Task: Sierpinski pentagon




Go: package main

import (
    "github.com/fogleman/gg"
    "image/color"
    "math"
)

var (
    red     = color.RGBA{255, 0, 0, 255}
    green   = color.RGBA{0, 255, 0, 255}
    blue    = color.RGBA{0, 0, 255, 255}
    magenta = color.RGBA{255, 0, 255, 255}
    cyan    = color.RGBA{0, 255, 255, 255}
)

var (
    w, h        = 640, 640
    dc          = gg.NewContext(w, h)
    deg72       = gg.Radians(72)
    scaleFactor = 1 / (2 + math.Cos(deg72)*2)
    palette     = [5]color.Color{red, green, blue, magenta, cyan}
    colorIndex  = 0
)

func drawPentagon(x, y, side float64, depth int) {
    angle := 3 * deg72
    if depth == 0 {
        dc.MoveTo(x, y)
        for i := 0; i < 5; i++ {
            x += math.Cos(angle) * side
            y -= math.Sin(angle) * side
            dc.LineTo(x, y)
            angle += deg72
        }
        dc.SetColor(palette[colorIndex])
        dc.Fill()
        colorIndex = (colorIndex + 1) % 5
    } else {
        side *= scaleFactor
        dist := side * (1 + math.Cos(deg72)*2)
        for i := 0; i < 5; i++ {
            x += math.Cos(angle) * dist
            y -= math.Sin(angle) * dist
            drawPentagon(x, y, side, depth-1)
            angle += deg72
        }
    }
}

func main() {
    dc.SetRGB(1, 1, 1) 
    dc.Clear()
    order := 5 
    hw := float64(w / 2)
    margin := 20.0
    radius := hw - 2*margin
    side := radius * math.Sin(math.Pi/5) * 2
    drawPentagon(hw, 3*margin, side, order-1)
    dc.SavePNG("sierpinski_pentagon.png")
}
Task: Generate Chess960 starting position




Go: package main

import (
    "fmt"
    "math/rand"
)

type symbols struct{ k, q, r, b, n rune }

var A = symbols{'K', 'Q', 'R', 'B', 'N'}
var W = symbols{'♔', '♕', '♖', '♗', '♘'}
var B = symbols{'♚', '♛', '♜', '♝', '♞'}

var krn = []string{
    "nnrkr", "nrnkr", "nrknr", "nrkrn",
    "rnnkr", "rnknr", "rnkrn",
    "rknnr", "rknrn",
    "rkrnn"}

func (sym symbols) chess960(id int) string {
    var pos [8]rune
    q, r := id/4, id%4
    pos[r*2+1] = sym.b
    q, r = q/4, q%4
    pos[r*2] = sym.b
    q, r = q/6, q%6
    for i := 0; ; i++ {
        if pos[i] != 0 {
            continue
        }
        if r == 0 {
            pos[i] = sym.q
            break
        }
        r--
    }
    i := 0
    for _, f := range krn[q] {
        for pos[i] != 0 {
            i++
        }
        switch f {
        case 'k':
            pos[i] = sym.k
        case 'r':
            pos[i] = sym.r
        case 'n':
            pos[i] = sym.n
        }
    }
    return string(pos[:])
}

func main() {
    fmt.Println(" ID  Start position")
    for _, id := range []int{0, 518, 959} {
        fmt.Printf("%3d  %s\n", id, A.chess960(id))
    }
    fmt.Println("\nRandom")
    for i := 0; i < 5; i++ {
        fmt.Println(W.chess960(rand.Intn(960)))
    }
}
Task: Write to Windows event log




Go: package main

import (
    "fmt"
    "os/exec"
)

func main() {
    command := "EventCreate"
    args := []string{"/T", "INFORMATION", "/ID", "123", "/L", "APPLICATION",
        "/SO", "Go", "/D", "\"Rosetta Code Example\""}
    cmd := exec.Command(command, args...)
    err := cmd.Run()
    if err != nil {
        fmt.Println(err)
    }
}
Task: Spelling of ordinal numbers




Go: import (
	"fmt"
	"strings"
)

func main() {
	for _, n := range []int64{
		1, 2, 3, 4, 5, 11, 65, 100, 101, 272, 23456, 8007006005004003,
	} {
		fmt.Println(sayOrdinal(n))
	}
}

var irregularOrdinals = map[string]string{
	"one":    "first",
	"two":    "second",
	"three":  "third",
	"five":   "fifth",
	"eight":  "eighth",
	"nine":   "ninth",
	"twelve": "twelfth",
}

func sayOrdinal(n int64) string {
	s := say(n)
	i := strings.LastIndexAny(s, " -")
	i++
	
	
	
	
	if x, ok := irregularOrdinals[s[i:]]; ok {
		s = s[:i] + x
	} else if s[len(s)-1] == 'y' {
		s = s[:i] + s[i:len(s)-1] + "ieth"
	} else {
		s = s[:i] + s[i:] + "th"
	}
	return s
}



var small = [...]string{"zero", "one", "two", "three", "four", "five", "six",
	"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
	"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
var tens = [...]string{"", "", "twenty", "thirty", "forty",
	"fifty", "sixty", "seventy", "eighty", "ninety"}
var illions = [...]string{"", " thousand", " million", " billion",
	" trillion", " quadrillion", " quintillion"}

func say(n int64) string {
	var t string
	if n < 0 {
		t = "negative "
		
		n = -n
	}
	switch {
	case n < 20:
		t += small[n]
	case n < 100:
		t += tens[n/10]
		s := n % 10
		if s > 0 {
			t += "-" + small[s]
		}
	case n < 1000:
		t += small[n/100] + " hundred"
		s := n % 100
		if s > 0 {
			t += " " + say(s)
		}
	default:
		
		sx := ""
		for i := 0; n > 0; i++ {
			p := n % 1000
			n /= 1000
			if p > 0 {
				ix := say(p) + illions[i]
				if sx != "" {
					ix += " " + sx
				}
				sx = ix
			}
		}
		t += sx
	}
	return t
}
Task: Machine code




Go: package main

import "fmt"


import "C"

func main() {
    code := []byte{
        0x55, 0x48, 0x89, 0xe5, 0x89, 0x7d,
        0xfc, 0x89, 0x75, 0xf8, 0x8b, 0x75,
        0xfc, 0x03, 0x75, 0xf8, 0x89, 0x75,
        0xf4, 0x8b, 0x45, 0xf4, 0x5d, 0xc3,
    }
    le := len(code)
    buf := C.mmap(nil, C.size_t(le), C.PROT_READ|C.PROT_WRITE|C.PROT_EXEC,
        C.MAP_PRIVATE|C.MAP_ANON, -1, 0)
    codePtr := C.CBytes(code)
    C.memcpy(buf, codePtr, C.size_t(le))
    var a, b byte = 7, 12
    fmt.Printf("%d + %d = ", a, b)
    C.runMachineCode(buf, C.byte(a), C.byte(b))
    C.munmap(buf, C.size_t(le))
    C.free(codePtr)
}
Task: Parse an IP Address




Go: package main

import (
	"encoding/hex"
	"fmt"
	"io"
	"net"
	"os"
	"strconv"
	"strings"
	"text/tabwriter"
)



func parseIPPort(address string) (net.IP, *uint64, error) {
	ip := net.ParseIP(address)
	if ip != nil {
		return ip, nil, nil
	}

	host, portStr, err := net.SplitHostPort(address)
	if err != nil {
		return nil, nil, fmt.Errorf("splithostport failed: %w", err)
	}

	port, err := strconv.ParseUint(portStr, 10, 16)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to parse port: %w", err)
	}

	ip = net.ParseIP(host)
	if ip == nil {
		return nil, nil, fmt.Errorf("failed to parse ip address")
	}

	return ip, &port, nil
}

func ipVersion(ip net.IP) int {
	if ip.To4() == nil {
		return 6
	}

	return 4
}

func main() {
	testCases := []string{
		"127.0.0.1",
		"127.0.0.1:80",
		"::1",
		"[::1]:443",
		"2605:2700:0:3::4713:93e3",
		"[2605:2700:0:3::4713:93e3]:80",
	}

	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)

	writeTSV := func(w io.Writer, args ...interface{}) {
		fmt.Fprintf(w, strings.Repeat("%s\t", len(args)), args...)
		fmt.Fprintf(w, "\n")
	}

	writeTSV(w, "Input", "Address", "Space", "Port")

	for _, addr := range testCases {
		ip, port, err := parseIPPort(addr)
		if err != nil {
			panic(err)
		}

		portStr := "n/a"
		if port != nil {
			portStr = fmt.Sprint(*port)
		}

		ipVersion := fmt.Sprintf("IPv%d", ipVersion(ip))

		writeTSV(w, addr, hex.EncodeToString(ip), ipVersion, portStr)
	}

	w.Flush()
}