package dynamicProgram
import (
"fmt"
"testing"
"time"
)
func hanoi1(n int) {
leftToRight(n)
}
func leftToRight(n int) {
if n == 1 {
fmt.Println("Move 1 from left to right")
return
}
leftToMid(n - 1)
fmt.Println("Move", n , "from left to right")
midToRight(n - 1)
}
func leftToMid( n int) {
if n == 1 {
fmt.Println("Move 1 from left to mid")
return
}
leftToRight(n - 1)
fmt.Println("Move",n,"from left to mid")
rightToMid(n - 1 )
}
func rightToMid(n int){
if n == 1 {
fmt.Println("Move 1 from right to mid")
return
}
rightToLeft(n - 1)
fmt.Println("Move",n,"from right to mid")
leftToMid(n - 1)
}
func midToRight(n int) {
if n == 1 {
fmt.Println("Move 1 fromo mid to right")
return
}
midToLeft(n - 1)
fmt.Println("Move",n,"from mid to right")
leftToRight(n - 1)
}
func rightToLeft(n int) {
if n == 1 {
fmt.Println("Move 1 from right to left")
return
}
rightToMid(n - 1)
fmt.Println("Move",n,"from right to left")
midToLeft(n - 1)
}
func midToLeft(n int) {
if n == 1 {
fmt.Println("Move 1 from mid to left")
return
}
midToRight(n - 1)
fmt.Println("Move",n,"from mid to left")
rightToLeft(n - 1)
}
func TestHanoi1(t *testing.T) {
hanoi1(3)
}
func hanoi2(n int) {
if n > 0 {
hanoi(n,"left","right","mid")
}
}
func hanoi(N int, from, to, other string) {
if N == 1 {
fmt.Println("Move 1 from",from,"to",to)
return
}else {
hanoi(N - 1,from , other,to)
fmt.Println("Move",N,"from",from,"to",to)
hanoi(N-1,other,to,from)
}
}
func TestHanoi2(t *testing.T) {
hanoi2(10)
}
type Record struct {
finish bool
base int
from string
to string
other string
}
type RecordStack struct {
Elem []Record
}
func NewRecordStack() *RecordStack {
return &RecordStack{Elem: make([]Record,0)}
}
func (s *RecordStack)Push(val Record) {
s.Elem = append(s.Elem, val)
}
func (s *RecordStack)Pop() Record {
res := s.Elem[len(s.Elem)-1]
s.Elem = s.Elem[:len(s.Elem)-1]
return res
}
func (s *RecordStack)Peek() *Record {
return &s.Elem[len(s.Elem)-1]
}
func (s *RecordStack)IsEmpty() bool {
return len(s.Elem) == 0
}
func hanoi3( N int) {
if N < 1 {
return
}
stack := NewRecordStack()
stack.Push(Record{
finish: false,
base: N,
from: "left",
to: "right",
other: "mid",
})
for !stack.IsEmpty() {
cur := stack.Pop()
if cur.base == 1 {
fmt.Println("Move 1 from",cur.from,"to",cur.to)
if !stack.IsEmpty() {
stack.Peek().finish = true
}
}else {
if !cur.finish {
stack.Push(cur)
stack.Push(Record{
finish: false,
base: cur.base-1,
from: cur.from,
to: cur.other,
other: cur.to,
})
}else {
fmt.Println("Move",cur.base,"from",cur.from,"to",cur.to)
stack.Push(Record{
finish: false,
base: cur.base-1,
from: cur.other,
to: cur.to,
other: cur.from,
})
}
}
}
}
func TestHanoi3(t *testing.T) {
hanoi3(3)
}
type Stack []int
func (s *Stack)IsEmpty() bool {
return len(*s) == 0
}
func (s *Stack)Pop() int {
res := (*s)[len(*s)-1]
*s = (*s)[:len(*s)-1]
return res
}
func (s *Stack)Push(val int) {
*s = append(*s,val)
}
func reverse(stack *Stack) {
if stack.IsEmpty() {
return
}
i := f(stack)
reverse(stack)
stack.Push(i)
}
func f(stack *Stack) int {
result := stack.Pop()
if stack.IsEmpty() {
return result
}else {
last := f(stack)
stack.Push(result)
return last
}
}
func TestReverse(t *testing.T) {
stack := &Stack{}
stack.Push(100)
stack.Push(200)
stack.Push(300)
reverse(stack)
for !stack.IsEmpty() {
fmt.Println(stack.Pop())
}
}
func Test(t *testing.T) {
b := false
go func() {
for !b {
fmt.Println("1")
}
fmt.Println("2")
}()
go func() {
b = true
}()
time.Sleep(time.Second *100)
}
func subs(str string) []string {
var path string
path = ""
ans := &[]string{}
process1(str,0,ans,path)
return *ans
}
func process1(str string,index int, ans *[]string,path string) {
if index == len(str) {
*ans = append(*ans,path)
return
}
no := path
process1(str, index + 1, ans, no)
yes := path + string(str[index])
process1(str, index + 1, ans, yes)
}
func TestSubStr(t *testing.T) {
fmt.Println(subs("abcdefg"))
}
func process2(str string,index int, ans map[string]bool,path string) {
if index == len(str) {
ans[path] = true
return
}
no := path
process2(str, index + 1, ans, no)
yes := path + string(str[index])
process2(str, index + 1, ans, yes)
}
func subs2(str string) []string {
var path string
path = ""
ans := map[string]bool{}
process2(str,0,ans,path)
result := []string{}
for key, _ := range ans{
result = append(result, key)
}
return result
}
func TestSubs2(t *testing.T) {
fmt.Println(subs2("aaaaa"))
}
func premution(str string) []string {
var res []string
if str == "" || len(str) == 0 {
return res
}
process([]byte(str),0,&res)
return res
}
func process(str []byte, i int,res *[]string) {
if i == len(str) {
*res = append(*res, string(str))
return
}
for j := i; j < len(str); j++ {
swap(str,i,j)
process(str,i+1,res)
swap(str,i,j)
}
}
func swap(str []byte,i,j int) {
str[i] , str[j] = str[j], str[i]
}
func TestPermutations(t *testing.T) {
fmt.Println(premution("abac"))
}
func TestPremution2(t *testing.T) {
fmt.Println(premution2("abac"))
}
func premution2(str string) []string {
var res []string
if str == "" || len(str) == 0 {
return res
}
process_2([]byte(str),0,&res)
return res
}
func process_2(str []byte, i int,res *[]string) {
if i == len(str) {
*res = append(*res, string(str))
return
}
visit := [26]bool{}
for j := i; j < len(str); j++ {
if !visit[str[j]-'a'] {
visit[str[j]-'a'] = true
swap(str, i, j)
process_2(str, i+1, res)
swap(str, i, j)
}
}
}
func premution3(str string) []string {
var res []string
if str == "" || len(str) == 0 {
return res
}
process_3([]byte(str),0,&res)
return res
}
func process_3(str []byte, i int,res *[]string) {
if i == len(str) {
*res = append(*res, string(str))
return
}
visit := 0
for j := i; j < len(str); j++ {
if visit >> (str[j]-'a') &1 == 0 {
visit |= 1 << (str[j]-'a')
swap(str, i, j)
process_3(str, i+1, res)
swap(str, i, j)
}
}
}
func TestPremution3(t *testing.T) {
fmt.Println(premution3("aaaa"))
}