Compare commits

...

49 Commits

Author SHA1 Message Date
RLogik
14f59eeb63 master > master: protokoll - woche 7 2021-11-26 17:30:07 +01:00
RLogik
a6cce9626c master > master: protokoll - woche 7 2021-11-26 14:47:24 +01:00
RLogik
8d726bf344 master > master: protokolle - woche 6+7 2021-11-25 18:52:38 +01:00
RLogik
04eecdb444 master > master: protokolle - Woche6 2021-11-22 08:49:26 +01:00
RLogik
60c47c20c5 master > master: protokoll - woche 5 (minor Anmerkung) 2021-11-13 18:30:32 +01:00
RLogik
89499f524f master > master: README.md 2021-11-13 16:55:57 +01:00
RLogik
e55d8708a7 master > master: protokoll - woche5 (minor) 2021-11-13 16:54:48 +01:00
RLogik
ea7dfc5bef master > mater: protokolle - woche4 + woche5 2021-11-13 09:01:35 +01:00
RLogik
18ece75b67 master > master: code - minor 2021-11-08 13:21:03 +01:00
RLogik
6541a5246d master > mater: code - nextGreaterElement, auxiliary methods entfernt 2021-11-07 18:56:49 +01:00
RLogik
3505401c7f master > master: minor 2021-11-07 18:52:46 +01:00
RLogik
b193d1d61e master > master: protokoll - woche4 2021-11-07 18:50:05 +01:00
RLogik
ae459547c2 master > master: code - umgang mit cli args vereinheitlicht 2021-11-07 18:17:31 +01:00
RLogik
0f1b426f94 master > master: config - fügte Daten aus Aufgabe + nicht trivialen Fall hinzu 2021-11-07 08:55:29 +01:00
RLogik
cccc6a14ba master > master: code - next greater element messages leicht verbessert 2021-11-07 08:54:54 +01:00
RLogik
8d2de4fa2b master > master: code - stacks + queues data structures überarbeitet 2021-11-07 08:49:52 +01:00
RLogik
5c13f8d4cd master > master: Makefiles - defaults für Windows leicht angepasst 2021-11-06 20:48:28 +01:00
fe93d96584 master > master: code - Kommentare 2021-11-06 18:27:40 +01:00
580cc97387 master > master: code - nextGreaterEl alg für python, vereinfachte Algorithmus für py + go 2021-11-06 18:22:17 +01:00
ef833533f6 master > master: code - metrics für moves 2021-11-06 18:21:37 +01:00
ab38c181c9 master > master: code go - logging debug dunkel 2021-11-06 18:15:35 +01:00
972027ce41 master > master: assets - VERSION 2021-11-06 18:15:10 +01:00
2d91e98904 master > master: .gitignore 2021-11-06 18:14:58 +01:00
9a56c63018 master > master: code - logik bei Einstellungen (debug default ein, quiet default aus beim interaktiven Modus) 2021-11-06 11:16:34 +01:00
d878c0b77d master > master: code - Makefiles 2021-11-06 11:02:53 +01:00
a7f3377677 master > master: README - makefiles 2021-11-06 10:55:53 +01:00
eaef3322d8 master > master: code - makefiles 2021-11-06 10:55:44 +01:00
9e04763782 master > master: code go - go.sum hinzugefügt 2021-11-06 10:53:38 +01:00
924104408f master > master: .gitignore aufgeteilt 2021-11-06 10:53:08 +01:00
3a4702429b master > master: README 2021-11-05 16:19:29 +01:00
9237dbfad0 master > master: code go - ordner von internal -> pkg umgezogen 2021-11-05 15:48:06 +01:00
dbdb6a8480 master > master: code go - fügte Fall für stacks algorithmus hinzu 2021-11-05 15:44:21 +01:00
337790f3cd master > master: code go - messages verbessert 2021-11-05 15:44:06 +01:00
38025247c7 master > master: code go - fügte algorithmus hinzu 2021-11-05 15:43:53 +01:00
1fd932c0ef master > master: code go - fügte datenstruktur (stacks) hinzu 2021-11-05 15:43:24 +01:00
66e0f912e3 master > master: README 2021-11-05 09:01:50 +01:00
7b655a1c0a master > master: README 2021-11-05 08:59:13 +01:00
85ba0a0936 master > master: README 2021-11-05 08:55:57 +01:00
8f08634720 master > master: README - fügte zu codeprojekten hinzu + vereinfachung 2021-11-05 08:52:21 +01:00
6f1ee1b85f master > master: .gitignore 2021-11-05 08:51:56 +01:00
c14efb0cc6 master > master: code go - requirements aktualisiert 2021-11-05 08:51:38 +01:00
30dffa20d4 master > master: code go - vereinheitlichte help messages 2021-11-05 08:51:11 +01:00
6bf15f936e master > master: code py - vereinheitlicht mit go projekt 2021-11-05 08:50:44 +01:00
f0d0c9ef8a master > master: code - asset entfernt + assets hinzugefügt 2021-11-05 07:58:38 +01:00
1934c3475a master > master: code go - methode -> private, da nur intern im package run gebraucht 2021-11-04 11:38:43 +01:00
a96d1bb6c9 master > master: code go - debug messages im algorithmus ausführlicher + minor stiländerung 2021-11-04 11:36:14 +01:00
31b3c19bf9 master > master: code go - minor 2021-11-04 11:17:31 +01:00
552c3197e8 master > master: code go - vereinfachte logging 2021-11-04 11:06:16 +01:00
701032a109 master > master: code go - refactoring 2021-11-04 10:36:31 +01:00
87 changed files with 2273 additions and 1029 deletions

15
.gitignore vendored
View File

@@ -24,20 +24,9 @@
!/scripts/*.sh
!/code
!/code/**/
!/code/python/**/*.py
!/code/golang/**/*.go
!/code/golang/go.mod
!/code/golang/assets/HELP
!/code/golang/assets/VERSION
!/code/golang/assets/LOGO
!/code/golang/assets/config.yml
!/code/*/requirements
!/code/python
!/code/golang
!/code/config.yml
## nicht synchronisieren:
/code/golang/go.sum
/code/python/build
/code/python/build/**
!/dist
!/dist/VERSION

101
README.md
View File

@@ -27,97 +27,10 @@ In diesem Repository findet man:
## Code ##
Im Unterordner [`code`](./code) kann man Codeprojekte in Python und Golang finden, in denen verschiedene Algorithmen implementiert werden
(siehe insbes. [`code/python/src/algorithms`](./code/python//src/algorithms)
und [`code/golang/internal/algorithms`](./code/golang/internal/algorithms)).
Gerne kann man den Code benutzen, in einem eigenen Repository verändern, und mit den im Kurs präsentierten Algorithmen **herumexperimentieren**.
**HINWEIS:** _Bei meiner Implementierung kann es zu leichten Abweichungen kommen. Bitte **stets** an dem Material im VL-Skript sich orientieren. Der Hauptzweck der Code-Projekte besteht darin, dass Wissbegierige die Algorithmen konkret ausprobieren können. Alle theoretischen Aspekte werden jedoch im Skript und in den Übungen ausführlicher erklärt._
### Systemvoraussetzungen ###
#### Bashscripts ####
Im Ordner [`scripts`](./scripts) sind mehrere Workflows als Bashscripts kodiert. (Man kann natürlich ohne sie arbeiten, insbesondere dann, wenn man einen guten IDE hat.)
Zunächst braucht man einen Bashterminal. Das kommt mit OSX (Terminal) und Linux. Für Windows-User braucht man [git-for-windows](https://gitforwindows.org) zu installieren, was auch bash mit installiert. (Und für diejenigen, die VSCode oder andere IDEs benutzen, lässt sich bash als integrierten Terminal im IDE selbst verwenden.)
Den Bashscripts benötigen Ausfuhrrechte. Hierfür führe man
```bash
chmod +x scripts/*.sh;
```
aus. Das muss danach nie wiederholt werden.
Jetzt können wir von dem Hauptordner des Repositorys Befehle wie
```bash
./scripts/build.sh
./scripts/build.sh ---mode setup
```
usw. in der Bash-Console ausführen.
#### Für das Python-Projekt ####
Python version 3.x.x (idealerweise zumindest 3.9.5) plus einige Module (siehe [code/requirements](./code/requirements)). Letztere lassen sich mittels
```bash
# Benutze die Option `--venv true`, um mit virtuellem Env zu arbeiten:
./scripts/build.sh --lang python --mode setup
## oder:
python3 -m pip install -r code/requirements; # linux, osx
py -3 -m pip install -r code/requirements; # Windows
```
installieren.
#### Für das Golang-Projekt ####
Man braucht [go](https://golang.org/dl/) Version **1.17.x**. (Man kann bestimmt bei späteren Releases höhere Versionen benutzen. Man muss lediglich dann in [`./code/golang/go.mod`](./code/golang/go.mod) die Version hochstellen und die Requirements nochmals installieren lassen.) Und einige Packages werden benötigt. Letztere lassen sich mittels
```bash
./scripts/build.sh --lang go --mode setup
```
installieren.
### Ausführung ###
#### Für das Python-Projekt ####
```bash
pushd code/python/src; ## <- auf Pfad mit main.py wechseln
## Anzeigen der Hilfsanleitung:
python3 main.py -h; # linux, OSX
py -3 main.py -h; # Windows
## Algorithmus auf Fälle in code/config.yml ausführen:
python3 main.py run [--debug]; # linux, OSX
py -3 main.py run [--debug]; # Windows
## NOTE: --debug = Infos über Schritte zeigen
## NOTE: --colour true/false = schaltet Farbenmodus ein/aus
popd; ## <- zum vorherigen Pfad zurückwechseln
```
Oder man erstelle ein bash Skript wie `run.sh`, trage die Befehle da ein und führe
```bash
chmod +x run.sh; # nur einmalig nötig
./run.sh
```
aus.
#### Für das Golang-Projekt ####
Zuerst den Artefakt kompilieren:
```bash
./scripts/build.sh --lang go --mode dist;
## oder:
go build -o "dist/ads" "code/golang/main.go";
```
und dann mit dem gebauten Artefakt arbeiten:
```bash
dist/ads # startet Programm im interaktiven Modus
dist/ads help; # zeigt Hilfsanleitung
dist/ads version; # zeigt Version
dist/ads run [--debug]; # Algorithmus auf Fälle in code/config.yml ausführen
dist/ads run [--debug] --it; # startet Programm im interaktiven Modus
## NOTE: --debug = Infos über Schritte zeigen
## NOTE: --colour true/false = schaltet Farbenmodus ein/aus
```
**ANMERKUNG.** Ich habe versucht in beiden Projekten alle unnötigen Komplikationen von den Algorithmen auszublenden. Dennoch kann es durchaus der Fall sein, dass die Python-Implementierung wesentlich einfacher zu verstehen ist als die Go-Implementierung. Das Go-Projekt wurde v.&nbsp;a. deshalb entwickelt, da man mit Python mit _Pointers_ (»Zeiger«, siehe Woche 3) nicht arbeiten kann. Dennoch versuche ich, beide Projekten parallel auf einem ähnlichen Stand zu halten. Beide Projekte sind außerdem so konzipiert, dass sie Inputs gleichen Formats (d. h. die **config.yml** Datei) akzeptieren.
In den Unterordnern
[`code/golang`](./code/golang)
und
[`code/python`](./code/python)
kann man Codeprojekte finden.
Dort kann man konkrete Implementierung der Algorithmen ansehen
und ggf. auch auf echte Daten austesten.

View File

@@ -85,3 +85,11 @@ parts:
- command: 'algorithm-search-interpolation'
description: 'Seminarblatt Woche 3, Aufgabe 1'
inputs: *ref_inputs_sem3_1
- command: 'algorithm-stacks-next-greater-element'
description: 'Seminarblatt Woche 4, Aufgabe 1'
inputs:
L: [4, 6, 3, 16]
- command: 'algorithm-stacks-next-greater-element'
description: 'Seminarblatt Woche 4, Aufgabe 1 mit anderen Daten'
inputs:
L: [20, 10, 10, 2, 1, 5, 30, 3, 16]

33
code/golang/.gitignore vendored Normal file
View File

@@ -0,0 +1,33 @@
*
!/.gitignore
################################################################
# MAIN FOLDER
################################################################
!/Makefile
!/README.md
!/requirements
################################################################
# PROJECT FILES
################################################################
!/assets
!/assets/VERSION
!/assets/LOGO
!/assets/config.yml
!/pkg
!/internal
!/*/**/
!/*/**/*.go
!/go.mod
!/go.sum
################################################################
# ARTEFACTS
################################################################
/**/.DS_Store
/**/__archive__*

27
code/golang/Makefile Normal file
View File

@@ -0,0 +1,27 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# LOCAL ARGUMENTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PATH_TO_CONFIG:=../config.yml#<- kann durch Pfad zur eigenen yml-Datei ersetzt werden
PATH_TO_ARTEFACT:=../../dist/ads#<- kann beliebiger Pfad sein
COLOUR:=true
## für Windows weichen Defaultsettings leicht ab:
ifeq ($(OS),Windows_NT)
PATH_TO_ARTEFACT:=${PATH_TO_ARTEFACT}.exe
COLOUR:=false# <- man kann als 'true' setzen, aber in Windows funktioniert es möglicherweise nicht
endif
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TARGETS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
setup:
go mod download
build:
go build -o ${PATH_TO_ARTEFACT} main.go
run: # non-interactive mode mit config-datei
${PATH_TO_ARTEFACT} run --debug --colour ${COLOUR} --config "${PATH_TO_CONFIG}"
run-it: # interactive mode
${PATH_TO_ARTEFACT} run --it --debug --colour ${COLOUR}
# Do everything:
all: setup build run
all-it: setup build run-it

88
code/golang/README.md Normal file
View File

