Browse Source

Add algorithm pages

master
Riyyi 2 weeks ago
parent
commit
48d768d53b
  1. 158
      content/articles/dijkstras-shortest-path.md
  2. 170
      content/articles/fizzbuzz.md
  3. 152
      content/articles/invert-binary-tree.md
  4. 65
      content/articles/sieve-of-eratosthenes.md
  5. 2
      nuxt.config.ts
  6. BIN
      public/img/algorithms/dijkstras-shortest-path.png
  7. BIN
      public/img/algorithms/invert-binary-tree.png
  8. BIN
      public/img/algorithms/sieve-of-eratosthenes.gif
  9. 4
      src/components/articles/overview.vue
  10. 2
      src/pages/algorithms.vue

158
content/articles/dijkstras-shortest-path.md

@ -0,0 +1,158 @@
---
title: "Dijkstra's Shortest Path"
description: "Dijkstra's shortest path."
navigation: false
date: "2021-03-02 02:31:20"
img: "/img/algorithms/dijkstras-shortest-path.png"
tags:
- Algorithm
---
Implementation of the shortest path algorithm, invented by Dijkstra.
```python
#!/usr/bin/python
import os
import time
# List of all the cities
cities = [
"Ab'Dendriel",
"Ankrahmun",
"Carlin",
"Darashia",
"Edron",
"Liberty Bay",
"Port Hope",
"Roshamuul",
"Oramond",
"Svargrond",
"Thais",
"Venore",
"Yalahar",
"Krailos",
"Issavi",
"Cormaya",
]
# Possible boat fares
fares = [
[None, None, 80, None, 70, None, None, None, None, None, 130, 90, 160, None, None, None], # Ab'Dendriel
[None, None, None, 100, 160, 90, 80, None, None, None, None, 150, 230, None, None, None], # Ankrahmun
[ 80, None, None, None, 110, None, None, None, None, 110, 110, 130, 185, None, None, None], # Carlin
[None, 100, None, None, None, 200, 180, None, None, None, None, 60, 210, 110, 130, None], # Darashia
[ 70, 160, 110, None, None, 170, 150, None, None, None, 160, 40, None, 100, None, 20], # Edron
[None, 90, None, 200, 170, None, 50, None, None, None, 180, 180, 275, None, None, None], # Liberty Bay
[None, 110, None, 180, 150, 50, None, None, None, None, 160, 160, 260, None, None, None], # Port Hope
[None, None, None, None, None, None, None, None, None, None, 210, None, None, None, None, None], # Roshamuul
[None, None, None, None, 110, None, 200, None, None, None, 150, 130, None, 60, 120, None], # Oramond
[None, None, 110, None, None, None, None, None, None, None, 180, 150, None, None, None, None], # Svargrond
[ 130, None, 110, None, 160, 180, 160, 210, 150, 180, None, 170, 200, None, None, None], # Thais
[ 90, 150, 130, 60, 40, 180, 160, None, None, 150, 170, None, 185, 110, 130, None], # Venore
[ 160, 230, 185, 210, None, 275, 260, None, None, None, 200, 185, None, None, None, None], # Yalahar
[None, None, None, 110, 100, None, None, None, 60, None, None, 110, None, None, 70, None], # Krailos
[None, None, None, 80, None, None, None, None, 100, None, None, 80, None, 80, None, None], # Issavi
[None, None, None, None, 20, None, None, None, None, None, None, None, None, None, None, None], # Cormaya
]
# Say phrase
def say(string):
time.sleep(0.2)
os.system('xdotool key Return')
os.system('xdotool keydown Alt')
os.system('xdotool type "' + string + '"')
os.system('xdotool keyup Alt')
os.system('xdotool key Return')
# Say fare
def typeFare(city):
say("hi")
time.sleep(1.0)
say(city)
say("yes")
def dijkstraShortestPath(sourceVertex):
explored = []
unexplored = []
# Setup vertices
for i, fare in enumerate(fares[sourceVertex]):
unexplored.append([i, None, None])
# Set the source vertex distance to 0
if i == sourceVertex:
unexplored[-1][1] = 0
while len(unexplored) > 0:
# Select the closest vertex
closest = None
distance = None
for i, vertex in enumerate(unexplored):
if (distance == None and vertex[1] != None) or \
(vertex[1] != None and vertex[1] < distance):
closest = i
distance = vertex[1]
# Move the closest vertex to explored
explored.append(unexplored.pop(closest))
ID = explored[-1][0]
# Explore this vertex
for i, vertex in enumerate(unexplored):
# Is linked
if fares[ID][vertex[0]] != None:
# If it hasnt been set before
if vertex[1] == None:
vertex[1] = fares[ID][vertex[0]] + explored[-1][1]
vertex[2] = ID
# Or is cheaper
elif vertex[1] > fares[ID][vertex[0]] + explored[-1][1]:
vertex[1] = fares[ID][vertex[0]] + explored[-1][1]
vertex[2] = ID
return explored
def dijkstraTraversePath(sourceVertex, targetVertex, explored):
find = targetVertex
path = [targetVertex]
while find != sourceVertex:
for i, vertex in enumerate(explored):
if vertex[0] == find:
find = vertex[2]
path.append(vertex[2])
break
path.pop()
path.reverse()
return path
def main():
locations = '\n'.join(cities)
current = os.popen('echo "' + locations + '" | rofi -dmenu -i -p "Where are you now?"').read().rstrip()
destination = os.popen('echo "' + locations + '" | rofi -dmenu -i -p "Where are you going?"').read().rstrip()
if not current or not destination: return
currentIndex = cities.index(current)
destinationIndex = cities.index(destination)
# If a direct route is possible
if fares[currentIndex][destinationIndex] != None:
typeFare(destination)
return
# Calculate possible non-direct route
data = dijkstraShortestPath(currentIndex)
path = dijkstraTraversePath(currentIndex, destinationIndex, data)
for index in path:
typeFare(cities[index])
if __name__ == "__main__":
main()
```
Source:<br>
[Dijkstra Algorithm - Example (YouTube)](https://www.youtube.com/watch?v=JcN_nq1EAr4){ target=_blank }

170
content/articles/fizzbuzz.md

@ -0,0 +1,170 @@
---
title: "FizzBuzz"
description: "FizzBuzz."
navigation: false
date: "2021-03-02 02:31:02"
tags:
- Algorithm
---
Implementation of the classic FizzBuzz interview question, done in two ways.
```cpp
#include <iostream>
void calculate()
{
for (int i = 1; i < 101; i++) {
if (i % 15 == 0) {
std::cout << "FizzBuzz" << std::endl;
}
else if (i % 5 == 0) {
std::cout << "Buzz" << std::endl;
}
else if (i % 3 == 0) {
std::cout << "Fizz" << std::endl;
}
else {
std::cout << i << std::endl;
}
}
}
void pattern()
{
const char* pattern[] = {
"%d\n",
"%d\n",
"Fizz\n",
"%d\n",
"Buzz\n",
"Fizz\n",
"%d\n",
"%d\n",
"Fizz\n",
"Buzz\n",
"%d\n",
"Fizz\n",
"%d\n",
"%d\n",
"FizzBuzz\n",
};
for (int i = 0; i < 100; i++) {
printf(pattern[i % 15], i + 1);
}
}
int main(int argc, char* argv[])
{
calculate();
pattern();
return 0;
}
```
Output (x2):
```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
```

152
content/articles/invert-binary-tree.md

@ -0,0 +1,152 @@
---
title: "Invert Binary Tree"
description: "Invert binary tree."
navigation: false
date: "2021-03-02 02:31:09"
img: "/img/algorithms/invert-binary-tree.png"
tags:
- Algorithm
---
Implementation of inverting a binary tree.
binarytree.h
```cpp
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <cstdint>
class BinaryTree {
public:
// Contructors, Destructors
BinaryTree(uint32_t value, BinaryTree* left = nullptr,
BinaryTree* right = nullptr);
// Functions
void print();
void invert();
// Getters, Setters
inline uint32_t value() { return m_value; }
private:
uint32_t m_value;
BinaryTree* m_left;
BinaryTree* m_right;
};
#endif // BINARYTREE_H
```
binarytree.cpp
```c
#include <iomanip>
#include <iostream>
#include <string>
#include "binarytree.h"
BinaryTree::BinaryTree(uint32_t value, BinaryTree *left, BinaryTree *right)
: m_value(value), m_left(left), m_right(right) {}
void BinaryTree::print()
{
// Skip nodes without children
if (!m_left && !m_right) {
return;
}
// Value
std::cout << std::setw(2) << m_value << " -> ";
// Left
std::cout << std::setw(2) << (m_left ? std::to_string(m_left->value()) : "") << " | ";
// Right
std::cout << (m_right ? std::to_string(m_right->value()) : "") << std::endl;
// Recursion
if (m_left) {
m_left->print();
}
if (m_right) {
m_right->print();
}
}
void BinaryTree::invert()
{
// Swap
BinaryTree* tmp = m_left;
m_left = m_right;
m_right = tmp;
// Recursion
if (m_left) {
m_left->invert();
}
if (m_right) {
m_right->invert();
}
}
```
main.cpp
```cpp
#include <iostream>
#include "binarytree.h"
int main(int argc, char* argv[])
{
(void) argc;
(void) argv;
BinaryTree n3(3);
BinaryTree n9(9);
BinaryTree n13(13);
BinaryTree n4(4, &n3);
BinaryTree n6(6);
BinaryTree n8(8, nullptr, &n9);
BinaryTree n12(12, nullptr, &n13);
BinaryTree n5(5, &n4, &n6);
BinaryTree n10(10, &n8, &n12);
BinaryTree n7(7, &n5, &n10);
std::cout << std::endl << "Binary Tree:" << std::endl;
n7.print();
n7.invert();
std::cout << std::endl << "Binary Tree Inverted:" << std::endl;
n7.print();
return 0;
}
```
Output:
```
Binary Tree:
7 -> 5 | 10
5 -> 4 | 6
4 -> 3 |
10 -> 8 | 12
8 -> | 9
12 -> | 13
Binary Tree Inverted:
7 -> 10 | 5
10 -> 12 | 8
12 -> 13 |
8 -> 9 |
5 -> 6 | 4
4 -> | 3
```
Source:<br>
[Binary Search Trees in Java (YouTube)](https://www.youtube.com/watch?v=Qa5r8Wsda70){ target=_blank }

65
content/articles/sieve-of-eratosthenes.md

@ -0,0 +1,65 @@
---
title: "Sieve of Eratosthenes"
description: "Sieve of Eratosthenes."
navigation: false
date: "2021-03-02 02:31:16"
img: "/img/algorithms/sieve-of-eratosthenes.gif"
tags:
- Algorithm
---
Implementation of the ancient sieve of Eratosthenes math algorithm, used for
finding prime numbers up to a given limit.
```c
#include <stdbool.h> // bool
#include <stdio.h> // printf
#include <string.h> // memset
int main(int argc, char* argv[]) {
int limit = 10000;
int calculate = limit * 20;
// Create an array and set all to true
bool numbers[calculate];
memset(&numbers, true, sizeof(bool) * calculate);
// Loop through all the numbers
for (int i = 2; i < calculate; i++) {
// Already crossed out numbers don't have to be checked
if (numbers[i]) {
// Cross out all the numbers that can't be a prime, which are multiples of itself
for (int j = i * i; j < calculate; j += i) {
numbers[j] = false;
}
// Once you exceed the calculate range, you can exit the loop
if (i * i > calculate) {
break;
}
}
}
int sum = 0;
int counter = 1;
// Get the sum of the first 10000 primes
for (int i = 2; i < calculate; i++) {
if (numbers[i]) {
sum += i;
if (counter >= limit) {
break;
}
counter++;
}
}
printf("sum of first %d primes is: %d\n", counter, sum);
return 0;
}
```
Source:<br>
[https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes){ target=_blank }

2
nuxt.config.ts

@ -15,7 +15,7 @@ export default defineNuxtConfig({
},
langs: [
// https://github.com/shikijs/shiki/blob/main/packages/langs/package.json
"c", "cpp", "css", "html", "js", "json", "lua", "md", "mdc", "php", "shell", "ts", "vue", "yaml"
"c", "cpp", "css", "html", "js", "json", "lua", "md", "mdc", "php", "python", "shell", "ts", "vue", "yaml"
]
},
toc: {

BIN
public/img/algorithms/dijkstras-shortest-path.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/img/algorithms/invert-binary-tree.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
public/img/algorithms/sieve-of-eratosthenes.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

4
src/components/articles/overview.vue

@ -1,6 +1,7 @@
<template>
<div>
<h1>{{ props.title }}</h1>
<p>{{ props.description }}</p>
<div class="row pt-5" v-for="article in props.articles" :key="article.path">
<div class="col-5 col-lg-4 col-xl-3">
@ -10,7 +11,7 @@
</NuxtLink>
</div>
<div class="col-7 col-lg-8 col-xl-9">
<NuxtLink v-if="article.img" :to="article.path">
<NuxtLink :to="article.path">
<h4 class="mb-0"><strong>{{ article.title }}</strong></h4>
</NuxtLink>
<p><i><small>{{ prettyDate(article.date) }}</small></i></p>
@ -54,6 +55,7 @@ import type { ContentCollectionItem } from "@nuxt/content"
const props = withDefaults(
defineProps<{
title?: string,
description?: string,
articles: ContentCollectionItem[] | null
}>(),
{

2
src/pages/algorithms.vue

@ -1,5 +1,5 @@
<template>
<ArticlesOverview title="Algorithms" :articles="articles" />
<ArticlesOverview title="Algorithms" description="My implementation of a few algorithms." :articles="articles" />
</template>
<script setup lang="ts">

Loading…
Cancel
Save