├── .gitignore ├── LICENSE ├── arrayChain ├── chain.go ├── chain_test.go ├── node.go ├── node_test.go └── utils.go ├── breadthFirst └── breadthFirst.go ├── breadthFirst2 ├── Searcher.go ├── breadthFirst2.go ├── map.go ├── map_test.go ├── pt.go └── searcher_test.go ├── depthFirst └── depthFirst.go ├── pipe └── pipe.go ├── pipe2 ├── map.go ├── pipe.go ├── pipeState.go └── pipe_test.go ├── playcard ├── playcard.go ├── queue.go ├── queue_test.go ├── stock.go ├── stock_test.go └── util.go ├── readme.md └── sort └── quickSort.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | 24 | .DS_Store 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 eruca 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /arrayChain/chain.go: -------------------------------------------------------------------------------- 1 | package arrayChain 2 | 3 | import ( 4 | "errors" 5 | "log" 6 | "unsafe" 7 | ) 8 | 9 | type List struct { 10 | chain []*node 11 | head int 12 | tail int 13 | exist map[unsafe.Pointer]struct{} 14 | } 15 | 16 | func NewList(l int) *List { 17 | chain := make([]*node, l) 18 | exist := make(map[unsafe.Pointer]struct{}, l) 19 | return &List{chain, -1, -1, exist} 20 | } 21 | 22 | func (this *List) Len() int { 23 | panicIfNil(this) 24 | return len(this.exist) 25 | } 26 | 27 | func (this *List) Cap() int { 28 | return len(this.chain) 29 | } 30 | 31 | //test just for prevent the same pt of node to add twice change the already one's index 32 | //break 33 | func (this *List) IsExist(n *node) (ok bool) { 34 | _, ok = this.exist[unsafe.Pointer(n)] 35 | return ok 36 | } 37 | 38 | func (this *List) Head() (n *node, pos int) { 39 | panicIfNil(this) 40 | return this.chain[this.head], this.head 41 | } 42 | 43 | func (this *List) Tail() (n *node, pos int) { 44 | panicIfNil(this) 45 | return this.chain[this.tail], this.tail 46 | } 47 | 48 | func (this *List) IsEmpty() bool { 49 | panicIfNil(this) 50 | return this.Len() == 0 51 | } 52 | 53 | func (this *List) IsFull() bool { 54 | panicIfNil(this) 55 | return len(this.chain) == this.Len() 56 | } 57 | 58 | func (this *List) pushIfEmpty(n *node) { 59 | this.head = 0 60 | this.tail = 0 61 | this.chain[0] = n 62 | this.chain[0].index = -1 63 | this.exist[unsafe.Pointer(n)] = struct{}{} 64 | } 65 | 66 | func (this *List) PushAfterPos(n *node, insertPos int) error { 67 | if insertPos < 0 || insertPos >= len(this.chain) { 68 | panic("pushPos:index out of range") 69 | } 70 | 71 | if this.chain[insertPos] == nil { 72 | panic("the node to been inserted after which is nil") 73 | } 74 | 75 | if this.IsExist(n) { 76 | return errors.New("the pt to the node is exist") 77 | } 78 | find, pos := this.searchNodeOfNil() 79 | if !find { 80 | this.pushIfFull(n, insertPos) 81 | } 82 | this.chain[pos] = n 83 | this.exist[unsafe.Pointer(n)] = struct{}{} 84 | this.pushAfterPos(pos, insertPos) 85 | return nil 86 | } 87 | 88 | func (this *List) pushAfterPos(nodePos, insertPos int) { 89 | this.chain[nodePos].index = this.chain[insertPos].index 90 | this.chain[insertPos].index = nodePos 91 | 92 | if insertPos == this.tail { 93 | this.tail = nodePos 94 | } 95 | } 96 | 97 | func (this *List) PopPos(popPos int) (n *node) { 98 | nodeBeforePos := this.getBeforePos(popPos) 99 | this.chain[nodeBeforePos].index = this.chain[popPos].index 100 | n = this.chain[popPos] 101 | this.chain[popPos] = nil 102 | delete(this.exist, unsafe.Pointer(n)) 103 | 104 | return n 105 | } 106 | 107 | func (this *List) getBeforePos(pos int) (beforePos int) { 108 | if pos == this.head { 109 | return -1 110 | } 111 | 112 | var find bool 113 | for i := this.head; i != -1; { 114 | if i == pos { 115 | find = true 116 | break 117 | } 118 | beforePos = i 119 | i = this.chain[i].index 120 | } 121 | if !find { 122 | panic("the pos is not in the chain") 123 | } 124 | 125 | return beforePos 126 | } 127 | 128 | //insertPos if -1,insert head 129 | func (this *List) pushIfFull(n *node, insertPos int) (head, next int) { 130 | if this.IsExist(n) { 131 | return -1, -1 132 | } 133 | 134 | newChain := make([]*node, len(this.chain)*2) 135 | 136 | var cnt int 137 | if insertPos == -1 { 138 | newChain[0] = n 139 | cnt++ 140 | newChain[0].index = cnt 141 | } 142 | 143 | var tmp int 144 | for i := this.head; i != -1; { 145 | tmp = i 146 | 147 | newChain[cnt] = this.chain[i] 148 | i = this.chain[i].index 149 | //重塑index 150 | newChain[cnt].index = cnt + 1 151 | cnt++ 152 | 153 | if tmp == insertPos { 154 | newChain[cnt] = n 155 | newChain[cnt].index = cnt + 1 156 | cnt++ 157 | } 158 | } 159 | 160 | newChain[cnt-1].index = -1 161 | 162 | if cnt != len(this.chain)+1 { 163 | panic("the len is not correct") 164 | } 165 | 166 | this.chain = newChain 167 | this.exist[unsafe.Pointer(n)] = struct{}{} 168 | this.head = 0 169 | this.tail = cnt - 1 170 | 171 | return 0, cnt 172 | } 173 | 174 | func (this *List) searchNodeOfNil() (find bool, pos int) { 175 | if this.IsFull() { 176 | return false, -1 177 | } 178 | for pos = this.tail; pos < len(this.chain); pos++ { 179 | if this.chain[pos] == nil { 180 | find = true 181 | break 182 | } 183 | } 184 | if !find { 185 | for pos = 0; pos < this.tail; pos++ { 186 | if this.chain[pos] == nil { 187 | find = true 188 | break 189 | } 190 | } 191 | } 192 | if !find { 193 | return find, -1 194 | } 195 | return find, pos 196 | } 197 | 198 | func (this *List) PushTail(n *node) error { 199 | panicIfNil(this) 200 | if this.IsExist(n) { 201 | return errors.New("the pt to the node is exist already!") 202 | } 203 | if this.IsEmpty() { 204 | this.pushIfEmpty(n) 205 | return nil 206 | } 207 | if this.IsFull() { 208 | this.pushIfFull(n, this.tail) 209 | return nil 210 | } 211 | 212 | defer func() { 213 | if r := recover(); r != nil { 214 | log.Println(r) 215 | this.pushIfFull(n, this.tail) 216 | } 217 | }() 218 | 219 | find, next := this.searchNodeOfNil() 220 | if !find { 221 | panic("should find one empty space") 222 | } 223 | this.chain[next] = n 224 | this.exist[unsafe.Pointer(n)] = struct{}{} 225 | 226 | this.pushAfterPos(next, this.tail) 227 | return nil 228 | } 229 | 230 | func (this *List) PushHead(n *node) { 231 | panicIfNil(this) 232 | if this.IsEmpty() { 233 | this.PushTail(n) 234 | return 235 | } 236 | 237 | if this.IsFull() { 238 | this.pushIfFull(n, -1) 239 | return 240 | } 241 | 242 | defer func() { 243 | if r := recover(); r != nil { 244 | log.Println(r) 245 | this.pushIfFull(n, -1) 246 | } 247 | }() 248 | 249 | find, next := this.searchNodeOfNil() 250 | if !find { 251 | panic("should find one empty space") 252 | } 253 | 254 | this.chain[next] = n 255 | this.exist[unsafe.Pointer(n)] = struct{}{} 256 | 257 | this.chain[next].index = this.head 258 | this.head = next 259 | } 260 | 261 | func (this *List) PopHead() (n *node, pos int, err error) { 262 | panicIfNil(this) 263 | if this.IsEmpty() { 264 | return nil, -1, errors.New("the list is empty") 265 | } 266 | n = this.chain[this.head] 267 | pos = this.head 268 | 269 | this.chain[this.head] = nil 270 | delete(this.exist, unsafe.Pointer(n)) 271 | 272 | this.head = n.index 273 | 274 | return n, pos, nil 275 | } 276 | 277 | func (this *List) PopTail() (n *node, pos int, err error) { 278 | panicIfNil(this) 279 | if this.IsEmpty() { 280 | return nil, -1, errors.New("the list is empty") 281 | } 282 | n = this.chain[this.tail] 283 | pos = this.tail 284 | 285 | this.chain[this.tail] = nil 286 | delete(this.exist, unsafe.Pointer(n)) 287 | 288 | this.tail = this.getBeforePos(this.tail) 289 | 290 | return n, pos, nil 291 | } 292 | -------------------------------------------------------------------------------- /arrayChain/chain_test.go: -------------------------------------------------------------------------------- 1 | package arrayChain 2 | 3 | import ( 4 | // "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestNewList(t *testing.T) { 9 | list := NewList(10) 10 | 11 | expect(t, list.Cap(), 10) 12 | expect(t, list.Len(), 0) 13 | if !list.IsEmpty() { 14 | t.Error("empty,but not") 15 | } 16 | 17 | if list.IsFull() { 18 | t.Error("not full,but full") 19 | } 20 | } 21 | 22 | func TestHeadTail(t *testing.T) { 23 | list := NewList(10) 24 | list.PushHead(NewNode(0)) 25 | h, hpos := list.Head() 26 | tr, tpos := list.Tail() 27 | if h != tr || hpos != tpos { 28 | t.Error("head equal,but not") 29 | } 30 | 31 | if h.data != 0 { 32 | t.Error("0,but", h.data) 33 | } 34 | 35 | if list.Len() != 1 { 36 | expect(t, 1, list.Len()) 37 | } 38 | } 39 | 40 | func TestpushIfEmpty(t *testing.T) { 41 | list := NewList(10) 42 | if list.IsEmpty() { 43 | list.pushIfEmpty(NewNode(0)) 44 | } 45 | n, index := list.Head() 46 | if index != -1 || n.data != 0 { 47 | t.Error("TestpushIfEmpty true ,but false") 48 | } 49 | } 50 | 51 | func TestPos(t *testing.T) { 52 | list := NewList(10) 53 | list.PushTail(NewNode(0)) 54 | list.PushTail(NewNode(1)) 55 | list.PushTail(NewNode(2)) 56 | list.PushTail(NewNode(3)) 57 | if list.Len() != 4 { 58 | expect(t, 4, list.Len()) 59 | } 60 | for i := 0; i < 3; i++ { 61 | if list.chain[i].index != i+1 { 62 | t.Error("list.chain[i].index != i+1") 63 | } 64 | } 65 | if list.chain[3].index != -1 { 66 | expect(t, -1, list.chain[3].index) 67 | } 68 | 69 | if list.getBeforePos(list.head) != -1 || list.getBeforePos(list.tail) != 2 { 70 | t.Error("true,but false") 71 | } 72 | } 73 | 74 | func TestPos2(t *testing.T) { 75 | list := NewList(5) 76 | list.PushTail(NewNode(0)) 77 | list.PushTail(NewNode(1)) 78 | list.PushTail(NewNode(2)) 79 | list.PushTail(NewNode(3)) 80 | list.PushTail(NewNode(4)) 81 | list.PushTail(NewNode(5)) 82 | if list.Cap() != 10 { 83 | t.Error("10,but", list.Cap()) 84 | } 85 | 86 | n := list.PopPos(3) 87 | if n.index != 4 { 88 | t.Error("2,but", n.index) 89 | } 90 | 91 | list.PopHead() 92 | list.PopTail() 93 | expect(t, 3, list.Len()) 94 | list.PushHead(n) 95 | expect(t, 4, list.Len()) 96 | head, _ := list.Head() 97 | expect(t, 3, head.data) 98 | expect(t, 1, head.index) 99 | } 100 | 101 | func TestPos3(t *testing.T) { 102 | list := NewList(5) 103 | list.PushTail(NewNode(0)) 104 | list.PushTail(NewNode(1)) 105 | list.PushTail(NewNode(2)) 106 | list.PushHead(NewNode(-1)) 107 | list.PushAfterPos(NewNode(3), 3) 108 | list.PopHead() 109 | list.PopTail() 110 | list.PopTail() 111 | list.PopTail() 112 | list.PopHead() 113 | if list.Len() != 0 { 114 | t.Error("0,but", list.Len()) 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /arrayChain/node.go: -------------------------------------------------------------------------------- 1 | package arrayChain 2 | 3 | type node struct { 4 | data int 5 | index int 6 | } 7 | 8 | func NewNode(data int) *node { 9 | return &node{data, -1} 10 | } 11 | -------------------------------------------------------------------------------- /arrayChain/node_test.go: -------------------------------------------------------------------------------- 1 | package arrayChain 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func expect(t *testing.T, lhs, rhs int) { 8 | if lhs != rhs { 9 | t.Errorf("should be %d,but %d", lhs, rhs) 10 | } 11 | } 12 | 13 | func TestNewNode(t *testing.T) { 14 | n := NewNode(1) 15 | expect(t, n.index, -1) 16 | } 17 | -------------------------------------------------------------------------------- /arrayChain/utils.go: -------------------------------------------------------------------------------- 1 | package arrayChain 2 | 3 | func panicIfNil(this interface{}) { 4 | if this == nil { 5 | panic("the object is nil") 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /breadthFirst/breadthFirst.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type node struct { 8 | x int 9 | y int 10 | f int 11 | s int 12 | } 13 | 14 | func main() { 15 | var que [2501]node 16 | var a, book [51][51]int 17 | var next = [4][2]int{{0, 1}, 18 | {1, 0}, 19 | {0, -1}, 20 | {-1, 0}, 21 | } 22 | 23 | var head, tail int 24 | 25 | var n, m int 26 | fmt.Println("input the n×m") 27 | fmt.Scanf("%d %d", &n, &m) 28 | for i := 1; i <= n; i++ { 29 | for j := 1; j <= m; j++ { 30 | fmt.Scanf("%d", &a[i][j]) 31 | } 32 | } 33 | 34 | var startX, startY, p, q int 35 | fmt.Scanf("%d %d %d %d", &startX, &startY, &p, &q) 36 | 37 | head = 1 38 | tail = 1 39 | 40 | que[tail].x = startX 41 | que[tail].y = startY 42 | que[tail].f = 0 43 | que[tail].s = 0 44 | tail++ 45 | book[startX][startY] = 1 46 | 47 | var flag = 0 48 | var tx, ty int 49 | for head < tail { 50 | for i := 0; i <= 3; i++ { 51 | tx = que[head].x + next[i][0] 52 | ty = que[head].y + next[i][1] 53 | 54 | if tx < 1 || tx > n || ty < 1 || ty > m { 55 | continue 56 | } 57 | 58 | if a[tx][ty] == 0 && book[tx][ty] == 0 { 59 | book[tx][ty] = 1 60 | que[tail].x = tx 61 | que[tail].y = ty 62 | que[tail].f = head 63 | que[tail].s = que[head].s + 1 64 | tail++ 65 | } 66 | 67 | if tx == p && ty == q { 68 | flag = 1 69 | break 70 | } 71 | } 72 | 73 | if flag == 1 { 74 | break 75 | } 76 | head++ 77 | } 78 | 79 | fmt.Print(que[tail-1].s) 80 | } 81 | -------------------------------------------------------------------------------- /breadthFirst2/Searcher.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "strings" 6 | ) 7 | 8 | type node struct { 9 | pt point 10 | steps int 11 | father int 12 | } 13 | 14 | var directions = [4][2]int{ 15 | {0, 1}, {1, 0}, {0, -1}, {-1, 0}, 16 | } 17 | 18 | type Searcher struct { 19 | StartPt point 20 | book []point 21 | m *Map 22 | queue []node 23 | head, tail int 24 | } 25 | 26 | func NewSearcher(m *Map, pt point) *Searcher { 27 | book := make([]point, 1, 16) 28 | book[0] = pt 29 | queue := make([]node, 1, 16) 30 | queue[0].pt = pt 31 | 32 | return &Searcher{StartPt: pt, book: book, m: m, queue: queue, tail: 1} 33 | } 34 | 35 | func (s Searcher) IsWalked(pt point) bool { 36 | for _, v := range s.book { 37 | if v == pt { 38 | return true 39 | } 40 | } 41 | return false 42 | } 43 | 44 | func (s Searcher) Path() string { 45 | res := make([]string, 0, 16) 46 | for i := len(s.queue) - 1; i != 0; i = s.queue[i].father { 47 | res = append(res, s.queue[i].pt.String()) 48 | } 49 | reverse := make([]string, len(res)) 50 | var index int 51 | for i := len(res) - 1; i >= 0; i-- { 52 | reverse[index] = res[i] 53 | index++ 54 | } 55 | return strings.Join(reverse, " ") 56 | } 57 | 58 | func (s *Searcher) Walk() string { 59 | var next point 60 | Label: 61 | for s.head < s.tail { 62 | for _, dir := range directions { 63 | next = s.queue[s.head].pt.walk(dir) 64 | if s.m.Illegal(next) || s.IsWalked(next) { 65 | continue 66 | } 67 | s.book = append(s.book, next) 68 | 69 | var newNode node 70 | newNode.pt = next 71 | newNode.father = s.head 72 | newNode.steps = s.queue[s.head].steps + 1 73 | s.queue = append(s.queue, newNode) 74 | s.tail++ 75 | 76 | if s.m.Arrive(next) { 77 | break Label 78 | } 79 | } 80 | s.head++ 81 | } 82 | return s.Path() 83 | } 84 | -------------------------------------------------------------------------------- /breadthFirst2/breadthFirst2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | m := NewMap(5, 4) 9 | searcher := NewSearcher(m, point{0, 0}) 10 | fmt.Println(searcher.Walk()) 11 | } 12 | -------------------------------------------------------------------------------- /breadthFirst2/map.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Map struct { 4 | data [][]int 5 | x int 6 | y int 7 | } 8 | 9 | func NewMap(n, m int) *Map { 10 | var M Map 11 | M.data = make([][]int, n) 12 | for k, _ := range M.data { 13 | M.data[k] = make([]int, m) 14 | } 15 | 16 | M.x = n - 1 17 | M.y = m - 1 18 | M.Init() 19 | return &M 20 | } 21 | 22 | func (m *Map) Init() { 23 | m.data[0][2] = -1 24 | m.data[2][2] = -1 25 | m.data[3][1] = -1 26 | m.data[4][3] = -1 27 | m.data[3][3] = 1 28 | } 29 | 30 | func (m Map) find(pt point) int { 31 | return m.data[pt.x][pt.y] 32 | } 33 | 34 | func (m Map) Illegal(pt point) bool { 35 | return pt.x < 0 || pt.x > m.x || pt.y < 0 || 36 | pt.y > m.y || m.find(pt) == -1 37 | } 38 | 39 | func (m Map) Arrive(pt point) bool { 40 | return m.find(pt) == 1 41 | } 42 | -------------------------------------------------------------------------------- /breadthFirst2/map_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestMap(t *testing.T) { 9 | m := NewMap(5, 4) 10 | fmt.Println(m.data) 11 | if m == nil { 12 | t.Error("should not happened") 13 | } 14 | if m.x != 4 || m.y != 3 { 15 | t.Error("5,4", m.y, m.x) 16 | } 17 | 18 | if !m.Illegal(point{-1, 0}) || !m.Illegal(point{4, 3}) { 19 | t.Error("illegal but not") 20 | } 21 | 22 | if m.Arrive(point{2, 3}) { 23 | t.Error("illegal but not") 24 | } 25 | if !m.Arrive(point{3, 3}) { 26 | t.Error("illegal but not") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /breadthFirst2/pt.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type point struct { 8 | x, y int 9 | } 10 | 11 | func (p point) walk(dir [2]int) (next point) { 12 | next.x = p.x + dir[0] 13 | next.y = p.y + dir[1] 14 | return next 15 | } 16 | 17 | func (p point) String() string { 18 | return fmt.Sprintf("(%d,%d)", p.x, p.y) 19 | } 20 | -------------------------------------------------------------------------------- /breadthFirst2/searcher_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestSearcher(t *testing.T) { 9 | m := NewMap(5, 4) 10 | s := NewSearcher(m, point{0, 0}) 11 | fmt.Println(s.Walk()) 12 | } 13 | -------------------------------------------------------------------------------- /depthFirst/depthFirst.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var ( 8 | n int 9 | a []int 10 | book []int 11 | ) 12 | 13 | func dfs(step int) { 14 | if step > n { 15 | for i := 1; i <= n; i++ { 16 | fmt.Print(a[i]) 17 | } 18 | fmt.Println("") 19 | return 20 | } 21 | for i := 1; i <= n; i++ { 22 | if book[i] == 0 { 23 | a[step] = i 24 | book[i] = 1 25 | 26 | dfs(step + 1) 27 | book[i] = 0 28 | } 29 | } 30 | } 31 | 32 | func main() { 33 | fmt.Println("请输入n的值") 34 | fmt.Scanf("%d", &n) 35 | fmt.Println("n:", n) 36 | a = make([]int, n+1) 37 | book = make([]int, n+1) 38 | fmt.Println(a) 39 | 40 | dfs(1) 41 | } 42 | -------------------------------------------------------------------------------- /pipe/pipe.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | var ( 8 | a [51][51]int 9 | book [51][51]int 10 | n, m, flag int = 5, 4, 0 11 | ) 12 | 13 | func dfs(x, y, front int) { 14 | if x == n && y == m+1 { 15 | flag = 1 16 | return 17 | } 18 | 19 | if x < 1 || x > n || y < 1 || y > m { 20 | return 21 | } 22 | if book[x][y] == 1 { 23 | return 24 | } 25 | 26 | book[x][y] = 1 27 | 28 | if a[x][y] == 5 || a[x][y] == 6 { 29 | switch front { 30 | case 1: 31 | dfs(x, y+1, 1) 32 | case 2: 33 | dfs(x+1, y, 2) 34 | case 3: 35 | dfs(x, y-1, 3) 36 | case 4: 37 | dfs(x-1, y, 4) 38 | } 39 | } 40 | if a[x][y] >= 1 && a[x][y] <= 4 { 41 | switch front { 42 | case 1: 43 | dfs(x+1, y, 2) 44 | dfs(x-1, y, 4) 45 | case 2: 46 | dfs(x, y+1, 1) 47 | dfs(x, y-1, 3) 48 | case 3: 49 | dfs(x-1, y, 4) 50 | dfs(x+1, y, 2) 51 | case 4: 52 | dfs(x, y+1, 1) 53 | dfs(x, y-1, 3) 54 | } 55 | } 56 | book[x][y] = 0 57 | } 58 | 59 | func main() { 60 | var res = []int{5, 3, 5, 3, 1, 5, 3, 0, 2, 3, 5, 1, 6, 1, 1, 5, 1, 5, 5, 4} 61 | var index int 62 | for i := 1; i <= n; i++ { 63 | for j := 1; j <= m; j++ { 64 | a[i][j] = res[index] 65 | index++ 66 | } 67 | } 68 | dfs(1, 1, 1) 69 | if flag == 0 { 70 | fmt.Println("impossible") 71 | } else { 72 | fmt.Println("找到铺设方法") 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pipe2/map.go: -------------------------------------------------------------------------------- 1 | package pipe 2 | 3 | // import ( 4 | // "fmt" 5 | // // "math/rand" 6 | // // "time" 7 | // ) 8 | 9 | //to record the ways,there are maybe several ways 10 | type Records struct { 11 | x int 12 | y int 13 | cnt int 14 | father int 15 | } 16 | 17 | var res = []int{4, 0, 1, 5, 0, 2, 4, 2, 0, 4, 4, 2, 4, 0, 4, 2, -1, 0, 4, 3} 18 | 19 | //finds index the end point,and the ways be the arraychain 20 | type Map struct { 21 | M [][]*Pipe 22 | 23 | inDir, outDir int 24 | maxX, maxY int 25 | 26 | Ways []Records 27 | finds []int //index of the find in Ways 28 | } 29 | 30 | func NewMap() *Map { 31 | M := make([][]*Pipe, 4) 32 | var index int 33 | for i := 0; i < 4; i++ { 34 | M[i] = make([]*Pipe, 5) 35 | for j := 0; j < 5; j++ { 36 | if i == 3 && j == 1 { 37 | index++ 38 | continue 39 | } 40 | M[i][j] = NewPipe(res[index]) 41 | // fmt.Printf("%d ", res[index]) 42 | index++ 43 | } 44 | // fmt.Println("") 45 | } 46 | return &Map{M: M, maxX: 3, maxY: 4} 47 | } 48 | 49 | // func NewMap(n, m int) *Map { 50 | // time.Now().UnixNano() 51 | // M := make([][]*Pipe, m) 52 | // for k, _ := range M { 53 | // M[k] = make([]*Pipe, n) 54 | // for i := 0; i < n; i++ { 55 | // if k == 1 && i == 3 { 56 | // continue 57 | // } 58 | // M[k][i] = NewPipe(rand.Intn(6)) 59 | // fmt.Print(M[k][i].Type, " ") 60 | // } 61 | // fmt.Println("") 62 | // } 63 | 64 | // ways := make([]Records, 0, 16) 65 | 66 | // return &Map{M: M, maxX: n - 1, maxY: m - 1, Ways: ways} 67 | // } 68 | 69 | func (m *Map) Init() { 70 | m.inDir = 2 71 | m.outDir = 2 72 | } 73 | 74 | func (m *Map) Start() { 75 | m.M[0][0].book = true 76 | switch m.M[0][0].Type { 77 | case pipeI: 78 | cnt := m.M[0][0].rawDir % 2 79 | r := Records{x: 0, y: 0, cnt: cnt} 80 | m.Ways = append(m.Ways, r) 81 | m.Next(1, 0, m.inDir) 82 | case pipeL: 83 | cnt := (5 - m.M[0][0].rawDir) &^ 4 84 | m.Ways = append(m.Ways, Records{0, 0, cnt, 0}) 85 | m.Next(0, 1, m.inDir-1) 86 | } 87 | m.M[0][0].book = false 88 | } 89 | 90 | func (m *Map) Next(x, y, front int) { 91 | if x == m.maxX+1 && y == m.maxY && front == m.outDir { 92 | m.find = true 93 | println("find way to finish it") 94 | return 95 | } 96 | 97 | if x < 0 || x > m.maxX || y < 0 || y > m.maxY || m.M[x][y] == nil || m.M[x][y].book { 98 | return 99 | } 100 | // fmt.Printf("x:%d,y:%d,front:%d\n", x, y, front) 101 | 102 | m.M[x][y].book = true 103 | 104 | switch m.M[x][y].Type { 105 | case pipeI: 106 | switch front { 107 | case 0: 108 | m.Next(x-1, y, front) 109 | case 1: 110 | m.Next(x, y-1, front) 111 | case 2: 112 | m.Next(x+1, y, front) 113 | case 3: 114 | m.Next(x, y+1, front) 115 | } 116 | case pipeL: 117 | switch front { 118 | case 0, 2: 119 | m.Next(x, y-1, 1) 120 | m.Next(x, y+1, 3) 121 | case 1, 3: 122 | m.Next(x-1, y, 0) 123 | m.Next(x+1, y, 2) 124 | } 125 | } 126 | m.M[x][y].book = false 127 | } 128 | -------------------------------------------------------------------------------- /pipe2/pipe.go: -------------------------------------------------------------------------------- 1 | package pipe 2 | 3 | import ( 4 | "log" 5 | ) 6 | 7 | type Pipe struct { 8 | Type state 9 | rawDir int 10 | book bool 11 | } 12 | 13 | func NewPipe(dir int) *Pipe { 14 | var t state 15 | switch dir { 16 | case 0, 1, 2, 3: 17 | t = pipeL 18 | case 4, 5: 19 | t = pipeI 20 | default: 21 | log.Panicln(dir, "should not happened") 22 | } 23 | return &Pipe{Type: t, rawDir: dir} 24 | } 25 | -------------------------------------------------------------------------------- /pipe2/pipeState.go: -------------------------------------------------------------------------------- 1 | package pipe 2 | 3 | type state int 4 | 5 | const ( 6 | pipeL state = iota 7 | pipeI 8 | ) 9 | -------------------------------------------------------------------------------- /pipe2/pipe_test.go: -------------------------------------------------------------------------------- 1 | package pipe 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestMap(t *testing.T) { 9 | m := NewMap() 10 | m.Init() 11 | m.Start() 12 | if m.find { 13 | fmt.Println("find") 14 | } else { 15 | fmt.Println("failed") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /playcard/playcard.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | //player 10 | type Player struct { 11 | q *queue 12 | } 13 | 14 | func NewPlayer(cards int) *Player { 15 | return &Player{NewQueue(cards)} 16 | } 17 | 18 | func (p *Player) Play() int { 19 | i, err := p.q.PopHead() 20 | if err != nil { 21 | panic(err) 22 | } 23 | return i 24 | } 25 | 26 | func (p *Player) Add(i ...int) { 27 | p.q.Push(i...) 28 | } 29 | 30 | func (p *Player) Empty() bool { 31 | return p.q.Len() == 0 32 | } 33 | 34 | func (p *Player) Card() string { 35 | return p.q.String() 36 | } 37 | 38 | func (p *Player) InitCard(card int) { 39 | p.q.Push(card) 40 | } 41 | 42 | //table 43 | type Table struct { 44 | s *stock 45 | } 46 | 47 | func NewTable(c int) *Table { 48 | return &Table{NewStock(c)} 49 | } 50 | 51 | func (t *Table) Add(i int) (ret []int) { 52 | res := t.s.search(i) 53 | if res == nil { 54 | t.s.Push(i) 55 | return 56 | } 57 | ret = append(ret, i) 58 | ret = append(ret, res...) 59 | return ret 60 | } 61 | 62 | func (t *Table) Card() string { 63 | return t.s.String() 64 | } 65 | 66 | var A, B = NewPlayer(8), NewPlayer(8) 67 | 68 | var T = NewTable(16) 69 | 70 | //init 71 | func Init() { 72 | rand.Seed(time.Now().UnixNano()) 73 | var n int 74 | for i := 0; i < 8; i++ { 75 | n = rand.Intn(8) + 1 76 | A.InitCard(n) 77 | } 78 | for i := 0; i < 8; i++ { 79 | n = rand.Intn(8) + 1 80 | B.InitCard(n) 81 | } 82 | fmt.Println("A", A.Card()) 83 | fmt.Println("B", B.Card()) 84 | } 85 | 86 | func main() { 87 | Init() 88 | 89 | var card int 90 | var backs []int 91 | 92 | for !A.Empty() && !B.Empty() { 93 | card = A.Play() 94 | backs = T.Add(card) 95 | if backs != nil { 96 | A.Add(backs...) 97 | } 98 | 99 | card = B.Play() 100 | backs = T.Add(card) 101 | if backs != nil { 102 | B.Add(backs...) 103 | } 104 | } 105 | if A.Empty() { 106 | fmt.Println("A Win") 107 | fmt.Println("B cards:", B.Card()) 108 | } else { 109 | fmt.Println("B Win") 110 | fmt.Println("A cards:", A.Card()) 111 | } 112 | fmt.Println("Table cards:", T.Card()) 113 | } 114 | -------------------------------------------------------------------------------- /playcard/queue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | //queue 9 | type queue struct { 10 | data []int 11 | head int 12 | trail int 13 | cross bool 14 | } 15 | 16 | func NewQueue(c int) *queue { 17 | return &queue{data: make([]int, c)} 18 | } 19 | 20 | func (q *queue) Len() int { 21 | if !q.cross && q.trail >= q.head { 22 | return q.trail - q.head 23 | } 24 | if q.cross && q.head >= q.trail { 25 | return len(q.data[:q.trail]) + len(q.data[q.head:]) 26 | } 27 | return 0 28 | } 29 | 30 | func (q *queue) IsEmpty() bool { 31 | return q.Len() == 0 32 | } 33 | 34 | func (q *queue) Rest() int { 35 | return len(q.data) - q.Len() 36 | } 37 | 38 | func (q *queue) Push(i ...int) { 39 | var data []int 40 | if q.Rest() < len(i) { 41 | data = make([]int, (len(q.data)+len(i))*2) 42 | if !q.cross { 43 | copy(data, q.data[q.head:q.trail]) 44 | } else { 45 | copy(data, q.data[q.head:]) 46 | copy(data[len(q.data)-q.head:], q.data[:q.trail]) 47 | } 48 | q.trail = q.Len() 49 | q.head = 0 50 | q.data = data 51 | q.cross = false 52 | } 53 | for _, v := range i { 54 | q.data[q.trail] = v 55 | q.trail++ 56 | if q.trail == len(q.data) { 57 | q.trail = 0 58 | q.cross = true 59 | } 60 | } 61 | } 62 | 63 | func (q *queue) PopHead() (i int, err error) { 64 | panicIfNil(q) 65 | 66 | i = q.data[q.head] 67 | q.head++ 68 | if q.head == len(q.data) && q.cross { 69 | q.cross = false 70 | q.head = 0 71 | } 72 | return i, nil 73 | } 74 | 75 | func (q *queue) String() string { 76 | slice := make([]string, q.Len()) 77 | if !q.cross { 78 | for k, v := range q.data[q.head:q.trail] { 79 | slice[k] = strconv.Itoa(v) 80 | } 81 | } else { 82 | var k, v int 83 | for k, v = range q.data[q.head:] { 84 | slice[k] = strconv.Itoa(v) 85 | } 86 | 87 | for i, j := range q.data[:q.trail] { 88 | slice[k+i+1] = strconv.Itoa(j) 89 | } 90 | } 91 | return strings.Join(slice, " ") 92 | } 93 | -------------------------------------------------------------------------------- /playcard/queue_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | // "fmt" 5 | "testing" 6 | ) 7 | 8 | var q = NewQueue(8) 9 | 10 | func TestLen(t *testing.T) { 11 | if q.Len() != 0 { 12 | t.Error("0,but", q.Len()) 13 | } 14 | q.Push(1, 2, 3, 4) 15 | if q.Len() != 4 { 16 | t.Error("4,but", q.Len()) 17 | } 18 | if q.Rest() != 4 { 19 | t.Error("4,but", q.Rest()) 20 | } 21 | 22 | q.Push(5, 6, 7, 8, 9) 23 | if q.Len() != 9 { 24 | t.Error("9 but", q.Len()) 25 | } 26 | } 27 | 28 | func TestPop(t *testing.T) { 29 | i, err := q.PopHead() 30 | if err != nil { 31 | t.Error(err) 32 | } 33 | if i != 1 { 34 | t.Error("1,but", i) 35 | } 36 | 37 | q.PopHead() 38 | q.PopHead() 39 | if q.Len() != 6 { 40 | t.Error("6 but", q.Len()) 41 | } 42 | if q.String() != "4 5 6 7 8 9" { 43 | t.Error("4 5 6 7 8 9--", q.String()) 44 | } 45 | } 46 | 47 | func TestString(t *testing.T) { 48 | que := NewQueue(4) 49 | que.Push(1, 2, 3, 4) 50 | que.PopHead() 51 | que.PopHead() 52 | que.PopHead() 53 | que.Push(1, 2) 54 | if que.String() != "4 1 2" { 55 | t.Error("4 1 2,but", que.String()) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /playcard/stock.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | //stock 9 | type stock struct { 10 | data []int 11 | top int 12 | } 13 | 14 | func NewStock(c int) *stock { 15 | data := make([]int, c) 16 | return &stock{data, 0} 17 | } 18 | 19 | func (s *stock) IsEmpty() bool { 20 | panicIfNil(s) 21 | return s.top == 0 22 | } 23 | 24 | func (s *stock) IsFull() bool { 25 | panicIfNil(s) 26 | return s.top == len(s.data) 27 | } 28 | 29 | func (s *stock) Len() int { 30 | return s.top 31 | } 32 | 33 | func (s *stock) Rest() int { 34 | panicIfNil(s) 35 | if s.IsFull() { 36 | return 0 37 | } 38 | return len(s.data) - s.top 39 | } 40 | 41 | func (s *stock) Push(iS ...int) { 42 | panicIfNil(s) 43 | if s.Rest() < len(iS) { 44 | new_data := make([]int, (len(s.data)+len(iS))*2) 45 | copy(new_data, s.data) 46 | s.data = new_data 47 | } 48 | 49 | for _, v := range iS { 50 | s.data[s.top] = v 51 | s.top++ 52 | } 53 | } 54 | 55 | func (s *stock) Pop() (i int) { 56 | panicIfNil(s) 57 | s.top-- 58 | i = s.data[s.top] 59 | return i 60 | } 61 | 62 | func (s *stock) search(card int) []int { 63 | if s.IsEmpty() { 64 | return nil 65 | } 66 | 67 | var cnt int 68 | for i := s.top - 1; i >= 0; i-- { 69 | if card == s.data[i] { 70 | break 71 | } 72 | cnt++ 73 | } 74 | if cnt == s.top { 75 | return nil 76 | } 77 | 78 | sint := make([]int, cnt+1) 79 | for i := 0; i <= cnt; i++ { 80 | sint[i] = s.Pop() 81 | } 82 | return sint 83 | } 84 | 85 | func (s *stock) String() string { 86 | if s.top == 0 { 87 | return "empty" 88 | } 89 | slice := make([]string, s.top) 90 | for i := 0; i < s.top; i++ { 91 | slice[i] = strconv.Itoa(s.data[i]) 92 | } 93 | 94 | return strings.Join(slice, " ") 95 | } 96 | -------------------------------------------------------------------------------- /playcard/stock_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | // "fmt" 5 | "testing" 6 | ) 7 | 8 | var s = NewStock(4) 9 | 10 | func TestNewStock(t *testing.T) { 11 | if s == nil { 12 | t.Error("stock not nil, but nil") 13 | } 14 | } 15 | 16 | func TestStockPush(t *testing.T) { 17 | if !s.IsEmpty() { 18 | t.Error("empty,but not") 19 | } 20 | 21 | s.Push(1, 2, 3) 22 | if s.Len() != 3 { 23 | t.Error("len 3", s.Len()) 24 | } 25 | 26 | if s.Rest() != 1 { 27 | t.Error("rest 5", s.Rest()) 28 | } 29 | s.Push(1) 30 | 31 | if !s.IsFull() { 32 | t.Error("full,but not") 33 | } 34 | 35 | if s.String() != "1 2 3 1" { 36 | t.Error("should 1 2 3 1,but not") 37 | } 38 | s.search(2) 39 | //fmt.Println("1 3 2", ints) 40 | 41 | s.Pop() 42 | if !s.IsEmpty() { 43 | t.Error("empty,but not") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /playcard/util.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func panicIfNil(o interface{}) { 4 | if o == nil { 5 | panic("is nil") 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 《啊哈!算法》 2 | == 3 | 使用go实现其中的算法 4 | -------------------------------------------------------------------------------- /sort/quickSort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type QuickSort interface { 8 | Len() int 9 | Less(i, j int) bool 10 | Swap(i, j int) 11 | } 12 | 13 | func Sort(data QuickSort) { 14 | quickSort(data, 0, data.Len()-1) 15 | } 16 | 17 | func quickSort(data QuickSort, left, right int) { 18 | if left >= right { 19 | return 20 | } 21 | 22 | i := left 23 | j := right 24 | 25 | for i != j { 26 | for data.Less(left, j) && i < j { 27 | j-- 28 | } 29 | 30 | for !data.Less(left, i) && i < j { 31 | i++ 32 | } 33 | 34 | if i < j { 35 | data.Swap(i, j) 36 | } 37 | } 38 | 39 | data.Swap(left, i) 40 | 41 | quickSort(data, left, i-1) 42 | quickSort(data, i+1, right) 43 | } 44 | 45 | type Aint []int 46 | 47 | func (a Aint) Len() int { 48 | return len(a) 49 | } 50 | 51 | func (a Aint) Less(i, j int) bool { 52 | if i == j { 53 | return false 54 | } 55 | return a[i] < a[j] 56 | } 57 | 58 | func (a Aint) Swap(i, j int) { 59 | if i == j { 60 | return 61 | } 62 | a[i], a[j] = a[j], a[i] 63 | } 64 | 65 | func main() { 66 | aint := []int{8, 23, 1, 4, 9, 32, 2, 72} 67 | 68 | Sort(Aint(aint)) 69 | fmt.Println(aint) 70 | } 71 | --------------------------------------------------------------------------------