Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions courses/golang/ex01-downcase/downcase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package downcase

func Downcase(str string) (lowerStr string, err error) {

for _, char := range str {
if 65 <= char && char <= 90 {
lowerStr += string(char + 32)
} else {
lowerStr += string(char)
}
}

return lowerStr, nil
}
3 changes: 3 additions & 0 deletions courses/golang/ex01-downcase/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module downcase

go 1.17
118 changes: 118 additions & 0 deletions courses/golang/ex02-cipher/cipher.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,124 @@
package cipher

import (
"regexp"
"strings"
)

type Cipher interface {
Encode(string) string
Decode(string) string
}

type caesar struct{}

type shift struct {
offset int
}

type vigenere struct {
s string
}

func NewCaesar() Cipher {
return caesar{}
}

func NewShift(offset int) Cipher {
if offset == 0 || offset > 25 || offset < -25 {
return nil
}
return shift{offset: offset}
}

func NewVigenere(s string) Cipher {
r, _ := regexp.Compile("^[a-z]+$")
if !r.MatchString(s) {
return nil
}
for _, v := range s {
if v != 'a' {
return vigenere{s: s}
}
}
return nil
}

func (c caesar) Encode(s string) string {
s = ToCleanAndLower(s)
return string(shiftLetters([]byte(s), 3))
}

func (c caesar) Decode(s string) string {
return string(shiftLetters([]byte(s), 26-3))
}

func (sh shift) Encode(s string) string {
var offset byte
s = ToCleanAndLower(s)
if sh.offset < 0 {
offset = byte(sh.offset + 26)
} else {
offset = byte(sh.offset)
}
return string(shiftLetters([]byte(s), offset))
}

func (sh shift) Decode(s string) string {
var offset byte
if sh.offset > 0 {
offset = byte(26 - sh.offset)
} else {
offset = byte(-sh.offset)
}
return string(shiftLetters([]byte(s), offset))
}

func (v vigenere) Encode(s string) string {
s = ToCleanAndLower(s)
return string(translateLetters([]byte(s), []byte(v.s)))
}

func (v vigenere) Decode(s string) string {
keys := reverseKeys([]byte(v.s))
return string(translateLetters([]byte(s), keys))
}

func ToCleanAndLower(s string) string {
r, _ := regexp.Compile("[^A-z]+")
letterChunks := r.Split(s, -1)
cleanS := strings.Join(letterChunks, "")
newS := strings.ToLower(cleanS)
return newS
}

func shiftLetters(bytes []byte, offset byte) []byte {
for i := range bytes {
bytes[i] += offset
if bytes[i] > 'z' {
bytes[i] -= 26
}
}
return bytes
}

func translateLetters(bytes []byte, keys []byte) []byte {
key_num := len(keys)
for i := range bytes {
key := byte(keys[i%key_num] - 'a')
bytes[i] += key
if bytes[i] > 'z' {
bytes[i] -= 26
}
}
return bytes
}

func reverseKeys(bytes []byte) []byte {
for i := range bytes {
bytes[i] -= 'a'
bytes[i] = 26 - bytes[i]
bytes[i] += 'a'
}
return bytes
}
3 changes: 3 additions & 0 deletions courses/golang/ex02-cipher/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module cipher

go 1.17
3 changes: 3 additions & 0 deletions courses/golang/ex03-stack/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module stack

go 1.17
21 changes: 21 additions & 0 deletions courses/golang/ex03-stack/stack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package stack

type Stack struct {
items []int
}

func New() *Stack {
myStack := Stack{}
return &myStack
}

func (s *Stack) Push(i int) {
s.items = append(s.items, i)
}

func (s *Stack) Pop() int {
l := len(s.items) - 1
toRemove := s.items[l]
s.items = s.items[:l]
return toRemove
}
27 changes: 27 additions & 0 deletions courses/golang/ex04-brackets/bracket_push.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package brackets