@@ -0,0 +1,88 @@
# ADS - Golang-Projekt #
**Golang** ist eine relativ moderne Programmiersprache, die immer populärer wird und viele Vorteile anbietet.
Dieses Projekt ist erneut kein nötiger Bestandteil des Kurses,
sondern nur für Wissbegierige gedacht.
Zunächst bietet sich an, sich die Algorithmen im Unterordner [`pkg/algorithms`](./pkg/algorithms) anzuschauen,
z.&nbsp;B. [`pkg/algorithms/search/binary/binary.go`](./pkg/algorithms/search/binary/binary.go) für den Binärsuchalgorithmus,
ohne irgendetwas installieren zu müssen.
**HINWEIS 1:** _Bei meiner Implementierung kann es zu leichten Abweichungen kommen. Bitte **stets** an dem Material im VL-Skript sich orientieren. Der Hauptzweck der Code-Projekte besteht darin, dass Wissbegierige die Algorithmen konkret ausprobieren können. Alle theoretischen Aspekte werden jedoch im Skript und in den Übungen ausführlicher erklärt._
Den Code kann man auch durch die u.&nbsp;s. Anweisungen selber austesten.
**HINWEIS 2:** _Während hier die Anweisungen ausführlich sind und klappen sollten,
bitte nur auf eigener Gewähr diesen Code benutzen._
## Systemvoraussetzungen ##
- **Bash**. Dies kommt mit OSX (Terminal) und Linux. Für Windows-User braucht man [git-for-windows](https://gitforwindows.org) zu installieren, was auch bash mit installiert.
- [**go**](https://golang.org/dl/) Version **1.17.x**. (Man kann bestimmt bei späteren Releases höhere Versionen benutzen. Man muss lediglich dann in [`go.mod`](./go.mod) die Version hochstellen.)
Alle u.&nbsp;s. Befehle sollen in einer Bash-Konsole von diesem Ordner aus ausgeführt werden.
## Einrichten mittels **Makefile** ##
Führe jeweils
```bash
make setup
make build
make run
# oder für interaktiven Modus
make run-it
```
aus, um Packages zu installieren
bzw. den Code zu kompilieren
bzw. den Code auszuführen.
Siehe [`Makefile`](./Makefile) für Details zu den Vorgängen.
Wer Makefile benutzt kann die u.&nbsp;s. Anweisungen ignorieren.
## Setup/Kompilieren ##
1. Requirements (Packages) einmalig mittels
```bash
go get $( cat requirements )
```
installieren. Oder man führe den Befehl
für jede Zeile aus [`requirements`](./requirements) aus,
</br>
z.&nbsp;B. `go get github.com/akamensky/argparse@v1.3.1`
installiert eines der Packages.
2. Codetree mittels
```bash
go build -o ads main.go
```
kompilieren.
</br>
Statt `-o ads` kann man einen beliebigen Pfad verwenden.
</br>
In Unix kann man `-o path/to/folder/ads` verwenden.
</br>
In Windows kann man `-o path/to/folder/ads.exe` verwenden.
## Ausführung ##
Nach Kompilieren wird ein Artefakt namens `ads` gebaut,
den man per Doppelklick ausführen kann.
Alternativ kann man in der Konsole im Ordner mit dem Artefakt einfach
```bash
ads
```
ausführen.
## Entwicklung ##
Gerne kann man den Code benutzen, in einem eigenen Repository weiter entwickeln,
und mit den im Kurs präsentierten Algorithmen und Fällen herumexperimentieren.

View File

@@ -1,11 +0,0 @@
Gebrauchsanleitung
~~~~~~~~~~~~~~~~~~
- Version und help:
ads \033[1mversion\033[0m
ads \033[1mhelp\033[0m
- Um die Algorithmen laufen zu lassen
ads \033[1mrun\033[0m [\033[1m--debug\033[0m] [\033[1m--config\033[0m=\033[2m<name of config file>\033[0m]

View File

@@ -1 +1 @@
X.Y.Z
0.0.0

View File

@@ -4,10 +4,10 @@ go 1.17
require (
github.com/akamensky/argparse v1.3.1
github.com/davecgh/go-spew v1.1.0
github.com/davecgh/go-spew v1.1.1
github.com/lithammer/dedent v1.1.0
github.com/pmezard/go-difflib v1.0.0
github.com/stretchr/objx v0.1.0
github.com/stretchr/objx v0.3.0
github.com/stretchr/testify v1.7.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
)

21
code/golang/go.sum Normal file
View File

@@ -0,0 +1,21 @@
github.com/akamensky/argparse v1.3.1 h1:kP6+OyvR0fuBH6UhbE6yh/nskrDEIQgEA1SUXDPjx4g=
github.com/akamensky/argparse v1.3.1/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -5,160 +5,38 @@ package logging
* ---------------------------------------------------------------- */
import (
"bufio"
"fmt"
"io"
"os"
"ads/internal/core/utils"
"ads/pkg/re"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES
* MAIN METHODS logging
* ---------------------------------------------------------------- */
var quietmode bool = false
var debugmode bool = false
var ansimode bool = false
var loggingPrefix string = ""
var force bool = false
var tagAll bool = false
var promptSymb string = ">"
func GetQuietMode() bool {
return quietmode
func Plain(line interface{}, args ...interface{}) {
logGeneric(os.Stdout, "", line, args...)
}
func SetQuietMode(mode bool) {
quietmode = mode
func Info(line interface{}, args ...interface{}) {
logGeneric(os.Stdout, "[\033[94;1mINFO\033[0m]", line, args...)
}
func GetDebugMode() bool {
return debugmode
}
func SetDebugMode(mode bool) {
debugmode = mode
}
func GetAnsiMode() bool {
return ansimode
}
func SetAnsiMode(mode bool) {
ansimode = mode
}
func GetForce() bool {
return force
}
func SetForce(mode bool) {
force = mode
}
func SetTagAll(mode bool) {
tagAll = mode
}
/* ---------------------------------------------------------------- *
* METHODS logging
* ---------------------------------------------------------------- */
func logGeneric(pipe *os.File, tag string, lines ...interface{}) {
if !force && quietmode {
return
}
if !(tag == "") {
tag = tag + " "
}
for _, line := range lines {
fmt.Fprintln(pipe, StripAnsiIfNecessary(fmt.Sprintf("%[1]s%[2]s%[3]v", loggingPrefix, tag, line)))
if !tagAll {
tag = ""
}
}
}
func LogPlain(lines ...interface{}) {
SetTagAll(false)
logGeneric(os.Stdout, "", lines...)
}
func LogInfo(lines ...interface{}) {
SetTagAll(true)
logGeneric(os.Stdout, "[\033[94;1mINFO\033[0m]", lines...)
}
func LogDebug(lines ...interface{}) {
func Debug(line interface{}, args ...interface{}) {
if !debugmode {
return
}
SetTagAll(true)
logGeneric(os.Stdout, "[\033[96;1mDEBUG\033[0m]", lines...)
logGeneric(os.Stdout, "\033[2m[\033[96;1mDEBUG\033[0m\033[2m]\033[0m", fmt.Sprintf("\033[2m%v\033[0m", line), args...)
}
func LogWarn(lines ...interface{}) {
SetTagAll(false)
logGeneric(os.Stdout, "[\033[93;1mWARNING\033[0m]", lines...)
func Warn(line interface{}, args ...interface{}) {
logGeneric(os.Stdout, "[\033[93;1mWARNING\033[0m]", line, args...)
}
func LogError(lines ...interface{}) {
SetTagAll(false)
logGeneric(os.Stderr, "[\033[91;1mERROR\033[0m]", lines...)
func Error(line interface{}, args ...interface{}) {
logGeneric(os.Stderr, "[\033[91;1mERROR\033[0m]", line, args...)
}
func LogFatal(lines ...interface{}) {
SetTagAll(false)
logGeneric(os.Stderr, "[\033[91;1mFATAL\033[0m]", lines...)
func Fatal(line interface{}, args ...interface{}) {
logGeneric(os.Stderr, "[\033[91;1mFATAL\033[0m]", line, args...)
os.Exit(1)
}
/* ---------------------------------------------------------------- *
* AUXILIARY METHODS
* ---------------------------------------------------------------- */
func StripAnsiIfNecessary(line string) string {
if !ansimode {
line = utils.StripAnsi(line)
}
return line
}
/* ---------------------------------------------------------------- *
* METHOD prompt
* ---------------------------------------------------------------- */
// Zeigt Prompt an und liest Usereingabe aus, erkennt auch ob Meta+D geklickt wurde
func Prompt(lines ...interface{}) (string, bool, error) {
pipe := os.Stdout
if len(lines) > 0 {
logGeneric(pipe, "", lines...)
logGeneric(pipe, "", "")
}
fmt.Fprintf(pipe, "%s ", promptSymb)
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
line = re.Sub(`\s+$`, "", line)
if err != nil && err == io.EOF {
fmt.Fprintln(pipe, "")
return line, true, err
}
return line, false, err
}
func PromptAnyKeyToContinue() bool {
pipe := os.Stdout
fmt.Fprint(pipe, StripAnsiIfNecessary("\033[2;3mEingabetaste (Enter) zum Fortsetzen drücken:\033[0m "))
_, exit, _ := Prompt()
return exit
}
/* ---------------------------------------------------------------- *
* METHODS terminal
* ---------------------------------------------------------------- */
func ClearScreen() {
fmt.Print("\033[2J")
}

View File

@@ -0,0 +1,45 @@
package logging
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"fmt"
"os"
"ads/internal/core/utils"
)
/* ---------------------------------------------------------------- *
* AUXILIARY METHODS
* ---------------------------------------------------------------- */
func logGeneric(pipe *os.File, tag string, line interface{}, args ...interface{}) {
if !force && quietmode {
return
}
if !(tag == "") {
tag = tag + " "
}
fmt.Fprintln(pipe, decorateLine(loggingPrefix, tag, expandLine(line, args)))
}
func expandLine(line interface{}, args []interface{}) string {
return fmt.Sprintf(fmt.Sprintf("%s", line), args...)
}
func decorateLine(loggingPrefix string, tag string, line string) string {
return stripAnsiIfNecessary(fmt.Sprintf("%[1]s%[2]s%[3]v", loggingPrefix, tag, line))
}
func stripAnsiIfNecessary(line string) string {
if !ansimode {
line = utils.StripAnsi(line)
}
return line
}
func ClearScreen() {
fmt.Print("\033[2J")
}

View File

@@ -0,0 +1,46 @@
package logging
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"bufio"
"fmt"
"io"
"os"
"ads/pkg/re"
)
/* ---------------------------------------------------------------- *
* METHOD prompts
* ---------------------------------------------------------------- */
// Zeigt Prompt an und liest Usereingabe aus, erkennt auch ob Meta+D geklickt wurde
func Prompt(lines ...interface{}) (string, bool, error) {
pipe := os.Stdout
if len(lines) > 0 {
tag := ""
for _, line := range lines {
logGeneric(pipe, tag, line)
}
logGeneric(pipe, tag, "")
}
fmt.Fprintf(pipe, "%s ", promptSymb)
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
line = re.Sub(`\s+$`, "", line)
if err != nil && err == io.EOF {
fmt.Fprintln(pipe, "")
return line, true, err
}
return line, false, err
}
func PromptAnyKeyToContinue() bool {
pipe := os.Stdout
fmt.Fprint(pipe, stripAnsiIfNecessary("\033[2;3mEingabetaste (Enter) zum Fortsetzen drücken:\033[0m "))
_, exit, _ := Prompt()
return exit
}

View File

@@ -0,0 +1,48 @@
package logging
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES
* ---------------------------------------------------------------- */
var quietmode bool = false
var debugmode bool = true
var ansimode bool = false
var loggingPrefix string = ""
var force bool = false
var promptSymb string = ">"
func GetQuietMode() bool {
return quietmode
}
func SetQuietMode(mode bool) {
quietmode = mode
}
func GetDebugMode() bool {
return debugmode
}
func SetDebugMode(mode bool) {
debugmode = mode
}
func GetAnsiMode() bool {
return ansimode
}
func SetAnsiMode(mode bool) {
ansimode = mode
}
func GetForce() bool {
return force
}
func SetForce(mode bool) {
force = mode
}

View File

@@ -17,6 +17,7 @@ import (
* ---------------------------------------------------------------- */
var _ctr_time = types.NewCounter()
var _ctr_moves = types.NewCounter()
var _ctr_space = types.NewCounter()
var _tmr = types.NewTimer()
@@ -26,6 +27,7 @@ var _tmr = types.NewTimer()
func ResetMetrics() {
_ctr_time.Reset()
_ctr_moves.Reset()
_ctr_space.Reset()
_tmr.Reset()
}
@@ -42,14 +44,26 @@ func AddTimeCost(options ...int) {
_ctr_time.Add(options...)
}
func AddMovesCost(options ...int) {
_ctr_moves.Add(options...)
}
func AddSpaceCost(options ...int) {
_ctr_space.Add(options...)
}
func SetSpaceCost(n int) {
_ctr_space.Set(n)
}
func GetTimeCost() int {
return _ctr_time.Size()
}
func GetMovesCost() int {
return _ctr_moves.Size()
}
func GetSpaceCost() int {
return _ctr_space.Size()
}

View File

@@ -1,506 +0,0 @@
package endpoints
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/core/logging"
"ads/internal/menus"
"ads/internal/setup"
algorithm_search_binary "ads/internal/algorithms/search/binary"
algorithm_search_interpol "ads/internal/algorithms/search/interpol"
algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
algorithm_search_jump "ads/internal/algorithms/search/jump"
algorithm_search_poison "ads/internal/algorithms/search/poison"
algorithm_search_sequential "ads/internal/algorithms/search/sequential"
algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
)
/* ---------------------------------------------------------------- *
* ENDPOINT run interactive modus
* ---------------------------------------------------------------- */
// Startet App im interaktiven Modus
func RunInteractive() error {
logging.LogPlain(setup.Logo())
_, err := menuMain.ShowMenu()
logging.LogInfo("Programm terminiert.")
return err
}
/* ---------------------------------------------------------------- *
* MENUS
* ---------------------------------------------------------------- */
var menuMain = menus.Menu{
IsRoot: true,
Path: []string{"Hauptmenü"},
PromptMessages: []string{
"Option wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Einstellungen", Submenu: &menuSettings},
{Label: "Version des Programms anzeigen", Action: actionShowVersion},
}, {
{Label: "Programm auf config Datei ausführen.", Action: actionRunOnConfig},
}, {
{Label: "Suchalgorithmen", Submenu: &menuSearchAlgorithms},
{Label: "Summenalgorithmen", Submenu: &menuSumAlgorithms},
},
},
Default: -1,
}
var menuSettings = menus.Menu{
Path: []string{"Hauptmenü", "Einstellungen"},
PromptMessages: []string{
"Option wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Aktueller Zustand", Action: actionShowSettings},
{Label: "Farbenmodus", Submenu: &menuColourMode},
{Label: "Debugmodus", Submenu: &menuDebugMode},
{Label: "Pre / Postchecking", Submenu: &menuPrePostChecking},
},
},
Default: -1,
}
var menuColourMode = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Farbenmodus"},
PromptMessages: []string{
"Soll Console-Output mit Formattierung dargestellt werden?",
"Option für den Farbenmodus wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionColourModeOn},
{Label: "aus", Action: actionColourModeOff},
},
},
Default: 1,
}
var menuDebugMode = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Debugmodus"},
PromptMessages: []string{
"Sollen Infos zu jedem Schritt der Algorithmen angezeigt werden?",
"Option für den Debugmodus wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionDebugModeOn},
{Label: "aus", Action: actionDebugModeOff},
},
},
Default: 1,
}
var menuPrePostChecking = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Pre/Postchecking"},
PromptMessages: []string{
"Sollen Inputs+Outputs bei Algorithmenausführungen geprüft werden?",
"Option für den Pre/Postchecking wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionPrePostCheckingOn},
{Label: "aus", Action: actionPrePostCheckingOff},
},
},
Default: 1,
}
var menuSearchAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Suchalgorithmen"},
PromptMessages: []string{
"Algorithmus wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Binärsuchalgorithmus", Action: actionAlgorithmSearchBinary},
{Label: "Interpolationsalgorithmus", Action: actionAlgorithmSearchInterpolation},
{Label: "Suche i. kleinstes Element", Action: actionAlgorithmSearchIthElement},
{Label: "Suche i. kleinstes Element", SubLabel: "D & C", Action: actionAlgorithmSearchIthElementDc},
{Label: "Sprungsuche", SubLabel: "linear", Action: actionAlgorithmSearchJump},
{Label: "Sprungsuche", SubLabel: "exponentiell", Action: actionAlgorithmSearchJumpExp},
{Label: "Giftsuche", Action: actionAlgorithmSearchPoison},
{Label: "Giftsuche", SubLabel: "optimiert", Action: actionAlgorithmSearchPoisonFast},
{Label: "Sequentiellsuchalgorithmus", Action: actionAlgorithmSearchSequential},
},
},
Default: -1,
}
var menuSumAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Summenalgorithmen"},
PromptMessages: []string{
"Algorithmus wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Maximale Teilsumme", SubLabel: "brute force", Action: actionAlgorithmSumMaxsub},
{Label: "Maximale Teilsumme", SubLabel: "D & C", Action: actionAlgorithmSumMaxsubDc},
},
},
Default: -1,
}
/* ---------------------------------------------------------------- *
* ACTIONS - basic
* ---------------------------------------------------------------- */
func actionShowVersion() (bool, error) {
logging.LogInfo("Version des Programms")
Version()
return false, nil
}
func actionShowSettings() (bool, error) {
var state string
state = "aus"
if logging.GetAnsiMode() {
state = "ein"
}
logging.LogInfo(fmt.Sprintf("Farbenmodus: %s", state))
state = "aus"
if logging.GetDebugMode() {
state = "ein"
}
logging.LogInfo(fmt.Sprintf("Debugmodus: %s", state))
state = "aus"
if setup.AppConfigPerformChecks() {
state = "ein"
}
logging.LogInfo(fmt.Sprintf("Pre/Postchecking: %s", state))
return false, nil
}
func actionColourModeOn() (bool, error) {
logging.SetAnsiMode(true)
return false, nil
}
func actionColourModeOff() (bool, error) {
logging.SetAnsiMode(false)
return false, nil
}
func actionDebugModeOn() (bool, error) {
logging.SetDebugMode(true)
return false, nil
}
func actionDebugModeOff() (bool, error) {
logging.SetDebugMode(false)
return false, nil
}
func actionPrePostCheckingOn() (bool, error) {
setup.SetAppConfigPerformChecks(true)
return false, nil
}
func actionPrePostCheckingOff() (bool, error) {
setup.SetAppConfigPerformChecks(false)
return false, nil
}
/* ---------------------------------------------------------------- *
* ACTIONS - Algorithmen
* ---------------------------------------------------------------- */
func actionRunOnConfig() (bool, error) {
path, cancel, err := logging.Prompt("Pfad zur Configdatei bitte eingeben:")
if cancel {
err = nil
} else if err == nil {
err = RunNonInteractive(path)
}
return cancel, err
}
func actionAlgorithmSearchBinary() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_binary.FancyBinarySearch(input_L, input_x)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchInterpolation() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
"sollte (idealerweise) nicht uniform verteilt sein",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_interpol.FancyInterpolationSearch(input_L, input_x, 0, len(input_L)-1)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchIthElement() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
input_i, cancel, err := PromptInputInteger("i", "Suchindex in sortierter Liste", []string{
"sollte zw. 1 und len(L) liegen",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_ith_element.FancyFindIthSmallest(input_L, input_i)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchIthElementDc() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
input_i, cancel, err := PromptInputInteger("i", "Suchindex in sortierter Liste", []string{
"sollte zw. 1 und len(L) liegen",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_ith_element.FancyFindIthSmallestDC(input_L, input_i)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchJump() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
"sollte (idealerweise) nicht uniform verteilt sein",
"sollte (idealerweise) keine Duplikate enthalten",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
input_m, cancel, err := PromptInputInteger("m", "Sprunggröße", []string{
"sollte >= 2 sein",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_jump.FancyJumpSearchLinear(input_L, input_x, input_m)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchJumpExp() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
"sollte (idealerweise) nicht uniform verteilt sein",
"sollte (idealerweise) keine Duplikate enthalten",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_jump.FancyJumpSearchExponentiell(input_L, input_x)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchPoison() (bool, error) {
input_L, cancel, err := PromptInputListOfZeroOnes("L", "Liste von Werten", []string{
"muss genau eine 1 enthalten",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_poison.FancyFindPoison(input_L)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchPoisonFast() (bool, error) {
input_L, cancel, err := PromptInputListOfZeroOnes("L", "Liste von Getränken", []string{
"muss genau eine 1 enthalten",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_poison.FancyFindPoisonFast(input_L)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchSequential() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := PromptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_sequential.FancySequentialSearch(input_L, input_x)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSumMaxsub() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, _, _, err = algorithm_sum_maxsubsum.FancyMaxSubSum(input_L)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSumMaxsubDc() (bool, error) {
input_L, cancel, err := PromptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, _, _, err = algorithm_sum_maxsubsum.FancyMaxSubSumDC(input_L)
if err != nil {
logging.LogError(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
/* ---------------------------------------------------------------- *
* CUSTOM PROMPTS für besondere Inputs
* ---------------------------------------------------------------- */
func PromptInputInteger(name string, descr string, requirements []string) (int, bool, error) {
type responseType struct {
Response int `yaml:"response"`
}
var response = responseType{}
var query = menus.PromptValueQuery{
Description: descr,
Name: name,
Type: "Integer",
Requirements: &requirements,
Response: &response,
}
cancel, err := query.Prompt()
return response.Response, cancel, err
}
func PromptInputListOfInt(name string, descr string, requirements []string) ([]int, bool, error) {
type responseType struct {
Response []int `yaml:"response"`
}
var response = responseType{}
var query = menus.PromptValueQuery{
Description: descr,
Name: name,
Type: "Integerliste",
ValidExamples: &[]string{
"[1, 2, 7, 8, 5]",
"[1000, 0, 4]",
},
Requirements: &requirements,
Response: &response,
}
cancel, err := query.Prompt()
return response.Response, cancel, err
}
func PromptInputListOfZeroOnes(name string, descr string, requirements []string) ([]int, bool, error) {
var values = []int{}
type responseType struct {
Response []uint8 `yaml:"response"`
}
var response = responseType{}
var query = menus.PromptValueQuery{
Description: descr,
Name: name,
Type: "Liste von 0er und 1er",
ValidExamples: &[]string{
"[0, 0, 0, 1, 0]",
"[1, 0, 1, 1]",
},
Requirements: &requirements,
Response: &response,
}
cancel, err := query.Prompt()
// uint8 -> int
if response.Response != nil {
for _, x := range response.Response {
values = append(values, int(x))
}
}
return values, cancel, err
}

View File

@@ -1,4 +1,4 @@
package endpoints
package print
/* ---------------------------------------------------------------- *
* IMPORTS
@@ -16,7 +16,7 @@ import (
func Version() {
logging.SetForce(true)
logging.LogPlain(setup.Version())
logging.Plain(setup.Version())
}
/* ---------------------------------------------------------------- *
@@ -26,11 +26,9 @@ func Version() {
func Help() {
logging.SetForce(true)
cli.ParseCli([]string{}) // <- generiere leere Instanz für Parser, um voll Hilfsanleitug zu zeigen
logging.LogPlain(
"",
setup.Logo(),
// setup.Help(),
cli.Parser.Usage(nil),
"",
)
logging.Plain("")
logging.Plain(setup.Logo())
// logging.Plain(setup.Help())
logging.Plain(cli.Parser.Usage(nil))
logging.Plain("")
}

View File

@@ -1,4 +1,4 @@
package endpoints
package run
/* ---------------------------------------------------------------- *
* IMPORTS
@@ -11,15 +11,28 @@ import (
"ads/internal/setup"
"ads/internal/types"
algorithm_search_binary "ads/internal/algorithms/search/binary"
algorithm_search_interpol "ads/internal/algorithms/search/interpol"
algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
algorithm_search_jump "ads/internal/algorithms/search/jump"
algorithm_search_poison "ads/internal/algorithms/search/poison"
algorithm_search_sequential "ads/internal/algorithms/search/sequential"
algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
algorithm_search_binary "ads/pkg/algorithms/search/binary"
algorithm_search_interpol "ads/pkg/algorithms/search/interpol"
algorithm_search_ith_element "ads/pkg/algorithms/search/ith_element"
algorithm_search_jump "ads/pkg/algorithms/search/jump"
algorithm_search_poison "ads/pkg/algorithms/search/poison"
algorithm_search_sequential "ads/pkg/algorithms/search/sequential"
algorithm_stacks_next_greater_element "ads/pkg/algorithms/stacks/next_greater_element"
algorithm_sum_maxsubsum "ads/pkg/algorithms/sum/maxsubsum"
)
/* ---------------------------------------------------------------- *
* ENDPOINT run interactive modus
* ---------------------------------------------------------------- */
// Startet App im interaktiven Modus
func RunInteractive() error {
logging.Plain(setup.Logo())
_, err := menuMain.ShowMenu()
logging.Plain("\033[2;3m...Programm terminiert.\033[0m")
return err
}
/* ---------------------------------------------------------------- *
* ENDPOINT run non-interactive modus
* ---------------------------------------------------------------- */
@@ -36,7 +49,7 @@ func RunNonInteractive(path string) error {
return err
}
logging.LogPlain(setup.Logo())
logging.Plain(setup.Logo())
// Fälle extrahieren
cases := []types.UserConfigCase{}
@@ -126,6 +139,13 @@ func RunNonInteractive(path string) error {
} else {
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
}
case "algorithm-stacks-next-greater-element":
L := inputs.List
if L != nil {
_, err_case = algorithm_stacks_next_greater_element.FancyNextGreaterElement(*L)
} else {
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
}
case "algorithm-sum-maxsub":
L := inputs.List
if L != nil {
@@ -145,7 +165,7 @@ func RunNonInteractive(path string) error {
}
}
if err_case != nil {
logging.LogError(err_case)
logging.Error(err_case)
}
}
setup.DisplayEndOfCase()

View File

@@ -0,0 +1,254 @@
package run
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/logging"
"ads/internal/setup"
algorithm_search_binary "ads/pkg/algorithms/search/binary"
algorithm_search_interpol "ads/pkg/algorithms/search/interpol"
algorithm_search_ith_element "ads/pkg/algorithms/search/ith_element"
algorithm_search_jump "ads/pkg/algorithms/search/jump"
algorithm_search_poison "ads/pkg/algorithms/search/poison"
algorithm_search_sequential "ads/pkg/algorithms/search/sequential"
algorithm_stacks_next_greater_element "ads/pkg/algorithms/stacks/next_greater_element"
algorithm_sum_maxsubsum "ads/pkg/algorithms/sum/maxsubsum"
)
/* ---------------------------------------------------------------- *
* ACTIONS algorithmen - search
* ---------------------------------------------------------------- */
func actionAlgorithmSearchBinary() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := promptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_binary.FancyBinarySearch(input_L, input_x)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchInterpolation() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
"sollte (idealerweise) nicht uniform verteilt sein",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := promptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_interpol.FancyInterpolationSearch(input_L, input_x, 0, len(input_L)-1)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchIthElement() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
input_i, cancel, err := promptInputInteger("i", "Suchindex in sortierter Liste", []string{
"sollte zw. 1 und len(L) liegen",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_ith_element.FancyFindIthSmallest(input_L, input_i)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchIthElementDc() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
input_i, cancel, err := promptInputInteger("i", "Suchindex in sortierter Liste", []string{
"sollte zw. 1 und len(L) liegen",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_ith_element.FancyFindIthSmallestDC(input_L, input_i)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchJump() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
"sollte (idealerweise) nicht uniform verteilt sein",
"sollte (idealerweise) keine Duplikate enthalten",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := promptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
input_m, cancel, err := promptInputInteger("m", "Sprunggröße", []string{
"sollte >= 2 sein",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_jump.FancyJumpSearchLinear(input_L, input_x, input_m)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchJumpExp() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{
"muss aufsteigend sortiert sein",
"sollte (idealerweise) nicht uniform verteilt sein",
"sollte (idealerweise) keine Duplikate enthalten",
})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := promptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_jump.FancyJumpSearchExponentiell(input_L, input_x)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchPoison() (bool, error) {
input_L, cancel, err := promptInputListOfZeroOnes("L", "Liste von Werten", []string{
"muss genau eine 1 enthalten",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_poison.FancyFindPoison(input_L)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchPoisonFast() (bool, error) {
input_L, cancel, err := promptInputListOfZeroOnes("L", "Liste von Getränken", []string{
"muss genau eine 1 enthalten",
})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_poison.FancyFindPoisonFast(input_L)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSearchSequential() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
input_x, cancel, err := promptInputInteger("x", "Suchwert", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_search_sequential.FancySequentialSearch(input_L, input_x)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
/* ---------------------------------------------------------------- *
* ACTIONS algorithmen - stacks
* ---------------------------------------------------------------- */
func actionAlgorithmStacksNextGreaterElement() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_stacks_next_greater_element.FancyNextGreaterElement(input_L)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
/* ---------------------------------------------------------------- *
* ACTIONS algorithmen - sum
* ---------------------------------------------------------------- */
func actionAlgorithmSumMaxsub() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, _, _, err = algorithm_sum_maxsubsum.FancyMaxSubSum(input_L)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
func actionAlgorithmSumMaxsubDc() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, _, _, err = algorithm_sum_maxsubsum.FancyMaxSubSumDC(input_L)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}

View File

@@ -0,0 +1,34 @@
package run
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/logging"
"ads/internal/setup"
)
/* ---------------------------------------------------------------- *
* ACTIONS - basic
* ---------------------------------------------------------------- */
func actionShowVersion() (bool, error) {
logging.Plain("")
logging.Plain(setup.Logo())
logging.Plain("Version: \033[1m%s\033[0m", setup.Version())
logging.Plain("")
return false, nil
}
func actionRunOnConfig() (bool, error) {
path, cancel, err := logging.Prompt("Pfad zur Configdatei bitte eingeben:")
if cancel {
return true, nil
}
if err != nil {
return false, err
}
err = RunNonInteractive(path)
return false, err
}

View File

@@ -0,0 +1,64 @@
package run
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/logging"
"ads/internal/setup"
)
/* ---------------------------------------------------------------- *
* ACTIONS - settting
* ---------------------------------------------------------------- */
func actionShowSettings() (bool, error) {
var state string
state = "aus"
if logging.GetAnsiMode() {
state = "ein"
}
logging.Info("Farbenmodus: %s", state)
state = "aus"
if logging.GetDebugMode() {
state = "ein"
}
logging.Info("Debugmodus: %s", state)
state = "aus"
if setup.AppConfigPerformChecks() {
state = "ein"
}
logging.Info("Pre/Postchecking: %s", state)
return false, nil
}
func actionColourModeOn() (bool, error) {
logging.SetAnsiMode(true)
return false, nil
}
func actionColourModeOff() (bool, error) {
logging.SetAnsiMode(false)
return false, nil
}
func actionDebugModeOn() (bool, error) {
logging.SetDebugMode(true)
return false, nil
}
func actionDebugModeOff() (bool, error) {
logging.SetDebugMode(false)
return false, nil
}
func actionPrePostCheckingOn() (bool, error) {
setup.SetAppConfigPerformChecks(true)
return false, nil
}
func actionPrePostCheckingOff() (bool, error) {
setup.SetAppConfigPerformChecks(false)
return false, nil
}

View File

@@ -0,0 +1,146 @@
package run
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/menus"
)
/* ---------------------------------------------------------------- *
* MENUS
* ---------------------------------------------------------------- */
var menuMain = menus.Menu{
IsRoot: true,
Path: []string{"Hauptmenü"},
PromptMessages: []string{
"Option wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Einstellungen", Submenu: &menuSettings},
{Label: "Version des Programms anzeigen", Action: actionShowVersion},
}, {
{Label: "Programm auf config Datei ausführen.", Action: actionRunOnConfig},
}, {
{Label: "Suchalgorithmen", Submenu: &menuSearchAlgorithms},
{Label: "Summenalgorithmen", Submenu: &menuSumAlgorithms},
{Label: "Algorithmen mit Stacks und Queues", Submenu: &menuStacksQueuesAlgorithms},
},
},
Default: -1,
}
var menuSettings = menus.Menu{
Path: []string{"Hauptmenü", "Einstellungen"},
PromptMessages: []string{
"Option wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Aktueller Zustand", Action: actionShowSettings},
{Label: "Farbenmodus", Submenu: &menuColourMode},
{Label: "Debugmodus", Submenu: &menuDebugMode},
{Label: "Pre / Postchecking", Submenu: &menuPrePostChecking},
},
},
Default: -1,
}
var menuColourMode = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Farbenmodus"},
PromptMessages: []string{
"Soll Console-Output mit Formattierung dargestellt werden?",
"Option für den Farbenmodus wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionColourModeOn},
{Label: "aus", Action: actionColourModeOff},
},
},
Default: 1,
}
var menuDebugMode = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Debugmodus"},
PromptMessages: []string{
"Sollen Infos zu jedem Schritt der Algorithmen angezeigt werden?",
"Option für den Debugmodus wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionDebugModeOn},
{Label: "aus", Action: actionDebugModeOff},
},
},
Default: 0,
}
var menuPrePostChecking = menus.Menu{
ForceReturn: true,
Path: []string{"Hauptmenü", "Einstellungen", "Pre/Postchecking"},
PromptMessages: []string{
"Sollen Inputs+Outputs bei Algorithmenausführungen geprüft werden?",
"Option für den Pre/Postchecking wählen:",
},
Options: [][]menus.MenuOption{
{
{Label: "ein", Action: actionPrePostCheckingOn},
{Label: "aus", Action: actionPrePostCheckingOff},
},
},
Default: 1,
}
var menuSearchAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Suchalgorithmen"},
PromptMessages: []string{
"Algorithmus wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Binärsuchalgorithmus", Action: actionAlgorithmSearchBinary},
{Label: "Interpolationsalgorithmus", Action: actionAlgorithmSearchInterpolation},
{Label: "Suche i. kleinstes Element", Action: actionAlgorithmSearchIthElement},
{Label: "Suche i. kleinstes Element", SubLabel: "D & C", Action: actionAlgorithmSearchIthElementDc},
{Label: "Sprungsuche", SubLabel: "linear", Action: actionAlgorithmSearchJump},
{Label: "Sprungsuche", SubLabel: "exponentiell", Action: actionAlgorithmSearchJumpExp},
{Label: "Giftsuche", Action: actionAlgorithmSearchPoison},
{Label: "Giftsuche", SubLabel: "optimiert", Action: actionAlgorithmSearchPoisonFast},
{Label: "Sequentiellsuchalgorithmus", Action: actionAlgorithmSearchSequential},
},
},
Default: -1,
}
var menuStacksQueuesAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Algorithmen mit Stacks und Queues"},
PromptMessages: []string{
"Algorithmus wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "'Next Greater Element' mit Stacks", Action: actionAlgorithmStacksNextGreaterElement},
},
},
Default: -1,
}
var menuSumAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Summenalgorithmen"},
PromptMessages: []string{
"Algorithmus wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "Maximale Teilsumme", SubLabel: "brute force", Action: actionAlgorithmSumMaxsub},
{Label: "Maximale Teilsumme", SubLabel: "D & C", Action: actionAlgorithmSumMaxsubDc},
},
},
Default: -1,
}

View File

@@ -0,0 +1,76 @@
package run
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/menus"
)
/* ---------------------------------------------------------------- *
* CUSTOM PROMPTS für besondere Inputs
* ---------------------------------------------------------------- */
func promptInputInteger(name string, descr string, requirements []string) (int, bool, error) {
type responseType struct {
Response int `yaml:"response"`
}
var response = responseType{}
var query = menus.PromptValueQuery{
Description: descr,
Name: name,
Type: "Integer",
Requirements: &requirements,
Response: &response,
}
cancel, err := query.Prompt()
return response.Response, cancel, err
}
func promptInputListOfInt(name string, descr string, requirements []string) ([]int, bool, error) {
type responseType struct {
Response []int `yaml:"response"`
}
var response = responseType{}
var query = menus.PromptValueQuery{
Description: descr,
Name: name,
Type: "Integerliste",
ValidExamples: &[]string{
"[1, 2, 7, 8, 5]",
"[1000, 0, 4]",
},
Requirements: &requirements,
Response: &response,
}
cancel, err := query.Prompt()
return response.Response, cancel, err
}
func promptInputListOfZeroOnes(name string, descr string, requirements []string) ([]int, bool, error) {
var values = []int{}
type responseType struct {
Response []uint8 `yaml:"response"`
}
var response = responseType{}
var query = menus.PromptValueQuery{
Description: descr,
Name: name,
Type: "Liste von 0er und 1er",
ValidExamples: &[]string{
"[0, 0, 0, 1, 0]",
"[1, 0, 1, 1]",
},
Requirements: &requirements,
Response: &response,
}
cancel, err := query.Prompt()
// uint8 -> int
if response.Response != nil {
for _, x := range response.Response {
values = append(values, int(x))
}
}
return values, cancel, err
}

View File

@@ -110,7 +110,7 @@ func (menu Menu) ShowMenu() (bool, error) {
} else if opt.Action != nil {
cancel, err = opt.Action()
if err != nil {
logging.LogError(err)
logging.Error(err)
}
// Falls ForceReturn, dann nach Ausführung der Action, -> return
if menu.ForceReturn {
@@ -127,7 +127,7 @@ func (menu Menu) ShowMenu() (bool, error) {
}
}
} else {
logging.LogWarn("Option noch nicht implementiert.")
logging.Warn("Option noch nicht implementiert.")
quit := logging.PromptAnyKeyToContinue()
if quit {
return true, nil
@@ -188,13 +188,15 @@ func (query *PromptValueQuery) Prompt() (bool, error) {
return true, nil
}
if err != nil {
logging.LogError(err, "")
logging.Error(err)
logging.Plain("")
continue
}
line = fmt.Sprintf("\"response\": %s", line)
err = yaml.Unmarshal([]byte(line), query.Response)
if err != nil {
logging.LogError(err, "")
logging.Error(err)
logging.Plain("")
continue
}
break

View File

@@ -63,7 +63,7 @@ func promptListOfOptions(messages []string, options [][2]string, breaks []int, d
}
if err != nil {
logging.ClearScreen()
logging.LogError(err)
logging.Error(err)
continue
}
if choice == "" {
@@ -72,7 +72,7 @@ func promptListOfOptions(messages []string, options [][2]string, breaks []int, d
}
if _, ok := optionsMap[choice]; !ok {
logging.ClearScreen()
logging.LogError("Ungültige eingabe")
logging.Error("Ungültige eingabe")
continue
}
break

View File

@@ -37,13 +37,13 @@ var optionsChecks = argparse.Options{
}
var optionsDebug = argparse.Options{
Help: "Blendet die Debugging-Befehle ein.",
Help: "Blendet Debugging-Befehle ein.",
Required: false,
Default: false,
}
var optionsInteractive = argparse.Options{
Help: "Startet die App im interaktiven Modus.",
Help: "Startet das Programm im interaktiven Modus.",
Required: false,
Default: false,
}
@@ -68,11 +68,14 @@ var optionsConfigFile = argparse.Options{
// Parst cli flags.
func ParseCli(args []string) (*types.CliArguments, error) {
var err error
Parser = argparse.NewParser("cli parser", "Liest Optionen + Flags von Kommandozeile.")
Parser = argparse.NewParser(
"cli parser",
"\033[93;2mEin Programm zur Ausführung verschiedener Algorithmen aus dem Kurs AlgoDat I.\033[0m",
)
arguments := types.CliArguments{
ModeHelp: Parser.NewCommand("help", ""),
ModeVersion: Parser.NewCommand("version", "Ruft Endpunkt auf, der die Version anzeigt."),
ModeRun: Parser.NewCommand("run", "Ruft Endpunkt auf, der die Algorithmen laufen lässt."),
ModeHelp: Parser.NewCommand("help", "Hilfsanleitung anzeigen"),
ModeVersion: Parser.NewCommand("version", "Version anzeigen."),
ModeRun: Parser.NewCommand("run", "Algorithmen ausführen."),
Quiet: Parser.Flag("q", "quiet", &optionsQuiet),
Debug: Parser.Flag("", "debug", &optionsDebug),
Interactive: Parser.Flag("", "it", &optionsInteractive),

View File

@@ -38,7 +38,7 @@ func ReadAsset(key string) string {
}
/* ---------------------------------------------------------------- *
* METHODS templates
* METHODS assets
* ---------------------------------------------------------------- */
func Help() string {

View File

@@ -20,9 +20,9 @@ import (
func DisplayStartOfCase(index int, descr *string) {
DisplayBar(80)
if descr == nil || *descr == "" {
logging.LogPlain(fmt.Sprintf("\033[92;1mCASE %[1]v\033[0m.", index))
logging.Plain("\033[92;1mCASE %[1]v\033[0m.", index)
} else {
logging.LogPlain(fmt.Sprintf("\033[92;1mCASE %[1]v\033[0m (\033[1;2m%[2]s\033[0m).", index, *descr))
logging.Plain("\033[92;1mCASE %[1]v\033[0m (\033[1;2m%[2]s\033[0m).", index, *descr)
}
}
@@ -86,25 +86,26 @@ func RepresentValue(value interface{}) interface{} {
* ---------------------------------------------------------------- */
func DisplayStartOfAlgorithm(name string, inputs map[string]interface{}) {
logging.LogPlain(fmt.Sprintf("Ausführung vom Algorithmus: \033[92;1m%[1]s\033[0m", name))
logging.LogPlain("INPUTS")
logging.Plain("Ausführung vom Algorithmus: \033[92;1m%[1]s\033[0m", name)
logging.Plain("INPUTS")
for varname, value := range inputs {
logging.LogPlain(fmt.Sprintf(" - %[1]s = %[2]v", varname, RepresentValue(value)))
logging.Plain(" - %[1]s = %[2]v", varname, RepresentValue(value))
}
}
func DisplayEndOfAlgorithm(outputs map[string]interface{}) {
logging.LogPlain("OUTPUTS:")
logging.Plain("OUTPUTS:")
for varname, value := range outputs {
logging.LogPlain(fmt.Sprintf(" - %[1]s = %[2]v", varname, RepresentValue(value)))
logging.Plain(" - %[1]s = %[2]v", varname, RepresentValue(value))
}
}
func DisplayMetrics() {
// logging.LogPlain(fmt.Sprintf("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsed()))
logging.LogPlain(fmt.Sprintf("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsedLongFormat()))
logging.LogPlain(fmt.Sprintf("Kosten (Zeit): T(n) = \033[1m%[1]v\033[0m", metrics.GetTimeCost()))
logging.LogPlain(fmt.Sprintf("Kosten (Platz): S(n) = \033[1m%[1]v\033[0m", metrics.GetSpaceCost()))
// logging.Plain("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsed())
logging.Plain("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsedLongFormat())
logging.Plain("Kosten (Zeit): T(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetTimeCost()))
logging.Plain("Kosten (#Züge): M(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetMovesCost()))
logging.Plain("Kosten (Platz): S(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetSpaceCost()))
return
}
@@ -117,6 +118,13 @@ func DisplayBar(options ...int) {
if len(options) > 0 {
n = options[0]
}
logging.LogPlain(fmt.Sprintf("+%[1]s+", strings.Repeat("-", n)))
logging.Plain("+%[1]s+", strings.Repeat("-", n))
return
}
func displayCost(cost int) string {
if cost > 0 {
return fmt.Sprintf("%v", cost)
}
return "-"
}

View File

@@ -39,6 +39,14 @@ func (self Counter) Size() int {
return self.nr
}
func (self *Counter) Reset() {
self.nr = 0
}
func (self *Counter) Set(n int) {
self.nr = n
}
func (self *Counter) Add(options ...int) {
n := 1
if len(options) > 0 {
@@ -46,7 +54,3 @@ func (self *Counter) Add(options ...int) {
}
self.nr += n
}
func (self *Counter) Reset() {
self.nr = 0
}

View File

@@ -9,10 +9,12 @@ import (
"os"
"ads/internal/core/logging"
"ads/internal/endpoints"
"ads/internal/setup"
"ads/internal/setup/cli"
"ads/internal/types"
endpoints_print "ads/internal/endpoints/print"
endpoints_run "ads/internal/endpoints/run"
)
/* ---------------------------------------------------------------- *
@@ -36,9 +38,11 @@ var (
* ---------------------------------------------------------------- */
func main() {
var err error
var arguments *types.CliArguments
var (
err1 error
err2 error
err3 error
cmdMissing bool
showChecks bool
)
@@ -48,45 +52,52 @@ func main() {
setup.Assets = assets
// cli arguments parsen
arguments, err = cli.ParseCli(os.Args)
cmdMissing = cli.ParseCliCommandMissing(err)
arguments, err1 = cli.ParseCli(os.Args)
cmdMissing = cli.ParseCliCommandMissing(err1)
// initialisiere basic optionen wie Logging
// Programmeinstellungen initialisieren
showChecks = false
if err == nil {
quiet := arguments.QuietModeOn()
if arguments.InteractiveMode() {
quiet = false
if err1 == nil {
if !(arguments.ModeRun.Happened() && arguments.InteractiveMode()) {
logging.SetQuietMode(arguments.QuietModeOn())
logging.SetDebugMode(arguments.DebugModeOn())
}
logging.SetQuietMode(quiet)
logging.SetDebugMode(arguments.DebugModeOn())
logging.SetAnsiMode(arguments.ShowColour())
showChecks = arguments.ShowChecks()
}
// app config (intern) intialisieren
err = setup.AppConfigInitialise()
err2 = setup.AppConfigInitialise()
setup.SetAppConfigPerformChecks(showChecks)
if err == nil {
if arguments.ModeVersion.Happened() {
endpoints.Version()
} else if arguments.ModeRun.Happened() {
if arguments.InteractiveMode() {
err = endpoints.RunInteractive()
} else {
err = endpoints.RunNonInteractive(arguments.GetConfigFile())
}
} else if arguments.ModeHelp.Happened() {
endpoints.Help()
} else {
err = endpoints.RunInteractive()
}
} else if cmdMissing {
err = endpoints.RunInteractive()
// Fehler melden (fatal)
if err1 != nil && !cmdMissing {
logging.Fatal(err1)
}
if err != nil {
logging.LogFatal(err)
if err2 != nil {
logging.Fatal(err2)
}
// Wenn der Artefakt ohne Argument aufgerufen wird, keinen Fehler melden, sondern im it-Modus ausführen
if cmdMissing {
endpoints_run.RunInteractive()
return
}
// Sonst Commands behandeln
if arguments.ModeHelp.Happened() {
endpoints_print.Help()
return
} else if arguments.ModeVersion.Happened() {
endpoints_print.Version()
return
} else if arguments.ModeRun.Happened() {
if arguments.InteractiveMode() {
endpoints_run.RunInteractive()
} else {
err3 = endpoints_run.RunNonInteractive(arguments.GetConfigFile())
if err3 != nil {
logging.Fatal(err3)
}
}
return
} else {
endpoints_run.RunInteractive()
}
}

View File

@@ -5,8 +5,6 @@ package binary
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/core/logging"
"ads/internal/core/metrics"
)
@@ -30,24 +28,27 @@ Outputs: Position von x in L, sonst 1 wenn x nicht in L.
*/
func BinarySearch(L []int, x int) int {
if len(L) == 0 {
logging.LogDebug(fmt.Sprintf("x nicht in L"))
logging.Debug("x nicht in L.")
return -1
}
metrics.AddTimeCost()
m := int(len(L) / 2)
if L[m] == x {
logging.LogDebug(fmt.Sprintf("x in Position m gefunden"))
logging.Debug("Suche in %v .. %v; m = %v; L[m] = x ==> Element gefunden.", 0, len(L)-1, m)
return m
} else if len(L) == 1 {
logging.Debug("L enthält 1 Element; L[m] =/= x; ==> x nicht in L.")
return -1
} else if x < L[m] {
logging.LogDebug(fmt.Sprintf("Suche in linker Hälfte fortsetzen."))
logging.Debug("Suche in %v .. %v; m = %v; L[m] = %v > x ==> Suche in linker Hälfte fortsetzen.", 0, len(L)-1, m, L[m])
index := BinarySearch(L[:m], x)
return index
} else { // } else if x > L[m] {
logging.LogDebug(fmt.Sprintf("Suche in rechter Hälfte fortsetzen."))
logging.Debug("Suche in %v .. %v; m = %v; L[m] = %v < x ==> Suche in rechter Hälfte fortsetzen.", 0, len(L)-1, m, L[m])
index := BinarySearch(L[m+1:], x)
if index >= 0 {
index += (m + 1) // NOTE: muss Indexwert kompensieren
if index == -1 {
return -1 // wenn nicht gefunden
}
return index
return index + (m + 1) // NOTE: muss Indexwert kompensieren
}
}

View File

@@ -5,7 +5,6 @@ package interpol
* ---------------------------------------------------------------- */
import (
"fmt"
"math"
"ads/internal/core/logging"
@@ -31,23 +30,22 @@ Outputs: Position von x in L, sonst 1 wenn x nicht in L.
*/
func InterpolationSearch(L []int, x int, u int, v int) int {
if len(L) == 0 {
logging.LogDebug(fmt.Sprintf("Liste L leer, also x nicht in L"))
logging.Debug("Liste L leer, also x nicht in L")
return -1
} else if !(L[u] <= x && x <= L[v]) {
logging.LogDebug(fmt.Sprintf("x liegt außerhalb der Grenzen von L"))
logging.Debug("x liegt außerhalb der Grenzen von L")
return -1
}
metrics.AddTimeCost()
p := getSuchposition(L, x, u, v)
logging.LogDebug(fmt.Sprintf("Interpolante von x in (u, v)=(%[1]v, %[2]v) ist p = %[3]v.", u, v, p))
if L[p] == x {
logging.LogDebug(fmt.Sprintf("x in Position p gefunden"))
logging.Debug("Interpolante in (%[1]v, %[2]v) ist p = %[3]v; L[p] == x; ===> Element gefunden", u, v, p)
return p
} else if x < L[p] {
logging.LogDebug(fmt.Sprintf("Suche in linker Hälfte fortsetzen."))
logging.Debug("Interpolante in (%[1]v, %[2]v) ist p = %[3]v; L[p] > x; ===> suche in linker Hälfte", u, v, p)
return InterpolationSearch(L, x, u, p-1)
} else { // } else if x > L[p] {
logging.LogDebug(fmt.Sprintf("Suche in rechter Hälfte fortsetzen."))
logging.Debug("Interpolante in (%[1]v, %[2]v) ist p = %[3]v; L[p] < x; ===> suche in rechter Hälfte", u, v, p)
return InterpolationSearch(L, x, p+1, v)
}
}

View File

@@ -5,8 +5,6 @@ package ith_element
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/internal/core/utils"
@@ -41,10 +39,10 @@ func FindIthSmallest(L []int, i int) int {
minValue := L[index]
// Falls i = 1, dann wird das Minimum gesucht, sonst Minimum entfernen und nach i-1. Element suchen
if i == 1 {
logging.LogDebug("Das i. kleinste Element wurde gefunden.")
logging.Debug("Das i. kleinste Element wurde gefunden.")
return minValue
} else {
logging.LogDebug(fmt.Sprintf("Entferne Minimum: %[1]v.", minValue))
logging.Debug("Entferne Minimum: %[1]v.", minValue)
i = i - 1
L_ := utils.PopIndexListInt(L, index) // entferne Element mit Index = index
return FindIthSmallest(L_, i)
@@ -83,13 +81,13 @@ func FindIthSmallestDC(L []int, i int) int {
}
// Fallunterscheidung:
if len(Ll) == i-1 {
logging.LogDebug(fmt.Sprintf("Es gibt i-1 Elemente vor p=%[1]v. ==> i. kleinste Element = p", p))
logging.Debug("Es gibt i-1 Elemente vor p=%[1]v. ==> i. kleinste Element = p", p)
return p
} else if len(Ll) >= i {
logging.LogDebug(fmt.Sprintf("Es gibt >= i Elemente vor p=%[1]v. ==> Suche in linker Hälfte!", p))
logging.Debug("Es gibt >= i Elemente vor p=%[1]v. ==> Suche in linker Hälfte!", p)
return FindIthSmallestDC(Ll, i)
} else {
logging.LogDebug(fmt.Sprintf("Es gibt < i-1 Elemente vor p=%[1]v. ==> Suche in rechter Hälfte!", p))
logging.Debug("Es gibt < i-1 Elemente vor p=%[1]v. ==> Suche in rechter Hälfte!", p)
i = i - (len(Ll) + 1)
return FindIthSmallestDC(Lr, i)
}

View File

@@ -5,11 +5,9 @@ package jump
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/algorithms/search/sequential"
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/pkg/algorithms/search/sequential"
)
/* ---------------------------------------------------------------- *
@@ -44,14 +42,14 @@ func JumpSearchLinear(L []int, x int, m int) int {
block := L[i0:i1]
elementAfterBlock := block[len(block)-1] + 1
if x < elementAfterBlock {
logging.LogDebug(fmt.Sprintf("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1))
logging.Debug("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1)
index := sequential.SequentialSearch(block, x)
if index >= 0 {
index += i0 // NOTE: muss wegen Offset kompensieren
if index == -1 {
return -1 // wenn nicht gefunden
}
return index
return index + i0 // NOTE: muss wegen Offset kompensieren
}
logging.LogDebug(fmt.Sprintf("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1))
logging.Debug("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1)
i0 = i1
i1 += m
}
@@ -83,14 +81,14 @@ func JumpSearchExponentiell(L []int, x int) int {
block := L[i0:i1]
elementAfterBlock := block[len(block)-1] + 1
if x < elementAfterBlock {
logging.LogDebug(fmt.Sprintf("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1))
logging.Debug("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1)
index := sequential.SequentialSearch(block, x)
if index >= 0 {
index += i0 // NOTE: muss wegen Offset kompensieren
if index == -1 {
return -1 // wenn nicht gefunden
}
return index
return index + i0 // NOTE: muss wegen Offset kompensieren
}
logging.LogDebug(fmt.Sprintf("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1))
logging.Debug("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1)
i0 = i1
i1 *= 2
}

View File

@@ -5,8 +5,6 @@ package poison
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/internal/core/utils"
@@ -32,17 +30,17 @@ Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1.
NOTE: Zeitkosten hier messen nur die Anzahl der Vorkoster.
*/
func FindPoison(L []int) int {
logging.LogDebug("Bereite Vorkoster vor")
logging.Debug("Bereite Vorkoster vor")
n := len(L)
testers := [][]int{}
for i := 0; i < n; i++ {
metrics.AddSpaceCost()
logging.LogDebug(fmt.Sprintf("Füge Vorkoster hinzu, der nur Getränk %[1]v testet.", i))
logging.Debug("Füge Vorkoster hinzu, der nur Getränk %[1]v testet.", i)
testers = append(testers, []int{i})
}
logging.LogDebug("Warte auf Effekte")
logging.Debug("Warte auf Effekte")
effects := waitForEffects(L, testers)
logging.LogDebug("Effekte auswerten, um vergiftete Getränke zu lokalisieren.")
logging.Debug("Effekte auswerten, um vergiftete Getränke zu lokalisieren.")
poisened := evaluateEffects(testers, effects)
if len(poisened) > 0 {
return poisened[0]
@@ -64,7 +62,7 @@ Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1.
NOTE: Zeitkosten hier messen nur die Anzahl der Vorkoster.
*/
func FindPoisonFast(L []int) int {
logging.LogDebug("Bereite Vorkoster vor")
logging.Debug("Bereite Vorkoster vor")
n := len(L)
p := utils.LengthOfBinary(n)
testers := [][]int{}
@@ -85,13 +83,13 @@ func FindPoisonFast(L []int) int {
* Darum zählen wir nicht 2 sondern 1 Vorkoster.
*/
metrics.AddSpaceCost(1)
logging.LogDebug(fmt.Sprintf("Füge Vorkoster hinzu, der alle Getränke k testet mit %[1]v. Bit von k = 0.", i))
logging.Debug("Füge Vorkoster hinzu, der alle Getränke k testet mit %[1]v. Bit von k = 0.", i)
testers = append(testers, tester0)
testers = append(testers, tester1)
}
logging.LogDebug("Warte auf Effekte")
logging.Debug("Warte auf Effekte")
effects := waitForEffects(L, testers)
logging.LogDebug("Effekte auswerten, um vergiftete Getränke zu lokalisieren.")
logging.Debug("Effekte auswerten, um vergiftete Getränke zu lokalisieren.")
poisened := evaluateEffects(testers, effects)
if len(poisened) > 0 {
return poisened[0]

View File

@@ -5,8 +5,6 @@ package sequential
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/core/logging"
"ads/internal/core/metrics"
)
@@ -30,10 +28,10 @@ func SequentialSearch(L []int, x int) int {
for i := 0; i < n; i++ {
metrics.AddTimeCost()
if L[i] == x {
logging.LogDebug(fmt.Sprintf("Element in Position %[1]v gefunden.", i))
logging.Debug("Element in Position %[1]v gefunden.", i)
return i
}
logging.LogDebug(fmt.Sprintf("Element nicht in Position %[1]v.", i))
logging.Debug("Element nicht in Position %[1]v.", i)
}
return -1
}

View File

@@ -0,0 +1,81 @@
package next_greater_element
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/pkg/data_structures/stacks"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* ALGORITHM next greater element
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen.
Outputs: Liste von Paaren von Elementen und ihrem nächsten größeren Element
*/
func NextGreaterElement(L []int) [][2]int {
output := [][2]int{}
S := stacks.CREATE()
S.INIT()
for i := 0; i < len(L); i++ {
logging.Debug("Stack S | %v", S)
logging.Debug("Nächstes List-Element L[%v] = %v betrachten", i, L[i])
nextElement := L[i]
logging.Debug("Alle top Elemente vom Stack, die < nextElement sind, mit L[i] paaren")
// Führe aus, bis top Element >= nextElement oder Stack leer ist.
for !S.EMPTY() { // ACHTUNG: schreibe 'while' im Pseudocode, denn dies ist eine while-Schleife in golang
element := S.TOP()
if element < nextElement {
// falls top Element < next Element, zum Output hinzufügen und vom Stack entfernen
logging.Debug("Stack S | %v; top Element < nextElement; ==> pop und Paar zum Output hinzufügen", S)
output = append(output, [2]int{element, nextElement})
S.POP()
metrics.AddMovesCost()
logging.Debug("Stack S | %v", S)
} else if element > nextElement {
// falls top Element > next Element, auf Stack lassen und Schleife abbrechen.
break
} else {
// falls top Element == next Element, vom Stack entfernen und Schleife abbrechen.
S.POP()
metrics.AddMovesCost()
break
}
}
logging.Debug("L[%v] auf Stack legen", i)
S.PUSH(nextElement)
metrics.AddMovesCost()
}
logging.Debug("Stack S | %v", S)
// was übrig bleibt hat kein größeres Element
logging.Debug("Alles übrige auf Stack hat kein nächstes größeres Element")
for !S.EMPTY() { // ACHTUNG: schreibe 'while' im Pseudocode, denn dies ist eine while-Schleife in golang
logging.Debug("Stack S | %v", S)
element := S.TOP()
output = append(output, [2]int{element, -1})
S.POP()
metrics.AddMovesCost()
}
logging.Debug("Stack S | %v", S)
return output
}

View File

@@ -0,0 +1,89 @@
package next_greater_element
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/metrics"
"ads/internal/setup"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* CHECKS
* ---------------------------------------------------------------- */
func preChecks(L []int, _ ...interface{}) error {
// TODO
return nil
}
func postChecks(L []int, pairs [][2]int, _ ...interface{}) error {
// TODO
return nil
}
/* ---------------------------------------------------------------- *
* ALGORITHM binary search + Display
* ---------------------------------------------------------------- */
func FancyNextGreaterElement(input_L []int) ([][2]int, error) {
var name = "Next Greater Element"
var inputs = map[string]interface{}{
"L": input_L,
}
var outputs map[string]interface{}
var (
pairs [][2]int
)
var err error
do_once := true
for do_once {
do_once = false
// Start Message
setup.DisplayStartOfAlgorithm(name, inputs)
// Prechecks:
if setup.AppConfigPerformChecks() {
err = preChecks(input_L)
if err != nil {
break
}
}
// Ausführung des Algorithmus:
metrics.ResetMetrics()
metrics.StartMetrics()
pairs = NextGreaterElement(input_L)
metrics.StopMetrics()
outputs = map[string]interface{}{
"pairs": pairs,
}
// Metriken anzeigen
if setup.AppConfigShowMetrics() {
setup.DisplayMetrics()
}
// End Message
setup.DisplayEndOfAlgorithm(outputs)
// Postchecks:
if setup.AppConfigPerformChecks() {
err = postChecks(input_L, pairs)
if err != nil {
break
}
}
}
return pairs, err
}

View File

@@ -5,8 +5,6 @@ package maxsubsum
* ---------------------------------------------------------------- */
import (
"fmt"
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/internal/core/utils"
@@ -41,7 +39,7 @@ func MaxSubSum(L []int) (int, int, int) {
if maxSum_ > maxSum {
k += i // NOTE: muss wegen Offset kompensieren
maxSum, u, v = maxSum_, i, k
logging.LogDebug(fmt.Sprintf("max Teilsumme aktualisiert: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
logging.Debug("max Teilsumme aktualisiert: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum)
}
}
return maxSum, u, v
@@ -85,13 +83,13 @@ func MaxSubSumDC(L []int) (int, int, int) {
maxSum = utils.MaxInt(maxSum1, maxSum2, maxSum3)
if maxSum == maxSum1 {
maxSum, u, v = maxSum1, u1, v1
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in linker Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
logging.Debug("max Teilsumme kommt in linker Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum)
} else if maxSum == maxSum3 {
maxSum, u, v = maxSum3, u3, v3
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in Überschneidung vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
logging.Debug("max Teilsumme kommt in Überschneidung vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum)
} else { // } else if maxSum == maxSum2 {
maxSum, u, v = maxSum2, u2, v2
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in rechter Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
logging.Debug("max Teilsumme kommt in rechter Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum)
}
}
return maxSum, u, v

View File

@@ -0,0 +1,81 @@
package queues
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"fmt"
"strings"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* TYPE
* ---------------------------------------------------------------- */
type QueueInt struct {
values *[]int
}
/* ---------------------------------------------------------------- *
* METHODS queues
* ---------------------------------------------------------------- */
func CREATE() QueueInt {
return QueueInt{}
}
func (S *QueueInt) INIT() {
S.values = &[]int{}
}
func (S QueueInt) Length() int {
if S.values == nil {
return 0
}
return len(*S.values)
}
func (S QueueInt) String() string {
if S.EMPTY() {
return "-"
}
values := []string{}
n := S.Length()
for i := n - 1; i >= 0; i-- {
value := (*S.values)[i]
values = append(values, fmt.Sprintf("%v", value))
}
return fmt.Sprintf(strings.Join(values, " -> "))
}
func (S QueueInt) EMPTY() bool {
return S.Length() == 0
}
func (S *QueueInt) ENQUEUE(x int) {
if S.values == nil {
panic("Queue not initialised!")
}
*S.values = append(*S.values, x)
}
func (S *QueueInt) FRONT() int {
if S.EMPTY() {
panic("Cannot read from empty queue!")
}
return (*S.values)[0]
}
func (S *QueueInt) DEQUEUE() {
if S.EMPTY() {
panic("Cannot remove from empty queue!")
}
*S.values = (*S.values)[1:]
}

View File

@@ -0,0 +1,81 @@
package stacks
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"fmt"
"strings"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* TYPE
* ---------------------------------------------------------------- */
type StackInt struct {
values *[]int
}
/* ---------------------------------------------------------------- *
* METHODS stacks
* ---------------------------------------------------------------- */
func CREATE() StackInt {
return StackInt{}
}
func (S *StackInt) INIT() {
S.values = &[]int{}
}
func (S StackInt) Length() int {
if S.values == nil {
return 0
}
return len(*S.values)
}
func (S StackInt) String() string {
if S.EMPTY() {
return "-"
}
values := []string{}
for _, value := range *S.values {
values = append(values, fmt.Sprintf("%v", value))
}
return fmt.Sprintf(strings.Join(values, ", "))
}
func (S StackInt) EMPTY() bool {
return S.Length() == 0
}
func (S *StackInt) PUSH(x int) {
if S.values == nil {
panic("Stack not initialised!")
}
*S.values = append(*S.values, x)
}
func (S *StackInt) TOP() int {
if S.EMPTY() {
panic("Cannot read from empty stack!")
}
n := S.Length()
return (*S.values)[n-1]
}
func (S *StackInt) POP() {
if S.EMPTY() {
panic("Cannot remove from empty stack!")
}
n := S.Length()
*S.values = (*S.values)[:(n - 1)]
}

38
code/python/.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
*
!/.gitignore
################################################################
# MAIN FOLDER
################################################################
!/Makefile
!/README.md
!/requirements
################################################################
# PROJECT FILES
################################################################
!/assets
!/assets/VERSION
!/assets/LOGO
!/assets/config.yml
!/src
!/src/**/
!/src/**/*.py
!/test
!/test/**/
!/test/**/*.py
## nicht synchronisieren:
!/build
################################################################
# ARTEFACTS
################################################################
/**/__pycache__
/**/.DS_Store
/**/__archive__*

27
code/python/Makefile Normal file
View File

@@ -0,0 +1,27 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# LOCAL ARGUMENTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PATH_TO_CONFIG:=../config.yml#<- kann durch Pfad zur eigenen yml-Datei ersetzt werden
COLOUR:=true
PYTHON:=python3
PIP:=python3 -m pip
## für Windows weichen Defaultsettings leicht ab:
ifeq ($(OS),Windows_NT)
COLOUR:=false# <- man kann als 'true' setzen, aber in Windows funktioniert es möglicherweise nicht
PYTHON:=py -3
PIP:=py -3 -m pip
endif
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TARGETS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
setup: # TODO: Variant mit venv
${PIP} install -r requirements;
run: # non-interactive mode mit config-datei
${PYTHON} src/main.py run --debug --colour ${COLOUR} --config "${PATH_TO_CONFIG}"
run-it: # interactive mode
${PYTHON} src/main.py run --it --debug --colour ${COLOUR}
# Do everything:
all: setup run
all-it: setup run-it

78
code/python/README.md Normal file
View File

@@ -0,0 +1,78 @@
# ADS - Python-Projekt #
**Python** ist eine sehr verbreitete Sprache, die eine Riesencommunity hat.
Sie ist sehr populär unter Wissenschaftlern und Ingenieuren.
Ein Vorteil mit Python ist, dass man sehr leicht und schnell Prototypen entwickeln kann.
Dieses Projekt ist erneut kein nötiger Bestandteil des Kurses,
sondern nur für Wissbegierige gedacht.
Zunächst bietet sich an, sich die Algorithmen im Unterordner [`src/algorithms`](./src/algorithms) anzuschauen,
z.&nbsp;B. [`src/algorithms/search/binary.py`](./src/algorithms/search/binary.py) für den Binärsuchalgorithmus,
ohne irgendetwas installieren zu müssen.
**HINWEIS 1:** _Bei meiner Implementierung kann es zu leichten Abweichungen kommen. Bitte **stets** an dem Material im VL-Skript sich orientieren. Der Hauptzweck der Code-Projekte besteht darin, dass Wissbegierige die Algorithmen konkret ausprobieren können. Alle theoretischen Aspekte werden jedoch im Skript und in den Übungen ausführlicher erklärt._
Den Code kann man auch durch die u.&nbsp;s. Anweisungen selber austesten.
**HINWEIS 2:** _Während hier die Anweisungen ausführlich sind und klappen sollten,
bitte nur auf eigener Gewähr diesen Code benutzen._
### Systemvoraussetzungen ###
- Python version 3.x.x (idealerweise zumindest 3.9.5)
## Einrichten mittels **Makefile** ##
Führe jeweils
```bash
make setup
make run
# oder für interaktiven Modus
make run-it
```
aus, um Packages zu installieren
bzw. den Code auszuführen.
Siehe [`Makefile`](./Makefile) für Details zu den Vorgängen.
Wer Makefile benutzt kann die u.&nbsp;s. Anweisungen ignorieren.
## Setup ##
Requirements (Packages) einmalig mittels
```bash
python3 -m pip install -r requirements; # linux, osx
py -3 -m pip install -r requirements; # Windows
```
installieren lassen.
## Ausführung ##
Zum Anzeigen der Hilfsanleitung in einer Konsole folgenden Befehl ausführen
```bash
python3 src/main.py help; # linux, OSX
py -3 src/main.py help; # Windows
```
Zur Ausführung der Algorithmen auf Fälle in der [Config-Datei](./../config.yml)
in einer Konsole folgenden Befehl ausführen
```bash
python3 src/main.py run; # linux, OSX
py -3 src/main.py run; # Windows
```
Mit dem `--debug` Flag werden Infos über Schritte mit angezeigt.
</br>
Mit dem `--colour true/false` Argument wird der Farbenmodus ein-/ausgeschaltet.
</br>
Mit dem `--config path/to/config` Argument kann man andere Config-Dateien verwenden.
## Entwicklung ##
Gerne kann man den Code benutzen, in einem eigenen Repository weiter entwickeln,
und mit den im Kurs präsentierten Algorithmen und Fällen herumexperimentieren.

3
code/python/assets/LOGO Normal file
View File

@@ -0,0 +1,3 @@
+--------------------+
| \033[32;1mAlgoDat I\033[0m |
+--------------------+

View File

@@ -0,0 +1 @@
0.0.0

View File

@@ -0,0 +1,7 @@
info:
title: "App für ADS1"
description: "Interne Configurationsdatei"
options:
display: true
checks: false
metrics: true

View File

@@ -17,6 +17,7 @@ import sys;
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), '..')));
from src.setup.cli import *;
from src.endpoints.exports import *;
from src.main import enter;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -24,10 +25,18 @@ from src.main import enter;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if __name__ == '__main__':
sys.tracebacklimit = 0;
sys.tracebacklimit = 0;
try:
args = GetArgumentsFromCli(sys.argv[1:]);
args = GetArgumentsFromCli(*sys.argv[1:]);
except:
endpoint_help();
exit(1);
enter(quiet=args.quiet, debug=args.debug, mode=args.mode[0], path=args.path);
enter(
mode=args.mode,
it=args.it,
quiet=args.quiet,
debug=args.debug,
checks=args.checks,
colour=args.colour,
config=args.config,
);

View File

@@ -6,4 +6,5 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.algorithms.search.exports import *;
from src.algorithms.stacks.exports import *;
from src.algorithms.sum.exports import *;

View File

@@ -5,9 +5,10 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import functools;
import functools
from src.core.log import *;
from src.setup import appconfig;
from src.core.metrics import *;
from src.setup.display import *;
@@ -38,8 +39,6 @@ nonnestedAlgorithms = OneShot();
def algorithmInfos(
name: str,
checks: bool = True,
metrics: bool = None,
outputnames: List[str] = ['result'],
preChecks: Any = None,
postChecks: Any = None
@@ -67,7 +66,7 @@ def algorithmInfos(
# Initialisierung
DisplayStartOfAlgorithm(name, **inputs);
# Prechecks
if checks and callable(preChecks):
if appconfig.AppConfigPerformChecks() and callable(preChecks):
preChecks(**inputs);
# Metriken initialisieren + starten
ResetMetrics();
@@ -85,11 +84,11 @@ def algorithmInfos(
outputs_ = outputs if isinstance(outputs, tuple) else tuple([outputs]);
outputsNamed = { outputnames[k]: value for k, value in enumerate(outputs_) };
# Letzte Messages
if metrics:
if appconfig.AppConfigShowMetrics():
DisplayMetrics();
DisplayEndOfAlgorithm(**outputsNamed);
# Postchecks
if checks and callable(postChecks):
if appconfig.AppConfigPerformChecks() and callable(postChecks):
postChecks(**inputs, **outputsNamed);
except Exception as e:
nonnestedAlgorithms.state = state1;

View File

@@ -37,7 +37,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
# ALGORITHM binary search
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Binärsuchalgorithmus', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Binärsuchalgorithmus', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def BinarySearch(L: List[int], x: int) -> int:
'''
Inputs: L = Liste von Zahlen, x = Zahl.

View File

@@ -37,7 +37,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
# ALGORITHM interpolation
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Interpolationssuchalgorithmus', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Interpolationssuchalgorithmus', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def InterpolationSearch(L: List[int], x: int, u: int, v: int) -> int:
'''
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.

View File

@@ -36,7 +36,7 @@ def postChecks(L: List[int], i: int, value: int, **_):
# ALGORITHM find ith smallest element
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Auswahlproblem (i. kleinstes Element)', outputnames=['value'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Auswahlproblem (i. kleinstes Element)', outputnames=['value'], preChecks=preChecks, postChecks=postChecks)
def FindIthSmallest(L: List[int], i: int) -> int:
'''
Inputs: L = Liste von Zahlen, i = Ordinalzahl
@@ -68,7 +68,7 @@ def FindIthSmallest(L: List[int], i: int) -> int:
# ALGORITHM find ith smallest element (D & C)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Auswahlproblem (i. kleinstes Element, D & C)', outputnames=['value'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Auswahlproblem (i. kleinstes Element, D & C)', outputnames=['value'], preChecks=preChecks, postChecks=postChecks)
def FindIthSmallestDC(L: List[int], i: int) -> int:
'''
Inputs: L = Liste von Zahlen, i = Ordinalzahl

View File

@@ -39,7 +39,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
# ALGORITHM jump search
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Sprungsuche', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Sprungsuche', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def JumpSearchLinear(L: List[int], x: int, m: int) -> int:
'''
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
@@ -71,7 +71,7 @@ def JumpSearchLinear(L: List[int], x: int, m: int) -> int:
# ALGORITHM jump search - exponentiell
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Sprungsuche (exponentiell)', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Sprungsuche (exponentiell)', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def JumpSearchExponentiell(L: List[int], x: int) -> int:
'''
Inputs: L = Liste von Zahlen, x = Zahl.

View File

@@ -36,7 +36,7 @@ def postChecks(L: List[int], index: int, **_):
# ALGORITHM find poison
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Giftsuche (O(n) Vorkoster)', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Giftsuche (O(n) Vorkoster)', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def FindPoison(L: List[int]) -> int:
'''
Inputs: L = Liste von Getränken: durch 0-1 Werte wird dargestellt, ob ein Getränk vergiftet ist.
@@ -64,7 +64,7 @@ def FindPoison(L: List[int]) -> int:
# ALGORITHM find poison fast
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Giftsuche (O(log(n)) Vorkoster)', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Giftsuche (O(log(n)) Vorkoster)', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def FindPoisonFast(L: List[int]) -> int:
'''
Inputs: L = Liste von Getränken: durch 0-1 Werte wird dargestellt, ob ein Getränk vergiftet ist.

View File

@@ -37,7 +37,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
# ALGORITHM sequential search
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='Sequenziellsuchalgorithmus', outputnames=['index'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='Sequenziellsuchalgorithmus', outputnames=['index'], preChecks=preChecks, postChecks=postChecks)
def SequentialSearch(L: List[int], x: int) -> int:
'''
Inputs: L = Liste von Zahlen, x = Zahl.

View File

@@ -0,0 +1,8 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.algorithms.stacks.next_greater_element import NextGreaterElement;

View File

@@ -0,0 +1,91 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.local.typing import *;
from src.core.log import *;
from src.core.metrics import *;
from src.data_structures.stacks import Stack;
from src.algorithms.methods import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES/CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CHECKS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def preChecks(L: List[int], **_):
# TODO
return;
def postChecks(L: List[int], **_):
# TODO
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ALGORITHM next greater element
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='NextGreaterElement (with stacks)', outputnames=['pairs'], preChecks=preChecks, postChecks=postChecks)
def NextGreaterElement(L: List[int]) -> List[Tuple[int,int]]:
'''
Inputs: L = Liste von Zahlen.
Outputs: Liste von Paaren von Elementen und ihrem nächsten größeren Element
'''
output = [];
S = Stack();
S.INIT();
for i in range(len(L)):
logDebug('Stack S | {S}'.format(S=S));
logDebug('Nächstes List-Element L[{i}] = {el} betrachten'.format(i=i, el=L[i]));
nextElement = L[i];
logDebug('Alle top Elemente vom Stack, die < nextElement sind, mit L[i] paaren');
# Führe aus, bis top Element >= nextElement oder Stack leer ist.
logDebug('Stack S | {S}'.format(S=S));
while not S.EMPTY():
element = S.TOP();
# falls element < next Element, zum Output hinzufügen und vom Stack entfernen
if element < nextElement:
logDebug('Stack S | {S}; top Element < nextElement; ==> pop und Paar zum Output hinzufügen'.format(S=S))
output.append((element, nextElement));
S.POP();
AddMovesCost();
logDebug('Stack S | {S}'.format(S=S));
# falls top Element > next Element, auf Stack lassen und Schleife abbrechen.
elif element > nextElement:
break
# falls top Element == next Element, vom Stack entfernen und Schleife abbrechen.
else:
S.POP()
AddMovesCost()
break
logDebug('Stack S | {S}'.format(S=S));
logDebug('L[{i}] auf Stack legen'.format(i=i));
S.PUSH(nextElement);
AddMovesCost();
logDebug('Stack S | {S}'.format(S=S));
# was übrig bleibt hat kein größeres Element
logDebug('Alles übrige auf Stack hat kein nächstes größeres Element')
while not S.EMPTY():
logDebug('Stack S | {S}'.format(S=S));
element = S.TOP();
S.POP();
AddMovesCost();
output.append((element, -1));
logDebug('Stack S | {S}'.format(S=S))
return output;

View File

@@ -33,7 +33,7 @@ def postChecks(L: List[int], **_):
# ALGORITHM max sub sum
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='MaxSubSum (Maximale Teilsumme)', outputnames=['maxSum', 'index_from', 'index_to'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='MaxSubSum (Maximale Teilsumme)', outputnames=['maxSum', 'index_from', 'index_to'], preChecks=preChecks, postChecks=postChecks)
def MaxSubSum(L: List[float]) -> Tuple[float, int, int]:
'''
Inputs: L = Liste von Zahlen
@@ -58,7 +58,7 @@ def MaxSubSum(L: List[float]) -> Tuple[float, int, int]:
# ALGORITHM max sub sum (D & C)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@algorithmInfos(name='MaxSubSum (Maximale Teilsumme mit D & C)', outputnames=['maxSum', 'index_from', 'index_to'], checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks)
@algorithmInfos(name='MaxSubSum (Maximale Teilsumme mit D & C)', outputnames=['maxSum', 'index_from', 'index_to'], preChecks=preChecks, postChecks=postChecks)
def MaxSubSumDC(L: List[float]) -> Tuple[float, int, int]:
'''
Inputs: L = Liste von Zahlen

View File

@@ -10,13 +10,16 @@ from src.local.misc import *;
from src.local.system import *;
from src.local.typing import *;
from src.core.utils import StripAnsi;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_logging_prefix: str = '';
_quietmode: bool = False;
_debugmode: bool = False;
_debugmode: bool = True;
_ansimode: bool = False;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHOD get/set quiet mode, logging depth, timer
@@ -38,6 +41,14 @@ def SetDebugMode(mode: bool):
_debugmode = mode;
return;
def GetAnsiMode() -> bool:
return _ansimode;
def SetAnsiMode(mode: bool):
global _ansimode;
_ansimode = mode;
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Logging
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -48,7 +59,10 @@ def logGeneric(tag: str, *lines: Any, file: io.TextIOWrapper, force: bool = Fals
tag = '' if tag == '' else tag + ' ';
file = file or sys.stdout;
for line in lines:
print('{}{}{}'.format('', tag, line), file=file);
line = '{}{}{}'.format('', tag, line);
if not _ansimode:
line = StripAnsi(line);
print(line, file=file);
if not tag_all:
tag = '';
return;

View File

@@ -22,24 +22,20 @@ _tmr = None;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Counter(object):
_nr_steps: int;
value: int;
def __init__(self):
self.reset();
def __str__(self) -> str:
return str(self._nr_steps);
@property
def numberOfStep(self) -> int:
return self._nr_steps;
return str(self.value);
def add(self, n: int = 1):
self._nr_steps += n;
self.value += n;
return self;
def reset(self):
self._nr_steps = 0;
self.value = 0;
return self;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -86,6 +82,7 @@ class Timer(object):
## Initialisierung:
_ctr_time = Counter();
_ctr_moves = Counter();
_ctr_space = Counter();
_tmr = Timer();
@@ -95,10 +92,12 @@ _tmr = Timer();
def ResetMetrics():
global _ctr_time;
global _ctr_moves;
global _ctr_space;
global _tmr;
_ctr_time.reset();
_ctr_moves.reset();
_ctr_space.reset();
_tmr.reset();
return;
@@ -116,16 +115,29 @@ def AddTimeCost(n: int = 1):
_ctr_time.add(n);
return;
def AddMovesCost(n: int = 1):
global _ctr_moves;
_ctr_moves.add(n);
return;
def AddSpaceCost(n: int = 1):
global _ctr_space;
_ctr_space.add(n);
return;
def SetSpaceCost(n: int):
global _ctr_space;
_ctr_space.value = n;
return;
def GetTimeCost() -> int:
return _ctr_time.numberOfStep;
return _ctr_time.value;
def GetMovesCost() -> int:
return _ctr_moves.value;
def GetSpaceCost() -> int:
return _ctr_space.numberOfStep;
return _ctr_space.value;
def GetTimeElapsed() -> timedelta:
global _tmr;

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import re;
from textwrap import dedent;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS ansi
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def StripAnsi(text: str) -> str:
return re.sub(r'\x1b[^m]*m', '', text);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS strings
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def DedentIgnoreFirstLast(text: str) -> str:
text = '\n'.join(re.split(r'\n', text)[1:][:-1])
return dedent(text);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS strings -> bool
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def IsTrue(text: str) -> bool:
text = text.strip();
if re.match(r'^(true|t|yes|y|1|\+|\+1)$', text, re.IGNORECASE):
return True;
return False;
def IsFalse(text: str) -> bool:
text = text.strip();
if re.match(r'^(false|f|no|n|0|-|-1)$', text, re.IGNORECASE):
return True;
return False;

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from local.typing import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES/CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CLASS Queue
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Queue(object):
_initialised: bool;
values: List[int];
def __init__(self):
self._initialised = False;
def INIT(self):
self.values = [];
self._initialised = True;
def EMPTY(self) -> bool:
return not self._initialised or len(self.values) == 0;
def ENQUEUE(self, x: int):
if not self._initialised:
raise Exception('Queue not initialised!')
self.values.append(x);
def FRONT(self) -> int:
if self.EMPTY():
raise Exception('Cannot read from empty queue!')
return self.values[0];
def DEQUEUE(self) -> int:
if self.EMPTY():
raise Exception('Cannot remove from empty queue!')
self.values = self.values[1:];
def __str__(self) -> str:
if len(self.values) == 0:
return '-';
return ', '.join([str(x) for x in self.values]);

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from local.typing import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES/CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# CLASS Stack
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Stack(object):
_initialised: bool;
values: List[int];
def __init__(self):
self._initialised = False;
def INIT(self):
self.values = [];
self._initialised = True;
def EMPTY(self) -> bool:
return not self._initialised or len(self.values) == 0;
def PUSH(self, x: int):
if not self._initialised:
raise Exception('Stack not initialised!');
self.values.append(x);
def TOP(self) -> int:
if self.EMPTY():
raise Exception('Cannot read from empty stack!');
return self.values[-1];
def POP(self) -> int:
if self.EMPTY():
raise Exception('Cannot remove from empty stack!');
self.values = self.values[:-1];
def __str__(self) -> str:
if len(self.values) == 0:
return '-';
return ', '.join([str(x) for x in self.values]);

View File

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# EXPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.endpoints.print import version as endpoint_version;
from src.endpoints.print import help as endpoint_help;
from src.endpoints.run import runInteractive as endpoint_runInteractive;
from src.endpoints.run import runNonInteractive as endpoint_runNonInteractive;

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.core.log import *;
from src.setup import assets;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ENDPOINT version
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def version():
logPlain(assets.Version());
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ENDPOINT help
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def help():
logPlain(assets.Help());
return;

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.core.log import *;
from src.core.config import *;
from src.setup.display import *;
from src.setup import assets;
from src.algorithms.exports import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ENDPOINT run interactive modus
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def runInteractive():
'''
Startet Programm im interaktiven Modus (Konsole).
'''
logPlain(assets.Logo());
logWarn('Interaktiver Modus noch nicht implementiert.');
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ENDPOINT run non-interactive
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def runNonInteractive(path: str):
'''
Liest Fälle aus Configdatei aus und führt Algorithmen darauf aus.
'''
config = ReadConfigFile(path);
cases = GetAttribute(config, 'parts', 'cases', expectedtype=list, default=[]);
logPlain(assets.Logo());
for caseindex, case in enumerate(cases):
command = GetAttribute(case, 'command', expectedtype=str, default='');
descr = GetAttribute(case, 'description', expectedtype=str, default='');
inputs = GetAttribute(case, 'inputs', expectedtype=dict, default={});
DisplayStartOfCase(caseindex, descr);
try:
if command == 'algorithm-search-sequential':
SequentialSearch(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-binary':
BinarySearch(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-interpolation':
InterpolationSearch(L=inputs['L'], x=inputs['x'], u=0, v=len(inputs['L'])-1);
elif command == 'algorithm-search-jump':
JumpSearchLinear(L=inputs['L'], x=inputs['x'], m=inputs['m']);
elif command == 'algorithm-search-jump-exp':
JumpSearchExponentiell(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-ith-element':
FindIthSmallest(L=inputs['L'], i=inputs['i']);
elif command == 'algorithm-search-ith-element-dc':
FindIthSmallestDC(L=inputs['L'], i=inputs['i']);
elif command == 'algorithm-search-poison':
FindPoison(L=inputs['L']);
elif command == 'algorithm-search-poison-fast':
FindPoisonFast(L=inputs['L']);
elif command == 'algorithm-stacks-next-greater-element':
NextGreaterElement(L=inputs['L']);
elif command == 'algorithm-sum-maxsub':
MaxSubSum(L=inputs['L']);
elif command == 'algorithm-sum-maxsub-dc':
MaxSubSumDC(L=inputs['L']);
else:
raise ValueError('Command \033[1m{}\033[0m nicht erkannt'.format(command));
except Exception as e:
logError(e);
DisplayEndOfCase();
return;

View File

@@ -8,80 +8,64 @@
import os;
import sys;
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..')));
os.chdir(os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..', '..', '..')));
_path_to_python_project = os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..'));
sys.path.insert(0, _path_to_python_project);
os.chdir(_path_to_python_project);
from src.core.log import *;
from src.core.config import *;
from src.setup.display import *;
from src.setup.cli import *;
from src.algorithms.exports import *;
from src.setup import appconfig;
from src.endpoints.exports import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES/CONSTANTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PATH_TO_CONFIG: str = 'code/config.yml';
PATH_TO_CONFIG: str = '../config.yml';
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN PROCESS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def enter(quiet: bool, debug: bool, mode: str, path: Any, **_):
SetQuietMode(quiet);
SetDebugMode(debug);
configpath = path if isinstance(path, str) else PATH_TO_CONFIG;
if mode in 'run':
LoopThroughCases(path=configpath);
def enter(
mode: Union[str, None],
it: bool,
quiet: bool,
debug: bool,
checks: bool,
colour: bool,
config: Union[str, None],
**_
):
# Programmeinstellungen initialisieren
if not (mode == 'run' and it):
SetQuietMode(quiet);
SetDebugMode(debug);
SetAnsiMode(colour);
appconfig.SetAppConfigPerformChecks(checks);
config = config if isinstance(config, str) else PATH_TO_CONFIG;
# Wenn der Artefakt ohne Argument aufgerufen wird, keinen Fehler melden, sondern im it-Modus ausführen
if mode is None:
endpoint_runInteractive();
return;
# Sonst Commands behandeln
if mode == 'help':
endpoint_help();
return;
elif mode == 'version':
endpoint_version();
return;
elif mode == 'run':
if it:
endpoint_runInteractive();
else:
endpoint_runNonInteractive(path=config);
return;
else:
DisplayHelpMessage();
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# SECONDARY PROCESSES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def LoopThroughCases(path: str):
'''
Durchlauf aller Testfälle.
'''
config = ReadConfigFile(path);
cases = GetAttribute(config, 'parts', 'cases', expectedtype=list, default=[]);
for caseindex, case in enumerate(cases):
command = GetAttribute(case, 'command', expectedtype=str, default='');
descr = GetAttribute(case, 'description', expectedtype=str, default='');
inputs = GetAttribute(case, 'inputs', expectedtype=dict, default={});
DisplayStartOfCase(caseindex, descr);
try:
if command == 'algorithm-sum-maxsub':
MaxSubSum(L=inputs['L']);
elif command == 'algorithm-sum-maxsub-dc':
MaxSubSumDC(L=inputs['L']);
elif command == 'algorithm-search-sequential':
SequentialSearch(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-binary':
BinarySearch(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-interpolation':
InterpolationSearch(L=inputs['L'], x=inputs['x'], u=0, v=len(inputs['L'])-1);
elif command == 'algorithm-search-jump':
JumpSearchLinear(L=inputs['L'], x=inputs['x'], m=inputs['m']);
elif command == 'algorithm-search-jump-exp':
JumpSearchExponentiell(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-ith-element':
FindIthSmallest(L=inputs['L'], i=inputs['i']);
elif command == 'algorithm-search-ith-element-dc':
FindIthSmallestDC(L=inputs['L'], i=inputs['i']);
elif command == 'algorithm-search-poison':
FindPoison(L=inputs['L']);
elif command == 'algorithm-search-poison-fast':
FindPoisonFast(L=inputs['L']);
else:
raise ValueError('Command \033[1m{}\033[0m nicht erkannt'.format(command));
except Exception as e:
logError(e);
DisplayEndOfCase();
endpoint_runInteractive();
return;
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -91,7 +75,16 @@ def LoopThroughCases(path: str):
if __name__ == '__main__':
sys.tracebacklimit = 0;
try:
args = GetArgumentsFromCli(sys.argv[1:]);
except:
args = GetArgumentsFromCli(*sys.argv[1:]);
except Exception as e:
endpoint_help();
exit(1);
enter(quiet=args.quiet, debug=args.debug, mode=args.mode[0], path=args.path);
enter(
mode=args.mode,
it=args.it,
quiet=args.quiet,
debug=args.debug,
checks=args.checks,
colour=args.colour,
config=args.config,
);

View File

@@ -0,0 +1,66 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.local.io import *;
from src.local.misc import *;
from src.local.system import *;
from src.local.typing import *;
from src.core.config import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_config: Dict[str, bool] = dict(
display = True,
metrics = True,
checks = False,
);
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHOD getters
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def AppConfigInitialise():
'''
Extrahiert Inhalte einer YAML Config und parset dies als Struktur
'''
global _config;
config = ReadConfigFile('assets/config.yml');
_config['display'] = GetAttribute(config, 'options', 'display', expectedtype=bool, default=True);
_config['metrics'] = GetAttribute(config, 'options', 'metrics', expectedtype=bool, default=True);
_config['checks'] = GetAttribute(config, 'options', 'checks', expectedtype=bool, default=True);
return;
def AppConfigFancyMode() -> bool:
return _config['display'];
def AppConfigShowMetrics() -> bool:
return _config['metrics'];
def AppConfigPerformChecks() -> bool:
return _config['checks'];
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHOD setters
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def SetAppConfigFancyMode(mode: bool):
global _config;
_config['display'] = mode;
return;
def SetAppConfigShowMetrics(mode: bool):
global _config;
_config['metrics'] = mode;
return;
def SetAppConfigPerformChecks(mode: bool):
global _config;
_config['checks'] = mode;
return;

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.local.io import *;
from src.core.utils import DedentIgnoreFirstLast
from src.setup.cli import GetArgumentParser;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# METHODS assets
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def Help() -> str:
parser = GetArgumentParser();
with io.StringIO() as fp:
parser.print_help(fp)
text = fp.getvalue();
return text;
def Logo() -> str:
## NOTE: expandiert ansi nicht:
# with open('assets/LOGO', 'r') as fp:
# logo = (''.join(fp.readlines())).strip();
logo = DedentIgnoreFirstLast('''
+--------------------+
| \033[32;1mAlgoDat I\033[0m |
+--------------------+
''') + '\n';
return logo;
def Version() -> str:
with open('assets/VERSION', 'r') as fp:
version = (''.join(fp.readlines())).strip();
return version;

View File

@@ -5,9 +5,13 @@
# IMPORTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from argparse import ArgumentError
from src.local.typing import *;
from src.core.log import *;
from src.core.utils import DedentIgnoreFirstLast;
from src.core.utils import IsTrue;
from src.core.utils import IsFalse;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES
@@ -24,18 +28,37 @@ def GetArgumentParser() -> argparse.ArgumentParser:
if not isinstance(parser, argparse.ArgumentParser):
parser = argparse.ArgumentParser(
prog='code/main.py',
description=dedent('''
description=DedentIgnoreFirstLast('''
\033[93;1mBeschreibung:\033[0m
\033[93;2mEin Programm, das verschiedene Algorithmen aus dem Kurs AlgoDat I testet.\033[0m
\033[93;2mEin Programm zur Ausführung verschiedener Algorithmen aus dem Kurs AlgoDat I.\033[0m
'''),
formatter_class=argparse.RawTextHelpFormatter,
);
parser.add_argument('mode', nargs=1, choices=['run'], help='run = Führt alle Testfälle in der config.yml Datei durch.');
parser.add_argument('--path', nargs=1, type=str, help='Pfad zur alternativen Configdatei.');
parser.add_argument('--debug', action='store_true', help='Debugging Messages stummschalten.')
parser.add_argument('-q', '--quiet', action='store_true', help='Alle console-messages bis auf Errors stummschalten.')
parser.add_argument('mode',
nargs='?',
choices=['version', 'help', 'run'],
help=DedentIgnoreFirstLast('''
help = Hilfsanleitung anzeigen.
version = Version anzeigen.
run = Algorithmen ausführen.
'''),
);
parser.add_argument('--it', action='store_true', help='Startet das Programm im interaktiven Modus.')
parser.add_argument('-q', '--quiet', action='store_true', help='Blendet alle Konsole-Messages aus.')
parser.add_argument('--debug', action='store_true', help='Blendet Debugging-Befehle ein.')
parser.add_argument('--checks', nargs=1, type=str, default=['False'],
help=DedentIgnoreFirstLast('''
(bool) Ob vor und nach Ausführung von Algorithmen Checks
auf Inputs/Outputs ausgeführt werden sollen.
'''),
),
parser.add_argument('--colour', nargs=1, type=str, default=['False'], help='(bool) Ob Logging färblich angezeigt wird.')
parser.add_argument('--config', nargs=1, type=str, help='(string) Pfad zur Configdatei (nur für run Endpunkt).');
return parser;
def GetArgumentsFromCli(cli_args: List[str]) -> argparse.Namespace:
def GetArgumentsFromCli(*cli_args: str) -> argparse.Namespace:
parser = GetArgumentParser();
return parser.parse_args(cli_args);
args = parser.parse_args(cli_args);
args.checks=IsTrue(args.checks[0]);
args.colour=IsTrue(args.colour[0]);
return args;

View File

@@ -69,8 +69,9 @@ def DisplayEndOfAlgorithm(*_: Any, **outputs: Any):
def DisplayMetrics():
logPlain('Dauer der Ausführung: t = \033[1m{}\033[0m'.format(GetTimeElapsed()));
logPlain('Kosten (Zeit): T(n) = \033[1m{}\033[0m'.format(GetTimeCost()));
logPlain('Kosten (Platz): S(n) = \033[1m{}\033[0m'.format(GetSpaceCost()));
logPlain('Kosten (Zeit): T(n) = \033[1m{}\033[0m'.format(displayCost(GetTimeCost())));
logPlain('Kosten (#Züge): M(n) = \033[1m{}\033[0m'.format(displayCost(GetMovesCost())));
logPlain('Kosten (Platz): S(n) = \033[1m{}\033[0m'.format(displayCost(GetSpaceCost())));
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -80,3 +81,6 @@ def DisplayMetrics():
def DisplayBar(n: int = 80):
logPlain('+{}+'.format('-'*n));
return;
def displayCost(cost: int) -> str:
return str(cost) if cost > 0 else '-';

View File

@@ -6,11 +6,11 @@ Inhaltsverzeichnis
- [Vorlesungswoche 2](./woche2.md)
- [Vorlesungswoche 3](./woche3.md)
- [Vorlesungswoche 4](./woche4.md)
- [Vorlesungswoche 5](./woche4.md)
- [Vorlesungswoche 6](./woche4.md)
- [Vorlesungswoche 7](./woche4.md)
- [Vorlesungswoche 8](./woche4.md)
- [Vorlesungswoche 9](./woche4.md)
- [Vorlesungswoche 5](./woche5.md)
- [Vorlesungswoche 6](./woche6.md)
- [Vorlesungswoche 7](./woche7.md)
- [Vorlesungswoche 8](./woche8.md)
- [Vorlesungswoche 9](./woche9.md)
- [Vorlesungswoche 10](./woche10.md)
- [Vorlesungswoche 11](./woche11.md)
- [Vorlesungswoche 12](./woche12.md)

View File

@@ -2,13 +2,26 @@
## Agenda ##
- [ ]
- [ ]
- Gruppe 1:
- Verkettete Listen
- basic methods/attributes
- Stacks + Queues
- LIFO=FILO vs. FIFO=LILO
- PseudoCode-Algorithmus für NextGreaterElement mittels Stacks erarbeitet und diskutiert
- ACHTUNG: im code-Ordner ([go-Variante](../code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go) und [python-Variante](../code/python/src/algorithms/stacks/next_greater_element.py)) habe ich einen vereinfachten Algorithmus implementiert.
- Gruppe 2:
- PseudoCode-Algorithmus für NextGreaterElement mittels Stacks erarbeitet und diskutiert
- ACHTUNG: im code-Ordner ([go-Variante](../code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go) und [python-Variante](../code/python/src/algorithms/stacks/next_greater_element.py)) habe ich einen vereinfachten Algorithmus implementiert.
- Grundkonzepte für gerichtete/ungerichtete Graphen und Bäume besprochen
## Nächste Woche ##
-
- Sortierungsalgorithmen
- Bäume
### TODOs (Studierende) ###
-
- VL-Inhalte aus Wochen 3 + 4 durchgehen
- jeden Sortierungsalgorithmus und MaxHeap verstehen
- Darstellung von Daten als Bäume verstehen
- freiwillige ÜB 4 + Pflichtserie 2

View File

@@ -2,13 +2,41 @@
## Agenda ##
- [ ]
- [ ]
- Gruppe 1
- [x] Alle Sortierverfahren durchgegangen; argumentierte, wieso die Algorithmen korrekt sind.
- [x] Bäume und Listendarstellung von **fast vollständige binäre Bäume**.
- [x] Max-Heap-Eigenschaft (MHE).
- [x] Theorem: folgende Aussagen sind äquivalent
- T hat MHE
- (Definition) alle Unterbäume von T haben Max in Wurzel, d. h.
für alle Knoten, e, gilt
```
value(e) ≥ max{value(e') | e' Unterhalb von e in T}
```
- für alle Knoten, e, gilt
```
value(e) ≥ max{value(e') | e' Tochterknoten von e in T}
```
- L[i] = L[2i+1] und L[i] = L[2i+2] (jeweils solange Indexes in Listendarstellung L, wobei L = Listendarstellung von Baum T).
- Gruppe 2
- [x] Alle Sortierverfahren durchgegangen; argumentierte, wieso die Algorithmen korrekt sind.
(Etwas ausführlicher, weil MHE, usw. schon in der Übung diskutiert wurden.)
**Anmerkung.**
Bei Quicksort konnten wir sehen, dass die Zeit- (und Satzbewegungs!) komplexität durch
$C(n) = 2C(n/2) + Θ(n)$ gegeben ist (warum diese Koeffizienten, warum Θ(n)?).
</br>
Laut **Mastertheorem** gilt also $C(n) ∈ Θ(n·log(n))$ (warum?).
</br>
Das ist aber der Worst-case.
</br>
Wie verhält sich das beim Average-Case ($C_{av}(n)$)?
## Nächste Woche ##
-
- Ab VL5 + Blatt 6.
### TODOs (Studierende) ###
-
- VL-Inhalte aus Wochen 4 + 5 durchgehen
- freiwillige ÜB 5 + Pflichtserie 3.

View File

@@ -2,13 +2,10 @@
## Agenda ##
- [ ]
- [ ]
## Nächste Woche ##
-
- [x] Mergesort, inkl. Pseudo-Code
- [x] natürliches Mergesort, inkl. Aspekte
- [x] k-Wege Mergesort
### TODOs (Studierende) ###
-
- weiter an Pflichtserie3 arbeiten.

View File

@@ -2,13 +2,19 @@
## Agenda ##
- [ ]
- [ ]
- [x] Orga: nochmalige Abstimmung der Studierenden über Präsenz v. Digital
---> überwiegende Mehrheit für weiteren Präsenzbetrieb.
## Nächste Woche ##
Aspekte und Berechnungen mit binären Suchbäumen
-
- Aspekte, insbesondere *ausgeglichen*.
- Motivation: wieso wollen wir *ausgeglichene* Suchbäume?
- Optimierung der Tiefe h vis-á-vis Anzahl der Knoten, n.
- Suchalgorithmus im Suchbaum
- welche Verhältnisse müssen zw. den Knoten gelten?
- Ansatz bei INSERT und ROTATE, um *ausgeglichenen* Baum
mit passenden Verhältnissen zw. Knoten zu erzeugen.
### TODOs (Studierende) ###
-
- weiter an Pflichtserie3 arbeiten und vor der Frist abgeben.