From 06ee65d9e59a0515aac08ca670854df8ae86f236 Mon Sep 17 00:00:00 2001 From: "Oleg A. Glushko" <44775781+oleg-glushko@users.noreply.github.com> Date: Fri, 29 Mar 2019 07:49:20 +1000 Subject: [PATCH] Please, merge my PowerShell examples for all chapters (#106) * PowerShell 01_introduction_to_algorithms example * PowerShell 02_selection_sort example * PowerShell 03_recursion examples * PowerShell 04_quicksort examples * PowerShell 05_hash_tables examples * PowerShell 06_breadth-first_search example * PowerShell 07_dijkstras_algorithm example * PowerShell 08_greedy_algorithms example * Powershell 09_dynamic_programming example --- .../PowerShell/01_binary_search.ps1 | 39 +++++++++ .../PowerShell/01_selection_sort.ps1 | 35 ++++++++ 03_recursion/PowerShell/01_countdown.ps1 | 17 ++++ 03_recursion/PowerShell/02_greet.ps1 | 21 +++++ 03_recursion/PowerShell/03_factorial.ps1 | 14 ++++ 04_quicksort/PowerShell/01_loop_sum.ps1 | 12 +++ 04_quicksort/PowerShell/02_recursive_sum.ps1 | 12 +++ .../PowerShell/03_recursive_count.ps1 | 11 +++ 04_quicksort/PowerShell/04_recursive_max.ps1 | 27 +++++++ 04_quicksort/PowerShell/05_quicksort.ps1 | 28 +++++++ .../PowerShell/01_price_of_groceries.ps1 | 2 + 05_hash_tables/PowerShell/02_check_voter.ps1 | 18 +++++ .../PowerShell/01_breadth-first_search.ps1 | 46 +++++++++++ .../PowerShell/01_dijkstras_algorithm.ps1 | 80 +++++++++++++++++++ .../PowerShell/01_set_covering.ps1 | 42 ++++++++++ .../01_longest_common_subsequence.ps1 | 32 ++++++++ 16 files changed, 436 insertions(+) create mode 100644 01_introduction_to_algorithms/PowerShell/01_binary_search.ps1 create mode 100644 02_selection_sort/PowerShell/01_selection_sort.ps1 create mode 100644 03_recursion/PowerShell/01_countdown.ps1 create mode 100644 03_recursion/PowerShell/02_greet.ps1 create mode 100644 03_recursion/PowerShell/03_factorial.ps1 create mode 100644 04_quicksort/PowerShell/01_loop_sum.ps1 create mode 100644 04_quicksort/PowerShell/02_recursive_sum.ps1 create mode 100644 04_quicksort/PowerShell/03_recursive_count.ps1 create mode 100644 04_quicksort/PowerShell/04_recursive_max.ps1 create mode 100644 04_quicksort/PowerShell/05_quicksort.ps1 create mode 100644 05_hash_tables/PowerShell/01_price_of_groceries.ps1 create mode 100644 05_hash_tables/PowerShell/02_check_voter.ps1 create mode 100644 06_breadth-first_search/PowerShell/01_breadth-first_search.ps1 create mode 100644 07_dijkstras_algorithm/PowerShell/01_dijkstras_algorithm.ps1 create mode 100644 08_greedy_algorithms/PowerShell/01_set_covering.ps1 create mode 100644 09_dynamic_programming/PowerShell/01_longest_common_subsequence.ps1 diff --git a/01_introduction_to_algorithms/PowerShell/01_binary_search.ps1 b/01_introduction_to_algorithms/PowerShell/01_binary_search.ps1 new file mode 100644 index 0000000..db8ebae --- /dev/null +++ b/01_introduction_to_algorithms/PowerShell/01_binary_search.ps1 @@ -0,0 +1,39 @@ +function Search-GRKBinary +{ + param ($list, $item) + + # $low and $high keep track of which part of the list you'll search in. + $low = 0; + $high = $list.Length - 1; + + # While you haven't narrowed it down to one element ... + while ($low -le $high) + { + # ... check the middle element + $mid = [int](($low + $high) / 2); + $guess = $list[$mid]; + # Found the item. + if ($guess -eq $item) + { + return $mid; + } + # The guess was too high. + if ($guess -gt $item) + { + $high = $mid - 1 + } + # The guess was too low + else + { + $low = $mid + 1 + } + + } + + # Item doesn't exist + return $null; +} + +$mylist = (1, 3, 5, 7, 9); +Search-GRKBinary $mylist 3 # => 1 +Search-GRKBinary $mylist -1 # => $null \ No newline at end of file diff --git a/02_selection_sort/PowerShell/01_selection_sort.ps1 b/02_selection_sort/PowerShell/01_selection_sort.ps1 new file mode 100644 index 0000000..cb5ab99 --- /dev/null +++ b/02_selection_sort/PowerShell/01_selection_sort.ps1 @@ -0,0 +1,35 @@ +# Finds the smallest value in an array +function Find-GRKSmallest +{ + param ($arr) + # Stores the smallest value + $smallest = $arr[0] + # Stores the index of the smallest value + $smallest_index = 0 + 0 .. ($arr.count - 1) | ForEach-Object { + if ($arr[$_] -lt $smallest) { + $smallest_index = $_ + $smallest = $arr[$_] + } + } + return $smallest_index +} + +# Sort array +function Sort-GRKSelection +{ + param ($arr) + $newArr = New-Object System.Collections.Generic.List[System.Object] + 1 .. $arr.count | ForEach-Object { + # Finds the smallest element in the array and adds it to the new array + $smallest = Find-GRKSmallest $arr + $newArr.Add($arr[$smallest]) + $arr.RemoveAt($smallest) + } + return $NewArr +} + +# Can't use a default "@()" range notation as it creates static arrays +$arr = New-Object System.Collections.Generic.List[System.Object] +$arr.AddRange((5, 3, 6, 2, 10)) +Sort-GRKSelection $arr \ No newline at end of file diff --git a/03_recursion/PowerShell/01_countdown.ps1 b/03_recursion/PowerShell/01_countdown.ps1 new file mode 100644 index 0000000..a2dbec7 --- /dev/null +++ b/03_recursion/PowerShell/01_countdown.ps1 @@ -0,0 +1,17 @@ +function Write-GRKCountdown +{ + param ($i) + # base case + if ($i -le 0) + { + return 0 + } + # recursive case + else + { + write-Host($i) + return Write-GRKCountdown($i-1) + } +} + +Write-GRKCountdown 5 \ No newline at end of file diff --git a/03_recursion/PowerShell/02_greet.ps1 b/03_recursion/PowerShell/02_greet.ps1 new file mode 100644 index 0000000..f562d41 --- /dev/null +++ b/03_recursion/PowerShell/02_greet.ps1 @@ -0,0 +1,21 @@ +function Write-GRKGreet2 +{ + param ($name) + Write-Host("how are you, " + $name + "?") +} + +function Write-GRKBye +{ + Write-Host "ok bye!" +} + +function Write-GRKGreet +{ + param($name) + Write-Host("hello, " + $name + "!") + Write-GRKGreet2 $name + Write-Host "getting ready to say bye..." + Write-GRKBye +} + +Write-GRKGreet adit \ No newline at end of file diff --git a/03_recursion/PowerShell/03_factorial.ps1 b/03_recursion/PowerShell/03_factorial.ps1 new file mode 100644 index 0000000..74f9662 --- /dev/null +++ b/03_recursion/PowerShell/03_factorial.ps1 @@ -0,0 +1,14 @@ +function Get-GRKFact +{ + param ($x) + if ($x -eq 1) + { + return 1 + } + else + { + return $x * (Get-GRKFact ($x-1)) + } +} + +Get-GRKFact 5 \ No newline at end of file diff --git a/04_quicksort/PowerShell/01_loop_sum.ps1 b/04_quicksort/PowerShell/01_loop_sum.ps1 new file mode 100644 index 0000000..da0544d --- /dev/null +++ b/04_quicksort/PowerShell/01_loop_sum.ps1 @@ -0,0 +1,12 @@ +function Get-GRKSum +{ + param($arr) + $total = 0 + foreach ($x in $arr) + { + $total += $x + } + return $total +} + +Get-GRKSum (1, 2, 3, 4) \ No newline at end of file diff --git a/04_quicksort/PowerShell/02_recursive_sum.ps1 b/04_quicksort/PowerShell/02_recursive_sum.ps1 new file mode 100644 index 0000000..903fde9 --- /dev/null +++ b/04_quicksort/PowerShell/02_recursive_sum.ps1 @@ -0,0 +1,12 @@ +function Get-GRKSum +{ + param($list) + if ($list -eq $null) + { + return 0 + } + return $list[0] + (Get-GRKSum ($list | Select-Object -Skip 1)) + +} + +Get-GRKSum (1, 2, 3, 4) \ No newline at end of file diff --git a/04_quicksort/PowerShell/03_recursive_count.ps1 b/04_quicksort/PowerShell/03_recursive_count.ps1 new file mode 100644 index 0000000..1903436 --- /dev/null +++ b/04_quicksort/PowerShell/03_recursive_count.ps1 @@ -0,0 +1,11 @@ +function Get-GRKCount +{ + param($list) + if ($list -eq $null) + { + return 0 + } + return 1 + (Get-GRKCount ($list | Select-Object -Skip 1)) +} + +Get-GRKCount ("one", "two", "three", "four") \ No newline at end of file diff --git a/04_quicksort/PowerShell/04_recursive_max.ps1 b/04_quicksort/PowerShell/04_recursive_max.ps1 new file mode 100644 index 0000000..78437c1 --- /dev/null +++ b/04_quicksort/PowerShell/04_recursive_max.ps1 @@ -0,0 +1,27 @@ +function Get-GRKMax +{ + param($lst) + if ($lst.count -eq 0) + { + return $null + } + if ($lst.count -eq 1) + { + return $lst[0] + } + else + { + $sub_max = Get-GRKMax ($lst | Select-Object -Skip 1) + if ($lst[0] -gt $sub_max) + { + return $lst[0] + } + else + { + return $sub_max + } + } +} + + +Get-GRKMax (33, 7, 6, 100, 15, 13) \ No newline at end of file diff --git a/04_quicksort/PowerShell/05_quicksort.ps1 b/04_quicksort/PowerShell/05_quicksort.ps1 new file mode 100644 index 0000000..697ffd3 --- /dev/null +++ b/04_quicksort/PowerShell/05_quicksort.ps1 @@ -0,0 +1,28 @@ +function Get-GRKQuickSort +{ + param($array) + if ($array.count -lt 2) + { + # base case, arrays with 0 or 1 element are already "sorted" + if ($null -ne $array) + { + return , $array + } + else + { + return $null + } + } + else + { + # recursive case + $pivot = $array[0] + # sub-array of all the elements less than the pivot + $less = @($array | Select-Object -Skip 1 | Where-Object {$_ -le $pivot}) + # sub-array of all the elements greater than the pivot + $greater = @($array | Select-Object -Skip 1 | Where-Object {$_ -gt $pivot}) + return @((Get-GRKQuickSort $less) + , $pivot + (Get-GRKQuickSort $greater)) + } +} + +Get-GRKQuickSort (5, 3, 6, 2, 10) \ No newline at end of file diff --git a/05_hash_tables/PowerShell/01_price_of_groceries.ps1 b/05_hash_tables/PowerShell/01_price_of_groceries.ps1 new file mode 100644 index 0000000..e719ca0 --- /dev/null +++ b/05_hash_tables/PowerShell/01_price_of_groceries.ps1 @@ -0,0 +1,2 @@ +$book = @{"apple" = 0.6; "milk" = 1.49; "avocado" = 1.49} +Write-Host ($book | Out-String) \ No newline at end of file diff --git a/05_hash_tables/PowerShell/02_check_voter.ps1 b/05_hash_tables/PowerShell/02_check_voter.ps1 new file mode 100644 index 0000000..57065c8 --- /dev/null +++ b/05_hash_tables/PowerShell/02_check_voter.ps1 @@ -0,0 +1,18 @@ +$voted = @{} +function Check-GRKVoter +{ + param($name) + if ($voted.Contains($name)) + { + Write-Host "kick them out!" + } + else + { + $voted[$name] = $True + Write-Host "let them vote!" + } +} + +Check-GRKVoter tom +Check-GRKVoter mike +Check-GRKVoter mike \ No newline at end of file diff --git a/06_breadth-first_search/PowerShell/01_breadth-first_search.ps1 b/06_breadth-first_search/PowerShell/01_breadth-first_search.ps1 new file mode 100644 index 0000000..9d9ad1e --- /dev/null +++ b/06_breadth-first_search/PowerShell/01_breadth-first_search.ps1 @@ -0,0 +1,46 @@ +$graph = @{} +$graph["you"] = @("alice", "bob", "claire") +$graph["bob"] = @("anuj", "peggy") +$graph["alice"] = @("peggy") +$graph["claire"] = @("thom", "jonny") +$graph["anuj"] = @() +$graph["peggy"] = @() +$graph["thom"] = @() +$graph["jonny"] = @() + +function Test-GRKPersonIsSeller +{ + param($name) + return $name[-1] -eq 'm' +} + +function Search-GRKPerson +{ + param($name) + $search_queue = New-Object System.Collections.Queue + $graph[$name] | % {$search_queue.Enqueue($_)} + # This array is how you keep track of which people you've searched before. + $searched = New-Object System.Collections.Generic.List[System.Object] + while ($search_queue.count -gt 0) { + $person = $search_queue.Dequeue() + # Only search this person if you haven't already searched them. + if ($person -notin $searched) + { + if (Test-GRKPersonIsSeller($person)) + { + Write-Host($person + " is a mango seller!") + return $True + } + else + { + $graph[$person] | % {$search_queue.Enqueue($_)} + # Marks this person as searched + $searched.Add($person) + } + + } + } + return $False +} + +Search-GRKPerson you \ No newline at end of file diff --git a/07_dijkstras_algorithm/PowerShell/01_dijkstras_algorithm.ps1 b/07_dijkstras_algorithm/PowerShell/01_dijkstras_algorithm.ps1 new file mode 100644 index 0000000..80c90e4 --- /dev/null +++ b/07_dijkstras_algorithm/PowerShell/01_dijkstras_algorithm.ps1 @@ -0,0 +1,80 @@ +$infinity = [float]::PositiveInfinity + +# the graph +$graph = @{} +$graph["start"] = @{} +$graph["start"]["a"] = 6 +$graph["start"]["b"] = 2 + +$graph["a"] = @{} +$graph["a"]["fin"] = 1 + +$graph["b"] = @{} +$graph["b"]["a"] = 3 +$graph["b"]["fin"] = 5 + +$graph["fin"] = @{} + +# the costs table +$costs = [ordered]@{} +$costs["a"] = 6 +$costs["b"] = 2 +$costs["fin"] = $infinity + +# the parents table +$parents = [ordered]@{} +$parents["a"] = "start" +$parents["b"] = "start" +$parents["fin"] = $null + +$processed = New-Object System.Collections.Generic.HashSet[String] + +function Find-GRKLowestCostNode +{ + param ($costs) + $lowest_cost = $infinity + $lowest_cost_node = $null + # Go through each node. + foreach ($node in $costs.GetEnumerator()) + { + $cost = $costs[$node.key] + # If it's the lowest cost so far and hasn't been processed yet... + if (($cost -lt $lowest_cost) -and ($node.key -notin $processed)) + { + # ... set it as the new lowest-cost node. + $lowest_cost = $cost + $lowest_cost_node = $node + } + } + return $lowest_cost_node +} + +# Find the lowest-cost node that you haven't processed yet. +$node = Find-GRKLowestCostNode $costs +$i = 0 +# If you've processed all the nodes, this while loop is done. +while ($node -ne $null) +{ + $i++ + $cost = $costs[$node.Key] + $neighbors = $graph[$node.Key] + foreach ($n in $neighbors.Keys) + { + $new_cost = $cost + $neighbors[$n] + # If it's cheaper to get to this neighbor by going through this node... + if ($costs[$n] -gt $new_cost) + { + # ... update the cost for this node. + $costs[$n] = $new_cost + # This node becomes the new parent for this neighbor. + $parents[$n] = $node.Key + } + } + # Mark the node as processed. + $processed.Add($node.Key) >$null + # Find the next node to process, and loop. + $node = Find-GRKLowestCostNode $costs +} + +Write-Host "Cost from the start to each node:" +Write-Host ($costs | Out-String) \ No newline at end of file diff --git a/08_greedy_algorithms/PowerShell/01_set_covering.ps1 b/08_greedy_algorithms/PowerShell/01_set_covering.ps1 new file mode 100644 index 0000000..8e13f5c --- /dev/null +++ b/08_greedy_algorithms/PowerShell/01_set_covering.ps1 @@ -0,0 +1,42 @@ +# You pass an array in, and it gets converted to a set. +$states_needed = New-Object System.Collections.Generic.HashSet[string] -ArgumentList ` + (, [string[]]("mt", "wa", "or", "id", "nv", "ut", "ca", "az")) + +$stations = [ordered]@{} +$stations["kone"] = New-Object System.Collections.Generic.HashSet[string] -ArgumentList ` + (, [string[]]("id", "nv", "ut")) +$stations["ktwo"] = New-Object System.Collections.Generic.HashSet[string] -ArgumentList ` + (, [string[]]("wa", "id", "mt")) +$stations["kthree"] = New-Object System.Collections.Generic.HashSet[string] -ArgumentList ` + (, [string[]]("or", "nv", "ca")) +$stations["kfour"] = New-Object System.Collections.Generic.HashSet[string] -ArgumentList ` + (, [string[]]("nv", "ut")) +$stations["kfive"] = New-Object System.Collections.Generic.HashSet[string] -ArgumentList ` + (, [string[]]("ca", "az")) + +$final_stations = New-Object System.Collections.Generic.HashSet[string] + +while ($states_needed.Count -gt 0) +{ + $best_station = $null + $states_covered = New-Object System.Collections.Generic.HashSet[string] + foreach ($station in $stations.GetEnumerator()) { + $covered = New-Object System.Collections.Generic.HashSet[string] + # The .IntersectWith method deletes entries from the object so we need a temporary + # copy, should work in .NET 4.6+ + $states_needed_inter = New-Object System.Collections.Generic.HashSet[string] $states_needed, $states_needed.Comparer + $states_needed_inter.IntersectWith($station.value) + $states_needed_inter | % {$covered.Add($_) >$null} + if ($covered.count -gt $states_covered.count) + { + $best_station = $station.Key + # See the previous comment + $states_covered = New-Object System.Collections.Generic.HashSet[string] $covered, $covered.Comparer + } + } + + $states_covered | % {$states_needed.Remove($_) >$null} + $final_stations.Add($best_station) >$null +} + +Write-Host $final_stations \ No newline at end of file diff --git a/09_dynamic_programming/PowerShell/01_longest_common_subsequence.ps1 b/09_dynamic_programming/PowerShell/01_longest_common_subsequence.ps1 new file mode 100644 index 0000000..9081c15 --- /dev/null +++ b/09_dynamic_programming/PowerShell/01_longest_common_subsequence.ps1 @@ -0,0 +1,32 @@ +$word_a = "fish" +$word_b = "vista" + +# Init the empty two-dimensional array +$cell = @() +for ($i = 0; $i -lt $word_a.Length; $i++) +{ + $list = @() + for ($j = 0; $j -lt $word_b.Length; $j++) + { + $list += , 0 + } + $cell += , $list +} + +for ($i = 0; $i -lt $word_a.Length; $i++) +{ + for ($j = 0; $j -lt $word_b.Length; $j++) + { + if ($word_a[$i] -eq $word_b[$j]) { + # The letters match. + $cell[$i][$j] = $cell[$i-1][$j-1] + 1 + } + else + { + # The letters don't match. + $cell[$i][$j] = 0 + } + } +} + +0..($cell.count-1) | ForEach-Object {Write-Host $cell[$_] -Separator `t} \ No newline at end of file