func Bracket(s string) (bool, error) {
bracket := map[rune]rune{
'}': '{',
')': '(',
']': '[',
}
stack := make([]rune, 0)
for _, b := range s {
v, ok := bracket[b]
if ok {
length := len(stack)
if length > 0 && stack[length-1] == v {
stack = stack[:len(stack)-1]
} else {
return false, nil
}
} else {
stack = append(stack, b)
}
}
if len(stack) > 0 {
return false, nil
}
return true, nil
}
3 changes: 3 additions & 0 deletions courses/golang/ex04-brackets/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module brackets

go 1.17
3 changes: 3 additions & 0 deletions courses/golang/ex05-parallel/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module letter

go 1.17
28 changes: 28 additions & 0 deletions courses/golang/ex05-parallel/parrallel_letter_frequency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package letter

func Frequency(s string) map[rune]uint64 {
freq := make(map[rune]uint64)
for _, l := range s {
freq[l]++
}
return freq
}

func ConcurrentFrequency(ss []string) map[rune]uint64 {
allFreq := make(map[rune]uint64)
c := make(chan map[rune]uint64, len(ss))

for _, s := range ss {
go func(c chan map[rune]uint64, s string) {
c <- Frequency(s)
}(c, s)
}

for i := 0; i < len(ss); i++ {
freq := <-c
for k, v := range freq {
allFreq[k] += v
}
}
return allFreq
}
78 changes: 78 additions & 0 deletions courses/golang/ex06-barbershop/barbershop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package main

import (
"fmt"
"time"
)

func Barber(client_start chan byte, client_end chan bool) {
for {
select {
case num := <-client_start:
fmt.Printf("Start working with client %d.\n", num)
time.Sleep(700 * time.Millisecond)
client_end <- true
fmt.Printf("End working with client %d.\n", num)
default:
fmt.Println("Sleeping...")
fmt.Println()
time.Sleep(100 * time.Millisecond)
}
}
}

func Barbershop(seats byte, passer_in chan byte, passer_out chan byte, done chan byte) {
client_start := make(chan byte, seats)
client_end := make(chan bool)
emptySeats := seats
go Barber(client_start, client_end)

for {
select {
case num := <-passer_in:
fmt.Printf("\nNew client: %d.\n", num)
if emptySeats > 0 {
client_start <- num
fmt.Printf("Client %d took an empty seat.\n", num)
emptySeats--
fmt.Printf("Empty seats: %d.\n", emptySeats)
} else {
go func() {
time.Sleep(600 * time.Millisecond)
passer_out <- num
}()
fmt.Printf("Client %d will come back later.\n", num)
}
case <-client_end:
emptySeats++
fmt.Printf("Empty seats: %d.\n", emptySeats)
done <- emptySeats
}
}
}

func main() {
passer_in := make(chan byte)
passer_out := make(chan byte)
done := make(chan byte, 15)
seats := byte(4)
go Barbershop(seats, passer_in, passer_out, done)

for i := byte(1); i < 16; {
time.Sleep(300 * time.Millisecond)
select {
case num := <-passer_out:
passer_in <- num
default:
passer_in <- i
i++
}
}

for {
emptySeats := <-done
if emptySeats == seats {
break
}
}
}
52 changes: 52 additions & 0 deletions courses/golang/ex07-container/container.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package main

import (
"fmt"
"os"
"os/exec"
"syscall"
)

func main() {
switch os.Args[1] {
case "run":
parent()
case "child":
child()
default:
panic("wat should i do")
}
}

func parent() {
cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID,
}

cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
must(cmd.Run())
}

func child() {
fmt.Printf("\nPID: %d\n\n", os.Getpid())

cmd := exec.Command(os.Args[2], os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

must(syscall.Chroot("rootfs"))
must(os.Chdir("/"))
must(syscall.Mount("proc", "proc", "proc", 0, ""))
must(cmd.Run())
must(syscall.Unmount("proc", 0))
}

func must(err error) {
if err != nil {
panic(err)
}
}
3 changes: 3 additions & 0 deletions courses/golang/ex07-container/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module main

go 1.17
Loading