diff --git a/impl/algorithms/Data Structures/graphs.go b/impl/algorithms/Data Structures/graphs.go new file mode 100644 index 00000000..77c29098 --- /dev/null +++ b/impl/algorithms/Data Structures/graphs.go @@ -0,0 +1,86 @@ +package main + +import "fmt" + +type Graph struct { + graph map[int][]int +} + +func NewGraph() *Graph { + return &Graph{ + graph: make(map[int][]int), + } +} + +func (g *Graph) AddEdge(node1, node2 int) { + g.graph[node1] = append(g.graph[node1], node2) +} + +func (g *Graph) AddNode(node int) { + if _, ok := g.graph[node]; !ok { + g.graph[node] = []int{} + } +} + +func (g *Graph) DFS(startNode int) { + visited := make(map[int]bool) + g.dfsHelper(startNode, visited) +} + +func (g *Graph) dfsHelper(node int, visited map[int]bool) { + visited[node] = true + fmt.Printf("%d ", node) + + for _, neighbor := range g.graph[node] { + if !visited[neighbor] { + g.dfsHelper(neighbor, visited) + } + } +} + +func (g *Graph) BFS(startNode int) { + visited := make(map[int]bool) + queue := []int{startNode} + visited[startNode] = true + + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + fmt.Printf("%d ", node) + + for _, neighbor := range g.graph[node] { + if !visited[neighbor] { + queue = append(queue, neighbor) + visited[neighbor] = true + } + } + } +} + +func main() { + // Create a graph + graph := NewGraph() + + // Add nodes + graph.AddNode(1) + graph.AddNode(2) + graph.AddNode(3) + graph.AddNode(4) + graph.AddNode(5) + + // Add edges + graph.AddEdge(1, 2) + graph.AddEdge(1, 3) + graph.AddEdge(2, 4) + graph.AddEdge(2, 5) + + // Perform DFS traversal + fmt.Println("DFS traversal:") + graph.DFS(1) + fmt.Println() + + // Perform BFS traversal + fmt.Println("BFS traversal:") + graph.BFS(1) + fmt.Println() +} \ No newline at end of file diff --git a/impl/algorithms/Data Structures/linkedlist.go b/impl/algorithms/Data Structures/linkedlist.go new file mode 100644 index 00000000..678bea0b --- /dev/null +++ b/impl/algorithms/Data Structures/linkedlist.go @@ -0,0 +1,171 @@ +package main + +import ( + "fmt" +) + +type Node struct { + data int + next *Node +} + +func newNode(data int) *Node { + return &Node{data: data, next: nil} +} + +func (n *Node) size(head *Node) int { + if head == nil { + fmt.Println("Linkedlist is empty") + return -1 + } + + size := 0 + for head != nil { + size += 1 + head = head.next + } + + return size +} + +func (n *Node) display(head *Node) { + if head == nil { + fmt.Println("Linkedlist is empty") + return + } + + for head != nil { + fmt.Print(head.data, " ") + head = head.next + } + fmt.Println() +} + +func (n *Node) insertAtHead(data int, head *Node) *Node { + newNode := newNode(data) + newNode.next = head + head = newNode + + return head +} + +func (n *Node) insertAtTail(data int, head *Node) *Node { + newNode := newNode(data) + if head == nil { + return newNode + } + + current := head + for current.next != nil { + current = current.next + } + + current.next = newNode + return head +} + +func (n *Node) insertAtPosition(headRef **Node, position, data int) { + newNode := newNode(data) + + if *headRef == nil || position == 0 { + newNode.next = *headRef + *headRef = newNode + return + } + + current := *headRef + for i := 0; current != nil && i < position-1; i++ { + current = current.next + } + + if current == nil { + return + } + + newNode.next = current.next + current.next = newNode +} + +func (n *Node) deleteAtHead(head *Node) *Node { + if head == nil { + return nil + } + newHead := head.next + head = nil + return newHead +} + +func (n *Node) deleteAtTail(head *Node) *Node { + if head == nil { + fmt.Println("Linked list is empty.") + return nil + } + + if head.next == nil { + head = nil + return nil + } + + cur := head + for cur.next.next != nil { + cur = cur.next + } + + cur.next = nil + return head +} + +func (n *Node) deleteAtPosition(position int, head *Node) *Node { + if head == nil { + fmt.Println("Linked list is empty.") + return nil + } + + current := head + var prev *Node + i := 0 + + for current != nil && i < position-1 { + prev = current + current = current.next + i++ + } + + if current == nil || current.next == nil { + fmt.Println("Invalid position") + return head + } + + temp := current.next + current.next = temp.next + temp = nil + + if position == 1 { + head = current.next + } + + return head +} + +func main() { + // create a linked list and perform operations + head := newNode(1) + head = head.insertAtTail(2, head) + head = head.insertAtTail(3, head) + head = head.insertAtHead(0, head) + head.display(head) // expected output: 0 1 2 3 + fmt.Println(head.size(head)) // expected output: 4 + head = head.deleteAtHead(head) + head.display(head) // expected output: 1 2 3 + head = head.deleteAtTail(head) + head.display(head) // expected output: 1 2 + head = head.deleteAtPosition(1, head) + head.display(head) // expected output: 1 + head = head.deleteAtPosition(0, head) + head.display(head) // expected output: + head = head.insertAtTail(2, head) + head = head.insertAtTail(3, head) + head = head.insertAtHead(1, head) + head = head.insertAtPosition(&head, 1, 4) + head.display(head) // expected output: 1 4 2 3 +} \ No newline at end of file diff --git a/impl/algorithms/Data Structures/queue.go b/impl/algorithms/Data Structures/queue.go new file mode 100644 index 00000000..00fa0cf1 --- /dev/null +++ b/impl/algorithms/Data Structures/queue.go @@ -0,0 +1,102 @@ +package main + +import "fmt" + +const QUEUE_SIZE int = 10 + +var queue [QUEUE_SIZE]int +var rear int = -1 +var front int = -1 + +func isEmpty() bool { +return front == -1 +} + +func peek() int { +if isEmpty() { +fmt.Println("Queue is empty") +return -1 +} +return queue[front] +} + +func isFull() bool { + return rear >= QUEUE_SIZE-1 + } + + func enqueue(data int) { + if isFull() { + fmt.Println("Queue Overflow") + return + }rear += 1 + queue[rear] = data + + if front == -1 { + front = 0 + } + } + + func dequeue() { + if isEmpty() { + fmt.Println("Queue Underflow") + return + } + + front += 1 + + if front > rear { + front = -1 + rear = -1 + } + } + + func size() int { + if isEmpty() { + return 0 + } + + return rear - front + 1 +} + +func display() { +if isEmpty() { +fmt.Println("Queue is empty") +return +} + +for i := front; i <= rear; i++ { + fmt.Printf("%d ", queue[i]) +} +fmt.Println() +} + +func main() { +// testing the queue implementation +enqueue(1) +enqueue(2) +enqueue(3) +enqueue(4) +display() // output: 1 2 3 4 +dequeue() +dequeue() +display() // output: 3 4 +enqueue(5) +enqueue(6) +enqueue(7) +enqueue(8) +enqueue(9) +enqueue(10) +display() // output: 3 4 5 6 7 8 9 10 +enqueue(11) // output: Queue Overflow +dequeue() +dequeue() +dequeue() +dequeue() +dequeue() +dequeue() +dequeue() +dequeue() +dequeue() +display() // output: Queue is empty +dequeue() // output: Queue Underflow +} \ No newline at end of file diff --git a/impl/algorithms/Data Structures/stack.go b/impl/algorithms/Data Structures/stack.go new file mode 100644 index 00000000..fd62b792 --- /dev/null +++ b/impl/algorithms/Data Structures/stack.go @@ -0,0 +1,72 @@ +package main + +import "fmt" + +type Node struct { + data int + next *Node +} + +func newNode(data int) *Node { + return &Node{data: data, next: nil} +} + +func (n *Node) display() { + fmt.Println(n.data) +} + +type Stack struct{} + +func (s *Stack) push(head *Node, value int) *Node { + new_node := newNode(value) + new_node.next = head + head = new_node + return head +} + +func (s *Stack) pop(head **Node) int { + if *head == nil { + fmt.Println("Stack is empty") + return -1 + } + value := (*head).data + temp := *head + *head = (*head).next + temp.next = nil + return value +} + +func (s *Stack) peek(head *Node) int { + if head == nil { + fmt.Println("Stack is empty") + return -1 + } + return head.data +} + +func (s *Stack) size(head *Node) int { + size := 0 + temp := head + for temp != nil { + size++ + temp = temp.next + } + return size +} + +func (s *Stack) isEmpty(head *Node) bool { + return head == nil +} + +func main() { + var head *Node = nil + var s Stack + head = s.push(head, 5) + head = s.push(head, 10) + head = s.push(head, 15) + fmt.Println("Top element: ", s.peek(head)) + fmt.Println("Stack size: ", s.size(head)) + for !s.isEmpty(head) { + fmt.Print(s.pop(&head), " ") + } +} diff --git a/impl/algorithms/Data Structures/tree.go b/impl/algorithms/Data Structures/tree.go new file mode 100644 index 00000000..85441abb --- /dev/null +++ b/impl/algorithms/Data Structures/tree.go @@ -0,0 +1,94 @@ +package main + +import ( + "fmt" +) + +type Node struct { + data int + left *Node + right *Node +} + +type BinaryTree struct { + root *Node +} + +func NewBinaryTree() *BinaryTree { + return &BinaryTree{} +} + +func (bt *BinaryTree) Insert(data int) { + newNode := &Node{data: data, left: nil, right: nil} + + if bt.root == nil { + bt.root = newNode + } else { + queue := []*Node{bt.root} + + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + + if node.left == nil { + node.left = newNode + break + } else { + queue = append(queue, node.left) + } + + if node.right == nil { + node.right = newNode + break + } else { + queue = append(queue, node.right) + } + } + } +} + +func (bt *BinaryTree) PreorderTraversal(node *Node) { + if node != nil { + fmt.Printf("%d ", node.data) + bt.PreorderTraversal(node.left) + bt.PreorderTraversal(node.right) + } +} + +func (bt *BinaryTree) InorderTraversal(node *Node) { + if node != nil { + bt.InorderTraversal(node.left) + fmt.Printf("%d ", node.data) + bt.InorderTraversal(node.right) + } +} + +func (bt *BinaryTree) PostorderTraversal(node *Node) { + if node != nil { + bt.PostorderTraversal(node.left) + bt.PostorderTraversal(node.right) + fmt.Printf("%d ", node.data) + } +} + +func main() { + binaryTree := NewBinaryTree() + + binaryTree.Insert(1) + binaryTree.Insert(2) + binaryTree.Insert(3) + binaryTree.Insert(4) + binaryTree.Insert(5) + + fmt.Println("Preorder Traversal:") + binaryTree.PreorderTraversal(binaryTree.root) + fmt.Println() + + fmt.Println("Inorder Traversal:") + binaryTree.InorderTraversal(binaryTree.root) + fmt.Println() + + fmt.Println("Postorder Traversal:") + binaryTree.PostorderTraversal(binaryTree.root) + fmt.Println() +} \ No newline at end of file diff --git a/impl/algorithms/Dynamic Programming/Fibonacci Sequence.go b/impl/algorithms/Dynamic Programming/Fibonacci Sequence.go new file mode 100644 index 00000000..f454adcd --- /dev/null +++ b/impl/algorithms/Dynamic Programming/Fibonacci Sequence.go @@ -0,0 +1,24 @@ +package main + +import "fmt" + +func fibonacci(n int) int { + // Create a memoization table to store previously computed values + memo := make([]int, n+1) + + // Base cases + memo[0] = 0 + memo[1] = 1 + + // Compute Fibonacci sequence using dynamic programming + for i := 2; i <= n; i++ { + memo[i] = memo[i-1] + memo[i-2] + } + + return memo[n] +} + +func main() { + n := 10 + fmt.Printf("Fibonacci(%d) = %d\n", n, fibonacci(n)) +} \ No newline at end of file diff --git a/impl/algorithms/Dynamic Programming/Knapsack Problem.go b/impl/algorithms/Dynamic Programming/Knapsack Problem.go new file mode 100644 index 00000000..8dcdd377 --- /dev/null +++ b/impl/algorithms/Dynamic Programming/Knapsack Problem.go @@ -0,0 +1,47 @@ +package main + +import "fmt" + +type Item struct { + value, weight int +} + +func knapsack(items []Item, capacity int) int { + n := len(items) + + // Create a memoization table + memo := make([][]int, n+1) + for i := range memo { + memo[i] = make([]int, capacity+1) + } + + // Fill the memoization table using dynamic programming + for i := 1; i <= n; i++ { + for w := 1; w <= capacity; w++ { + if items[i-1].weight <= w { + memo[i][w] = max(items[i-1].value+memo[i-1][w-items[i-1].weight], memo[i-1][w]) + } else { + memo[i][w] = memo[i-1][w] + } + } + } + + return memo[n][capacity] +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func main() { + items := []Item{ + {value: 60, weight: 10}, + {value: 100, weight: 20}, + {value: 120, weight: 30}, + } + capacity := 50 + fmt.Printf("Maximum value: %d\n", knapsack(items, capacity)) +} \ No newline at end of file diff --git a/impl/algorithms/Dynamic Programming/Longest Common Subsequence.go b/impl/algorithms/Dynamic Programming/Longest Common Subsequence.go new file mode 100644 index 00000000..cc56134e --- /dev/null +++ b/impl/algorithms/Dynamic Programming/Longest Common Subsequence.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "math" +) + +func lcsLength(s1, s2 string) int { + m := len(s1) + n := len(s2) + + // Create a memoization table + memo := make([][]int, m+1) + for i := range memo { + memo[i] = make([]int, n+1) + } + + // Fill the memoization table using dynamic programming + for i := 1; i <= m; i++ { + for j := 1; j <= n; j++ { + if s1[i-1] == s2[j-1] { + memo[i][j] = memo[i-1][j-1] + 1 + } else { + memo[i][j] = int(math.Max(float64(memo[i-1][j]), float64(memo[i][j-1]))) + } + } + } + + return memo[m][n] +} + +func main() { + s1 := "AGGTAB" + s2 := "GXTXAYB" + fmt.Printf("Longest Common Subsequence: %d\n", lcsLength(s1, s2)) +} \ No newline at end of file diff --git a/impl/algorithms/Dynamic Programming/README.md b/impl/algorithms/Dynamic Programming/README.md new file mode 100644 index 00000000..7255f808 --- /dev/null +++ b/impl/algorithms/Dynamic Programming/README.md @@ -0,0 +1,29 @@ +# Dynamic Programming Examples in Go + +This repository contains three well-commented programs in Go that demonstrate the concept of dynamic programming. + +## What is Dynamic Programming? + +Dynamic programming is a problem-solving technique used to solve complex problems by breaking them down into overlapping subproblems. It involves solving each subproblem only once and storing the solution for future use, which can greatly improve the efficiency of computations. + +Dynamic programming is especially useful for optimization problems and combinatorial problems, where the solution can be expressed as a combination of solutions to smaller subproblems. + +## Programs + +1. **Fibonacci Sequence using Dynamic Programming:** This program efficiently computes the Fibonacci sequence using a memoization table to store previously computed values. [Source code](fibonacci.go) + +2. **Longest Common Subsequence (LCS) using Dynamic Programming:** This program finds the length of the longest common subsequence between two strings using dynamic programming and a memoization table. [Source code](lcs.go) + +3. **0/1 Knapsack Problem using Dynamic Programming:** This program solves the 0/1 Knapsack problem, maximizing the value of items that can be included in a knapsack with limited capacity, using dynamic programming and a memoization table. [Source code](knapsack.go) + +Feel free to explore the source code of each program for detailed comments and explanations. + +## Getting Started + +To run these programs, make sure you have Go installed on your machine. Clone this repository and navigate to the program's directory you want to execute. Then, run the following command: + +```shell +go run .go +``` + +Replace with the name of the program \ No newline at end of file diff --git a/impl/algorithms/Greedy Algorithms/dijkstra.go b/impl/algorithms/Greedy Algorithms/dijkstra.go new file mode 100644 index 00000000..81ecc289 --- /dev/null +++ b/impl/algorithms/Greedy Algorithms/dijkstra.go @@ -0,0 +1,203 @@ +// C++ program for Dijkstra's single source shortest path +// algorithm. The program is for adjacency matrix +// representation of the graph +#include +using namespace std; +#include + +// Number of verticepackage main + +import ( + "fmt" + "math" +) + +// Number of vertices in the graph +const V = 9 + +// A utility function to find the vertex with minimum +// distance value, from the set of vertices not yet included +// in shortest path tree +func minDistance(dist []int, sptSet []bool) int { + // Initialize min value + min := math.MaxInt32 + var minIndex int + + for v := 0; v < V; v++ { + if sptSet[v] == false && dist[v] <= min { + min = dist[v] + minIndex = v + } + } + + return minIndex +} + +// A utility function to print the constructed distance +// array +func printSolution(dist []int) { + fmt.Println("Vertex \t Distance from Source") + for i := 0; i < V; i++ { + fmt.Printf("%d \t\t\t\t %d\n", i, dist[i]) + } +} + +// Function that implements Dijkstra's single source +// shortest path algorithm for a graph represented using +// adjacency matrix representation +func dijkstra(graph [V][V]int, src int) { + dist := make([]int, V) + sptSet := make([]bool, V) + + // Initialize all distances as INFINITE and stpSet[] as false + for i := 0; i < V; i++ { + dist[i] = math.MaxInt32 + sptSet[i] = false + } + + // Distance of source vertex from itself is always 0 + dist[src] = 0 + + // Find shortest path for all vertices + for count := 0; count < V-1; count++ { + // Pick the minimum distance vertex from the set of + // vertices not yet processed. u is always equal to + // src in the first iteration. + u := minDistance(dist, sptSet) + + // Mark the picked vertex as processed + sptSet[u] = true + + // Update dist value of the adjacent vertices of the + // picked vertex. + for v := 0; v < V; v++ { + // Update dist[v] only if is not in sptSet, + // there is an edge from u to v, and total + // weight of path from src to v through u is + // smaller than current value of dist[v] + if !sptSet[v] && graph[u][v] != 0 && dist[u] != math.MaxInt32 && dist[u]+graph[u][v] < dist[v] { + dist[v] = dist[u] + graph[u][v] + } + } + } + + // print the constructed distance array + printSolution(dist) +} + + +func main() { + // Create a sample adjacency matrix graph + graph := [V][V]int{ + {0, 4, 0, 0, 0, 0, 0, 8, 0}, + {4, 0, 8, 0, 0, 0, 0, 11, 0}, + {0, 8, 0, 7, 0, 4, 0, 0, 2}, + {0, 0, 7, 0, 9, 14, 0, 0, 0}, + {0, 0, 0, 9, 0, 10, 0, 0, 0}, + {0, 0, 4, 14, 10, 0, 2, 0, 0}, + {0, 0, 0, 0, 0, 2, 0, 1, 6}, + {8, 11, 0, 0, 0, 0, 1, 0, 7}, + {0, 0, 2, 0, 0, 0, 6, 7, 0}, + } + + // Set the source vertex for the algorithm + src := 0 + + // Call the Dijkstra's algorithm function with the graph and source vertex + dijkstra(graph, src) +}s in the graph +#define V 9 + +// A utility function to find the vertex with minimum +// distance value, from the set of vertices not yet included +// in shortest path tree +int minDistance(int dist[], bool sptSet[]) { + + // Initialize min value + int min = INT_MAX, min_index; + + for (int v = 0; v < V; v++) + if (sptSet[v] == false && dist[v] <= min) + min = dist[v], min_index = v; + + return min_index; +} + +// A utility function to print the constructed distance +// array +void printSolution(int dist[]) { + cout << "Vertex \t Distance from Source" << endl; + for (int i = 0; i < V; i++) + cout << i << " \t\t\t\t" << dist[i] << endl; +} + +// Function that implements Dijkstra's single source +// shortest path algorithm for a graph represented using +// adjacency matrix representation +void dijkstra(int graph[V][V], int src) { + int dist[V]; // The output array. dist[i] will hold the + // shortest + // distance from src to i + + bool sptSet[V]; // sptSet[i] will be true if vertex i is + // included in shortest + // path tree or shortest distance from src to i is + // finalized + + // Initialize all distances as INFINITE and stpSet[] as + // false + for (int i = 0; i < V; i++) + dist[i] = INT_MAX, sptSet[i] = false; + + // Distance of source vertex from itself is always 0 + dist[src] = 0; + + // Find shortest path for all vertices + for (int count = 0; count < V - 1; count++) { + // Pick the minimum distance vertex from the set of + // vertices not yet processed. u is always equal to + // src in the first iteration. + int u = minDistance(dist, sptSet); + + // Mark the picked vertex as processed + sptSet[u] = true; + + // Update dist value of the adjacent vertices of the + // picked vertex. + for (int v = 0; v < V; v++) + + // Update dist[v] only if is not in sptSet, + // there is an edge from u to v, and total + // weight of path from src to v through u is + // smaller than current value of dist[v] + if (!sptSet[v] && graph[u][v] + && dist[u] != INT_MAX + && dist[u] + graph[u][v] < dist[v]) + dist[v] = dist[u] + graph[u][v]; + } + + // print the constructed distance array + printSolution(dist); +} + +// driver's code +int main() { + + /* Let us create the example graph discussed above */ + int graph[V][V] = { { 0, 4, 0, 0, 0, 0, 0, 8, 0 }, + { 4, 0, 8, 0, 0, 0, 0, 11, 0 }, + { 0, 8, 0, 7, 0, 4, 0, 0, 2 }, + { 0, 0, 7, 0, 9, 14, 0, 0, 0 }, + { 0, 0, 0, 9, 0, 10, 0, 0, 0 }, + { 0, 0, 4, 14, 10, 0, 2, 0, 0 }, + { 0, 0, 0, 0, 0, 2, 0, 1, 6 }, + { 8, 11, 0, 0, 0, 0, 1, 0, 7 }, + { 0, 0, 2, 0, 0, 0, 6, 7, 0 } + }; + + // Function call + dijkstra(graph, 0); + + return 0; + +} \ No newline at end of file diff --git a/impl/algorithms/Greedy Algorithms/kruskal.go b/impl/algorithms/Greedy Algorithms/kruskal.go new file mode 100644 index 00000000..e4edc2d3 --- /dev/null +++ b/impl/algorithms/Greedy Algorithms/kruskal.go @@ -0,0 +1,93 @@ +package main + +import ( + "fmt" + "sort" +) + +type Edge struct { + source int + destination int + weight int +} + +type Graph struct { + vertices []int + edges []Edge +} + +func (g *Graph) AddEdge(u, v, w int) { + edge := Edge{source: u, destination: v, weight: w} + g.edges = append(g.edges, edge) +} + +func (g *Graph) Find(parent []int, i int) int { + if parent[i] != i { + parent[i] = g.Find(parent, parent[i]) + } + return parent[i] +} + +func (g *Graph) Union(parent []int, rank []int, x, y int) { + xroot := g.Find(parent, x) + yroot := g.Find(parent, y) + + if rank[xroot] < rank[yroot] { + parent[xroot] = yroot + } else if rank[xroot] > rank[yroot] { + parent[yroot] = xroot + } else { + parent[yroot] = xroot + rank[xroot]++ + } +} + +func KruskalMST(graph *Graph) { + vertices := graph.vertices + edges := graph.edges + + result := make([]Edge, 0) + parent := make([]int, len(vertices)) + rank := make([]int, len(vertices)) + + // Initialize parent and rank + for i := 0; i < len(vertices); i++ { + parent[i] = i + rank[i] = 0 + } + + // Sort edges in ascending order of their weights + sort.Slice(edges, func(i, j int) bool { + return edges[i].weight < edges[j].weight + }) + + for _, edge := range edges { + x := graph.Find(parent, edge.source) + y := graph.Find(parent, edge.destination) + + if x != y { + result = append(result, edge) + graph.Union(parent, rank, x, y) + } + } + + // Print the constructed MST + fmt.Println("Edge \tWeight") + for _, edge := range result { + fmt.Printf("%d - %d \t%d\n", edge.source, edge.destination, edge.weight) + } +} + +func main() { + graph := Graph{ + vertices: []int{0, 1, 2, 3, 4}, + } + graph.AddEdge(0, 1, 2) + graph.AddEdge(0, 3, 6) + graph.AddEdge(1, 2, 3) + graph.AddEdge(1, 4, 5) + graph.AddEdge(2, 4, 7) + graph.AddEdge(3, 4, 9) + + KruskalMST(&graph) +} \ No newline at end of file diff --git a/impl/algorithms/Greedy Algorithms/prim.go b/impl/algorithms/Greedy Algorithms/prim.go new file mode 100644 index 00000000..1baa3cc5 --- /dev/null +++ b/impl/algorithms/Greedy Algorithms/prim.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" +) + +type Edge struct { + source int + destination int + weight int +} + +func PrimMST(graph [][]int) { + vertexCount := len(graph) + parent := make([]int, vertexCount) + key := make([]int, vertexCount) + mstSet := make([]bool, vertexCount) + + // Initialize key values as infinity + for i := 0; i < vertexCount; i++ { + key[i] = int(^uint(0) >> 1) // set as maximum int value + mstSet[i] = false + } + + // Always include the first vertex in MST + key[0] = 0 // Make key 0 so that this vertex is picked as first vertex + parent[0] = -1 // First node is always the root of MST + + for count := 0; count < vertexCount-1; count++ { + u := minKey(key, mstSet, vertexCount) + mstSet[u] = true + + for v := 0; v < vertexCount; v++ { + if graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v] { + parent[v] = u + key[v] = graph[u][v] + } + } + } + + // Print the constructed MST + fmt.Println("Edge \tWeight") + for i := 1; i < vertexCount; i++ { + fmt.Printf("%d - %d \t%d\n", parent[i], i, graph[i][parent[i]]) + } +} + +func minKey(key []int, mstSet []bool, vertexCount int) int { + min := int(^uint(0) >> 1) + minIndex := -1 + + for v := 0; v < vertexCount; v++ { + if mstSet[v] == false && key[v] < min { + min = key[v] + minIndex = v + } + } + + return minIndex +} + +func main() { + graph := [][]int{ + {0, 2, 0, 6, 0}, + {2, 0, 3, 8, 5}, + {0, 3, 0, 0, 7}, + {6, 8, 0, 0, 9}, + {0, 5, 7, 9, 0}, + } + + PrimMST(graph) +} \ No newline at end of file diff --git a/impl/algorithms/searching/binary.go b/impl/algorithms/searching/binary.go new file mode 100644 index 00000000..b1dfb9cd --- /dev/null +++ b/impl/algorithms/searching/binary.go @@ -0,0 +1,47 @@ +package main + +import "fmt" + +// binarySearch returns the index of key in the given sorted slice of integers. +// If key is not found, it returns -1. +func binarySearch(arr []int, key int) int { + // Initialize low and high indices + low := 0 + high := len(arr) - 1 + + // Loop until low index is less than or equal to high index + for low <= high { + // Calculate middle index + mid := (low + high) / 2 + + // If key is found at middle index, return it + if arr[mid] == key { + return mid + } + + // If key is less than the middle element, search in the left half + if arr[mid] > key { + high = mid - 1 + } + + // If key is greater than the middle element, search in the right half + if arr[mid] < key { + low = mid + 1 + } + } + + // If key is not found, return -1 + return -1 +} + +func main() { + // Example usage of binarySearch function + arr := []int{2, 3, 4, 10, 40} + key := 10 + index := binarySearch(arr, key) + if index == -1 { + fmt.Println("Element not present") + } else { + fmt.Printf("Element found at index %d\n", index) + } +} diff --git a/impl/algorithms/searching/jump.go b/impl/algorithms/searching/jump.go new file mode 100644 index 00000000..d05c827c --- /dev/null +++ b/impl/algorithms/searching/jump.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "math" +) + +// Jump Search function +func jumpSearch(arr []int, x int) int { + n := len(arr) + // Finding block size to be jumped + step := int(math.Sqrt(float64(n))) + // Finding the block where element is present (if it is present) + prev := 0 + for arr[int(math.Min(float64(step), float64(n))-1)] < x { + prev = step + step += int(math.Sqrt(float64(n))) + if prev >= n { + return -1 + } + } + // Doing a linear search for x in block beginning with prev + for arr[prev] < x { + prev++ + // If we reached next block or end of array, element is not present + if prev == int(math.Min(float64(step), float64(n))) { + return -1 + } + } + // If element is found + if arr[prev] == x { + return prev + } + // Element not found + return -1 +} + +func main() { + arr := []int{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610} + x := 55 + index := jumpSearch(arr, x) + if index == -1 { + fmt.Printf("Element %d is not present in the array\n", x) + } else { + fmt.Printf("Element %d is present at index %d\n", x, index) + } +} diff --git a/impl/algorithms/searching/linear.go b/impl/algorithms/searching/linear.go new file mode 100644 index 00000000..a88a5154 --- /dev/null +++ b/impl/algorithms/searching/linear.go @@ -0,0 +1,30 @@ +package main + +import "fmt" + +// linearSearch performs a linear search on the given slice of integers. +// It returns the index of the first occurrence of the target value, or -1 +// if the target value is not found in the slice. +func linearSearch(arr []int, target int) int { + for i, val := range arr { + if val == target { + return i + } + } + return -1 +} + +func main() { + arr := []int{5, 10, 3, 8, 6, 12, 1} + target := 8 + + // Perform a linear search on the array for the target value + idx := linearSearch(arr, target) + + // Print the result + if idx == -1 { + fmt.Printf("%d was not found in the array.\n", target) + } else { + fmt.Printf("%d was found at index %d.\n", target, idx) + } +} diff --git a/impl/algorithms/sorting/bubble.go b/impl/algorithms/sorting/bubble.go new file mode 100644 index 00000000..431d76c1 --- /dev/null +++ b/impl/algorithms/sorting/bubble.go @@ -0,0 +1,32 @@ +package main + +import "fmt" + +// The bubbleSort function takes an array of integers and sorts it in ascending order using the bubble sort algorithm +func bubbleSort(arr []int) { + n := len(arr) + + // Traverse through all array elements + for i := 0; i < n-1; i++ { + + // Last i elements are already in place + for j := 0; j < n-i-1; j++ { + + // Swap the elements if they are in wrong order + if arr[j] > arr[j+1] { + arr[j], arr[j+1] = arr[j+1], arr[j] + } + } + } +} + +func main() { + // Example usage + arr := []int{64, 34, 25, 12, 22, 11, 90} + + fmt.Println("Original array:", arr) + + bubbleSort(arr) + + fmt.Println("Sorted array:", arr) +} diff --git a/impl/algorithms/sorting/heap.go b/impl/algorithms/sorting/heap.go new file mode 100644 index 00000000..b2c4ac9c --- /dev/null +++ b/impl/algorithms/sorting/heap.go @@ -0,0 +1,58 @@ +package main + +import "fmt" + +// The heapify function takes a slice, a length n and an index i, +// and ensures that the subtree rooted at index i satisfies the heap property. +// The heap property is satisfied if the parent node at index i is larger than or equal to +// its children. +func heapify(arr []int, n, i int) { + largest := i // Initialize largest as root + left := 2*i + 1 // left child of i + right := 2*i + 2 // right child of i + + // If left child is larger than root + if left < n && arr[left] > arr[largest] { + largest = left + } + + // If right child is larger than largest so far + if right < n && arr[right] > arr[largest] { + largest = right + } + + // If largest is not root + if largest != i { + arr[i], arr[largest] = arr[largest], arr[i] // swap + // Recursively heapify the affected sub-tree + heapify(arr, n, largest) + } +} + +// The heapSort function takes a slice and sorts it in increasing order +func heapSort(arr []int) { + n := len(arr) + + // Build heap (rearrange array) + // Starting with the last non-leaf node and heapifying all nodes in reverse level order + for i := n/2 - 1; i >= 0; i-- { + heapify(arr, n, i) + } + + // One by one extract an element from heap + for i := n - 1; i > 0; i-- { + // Move current root to end + arr[0], arr[i] = arr[i], arr[0] + + // call max heapify on the reduced heap + heapify(arr, i, 0) + } +} + +func main() { + // Example usage + arr := []int{12, 11, 13, 5, 6, 7} + fmt.Println("Original array:", arr) + heapSort(arr) + fmt.Println("Sorted array:", arr) +} diff --git a/impl/algorithms/sorting/insertion.go b/impl/algorithms/sorting/insertion.go new file mode 100644 index 00000000..f7413058 --- /dev/null +++ b/impl/algorithms/sorting/insertion.go @@ -0,0 +1,31 @@ +package main + +import "fmt" + +// Insertion sort function +func insertionSort(arr []int) { + // Iterate through each element of the array + for i := 1; i < len(arr); i++ { + // Save the current element and its index + key := arr[i] + j := i - 1 + + // Shift all elements that are greater than the current element + // one position to the right + for j >= 0 && arr[j] > key { + arr[j+1] = arr[j] + j-- + } + + // Insert the current element in its correct position + arr[j+1] = key + } +} + +func main() { + // Example usage + arr := []int{5, 2, 4, 6, 1, 3} + fmt.Println("Before sorting:", arr) + insertionSort(arr) + fmt.Println("After sorting:", arr) +} diff --git a/impl/algorithms/sorting/merge.go b/impl/algorithms/sorting/merge.go new file mode 100644 index 00000000..084a897f --- /dev/null +++ b/impl/algorithms/sorting/merge.go @@ -0,0 +1,91 @@ +package main + +import "fmt" + +// Merge two subarrays of 'arr[]' +// First subarray is arr[l..m] +// Second subarray is arr[m+1..r] +func merge(arr []int, l, m, r int) { + // Create temporary arrays to store the two subarrays + n1 := m - l + 1 + n2 := r - m + + L := make([]int, n1) + R := make([]int, n2) + + // Copy data to temporary arrays + for i := 0; i < n1; i++ { + L[i] = arr[l+i] + } + for j := 0; j < n2; j++ { + R[j] = arr[m+1+j] + } + + // Merge the two temporary arrays back into 'arr[]' + + // Initial indexes of the first and second subarrays + i := 0 // index of first subarray + j := 0 // index of second subarray + + // Initial index of merged subarray + k := l + + for i < n1 && j < n2 { + // Compare the elements from the two subarrays + if L[i] <= R[j] { + // The element from the left subarray is smaller or equal + // Copy it to arr[k] and increment i + arr[k] = L[i] + i++ + } else { + // The element from the right subarray is smaller + // Copy it to arr[k] and increment j + arr[k] = R[j] + j++ + } + k++ + } + + // Copy the remaining elements of L[], if there are any + for i < n1 { + arr[k] = L[i] + i++ + k++ + } + + // Copy the remaining elements of R[], if there are any + for j < n2 { + arr[k] = R[j] + j++ + k++ + } +} + +// Main function that sorts arr[l..r] using merge() +func mergeSort(arr []int, l, r int) { + if l < r { + // Same as (l+r)/2, but avoids overflow for + // large l and h + m := l + (r-l)/2 + + // Sort first and second halves + mergeSort(arr, l, m) + mergeSort(arr, m+1, r) + + // Merge the sorted halves + merge(arr, l, m, r) + } +} + +func main() { + // Example usage of Merge Sort + + arr := []int{12, 11, 13, 5, 6, 7} + n := len(arr) + + fmt.Println("Original array:", arr) + + mergeSort(arr, 0, n-1) + + fmt.Println("Sorted array:", arr) +} diff --git a/impl/algorithms/sorting/quick.go b/impl/algorithms/sorting/quick.go new file mode 100644 index 00000000..135438cd --- /dev/null +++ b/impl/algorithms/sorting/quick.go @@ -0,0 +1,52 @@ +package main + +import "fmt" + +// Function to partition the array +func partition(arr []int, low, high int) int { + // Choose the rightmost element as pivot + pivot := arr[high] + // Index of smaller element and indicates the right position + // of pivot found so far + i := low - 1 + + for j := low; j <= high-1; j++ { + // If current element is smaller than or equal to pivot + if arr[j] <= pivot { + // Increment index of smaller element + i++ + // Swap arr[i] and arr[j] + arr[i], arr[j] = arr[j], arr[i] + } + } + + // Swap arr[i+1] and arr[high] (or pivot) + arr[i+1], arr[high] = arr[high], arr[i+1] + // Return partition index + 1 + return i + 1 +} + +// Function implementing QuickSort +func quickSort(arr []int, low, high int) { + if low < high { + // Find pivot index such that, all elements left to pivot are smaller and + // all elements right to pivot are greater + pi := partition(arr, low, high) + // Recursively apply the same on left and right partitions + quickSort(arr, low, pi-1) + quickSort(arr, pi+1, high) + } +} + +func main() { + // Input array + arr := []int{64, 34, 25, 12, 22, 11, 90} + // Get length of the array + n := len(arr) + + // Call quickSort function + quickSort(arr, 0, n-1) + + // Print the sorted array + fmt.Println("Sorted array is:", arr) +} diff --git a/impl/algorithms/sorting/selection.go b/impl/algorithms/sorting/selection.go new file mode 100644 index 00000000..73bba2e9 --- /dev/null +++ b/impl/algorithms/sorting/selection.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" +) + +func selectionSort(arr []int) { + // Loop through each element in the array + for i := 0; i < len(arr)-1; i++ { + // Assume the current element is the minimum + min := i + + // Loop through the remaining elements in the array + for j := i + 1; j < len(arr); j++ { + // If the current element is less than the assumed minimum, update the minimum + if arr[j] < arr[min] { + min = j + } + } + + // Swap the current element with the minimum element + arr[i], arr[min] = arr[min], arr[i] + } +} + +func main() { + // Example usage + arr := []int{5, 2, 4, 6, 1, 3} + fmt.Println("Before sorting:", arr) + selectionSort(arr) + fmt.Println("After sorting:", arr) +} diff --git a/impl/files-manipulation/01-CreateEmptyFile.go b/impl/files-manipulation/01-CreateEmptyFile.go new file mode 100644 index 00000000..5b96c6b7 --- /dev/null +++ b/impl/files-manipulation/01-CreateEmptyFile.go @@ -0,0 +1,23 @@ +package main + +import ( + "log" + "os" +) + +var ( + newFile *os.File + err error +) + +func main() { + + /* + Boş Dosya Oluşturma (Create Empty File) + */ + + newFile, err = os.Create("demo.txt") + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/02-TruncateFile.go b/impl/files-manipulation/02-TruncateFile.go new file mode 100644 index 00000000..31d5bd72 --- /dev/null +++ b/impl/files-manipulation/02-TruncateFile.go @@ -0,0 +1,24 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Dosyayı Kes (Truncate a File) + + Bir dosya 100 byte'a kesilmelidir. + Eğer dosya 100 byte'tan az ise içerik kalır, geri kalan kısım boş byte ile dolacaktır. + Eğer dosya 100 byte'ın üzerinde ise 100 byte'tan sonraki herşey kaybolur. + Her iki durumda da kesme işlemi 100 byte üzerinden gerçekleştirilmelidir. + Eğer kesilecek dosya boş ise sıfır değeri kullanılır. + */ + + err := os.Truncate("demo.txt", 100) + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/03-GetFileInfo.go b/impl/files-manipulation/03-GetFileInfo.go new file mode 100644 index 00000000..f50a565a --- /dev/null +++ b/impl/files-manipulation/03-GetFileInfo.go @@ -0,0 +1,33 @@ +package main + +import ( + "fmt" + "log" + "os" +) + +var ( + fileInfo *os.FileInfo + err error +) + +func main() { + + /* + Dosya Bilgisi Almak (Get File Info) + */ + + // Dosya bilgisini döndürür. + // Eğer dosya yoksa hata döndürür. + fileInfo, err := os.Stat("demo.txt") + if err != nil { + log.Fatal(err) + } + fmt.Println("File name: ", fileInfo.Name()) + fmt.Println("Size in bytes: ", fileInfo.Size()) + fmt.Println("Permissions: ", fileInfo.Mode()) + fmt.Println("Last Modified: ", fileInfo.ModTime()) + fmt.Println("Is Directory: ", fileInfo.IsDir()) + fmt.Println("System interface type: %T\n", fileInfo.Sys()) + fmt.Println("System info: %+v\n\n ", fileInfo.Sys()) +} diff --git a/impl/files-manipulation/04-RenameFile.go b/impl/files-manipulation/04-RenameFile.go new file mode 100644 index 00000000..28726db5 --- /dev/null +++ b/impl/files-manipulation/04-RenameFile.go @@ -0,0 +1,22 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Yeniden İsimlendirme ve Taşıma (Rename and Move a File) + */ + + originalPath := "demo.txt" + newPath := "test.txt" + err := os.Rename(originalPath, newPath) + if err != nil { + log.Fatal(err) + } + + // Taşıma işlemini de Rename() ile yapmayı dene! +} diff --git a/impl/files-manipulation/05-RemoveFile.go b/impl/files-manipulation/05-RemoveFile.go new file mode 100644 index 00000000..0fa45389 --- /dev/null +++ b/impl/files-manipulation/05-RemoveFile.go @@ -0,0 +1,18 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Dosya Silme (Delete a file) + */ + + err := os.Remove("demo.txt") + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/06-OpenCloseFile.go b/impl/files-manipulation/06-OpenCloseFile.go new file mode 100644 index 00000000..769f940f --- /dev/null +++ b/impl/files-manipulation/06-OpenCloseFile.go @@ -0,0 +1,45 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Dosyaları Açma ve Kapama (Open and Close Files) + */ + + // Dosyayı salt okunur olarak açtık + file, err := os.Open("demo.txt") + if err != nil { + log.Fatal(err) + } + file.Close() + + // OpenFile çok seçenekli dosya açma yöntemidir. + // İkinci parametre dosya açılış amacını ayarlarken, üçüncü parametre dosya izinlerini belirler. + file, err = os.OpenFile("demo.txt", os.O_APPEND, 0666) + if err != nil { + log.Fatal(err) + } + file.Close() + + /* + + OpenFile() ikinci parametrenin tipleri; + + os.O_RDONLY : Sadece okuma + os.O_WRONLY : Sadece yazma + os.O_RDWR : Okuma ve yazma yapılabilir + os.O_APPEND : Dosyanın sonuna ekle + os.O_CREATE : Dosya yoksa oluştur + os.O_TRUNC : Açılırken dosyayı kes + + Bu ayarlar birden fazla olarak da kullanılabilir + + -> os.O_CREATE|os.O_APPEND + -> os.O_CREATE|os.O_TRUNC|os.O_WRONLY + */ +} diff --git a/impl/files-manipulation/07-CheckFileExist.go b/impl/files-manipulation/07-CheckFileExist.go new file mode 100644 index 00000000..febd19f5 --- /dev/null +++ b/impl/files-manipulation/07-CheckFileExist.go @@ -0,0 +1,29 @@ +package main + +import ( + "log" + "os" +) + +var ( + fileInfo *os.FileInfo + err error +) + +func main() { + + /* + Dosyanın var olup olmadığını kontrol etmek (Check if File Exists) + */ + + // Dosya bilgisini döndürür. + // Eğer dosya yoksa hata döndürür. + fileInfo, err := os.Stat("demo.txt") + if err != nil { + if os.IsNotExist(err) { + log.Fatal("File does not exist") + } + } + log.Println("File does exist. File information : ") + log.Println(fileInfo) +} diff --git a/impl/files-manipulation/08-CheckFilePermissions.go b/impl/files-manipulation/08-CheckFilePermissions.go new file mode 100644 index 00000000..d592963f --- /dev/null +++ b/impl/files-manipulation/08-CheckFilePermissions.go @@ -0,0 +1,33 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Okuma ve Yazma İzinlerini Kontrol Etmek ( Check Read and Write Permissions) + */ + + // Yazma izinleri testi + // Dosyanyı açmaya çalışmadan önce varlığını kontrol edebilirsiniz; + // Bunun için; os.IsNotExist + file, err := os.OpenFile("demo.txt", os.O_WRONLY, 0666) + if err != nil { + if os.IsPermission(err) { + log.Println("Hata : Yazma izni reddedildi") + } + } + file.Close() + + // Okuma izinleri testi + file, err = os.OpenFile("demo.txt", os.O_RDONLY, 0666) + if err != nil { + if os.IsPermission(err) { + log.Println("Hata : Okuma izni reddedildi") + } + } + file.Close() +} diff --git a/impl/files-manipulation/09-ChangeFilePermissions.go b/impl/files-manipulation/09-ChangeFilePermissions.go new file mode 100644 index 00000000..67cc980e --- /dev/null +++ b/impl/files-manipulation/09-ChangeFilePermissions.go @@ -0,0 +1,36 @@ +package main + +import ( + "log" + "os" + "time" +) + +func main() { + + /* + İzinleri, Sahipliği ve Zaman Damgalarını(Timestamps) Değiştirmek Change Permissions, Ownership, and Timestamps + */ + + // İzinleri değiştirme (Linux tarzı) + err := os.Chmod("demo.txt", 0777) + if err != nil { + log.Println(err) + + } + + // Sahipliği değiştirme + err = os.Chown("demo.txt", os.Getuid(), os.Getgid()) + if err != nil { + log.Println(err) + } + + // Zaman Damgalarını(Timestamps) Değiştirme + twoDaysFromNow := time.Now().Add(48 * time.Hour) + lastAccessTime := twoDaysFromNow + lastModifyTime := twoDaysFromNow + err = os.Chtimes("demo.txt", lastAccessTime, lastModifyTime) + if err != nil { + log.Println(err) + } +} diff --git a/impl/files-manipulation/10-HardlinkSymlink.go b/impl/files-manipulation/10-HardlinkSymlink.go new file mode 100644 index 00000000..0d27e1a8 --- /dev/null +++ b/impl/files-manipulation/10-HardlinkSymlink.go @@ -0,0 +1,48 @@ +package main + +import ( + "fmt" + "log" + "os" +) + +func main() { + + /* + Hard Links and Symlinks + */ + + // Bir "Hard Link" oluştur + // Aynı içeriğe işaret eden iki dosya adı olacaktır. + // Birinin içeriğini değiştirmek diğerini değiştirecek + // Birini silmek / yeniden adlandırmak diğerini etkilemez + err := os.Link("demo.txt", "demo_also.txt") + if err != nil { + log.Fatal(err) + } + + fmt.Println("sym oluşturma") + + // Symlink oluştur + err = os.Symlink("demo.txt", "demo_also.txt") + if err != nil { + log.Fatal(err) + } + + // Lstat dosya bilgisini döndürür. + // Ama aslında o bir symlink ise symlink hakkında bilgi döndürür. + // Bağlantıyı takip etmeyecek ve gerçek dosya hakkında bilgi vermeyecektir. + // Symlink'ler Windows'da çalışmaz. + fileInfo, err := os.Lstat("demo_sym.txt") + if err != nil { + log.Fatal(err) + } + fmt.Printf("Bağlantı Bilgisi: %+v", fileInfo) + + // Sadece bir symlink'in sahipliğini değiştir. + // Ama işaret ettiği dosyanın sahipliğini değiştirmez. + err = os.Lchown("demo_sym.txt", os.Getuid(), os.Getgid()) + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/11-CopyFile.go b/impl/files-manipulation/11-CopyFile.go new file mode 100644 index 00000000..fcf4a121 --- /dev/null +++ b/impl/files-manipulation/11-CopyFile.go @@ -0,0 +1,41 @@ +package main + +import ( + "io" + "log" + "os" +) + +func main() { + + /* + Dosya Kopyalama (Copy a file) + */ + + originalFile, err := os.Open("demo.txt") + if err != nil { + log.Fatal(err) + } + defer originalFile.Close() + + // Yeni bir dosya oluştur + newFile, err := os.Create("demo_copy.txt") + if err != nil { + log.Fatal(err) + } + defer newFile.Close() + + // Byte'ları kaynaktan hedefe Kopyalama + bytesWritten, err := io.Copy(newFile, originalFile) + if err != nil { + log.Fatal(err) + } + log.Printf("Copied %d bytes.", bytesWritten) + + // Dosya içeriğini işle(commit) + // Belleği diske boşalt(flush) + err = newFile.Sync() + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/12-SeekPositionInFile.go b/impl/files-manipulation/12-SeekPositionInFile.go new file mode 100644 index 00000000..eab31ff6 --- /dev/null +++ b/impl/files-manipulation/12-SeekPositionInFile.go @@ -0,0 +1,50 @@ +package main + +import ( + "fmt" + "log" + "os" +) + +func main() { + + /* + Seek Positions in File + */ + + file, _ := os.Open("demo.txt") + defer file.Close() + + // Offset kaç byte taşımalıdır? + // Offset negatif(-) ya da pozitif(+) olabilir + var offset int64 = 5 + + // Offset için referans noktası nerededir? + // 0 = Dosyanın başlangıcı + // 1 = Şu anki pozisyon + // 2 = Dosyanın sonu + var whence int = 0 + newPosition, err := file.Seek(offset, whence) + if err != nil { + log.Fatal(err) + } + fmt.Println("Just moved to 5: ", newPosition) + + // Şu anki pozisyondan 2 byte geri git + newPosition, err = file.Seek(-2, 1) + if err != nil { + log.Fatal(err) + } + fmt.Println("Just momved back two: ", newPosition) + + // 0 byte taşındıktan sonra Seek'den dönüş değerini elde ederek geçerli konumu bul. + currentPosition, err := file.Seek(0, 1) + fmt.Println("Current position: ", currentPosition) + + // Dosyanın başlangıcına git + newPosition, err = file.Seek(0, 0) + if err != nil { + log.Fatal(err) + } + fmt.Println("Position after seeking 0,0: ", newPosition) +} diff --git a/impl/files-manipulation/13-WriteBytesToFile.go b/impl/files-manipulation/13-WriteBytesToFile.go new file mode 100644 index 00000000..e29c1917 --- /dev/null +++ b/impl/files-manipulation/13-WriteBytesToFile.go @@ -0,0 +1,30 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Byte'ları Bir Dosyaya Yazın (Write Bytes to a File) + */ + + // Demo.txt dosyasını sadece yazılabilir bir dosya olarak aç + file, err := os.OpenFile( + "demo.txt", + os.O_WRONLY|os.O_TRUNC|os.O_CREATE, + 0666) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + byteSlice := []byte("Bytes!\n") + bytesWritten, err := file.Write(byteSlice) + if err != nil { + log.Fatal(err) + } + log.Printf("Wrote %d bytes.\n", bytesWritten) +} diff --git a/impl/files-manipulation/14-QuickWriteToFile.go b/impl/files-manipulation/14-QuickWriteToFile.go new file mode 100644 index 00000000..764b12fb --- /dev/null +++ b/impl/files-manipulation/14-QuickWriteToFile.go @@ -0,0 +1,18 @@ +package main + +import ( + "io/ioutil" + "log" +) + +func main() { + + /* + Hızlıca Dosya Yazma (Quick Write to File) + */ + + err := ioutil.WriteFile("demo.txt", []byte("Hi!\n"), 0666) + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/15-OpenFileToWrite.go b/impl/files-manipulation/15-OpenFileToWrite.go new file mode 100644 index 00000000..79f2a954 --- /dev/null +++ b/impl/files-manipulation/15-OpenFileToWrite.go @@ -0,0 +1,76 @@ +package main + +import ( + "bufio" + "log" + "os" +) + +func main() { + // Yazmak için dosyayı aç + file, err := os.OpenFile("test.txt", os.O_WRONLY, 0666) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + // Dosyadan bir "buffered writer" oluştur + bufferedWriter := bufio.NewWriter(file) + + // Arabelleğe byte yaz + bytesWritten, err := bufferedWriter.Write( + []byte{65, 66, 67}, + ) + if err != nil { + log.Fatal(err) + } + log.Printf("Bytes written: %d\n", bytesWritten) + + // String'i belleğe(buffer) yaz + // Ayrıca bunlarda mevcut: WriteRune() ve WriteByte() + bytesWritten, err = bufferedWriter.WriteString( + "Buffered string\n", + ) + if err != nil { + log.Fatal(err) + } + log.Printf("Bytes written: %d\n", bytesWritten) + + // Buffer beklenirken ne kadar depolandığını kontrol etme + unflushedBufferSize := bufferedWriter.Buffered() + log.Printf("Bytes buffered: %d\n", unflushedBufferSize) + + // Kullanılabilir arabellek miktarını görme + bytesAvailable := bufferedWriter.Available() + if err != nil { + log.Fatal(err) + } + log.Printf("Available buffer: %d\n", bytesAvailable) + + // Belleği diske yaz + bufferedWriter.Flush() + + // Henüz Flush() ile dosyaya yazılmamış arabellekte yapılan değişiklikleri geri alın. + bufferedWriter.Reset(bufferedWriter) + + // Kullanılabilir arabellek miktarını görme + bytesAvailable = bufferedWriter.Available() + if err != nil { + log.Fatal(err) + } + log.Printf("Available buffer: %d\n", bytesAvailable) + + // Tamponu yeniden boyutlandırır. + // Bu kullanınmda aynı buffer'ı yeniden boyutlandırıp kullanıyoruz. + bufferedWriter = bufio.NewWriterSize( + bufferedWriter, + 8000, + ) + + // Yeniden boyutlandırma sonrasında tekrar kullanılabilir arabellek miktarını kontrol etme + bytesAvailable = bufferedWriter.Available() + if err != nil { + log.Fatal(err) + } + log.Printf("Available buffer: %d\n", bytesAvailable) +} diff --git a/impl/files-manipulation/16-ReadFromFile.go b/impl/files-manipulation/16-ReadFromFile.go new file mode 100644 index 00000000..0e62ceea --- /dev/null +++ b/impl/files-manipulation/16-ReadFromFile.go @@ -0,0 +1,30 @@ +package main + +import ( + "log" + "os" +) + +func main() { + + /* + Dosyadan n byte kadarlık akışı okuma (Read up to n Bytes from File) + */ + + // Okumak için dosyayı aç + file, err := os.Open("demo.txt") + if err != nil { + log.Fatal(err) + } + defer file.Close() + + // len(b) kadar byte okuma yapılabilir. + // Dosya sonu io.EOF hata türünü döndürür. + byteSlice := make([]byte, 16) + bytesRead, err := file.Read(byteSlice) + if err != nil { + log.Fatal(err) + } + log.Printf("Number of bytes read: %d\n", bytesRead) + log.Printf("Data read: %s\n", byteSlice) +} diff --git a/impl/files-manipulation/17-OpenFileToRead.go b/impl/files-manipulation/17-OpenFileToRead.go new file mode 100644 index 00000000..1c7b5553 --- /dev/null +++ b/impl/files-manipulation/17-OpenFileToRead.go @@ -0,0 +1,28 @@ +package main + +import ( + "io" + "log" + "os" +) + +func main() { + + /* + Tam olarak n byte'ı oku (Read Exactly n Bytes) + */ + + // Okumak için dosyayı aç + file, err := os.Open("demo.txt") + if err != nil { + log.Fatal(err) + } + + byteSlice := make([]byte, 2) + numBytesRead, err := io.ReadFull(file, byteSlice) + if err != nil { + log.Fatal(err) + } + log.Printf("Number of bytes read: %d\n", numBytesRead) + log.Printf("Data read: %s\n", byteSlice) +} diff --git a/impl/files-manipulation/18-ReadNBytesFromFile.go b/impl/files-manipulation/18-ReadNBytesFromFile.go new file mode 100644 index 00000000..b77f46c0 --- /dev/null +++ b/impl/files-manipulation/18-ReadNBytesFromFile.go @@ -0,0 +1,30 @@ +package main + +import ( + "io" + "log" + "os" +) + +func main() { + + /* + En az n byte oku (Read At Least n Bytes) + */ + + // Okumak için dosyayı aç + file, err := os.Open("demo.txt") + if err != nil { + log.Fatal(err) + } + + byteSlice := make([]byte, 512) + minBytes := 8 + // io.ReadAtLeast() okumak için en az minBytes bulamıyorsa hata döndürecektir. + numBytesRead, err := io.ReadAtLeast(file, byteSlice, minBytes) + if err != nil { + log.Fatal(err) + } + log.Printf("Number of bytes read: %d\n", numBytesRead) + log.Printf("Data read: %s\n", byteSlice) +} diff --git a/impl/files-manipulation/19-ReadAllBytesFromFile.go b/impl/files-manipulation/19-ReadAllBytesFromFile.go new file mode 100644 index 00000000..5b00b012 --- /dev/null +++ b/impl/files-manipulation/19-ReadAllBytesFromFile.go @@ -0,0 +1,31 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" +) + +func main() { + + /* + Dosyanın Tüm Byte'ları Oku (Read All Bytes of File) + */ + + // Okumak için dosya aç + file, err := os.Open("demo.txt") + if err != nil { + log.Fatal(err) + } + + // os.File.Read(), io.ReadFull(), ioutil.ReadAll() ve io.ReadAtLeast() da kullanılabilir + data, err := ioutil.ReadAll(file) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Data as hex: %x\n", data) + fmt.Printf("Data as string: &s\n", data) + fmt.Printf("Number of bytes read:", len(data)) +} diff --git a/impl/files-manipulation/20-QuickReadWholeFile.go b/impl/files-manipulation/20-QuickReadWholeFile.go new file mode 100644 index 00000000..a25d7c1e --- /dev/null +++ b/impl/files-manipulation/20-QuickReadWholeFile.go @@ -0,0 +1,20 @@ +package main + +import ( + "io/ioutil" + "log" +) + +func main() { + + /* + Dosyayı Hızlı Okuma (Quick Read Whole File to Memory) + */ + + // Dosyadan byte dilimine okuma yapma + data, err := ioutil.ReadFile("demo.txt") + if err != nil { + log.Fatal(err) + } + log.Printf("Data read: %s\n", data) +} diff --git a/impl/files-manipulation/21-UseBufferedReader.go b/impl/files-manipulation/21-UseBufferedReader.go new file mode 100644 index 00000000..f1ebf0f2 --- /dev/null +++ b/impl/files-manipulation/21-UseBufferedReader.go @@ -0,0 +1,61 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" +) + +func main() { + + /* + Use Buffered Reader + */ + + // Dosyayı aç ve onun üzerinden "buffered reader" oluştur + file, err := os.Open("test.txt") + if err != nil { + log.Fatal(err) + } + bufferedReader := bufio.NewReader(file) + + byteSlice := make([]byte, 5) + byteSlice, err = bufferedReader.Peek(5) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Peeked at 5 bytes: %s\n", byteSlice) + + numBytesRead, err := bufferedReader.Read(byteSlice) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Read %d bytes: %s\n", numBytesRead, byteSlice) + + // Bir byte döner. Eğer okunacak byte yoksa hata döner. + myByte, err := bufferedReader.ReadByte() + if err != nil { + log.Fatal(err) + } + fmt.Printf("Read 1 byte: %c\n", myByte) + + // Read up to and including delimiter + // Returns byte slice + dataBytes, err := bufferedReader.ReadBytes('\n') + if err != nil { + log.Fatal(err) + } + fmt.Printf("Read bytes: %s\n", dataBytes) + + // Read up to and including delimiter + // Returns string + dataString, err := bufferedReader.ReadString('\n') + if err != nil { + log.Fatal(err) + } + fmt.Printf("Read string: %s\n", dataString) + + // This example reads a few lines so test.txt + // should have a few lines of text to work correct +} diff --git a/impl/files-manipulation/22-ReadWithScanner.go b/impl/files-manipulation/22-ReadWithScanner.go new file mode 100644 index 00000000..1878ed62 --- /dev/null +++ b/impl/files-manipulation/22-ReadWithScanner.go @@ -0,0 +1,43 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" +) + +func main() { + + /* + Read with a Scanner + */ + + // Open file and create scanner on top of it + file, err := os.Open("test.txt") + if err != nil { + log.Fatal(err) + } + scanner := bufio.NewScanner(file) + + // Default scanner is bufio.ScanLines. Lets use ScanWords. + // Could also use a custom function of SplitFunc type + scanner.Split(bufio.ScanWords) + + // Scan for next token. + success := scanner.Scan() + if success == false { + // False on error or EOF. Check error + err = scanner.Err() + if err == nil { + log.Println("Scan completed and reached EOF") + } else { + log.Fatal(err) + } + } + + // Get data from scan with Bytes() or Text() + fmt.Println("First word found:", scanner.Text()) + + // Call scanner.Scan() again to find next token +} diff --git a/impl/files-manipulation/23-ArchiveFiles.go b/impl/files-manipulation/23-ArchiveFiles.go new file mode 100644 index 00000000..e9a5991b --- /dev/null +++ b/impl/files-manipulation/23-ArchiveFiles.go @@ -0,0 +1,61 @@ +// This example uses zip but standard library +// also supports tar archives +package main + +import ( + "archive/zip" + "log" + "os" +) + +func main() { + + /* + Archive Files + */ + + // Create a file to write the archive buffer to + // Could also use an in memory buffer. + outFile, err := os.Create("test.zip") + if err != nil { + log.Fatal(err) + } + defer outFile.Close() + + // Create a zip writer on top of the file writer + zipWriter := zip.NewWriter(outFile) + + // Add files to archive + // We use some hard coded data to demonstrate, + // but you could iterate through all the files + // in a directory and pass the name and contents + // of each file, or you can take data from your + // program and write it write in to the archive + // without + var filesToArchive = []struct { + Name, Body string + }{ + {"test.txt", "String contents of file"}, + {"test2.txt", "\x61\x62\x63\n"}, + } + + // Create and write files to the archive, which in turn + // are getting written to the underlying writer to the + // .zip file we created at the beginning + for _, file := range filesToArchive { + fileWriter, err := zipWriter.Create(file.Name) + if err != nil { + log.Fatal(err) + } + _, err = fileWriter.Write([]byte(file.Body)) + if err != nil { + log.Fatal(err) + } + } + + // Clean up + err = zipWriter.Close() + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/24-ExtractFiles.go b/impl/files-manipulation/24-ExtractFiles.go new file mode 100644 index 00000000..b2df4285 --- /dev/null +++ b/impl/files-manipulation/24-ExtractFiles.go @@ -0,0 +1,64 @@ +package main + +import ( + "archive/zip" + "io" + "log" + "os" + "path/filepath" +) + +func main() { + + /* + Extract Archived Files + */ + + // Create a reader out of the zip archive + zipReader, err := zip.OpenReader("test.zip") + if err != nil { + log.Fatal(err) + } + defer zipReader.Close() + + // Iterate through each file/dir found in + for _, file := range zipReader.Reader.File { + // Open the file inside the zip archive + // like a normal file + zippedFile, err := file.Open() + if err != nil { + log.Fatal(err) + } + defer zippedFile.Close() + + targetDir := "./" + extractedFilePath := filepath.Join( + targetDir, + file.Name, + ) + + if file.FileInfo().IsDir() { + log.Println("Creating directory:", extractedFilePath) + os.MkdirAll(extractedFilePath, file.Mode()) + } else { + // Extract regular file since not a directory + log.Println("Extracting file:", file.Name) + + // Open an output file for writing + outputFile, err := os.OpenFile( + extractedFilePath, + os.O_WRONLY|os.O_CREATE|os.O_TRUNC, + file.Mode(), + ) + if err != nil { + log.Fatal(err) + } + defer outputFile.Close() + + _, err = io.Copy(outputFile, zippedFile) + if err != nil { + log.Fatal(err) + } + } + } +} diff --git a/impl/files-manipulation/25-CompressFile.go b/impl/files-manipulation/25-CompressFile.go new file mode 100644 index 00000000..2b1adf93 --- /dev/null +++ b/impl/files-manipulation/25-CompressFile.go @@ -0,0 +1,30 @@ +package main + +import ( + "compress/gzip" + "log" + "os" +) + +func main() { + + /* + Compress a File + */ + + // Create .gz file to write to + outputFile, err := os.Create("test.txt.gz") + if err != nil { + log.Fatal(err) + } + + gzipWriter := gzip.NewWriter(outputFile) + defer gzipWriter.Close() + + _, err = gzipWriter.Write([]byte("Gophers rule!\n")) + if err != nil { + log.Fatal(err) + } + + log.Println("Compressed data written to file.") +} diff --git a/impl/files-manipulation/26-DecompressFile.go b/impl/files-manipulation/26-DecompressFile.go new file mode 100644 index 00000000..fd775c7d --- /dev/null +++ b/impl/files-manipulation/26-DecompressFile.go @@ -0,0 +1,39 @@ +package main + +import ( + "compress/gzip" + "io" + "log" + "os" +) + +func main() { + + /* + Uncompress a File + Uncompress means = never compressed + Decompress correct word. + */ + + gzipFile, err := os.Open("test.txt.gz") + if err != nil { + log.Fatal(err) + } + + gzipReader, err := gzip.NewReader(gzipFile) + if err != nil { + log.Fatal(err) + } + defer gzipReader.Close() + + outfileWriter, err := os.Create("unzipped.txt") + if err != nil { + log.Fatal(err) + } + defer outfileWriter.Close() + + _, err = io.Copy(outfileWriter, gzipReader) + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/27-TempFilesAndDirs.go b/impl/files-manipulation/27-TempFilesAndDirs.go new file mode 100644 index 00000000..0d48340f --- /dev/null +++ b/impl/files-manipulation/27-TempFilesAndDirs.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" +) + +func main() { + + /* + Temporary Files and Directories + */ + + // Create a temp dir in the system default temp folder + tempDirPath, err := ioutil.TempDir("", "myTempDir") + if err != nil { + log.Fatal(err) + } + fmt.Println("Temp dir created:", tempDirPath) + + // Create a file in new temp directory + tempFile, err := ioutil.TempFile(tempDirPath, "myTempFile.txt") + if err != nil { + log.Fatal(err) + } + fmt.Println("Temp file created:", tempFile.Name()) + + // ... do something with temp file/dir ... + + // Close file + err = tempFile.Close() + if err != nil { + log.Fatal(err) + } + + // Delete the resources we created + err = os.Remove(tempFile.Name()) + if err != nil { + log.Fatal(err) + } + err = os.Remove(tempDirPath) + if err != nil { + log.Fatal(err) + } +} diff --git a/impl/files-manipulation/28-DownloadFileOverHTTP.go b/impl/files-manipulation/28-DownloadFileOverHTTP.go new file mode 100644 index 00000000..3ee2e688 --- /dev/null +++ b/impl/files-manipulation/28-DownloadFileOverHTTP.go @@ -0,0 +1,33 @@ +package main + +import ( + "io" + "log" + "net/http" + "os" +) + +func main() { + + /* + Downloading a File Over HTTP + */ + + // Create output file + newFile, err := os.Create("courses.html") + if err != nil { + log.Fatal(err) + } + defer newFile.Close() + + // HTTP GET request dijibil.com + url := "http://www.dijibil.com/courses" + response, err := http.Get(url) + defer response.Body.Close() + + numBytesWritten, err := io.Copy(newFile, response.Body) + if err != nil { + log.Fatal(err) + } + log.Printf("Downloaded %d byte file.\n", numBytesWritten) +} diff --git a/impl/files-manipulation/29-HashAndChecksum.go b/impl/files-manipulation/29-HashAndChecksum.go new file mode 100644 index 00000000..0b5fbb55 --- /dev/null +++ b/impl/files-manipulation/29-HashAndChecksum.go @@ -0,0 +1,30 @@ +package main + +import ( + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "fmt" + "io/ioutil" + "log" +) + +func main() { + + /* + Hashing and Checksums + */ + + // Get bytes from file + data, err := ioutil.ReadFile("test.txt") + if err != nil { + log.Fatal(err) + } + + // Hash the file and output results + fmt.Printf("Md5: %x\n\n", md5.Sum(data)) + fmt.Printf("Sha1: %x\n\n", sha1.Sum(data)) + fmt.Printf("Sha256: %x\n\n", sha256.Sum256(data)) + fmt.Printf("Sha512: %x\n\n", sha512.Sum512(data)) +} diff --git a/impl/files-manipulation/30-HasAndChecksum2.go b/impl/files-manipulation/30-HasAndChecksum2.go new file mode 100644 index 00000000..13875b83 --- /dev/null +++ b/impl/files-manipulation/30-HasAndChecksum2.go @@ -0,0 +1,33 @@ +package main + +import ( + "crypto/md5" + "fmt" + "io" + "log" + "os" +) + +func main() { + + /* + Hashing and Checksums + */ + + // Open file for reading + file, err := os.Open("test.txt") + if err != nil { + log.Fatal(err) + } + defer file.Close() + + // Create new hasher, which is a writer interface + hasher := md5.New() + _, err = io.Copy(hasher, file) + if err != nil { + log.Fatal(err) + } + + sum := hasher.Sum(nil) + fmt.Printf("Md5 checksum: %x\n", sum) +} diff --git a/impl/files-manipulation/COPYRIGHT.md b/impl/files-manipulation/COPYRIGHT.md new file mode 100644 index 00000000..375243e7 --- /dev/null +++ b/impl/files-manipulation/COPYRIGHT.md @@ -0,0 +1 @@ +Original Repo By Cihan Özhan