Skip to content

Instantly share code, notes, and snippets.

@esehara
Last active May 16, 2016 08:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esehara/33bb4df90fa9c168b7949ed4fc253ab2 to your computer and use it in GitHub Desktop.
Save esehara/33bb4df90fa9c168b7949ed4fc253ab2 to your computer and use it in GitHub Desktop.
コラッツの計算をなんとか…
package main
import (
"flag"
"fmt"
"os"
"runtime"
"sort"
"strconv"
"strings"
)
type CommandType struct {
Simple *bool
Sort *bool
Increment *bool
FilterMax *int
Number int
}
type CollatzResult struct {
Number int
Route []int
Step int
}
func (result CollatzResult) Merge(target CollatzResult) CollatzResult {
var new_route []int
if len(target.Route) == 0 && len(result.Route) == 0 {
new_route = make([]int, 0)
} else {
new_route = append(target.Route, result.Route...)
}
return CollatzResult{
target.Number,
new_route,
result.Step + target.Step,
}
}
func (result CollatzResult) RouteTemplate(joinstr string) (route string) {
return strings.Join(IatoAa(result.Route), joinstr)
}
func (result CollatzResult) Println() {
fmt.Print(result.Number)
fmt.Print(",")
fmt.Println(result.Step)
}
func (result CollatzResult) PrintVerbose() {
fmt.Println("Number:" + strconv.Itoa(result.Number))
fmt.Print("Route:")
fmt.Println(result.RouteTemplate(" -> "))
fmt.Println("Step:" + strconv.Itoa(result.Step))
}
// const CACHE_SIZE = 1000
// var collatzcache map[int]CollatzResult = make(map[int]CollatzResult)
func collatz(n int, use_route bool) CollatzResult {
var step int
var route []int
x := n
for x > 1 {
if use_route {
route = append(route, x)
}
if x%2 == 1 {
x = x*3 + 1
} else {
x = x / 2
}
step++
}
if use_route {
route = append(route, x)
}
return CollatzResult{n, route, step}
}
// My Library
func IatoAa(xs []int) (ys []string) {
for _, i := range xs {
j := strconv.Itoa(i)
ys = append(ys, j)
}
return ys
}
// Sort Interface
type CollatzResults []CollatzResult
func (cs CollatzResults) Len() int {
return len(cs)
}
func (cs CollatzResults) Less(i, j int) bool {
return cs[i].Step < cs[j].Step
}
func (cs CollatzResults) Swap(i, j int) {
cs[i], cs[j] = cs[j], cs[i]
}
// End
func initialize() (n CommandType) {
// flag
n.Simple = flag.Bool(
"s", false, "Simple Output. Number and Step only")
n.Increment = flag.Bool(
"i", false, "Increment Output")
n.FilterMax = flag.Int(
"fmax", 0, "Under Step, not show")
n.Sort = flag.Bool(
"sort", false, "Sort by Step")
// Get Command Line
flag.Parse()
f := flag.Args()
if flag.NArg() == 0 {
n.Number = 21
} else {
n.Number, _ = strconv.Atoi(f[0])
}
if n.Number < 1 {
fmt.Println("under zero number cannot end")
os.Exit(1)
}
return
}
func collatzOutput(context CommandType, n int) {
var c CollatzResult
c = collatz(n, !*context.Simple)
if !*context.Increment || c.Step > *context.FilterMax {
if *context.Simple {
c.Println()
} else {
c.PrintVerbose()
}
}
}
func collatzGenerate(context CommandType) {
const IncrementNumber = 500000
var cs CollatzResults
var current_n int
var next_n int = IncrementNumber
var ch chan CollatzResult = make(chan CollatzResult)
gocollatz := func(j int) {
ch <- collatz(j, !*context.Simple)
}
for next_n < context.Number {
for i := 1 + current_n; next_n > i; i++ {
go gocollatz(i)
}
for i := 1 + current_n; next_n > i; i++ {
c := <-ch
if c.Step > *context.FilterMax {
cs = append(cs, c)
}
}
current_n += IncrementNumber
next_n += IncrementNumber
}
var reminder_ap int = current_n
for current_n < context.Number {
go gocollatz(current_n)
current_n++
}
for reminder_ap < context.Number {
c := <-ch
if c.Step > *context.FilterMax {
cs = append(cs, c)
}
reminder_ap++
}
sort.Sort(cs)
for _, elem := range cs {
elem.Println()
}
}
func main() {
cpus := runtime.NumCPU()
runtime.GOMAXPROCS(cpus)
var context CommandType
context = initialize()
if *context.Increment {
if *context.Sort {
collatzGenerate(context)
} else {
for i := 1; context.Number >= i; i++ {
collatzOutput(context, i)
}
}
} else {
collatzOutput(context, context.Number)
}
os.Exit(0)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment