Compare commits
75 Commits
15c2c37213
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14f59eeb63 | ||
|
|
a6cce9626c | ||
|
|
8d726bf344 | ||
|
|
04eecdb444 | ||
|
|
60c47c20c5 | ||
|
|
89499f524f | ||
|
|
e55d8708a7 | ||
|
|
ea7dfc5bef | ||
|
|
18ece75b67 | ||
|
|
6541a5246d | ||
|
|
3505401c7f | ||
|
|
b193d1d61e | ||
|
|
ae459547c2 | ||
|
|
0f1b426f94 | ||
|
|
cccc6a14ba | ||
|
|
8d2de4fa2b | ||
|
|
5c13f8d4cd | ||
| fe93d96584 | |||
| 580cc97387 | |||
| ef833533f6 | |||
| ab38c181c9 | |||
| 972027ce41 | |||
| 2d91e98904 | |||
| 9a56c63018 | |||
| d878c0b77d | |||
| a7f3377677 | |||
| eaef3322d8 | |||
| 9e04763782 | |||
| 924104408f | |||
| 3a4702429b | |||
| 9237dbfad0 | |||
| dbdb6a8480 | |||
| 337790f3cd | |||
| 38025247c7 | |||
| 1fd932c0ef | |||
| 66e0f912e3 | |||
| 7b655a1c0a | |||
| 85ba0a0936 | |||
| 8f08634720 | |||
| 6f1ee1b85f | |||
| c14efb0cc6 | |||
| 30dffa20d4 | |||
| 6bf15f936e | |||
| f0d0c9ef8a | |||
| 1934c3475a | |||
| a96d1bb6c9 | |||
| 31b3c19bf9 | |||
| 552c3197e8 | |||
| 701032a109 | |||
| 01dd4e1537 | |||
| be6fc48c0b | |||
| 1a387ac308 | |||
| d6bc4b9d72 | |||
| 6b5c81c276 | |||
| be9ce8bb82 | |||
| 47414d6d60 | |||
| f7ef295ec8 | |||
| f55677ed8b | |||
| 324b8d2fcd | |||
| 53978d584b | |||
| 893db52d90 | |||
| 43f5447ed7 | |||
| e9f83317d8 | |||
| 6d97bcc6db | |||
| e8e36113be | |||
| d157cd3e92 | |||
| fce25de013 | |||
| 8cd99c1632 | |||
| 10bad8fcd9 | |||
| d0fa57b46d | |||
| 7e2399c819 | |||
| 7f5f3e9541 | |||
| f563c8e6e9 | |||
| a38f18ee81 | |||
| 2c23f4c728 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -24,16 +24,9 @@
|
|||||||
!/scripts/*.sh
|
!/scripts/*.sh
|
||||||
|
|
||||||
!/code
|
!/code
|
||||||
!/code/**/
|
!/code/python
|
||||||
!/code/python/**/*.py
|
!/code/golang
|
||||||
!/code/golang/**/*.go
|
|
||||||
!/code/golang/go.mod
|
|
||||||
!/code/*/requirements
|
|
||||||
!/code/config.yml
|
!/code/config.yml
|
||||||
## nicht synchronisieren:
|
|
||||||
/code/golang/go.sum
|
|
||||||
/code/python/build
|
|
||||||
/code/python/build/**
|
|
||||||
|
|
||||||
!/dist
|
!/dist
|
||||||
!/dist/VERSION
|
!/dist/VERSION
|
||||||
|
|||||||
97
README.md
97
README.md
@@ -3,7 +3,9 @@
|
|||||||
Diese Repository ist für die Seminargruppe **j/l** am Freitag um 13:15–14:45
|
Diese Repository ist für die Seminargruppe **j/l** am Freitag um 13:15–14:45
|
||||||
im Raum SG 3-14 bzw. SG 4-10 (alternierend).
|
im Raum SG 3-14 bzw. SG 4-10 (alternierend).
|
||||||
|
|
||||||
**HINWEIS:** In diesem Repository werden keine Personen bezogenen Daten der Studierenden gespeichert.
|
**HINWEIS 1:** In diesem Repository werden keine Personen bezogenen Daten der Studierenden gespeichert.
|
||||||
|
|
||||||
|
**HINWEIS 2:** Es besteht absolut gar keine Pflicht, die Materialien in diesem Repo zu verwenden. Diese sind lediglich zusätzliche Hilfsmittel. **Im Zweifelsfalls** sollte man sich immer an den Definitionen und Auslegungen in der VL orientieren.
|
||||||
|
|
||||||
In diesem Repository findet man:
|
In diesem Repository findet man:
|
||||||
|
|
||||||
@@ -25,89 +27,10 @@ In diesem Repository findet man:
|
|||||||
|
|
||||||
## Code ##
|
## Code ##
|
||||||
|
|
||||||
Im Unterordner [`code`](./code) kann man Codeprojekte in Python und Golang finden, in denen verschiedene Algorithmen implementiert werden
|
In den Unterordnern
|
||||||
(siehe insbes. [`code/python/src/algorithms`](./code/python//src/algorithms)
|
[`code/golang`](./code/golang)
|
||||||
und [`code/golang/pkg/algorithms`](./code/golang/pkg/algorithms)).
|
und
|
||||||
Man kann gerne den Code benutzen, in einer eigenen Repository verändern,
|
[`code/python`](./code/python)
|
||||||
und mit den in dem Kurs präsentierten Algorithmen herumexperimentieren.
|
kann man Codeprojekte finden.
|
||||||
|
Dort kann man konkrete Implementierung der Algorithmen ansehen
|
||||||
### Systemvoraussetzungen ###
|
und ggf. auch auf echte Daten austesten.
|
||||||
|
|
||||||
#### 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 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ötigen. Letztere lassen sich mittels
|
|
||||||
```bash
|
|
||||||
./scripts/build.sh --lang go --mode setup
|
|
||||||
```
|
|
||||||
installieren.
|
|
||||||
|
|
||||||
#### 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
|
|
||||||
./scripts/build.sh --lang python --mode setup
|
|
||||||
## mit virtuellem Env:
|
|
||||||
./scripts/build.sh --lang python --venv true --mode setup
|
|
||||||
## alternative:
|
|
||||||
python3 -m pip install -r code/requirements; # linux, osx
|
|
||||||
py -3 -m pip install -r code/requirements; # Windows
|
|
||||||
```
|
|
||||||
installieren.
|
|
||||||
|
|
||||||
### Ausführung ###
|
|
||||||
|
|
||||||
#### 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/ads1 help; # zeigt Hilfsanleitung
|
|
||||||
./dist/ads1 version; # zeigt Version
|
|
||||||
./dist/ads1 run [--debug]; # führt code aus
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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
|
|
||||||
## Ausführung der Testfälle in code/config.yml:
|
|
||||||
python3 main.py run [--debug]; # linux, OSX
|
|
||||||
py -3 main.py run [--debug]; # Windows
|
|
||||||
## --debug Option benutzen, um Infos über Schritte zu zeigen.
|
|
||||||
|
|
||||||
popd; ## <- zum vorherigen Pfad zurückwechseln
|
|
||||||
```
|
|
||||||
Oder man erstelle einen 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.
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ parts:
|
|||||||
- command: 'algorithm-search-poison'
|
- command: 'algorithm-search-poison'
|
||||||
description: 'Freiwilliges ÜB2, A4, Beispiel'
|
description: 'Freiwilliges ÜB2, A4, Beispiel'
|
||||||
inputs: &ref_inputs_ueb2_4
|
inputs: &ref_inputs_ueb2_4
|
||||||
L: [ false, false, false, false, false, false, false, false, true, false, false, false, false, false ]
|
L: [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ]
|
||||||
- command: 'algorithm-search-poison-fast'
|
- command: 'algorithm-search-poison-fast'
|
||||||
description: 'Freiwilliges ÜB2, A4, Beispiel'
|
description: 'Freiwilliges ÜB2, A4, Beispiel'
|
||||||
inputs: *ref_inputs_ueb2_4
|
inputs: *ref_inputs_ueb2_4
|
||||||
@@ -75,7 +75,7 @@ parts:
|
|||||||
- command: 'algorithm-search-binary'
|
- command: 'algorithm-search-binary'
|
||||||
description: 'Seminarblatt Woche 3, Aufgabe 1'
|
description: 'Seminarblatt Woche 3, Aufgabe 1'
|
||||||
inputs: &ref_inputs_sem3_1
|
inputs: &ref_inputs_sem3_1
|
||||||
L: [7, 12, 29, 33, 40, 44, 45, 55, 64, 68, 78, 81, 84, 89, 95, 117, 120, 124, 133, 148, 152, 157, 174, 209, 219, 226, 237, 241, 273, 277, 282]
|
L: [7, 12, 29, 33, 40, 44, 45, 55, 64, 68, 78, 81, 84, 89, 95, 117, 120, 124, 133, 148, 152, 157, 174, 209, 219, 226, 226, 237, 241, 273, 277, 282]
|
||||||
x: 101
|
x: 101
|
||||||
- command: 'algorithm-search-jump'
|
- command: 'algorithm-search-jump'
|
||||||
description: 'Seminarblatt Woche 3, Aufgabe 1'
|
description: 'Seminarblatt Woche 3, Aufgabe 1'
|
||||||
@@ -85,3 +85,11 @@ parts:
|
|||||||
- command: 'algorithm-search-interpolation'
|
- command: 'algorithm-search-interpolation'
|
||||||
description: 'Seminarblatt Woche 3, Aufgabe 1'
|
description: 'Seminarblatt Woche 3, Aufgabe 1'
|
||||||
inputs: *ref_inputs_sem3_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
33
code/golang/.gitignore
vendored
Normal 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
27
code/golang/Makefile
Normal 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
88
code/golang/README.md
Normal 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. 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. 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. 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. 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. 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.
|
||||||
3
code/golang/assets/LOGO
Normal file
3
code/golang/assets/LOGO
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
+--------------------+
|
||||||
|
| \033[32;1mAlgoDat I\033[0m |
|
||||||
|
+--------------------+
|
||||||
1
code/golang/assets/VERSION
Normal file
1
code/golang/assets/VERSION
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.0.0
|
||||||
7
code/golang/assets/config.yml
Normal file
7
code/golang/assets/config.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
info:
|
||||||
|
title: "App für ADS1"
|
||||||
|
description: "Interne Configurationsdatei"
|
||||||
|
options:
|
||||||
|
display: true
|
||||||
|
checks: false
|
||||||
|
metrics: true
|
||||||
@@ -7,9 +7,7 @@ require (
|
|||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/lithammer/dedent v1.1.0
|
github.com/lithammer/dedent v1.1.0
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/slongfield/pyfmt v0.0.0-20180124071345-020a7cb18bca
|
github.com/stretchr/objx v0.3.0
|
||||||
github.com/stretchr/objx v0.1.0
|
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/tools v0.1.7
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
)
|
)
|
||||||
|
|||||||
21
code/golang/go.sum
Normal file
21
code/golang/go.sum
Normal 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=
|
||||||
@@ -7,110 +7,36 @@ package logging
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"ads/internal/core/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* GLOBAL VARIABLES
|
* MAIN METHODS logging
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
var quietmode bool = false
|
func Plain(line interface{}, args ...interface{}) {
|
||||||
var debugmode bool = false
|
logGeneric(os.Stdout, "", line, args...)
|
||||||
var ansimode bool = true
|
|
||||||
var loggingPrefix string = ""
|
|
||||||
var force bool = false
|
|
||||||
var tagAll bool = false
|
|
||||||
|
|
||||||
func GetQuietMode() bool {
|
|
||||||
return quietmode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetQuietMode(mode bool) {
|
func Info(line interface{}, args ...interface{}) {
|
||||||
quietmode = mode
|
logGeneric(os.Stdout, "[\033[94;1mINFO\033[0m]", line, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetDebugMode() bool {
|
func Debug(line interface{}, args ...interface{}) {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
|
||||||
* METHOD logging
|
|
||||||
* ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
func logGeneric(tag string, lines ...interface{}) {
|
|
||||||
if !force && quietmode {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !(tag == "") {
|
|
||||||
tag = tag + " "
|
|
||||||
}
|
|
||||||
for _, line := range lines {
|
|
||||||
_line := fmt.Sprintf("%[1]s%[2]s%[3]v", loggingPrefix, tag, line)
|
|
||||||
if !ansimode {
|
|
||||||
_line = utils.StripAnsi(_line)
|
|
||||||
}
|
|
||||||
fmt.Println(_line)
|
|
||||||
if !tagAll {
|
|
||||||
tag = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogPlain(lines ...interface{}) {
|
|
||||||
SetTagAll(false)
|
|
||||||
logGeneric("", lines...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogInfo(lines ...interface{}) {
|
|
||||||
SetTagAll(true)
|
|
||||||
logGeneric("[\033[94;1mINFO\033[0m]", lines...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogDebug(lines ...interface{}) {
|
|
||||||
if !debugmode {
|
if !debugmode {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
SetTagAll(true)
|
logGeneric(os.Stdout, "\033[2m[\033[96;1mDEBUG\033[0m\033[2m]\033[0m", fmt.Sprintf("\033[2m%v\033[0m", line), args...)
|
||||||
logGeneric("[\033[96;1mDEBUG\033[0m]", lines...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogWarn(lines ...interface{}) {
|
func Warn(line interface{}, args ...interface{}) {
|
||||||
SetTagAll(false)
|
logGeneric(os.Stdout, "[\033[93;1mWARNING\033[0m]", line, args...)
|
||||||
logGeneric("[\033[93;1mWARNING\033[0m]", lines...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogError(lines ...interface{}) {
|
func Error(line interface{}, args ...interface{}) {
|
||||||
SetTagAll(false)
|
logGeneric(os.Stderr, "[\033[91;1mERROR\033[0m]", line, args...)
|
||||||
logGeneric("[\033[91;1mERROR\033[0m]", lines...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func LogFatal(lines ...interface{}) {
|
func Fatal(line interface{}, args ...interface{}) {
|
||||||
SetTagAll(false)
|
logGeneric(os.Stderr, "[\033[91;1mFATAL\033[0m]", line, args...)
|
||||||
logGeneric("[\033[91;1mFATAL\033[0m]", lines...)
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
45
code/golang/internal/core/logging/logging_auxiliary.go
Normal file
45
code/golang/internal/core/logging/logging_auxiliary.go
Normal 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")
|
||||||
|
}
|
||||||
46
code/golang/internal/core/logging/logging_prompt.go
Normal file
46
code/golang/internal/core/logging/logging_prompt.go
Normal 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
|
||||||
|
}
|
||||||
48
code/golang/internal/core/logging/logging_settings.go
Normal file
48
code/golang/internal/core/logging/logging_settings.go
Normal 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
|
||||||
|
}
|
||||||
90
code/golang/internal/core/metrics/metrics.go
Normal file
90
code/golang/internal/core/metrics/metrics.go
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package metrics
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
var _ctr_time = types.NewCounter()
|
||||||
|
var _ctr_moves = types.NewCounter()
|
||||||
|
var _ctr_space = types.NewCounter()
|
||||||
|
var _tmr = types.NewTimer()
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func ResetMetrics() {
|
||||||
|
_ctr_time.Reset()
|
||||||
|
_ctr_moves.Reset()
|
||||||
|
_ctr_space.Reset()
|
||||||
|
_tmr.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartMetrics() {
|
||||||
|
_tmr.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopMetrics() {
|
||||||
|
_tmr.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTimeElapsed() time.Duration {
|
||||||
|
return _tmr.ElapsedTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTimeElapsedLongFormat() string {
|
||||||
|
t := _tmr.ElapsedTime()
|
||||||
|
h := utils.Floor(t.Hours())
|
||||||
|
m := utils.Floor(t.Minutes()) - h*60
|
||||||
|
s := t.Seconds() - float64(m*60)
|
||||||
|
h_string := fmt.Sprintf("%v", h)
|
||||||
|
for len(h_string) < 2 {
|
||||||
|
h_string = "0" + h_string
|
||||||
|
}
|
||||||
|
m_string := fmt.Sprintf("%v", m)
|
||||||
|
for len(m_string) < 2 {
|
||||||
|
m_string = "0" + m_string
|
||||||
|
}
|
||||||
|
s_string := fmt.Sprintf("%f", s)
|
||||||
|
return fmt.Sprintf("%[1]s:%[2]s:%[3]s", h_string, m_string, s_string)
|
||||||
|
}
|
||||||
@@ -24,26 +24,41 @@ func ArrayContains(x interface{}, elem interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// func ListComprehension(x interface{}, cond (interface{}) bool) bool {
|
|
||||||
// xAsArray := reflect.ValueOf(x)
|
|
||||||
// if xAsArray.Kind() == reflect.Slice {
|
|
||||||
// for i := 0; i < xAsArray.Len(); i++ {
|
|
||||||
// if xAsArray.Index(i).Interface() == elem {
|
|
||||||
// return true
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* METHOD array contains
|
* METHOD sort
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
func UniqueListOfStrings(X []string) []string {
|
func IsSortedListInt(X []int) bool {
|
||||||
|
n := len(X)
|
||||||
|
for i, x := range X {
|
||||||
|
for j := i + 1; j < n; j++ {
|
||||||
|
if X[j] < x {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD insert, pop
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func PopIndexListInt(X []int, index int) []int {
|
||||||
|
// NOTE: aus irgendeinem Grund reicht es nicht aus mit X zu arbeiten, denn sonst die u. s. Zeile überschreibt X
|
||||||
|
X_ := make([]int, len(X))
|
||||||
|
copy(X_, X)
|
||||||
|
return append(X_[:index], X_[(index+1):]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD unique
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func UniqueListInt(X []int) []int {
|
||||||
var ok bool
|
var ok bool
|
||||||
m := map[string]bool{}
|
m := map[int]bool{}
|
||||||
X_unique := []string{}
|
X_unique := []int{}
|
||||||
for _, x := range X {
|
for _, x := range X {
|
||||||
if _, ok = m[x]; !ok {
|
if _, ok = m[x]; !ok {
|
||||||
X_unique = append(X_unique, x)
|
X_unique = append(X_unique, x)
|
||||||
@@ -52,6 +67,10 @@ func UniqueListOfStrings(X []string) []string {
|
|||||||
return X_unique
|
return X_unique
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ContainsNoDuplicatesListInt(X []int) bool {
|
||||||
|
return len(X) <= len(UniqueListInt(X))
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* METHOD get value from array of unknown length
|
* METHOD get value from array of unknown length
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|||||||
147
code/golang/internal/core/utils/utils_maths.go
Normal file
147
code/golang/internal/core/utils/utils_maths.go
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
/*
|
||||||
|
In Golang sind manche (basic!) mathematischen Vorgänge etwas umständlich zu implementieren.
|
||||||
|
Wir wollen diese Methoden komplett einhüllen, damit wir von ihrer Komplexität
|
||||||
|
in den Algorithmen nicht abgelenkt werden.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD floor, ceil
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func Floor(x float64) int {
|
||||||
|
return int(math.Floor(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ceil(x float64) int {
|
||||||
|
return int(math.Ceil(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD max, min
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func MinInt(x int, y ...int) int {
|
||||||
|
if len(y) == 0 {
|
||||||
|
return x
|
||||||
|
} else if x < y[0] {
|
||||||
|
return MinInt(x, y[1:]...)
|
||||||
|
} else {
|
||||||
|
return MinInt(y[0], y[1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func MaxInt(x int, y ...int) int {
|
||||||
|
if len(y) == 0 {
|
||||||
|
return x
|
||||||
|
} else if x > y[0] {
|
||||||
|
return MaxInt(x, y[1:]...)
|
||||||
|
} else {
|
||||||
|
return MaxInt(y[0], y[1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArgMinInt(X []int) int {
|
||||||
|
if len(X) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
minValue := X[0]
|
||||||
|
index := 0
|
||||||
|
for i, x := range X {
|
||||||
|
if x < minValue {
|
||||||
|
minValue = x
|
||||||
|
index = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArgMaxInt(X []int) int {
|
||||||
|
if len(X) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
maxValue := X[0]
|
||||||
|
index := 0
|
||||||
|
for i, x := range X {
|
||||||
|
if x > maxValue {
|
||||||
|
maxValue = x
|
||||||
|
index = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD sum
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func SumListInt(X []int) int {
|
||||||
|
result := 0
|
||||||
|
for _, x := range X {
|
||||||
|
result += x
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func SumListFloat(X []float64) float64 {
|
||||||
|
result := 0.
|
||||||
|
for _, x := range X {
|
||||||
|
result += x
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS binary
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Für eine Zahl n != 0 liefert die Länge der binären Darstellung der Zahl,
|
||||||
|
und für n == 0 liefert 0
|
||||||
|
*/
|
||||||
|
func LengthOfBinary(number int) int {
|
||||||
|
if number == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
if number < 0 {
|
||||||
|
number = -number
|
||||||
|
}
|
||||||
|
number_binary := fmt.Sprintf("%b", int64(number))
|
||||||
|
return len([]rune(number_binary))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Für eine Zahl n != 0 liefert die Bits der binären Darstellung
|
||||||
|
*/
|
||||||
|
func IntToBinary(number int) []int {
|
||||||
|
if number == 0 || number == 1 {
|
||||||
|
return []int{number}
|
||||||
|
}
|
||||||
|
number_binary := fmt.Sprintf("%b", int64(number))
|
||||||
|
runes := []rune(number_binary)
|
||||||
|
bits := make([]int, len(runes))
|
||||||
|
for i, rune := range runes {
|
||||||
|
bit, _ := strconv.ParseInt(fmt.Sprintf("%c", rune), 2, 64)
|
||||||
|
bits[len(runes)-1-i] = int(bit)
|
||||||
|
}
|
||||||
|
return bits
|
||||||
|
}
|
||||||
|
|
||||||
|
func NthBit(number int, digit int) int {
|
||||||
|
bits := IntToBinary(number)
|
||||||
|
if digit < len(bits) {
|
||||||
|
return bits[digit]
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
@@ -7,48 +7,14 @@ package utils
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"reflect"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/lithammer/dedent"
|
"github.com/lithammer/dedent"
|
||||||
"github.com/slongfield/pyfmt"
|
|
||||||
|
|
||||||
"ads/pkg/re"
|
"ads/pkg/re"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
|
||||||
* METHOD format strings with dictionary substitution
|
|
||||||
* ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
func FormatPythonString(text string, arguments map[string]interface{}) string {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
key string
|
|
||||||
value interface{}
|
|
||||||
kind reflect.Kind
|
|
||||||
refValue reflect.Value
|
|
||||||
)
|
|
||||||
// force compatibility of expressions with python
|
|
||||||
for key, value = range arguments {
|
|
||||||
kind = reflect.TypeOf(value).Kind()
|
|
||||||
switch kind {
|
|
||||||
case reflect.Ptr:
|
|
||||||
refValue = reflect.ValueOf(value)
|
|
||||||
if refValue.IsNil() {
|
|
||||||
arguments[key] = "None"
|
|
||||||
}
|
|
||||||
case reflect.Bool:
|
|
||||||
arguments[key] = strings.Title(fmt.Sprintf(`%v`, value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text, err = pyfmt.Fmt(text, arguments)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* METHOD dedent textblock and expand escaped symbols
|
* METHOD dedent textblock and expand escaped symbols
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
@@ -94,3 +60,17 @@ func FormatTextBlockAsList(text string, options ...bool) []string {
|
|||||||
func StripAnsi(text string) string {
|
func StripAnsi(text string) string {
|
||||||
return re.Sub(`\x1b[^m]*m`, ``, text)
|
return re.Sub(`\x1b[^m]*m`, ``, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS string -> bool
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func IsTrue(text string) bool {
|
||||||
|
text = strings.TrimSpace(text)
|
||||||
|
return re.Matches(`(?i)(^(true|t|yes|y|1|\+|\+1)$)`, text)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsFalse(text string) bool {
|
||||||
|
text = strings.TrimSpace(text)
|
||||||
|
return re.Matches(`(?i)(^(false|f|no|n|0|-|-1)$)`, text)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
|
||||||
* IMPORTS
|
|
||||||
* ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
import (
|
|
||||||
"ads/internal/core/logging"
|
|
||||||
"ads/internal/setup"
|
|
||||||
)
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
|
||||||
* ENDPOINT run
|
|
||||||
* ---------------------------------------------------------------- */
|
|
||||||
|
|
||||||
func Run(fnameConfig string) error {
|
|
||||||
logging.LogPlain(setup.Logo())
|
|
||||||
logging.LogWarn("Die Go-Implementierung ist noch unter Arbeit.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package endpoints
|
package print
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* IMPORTS
|
* IMPORTS
|
||||||
@@ -7,6 +7,7 @@ package endpoints
|
|||||||
import (
|
import (
|
||||||
"ads/internal/core/logging"
|
"ads/internal/core/logging"
|
||||||
"ads/internal/setup"
|
"ads/internal/setup"
|
||||||
|
"ads/internal/setup/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
@@ -15,7 +16,7 @@ import (
|
|||||||
|
|
||||||
func Version() {
|
func Version() {
|
||||||
logging.SetForce(true)
|
logging.SetForce(true)
|
||||||
logging.LogPlain(setup.Version())
|
logging.Plain(setup.Version())
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
@@ -24,11 +25,10 @@ func Version() {
|
|||||||
|
|
||||||
func Help() {
|
func Help() {
|
||||||
logging.SetForce(true)
|
logging.SetForce(true)
|
||||||
logging.LogPlain(
|
cli.ParseCli([]string{}) // <- generiere leere Instanz für Parser, um voll Hilfsanleitug zu zeigen
|
||||||
"",
|
logging.Plain("")
|
||||||
setup.Logo(),
|
logging.Plain(setup.Logo())
|
||||||
// cli.Parser.Usage(nil),
|
// logging.Plain(setup.Help())
|
||||||
setup.Help(),
|
logging.Plain(cli.Parser.Usage(nil))
|
||||||
"",
|
logging.Plain("")
|
||||||
)
|
|
||||||
}
|
}
|
||||||
173
code/golang/internal/endpoints/run/run.go
Normal file
173
code/golang/internal/endpoints/run/run.go
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
package run
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/setup"
|
||||||
|
"ads/internal/types"
|
||||||
|
|
||||||
|
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
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// Liest Config Datei ein und führt Algorithmen auf Fälle durch
|
||||||
|
func RunNonInteractive(path string) error {
|
||||||
|
var err error
|
||||||
|
var err_case error
|
||||||
|
|
||||||
|
// extrahiere user config
|
||||||
|
config := setup.NewUserConfig()
|
||||||
|
err = setup.GetUserConfig(path, &config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.Plain(setup.Logo())
|
||||||
|
|
||||||
|
// Fälle extrahieren
|
||||||
|
cases := []types.UserConfigCase{}
|
||||||
|
if config.Parts != nil && config.Parts.Cases != nil {
|
||||||
|
cases = *config.Parts.Cases
|
||||||
|
}
|
||||||
|
for i := 0; i < len(cases); i++ {
|
||||||
|
err_case = nil
|
||||||
|
problem := cases[i]
|
||||||
|
setup.DisplayStartOfCase(i, problem.Description)
|
||||||
|
inputs := types.UserConfigInputs{}
|
||||||
|
if problem.Inputs != nil {
|
||||||
|
inputs = *problem.Inputs
|
||||||
|
}
|
||||||
|
if problem.Command == nil {
|
||||||
|
err_case = fmt.Errorf("Attribute 'command:' fehlt!")
|
||||||
|
} else {
|
||||||
|
switch *problem.Command {
|
||||||
|
case "algorithm-search-binary":
|
||||||
|
L := inputs.List
|
||||||
|
x := inputs.SearchValue
|
||||||
|
if L != nil && x != nil {
|
||||||
|
_, err_case = algorithm_search_binary.FancyBinarySearch(*L, *x)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-interpolation":
|
||||||
|
L := inputs.List
|
||||||
|
x := inputs.SearchValue
|
||||||
|
if L != nil && x != nil {
|
||||||
|
_, err_case = algorithm_search_interpol.FancyInterpolationSearch(*L, *x, 0, len(*L)-1)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-ith-element":
|
||||||
|
L := inputs.List
|
||||||
|
i := inputs.SearchRank
|
||||||
|
if L != nil && i != nil {
|
||||||
|
_, err_case = algorithm_search_ith_element.FancyFindIthSmallest(*L, *i)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-ith-element-dc":
|
||||||
|
L := inputs.List
|
||||||
|
i := inputs.SearchRank
|
||||||
|
if L != nil && i != nil {
|
||||||
|
_, err_case = algorithm_search_ith_element.FancyFindIthSmallestDC(*L, *i)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-jump":
|
||||||
|
L := inputs.List
|
||||||
|
x := inputs.SearchValue
|
||||||
|
m := inputs.JumpSize
|
||||||
|
if L != nil && x != nil {
|
||||||
|
_, err_case = algorithm_search_jump.FancyJumpSearchLinear(*L, *x, *m)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-jump-exp":
|
||||||
|
L := inputs.List
|
||||||
|
x := inputs.SearchValue
|
||||||
|
if L != nil && x != nil {
|
||||||
|
_, err_case = algorithm_search_jump.FancyJumpSearchExponentiell(*L, *x)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-poison":
|
||||||
|
L := inputs.List
|
||||||
|
if L != nil {
|
||||||
|
_, err_case = algorithm_search_poison.FancyFindPoison(*L)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-poison-fast":
|
||||||
|
L := inputs.List
|
||||||
|
if L != nil {
|
||||||
|
_, err_case = algorithm_search_poison.FancyFindPoisonFast(*L)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-search-sequential":
|
||||||
|
L := inputs.List
|
||||||
|
x := inputs.SearchValue
|
||||||
|
if L != nil && x != nil {
|
||||||
|
_, err_case = algorithm_search_sequential.FancySequentialSearch(*L, *x)
|
||||||
|
} 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 {
|
||||||
|
_, _, _, err_case = algorithm_sum_maxsubsum.FancyMaxSubSum(*L)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
case "algorithm-sum-maxsub-dc":
|
||||||
|
L := inputs.List
|
||||||
|
if L != nil {
|
||||||
|
_, _, _, err_case = algorithm_sum_maxsubsum.FancyMaxSubSumDC(*L)
|
||||||
|
} else {
|
||||||
|
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
err_case = fmt.Errorf("Unbekannter Befehl '%[1]s'.", *problem.Command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err_case != nil {
|
||||||
|
logging.Error(err_case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setup.DisplayEndOfCase()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
254
code/golang/internal/endpoints/run/run_actions_algorithms.go
Normal file
254
code/golang/internal/endpoints/run/run_actions_algorithms.go
Normal 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
|
||||||
|
}
|
||||||
34
code/golang/internal/endpoints/run/run_actions_basic.go
Normal file
34
code/golang/internal/endpoints/run/run_actions_basic.go
Normal 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
|
||||||
|
}
|
||||||
64
code/golang/internal/endpoints/run/run_actions_settings.go
Normal file
64
code/golang/internal/endpoints/run/run_actions_settings.go
Normal 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
|
||||||
|
}
|
||||||
146
code/golang/internal/endpoints/run/run_menus.go
Normal file
146
code/golang/internal/endpoints/run/run_menus.go
Normal 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,
|
||||||
|
}
|
||||||
76
code/golang/internal/endpoints/run/run_prompts.go
Normal file
76
code/golang/internal/endpoints/run/run_prompts.go
Normal 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
|
||||||
|
}
|
||||||
206
code/golang/internal/menus/menus.go
Normal file
206
code/golang/internal/menus/menus.go
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
package menus
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD menu class methods
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func (menu *Menu) SetDefault(index int) {
|
||||||
|
menu.Default = index
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD show menu
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func (menu Menu) ShowMenu() (bool, error) {
|
||||||
|
var (
|
||||||
|
choice string
|
||||||
|
index int
|
||||||
|
meta bool
|
||||||
|
quit bool
|
||||||
|
cancel bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
var promptMessages []string
|
||||||
|
var optionsFlattened []MenuOption
|
||||||
|
var optionsKeyValue [][2]string
|
||||||
|
var defaultOption string
|
||||||
|
var breaks []int
|
||||||
|
|
||||||
|
// Headline einfügen
|
||||||
|
promptMessages = make([]string, len(menu.PromptMessages))
|
||||||
|
copy(promptMessages, menu.PromptMessages)
|
||||||
|
head := fmt.Sprintf("\033[2m%s\033[0m", strings.Join(menu.Path, " > "))
|
||||||
|
promptMessages = append([]string{head}, promptMessages...)
|
||||||
|
|
||||||
|
// Zurück-Option einfügen
|
||||||
|
defaultOption = ""
|
||||||
|
if menu.Default >= 0 {
|
||||||
|
defaultOption = fmt.Sprintf("%v", menu.Default+1)
|
||||||
|
}
|
||||||
|
breaks = []int{}
|
||||||
|
optionsFlattened = []MenuOption{}
|
||||||
|
optionsKeyValue = []([2]string){}
|
||||||
|
index = 0
|
||||||
|
for _, suboptions := range menu.Options {
|
||||||
|
for _, opt := range suboptions {
|
||||||
|
optionsFlattened = append(optionsFlattened, opt)
|
||||||
|
key := fmt.Sprintf("%v", index+1)
|
||||||
|
subLabel := opt.SubLabel
|
||||||
|
label := opt.Label
|
||||||
|
if !(subLabel == "") {
|
||||||
|
label = fmt.Sprintf("%v (\033[2m%v\033[0m)", opt.Label, subLabel)
|
||||||
|
}
|
||||||
|
optionsKeyValue = append(optionsKeyValue, [2]string{key, label})
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
breaks = append(breaks, index-1)
|
||||||
|
}
|
||||||
|
if !menu.IsRoot {
|
||||||
|
optionsKeyValue = append(optionsKeyValue, [2]string{"z", "Zurück zum vorherigen Menü"})
|
||||||
|
}
|
||||||
|
optionsKeyValue = append(optionsKeyValue, [2]string{"q", "Programm schließen"})
|
||||||
|
|
||||||
|
// User Response immer abfragen und abarbeiten, bis quit/return.
|
||||||
|
performClearScreen := !menu.IsRoot
|
||||||
|
for {
|
||||||
|
if performClearScreen {
|
||||||
|
logging.ClearScreen()
|
||||||
|
}
|
||||||
|
performClearScreen = true
|
||||||
|
|
||||||
|
choice, meta = promptListOfOptions(promptMessages, optionsKeyValue, breaks, defaultOption)
|
||||||
|
|
||||||
|
// Falls quit wählt, -> quit:
|
||||||
|
if (menu.IsRoot && meta) || choice == "q" {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Falls User back wählt, -> return:
|
||||||
|
if (!menu.IsRoot && meta) || choice == "z" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// sonst führe die assoziierte Methode aus
|
||||||
|
index64, _ := strconv.ParseInt(choice, 10, 64)
|
||||||
|
index = int(index64) - 1
|
||||||
|
if 0 <= index && index < len(optionsFlattened) {
|
||||||
|
opt := optionsFlattened[index]
|
||||||
|
// Entweder Untermenü öffnen oder Action ausführen
|
||||||
|
if opt.Submenu != nil {
|
||||||
|
quit, err = opt.Submenu.ShowMenu()
|
||||||
|
if quit {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
} else if opt.Action != nil {
|
||||||
|
cancel, err = opt.Action()
|
||||||
|
if err != nil {
|
||||||
|
logging.Error(err)
|
||||||
|
}
|
||||||
|
// Falls ForceReturn, dann nach Ausführung der Action, -> return
|
||||||
|
if menu.ForceReturn {
|
||||||
|
return false, nil
|
||||||
|
} else {
|
||||||
|
// Falls während der Action der User Meta+D klickt, -> return:
|
||||||
|
if cancel {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
quit := logging.PromptAnyKeyToContinue()
|
||||||
|
// Falls nach der Action der User Meta+D klickt, -> quit:
|
||||||
|
if quit {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logging.Warn("Option noch nicht implementiert.")
|
||||||
|
quit := logging.PromptAnyKeyToContinue()
|
||||||
|
if quit {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD prompt values
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func (query *PromptValueQuery) Prompt() (bool, error) {
|
||||||
|
var lines = []interface{}{}
|
||||||
|
var responsePtr = query.Response
|
||||||
|
var (
|
||||||
|
line string
|
||||||
|
cancel bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
// prüfen, dass response ein Ptr auf eine Struct ist:
|
||||||
|
if !(reflect.ValueOf(responsePtr).Kind() == reflect.Ptr) || !(reflect.ValueOf(responsePtr).Elem().Kind() == reflect.Struct) {
|
||||||
|
panic("Input muss ein Pointer auf einen struct sein")
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt message vorbereiten:
|
||||||
|
lines = append(lines, fmt.Sprintf("%s, \033[1;3m%s\033[0m, als \033[1m%s\033[0m bitte eingeben.", query.Description, query.Name, query.Type))
|
||||||
|
if query.ValidExamples != nil && len(*query.ValidExamples) > 0 {
|
||||||
|
if len(*query.ValidExamples) == 1 {
|
||||||
|
example := (*query.ValidExamples)[0]
|
||||||
|
lines = append(lines, fmt.Sprintf(" \033[3;4mBeispiel von Input im gültigen Format:\033[0m \033[2m%s\033[0m", example))
|
||||||
|
} else {
|
||||||
|
lines = append(lines, fmt.Sprintf(" \033[3;4mBeispiele von Inputs im gültigen Format:\033[0m"))
|
||||||
|
for _, example := range *query.ValidExamples {
|
||||||
|
lines = append(lines, fmt.Sprintf(" - \033[2m%s\033[0m", example))
|
||||||
|
}
|
||||||
|
lines = append(lines, fmt.Sprintf(" - \033[2;3metc.\033[0m"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if query.Requirements != nil && len(*query.Requirements) > 0 {
|
||||||
|
if len(*query.Requirements) == 1 {
|
||||||
|
requirement := (*query.Requirements)[0]
|
||||||
|
lines = append(lines, fmt.Sprintf(" \033[3;4mAnforderung(en) auf Input:\033[0m \033[2m%s\033[0m", requirement))
|
||||||
|
} else {
|
||||||
|
lines = append(lines, fmt.Sprintf(" \033[3;4mAnforderung(en) auf Input:\033[0m"))
|
||||||
|
for _, requirement := range *query.Requirements {
|
||||||
|
lines = append(lines, fmt.Sprintf(" - \033[2m%s\033[0m", requirement))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt Eingabe eines Werts:
|
||||||
|
for {
|
||||||
|
line, cancel, err = logging.Prompt(lines...)
|
||||||
|
if cancel {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
logging.Error(err)
|
||||||
|
logging.Plain("")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
line = fmt.Sprintf("\"response\": %s", line)
|
||||||
|
err = yaml.Unmarshal([]byte(line), query.Response)
|
||||||
|
if err != nil {
|
||||||
|
logging.Error(err)
|
||||||
|
logging.Plain("")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return cancel, err
|
||||||
|
}
|
||||||
81
code/golang/internal/menus/menus_prompt.go
Normal file
81
code/golang/internal/menus/menus_prompt.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package menus
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD prompt options
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// Zeigt Prompt mit Liste von Optionen an
|
||||||
|
func promptListOfOptions(messages []string, options [][2]string, breaks []int, defaultChoice string) (string, bool) {
|
||||||
|
var n = len(options)
|
||||||
|
var (
|
||||||
|
choice string
|
||||||
|
cancel bool
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
var lines []interface{}
|
||||||
|
var optionsMap = map[string]string{}
|
||||||
|
|
||||||
|
// Erzeuge Messages
|
||||||
|
lines = []interface{}{}
|
||||||
|
for _, message := range messages {
|
||||||
|
lines = append(lines, message)
|
||||||
|
}
|
||||||
|
lines = append(lines, "")
|
||||||
|
textbar := fmt.Sprintf(" \033[93m+%s+\033[0m", strings.Repeat("-", 40))
|
||||||
|
lines = append(lines, textbar)
|
||||||
|
for i, obj := range options {
|
||||||
|
key := obj[0]
|
||||||
|
label := obj[1]
|
||||||
|
optionsMap[key] = label
|
||||||
|
if key == defaultChoice {
|
||||||
|
lines = append(lines, fmt.Sprintf("\033[91m*\033[0m\033[93;1m%v)\033[0m %v", key, label))
|
||||||
|
} else {
|
||||||
|
lines = append(lines, fmt.Sprintf(" \033[93;1m%v)\033[0m %v", key, label))
|
||||||
|
}
|
||||||
|
if i < n-1 && utils.ArrayContains(breaks, i) {
|
||||||
|
lines = append(lines, " \033[93m+----\033[0m")
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
lines = append(lines, textbar)
|
||||||
|
if !(defaultChoice == "") {
|
||||||
|
lines = append(lines, "")
|
||||||
|
lines = append(lines, " \033[91;2m*\033[0m\033[2m = Default\033[0m")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wiederhole Prompt, bis gültige Eingabe erreicht
|
||||||
|
for {
|
||||||
|
choice, cancel, err = logging.Prompt(lines...)
|
||||||
|
if cancel {
|
||||||
|
return "", true
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
logging.ClearScreen()
|
||||||
|
logging.Error(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if choice == "" {
|
||||||
|
choice = defaultChoice
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if _, ok := optionsMap[choice]; !ok {
|
||||||
|
logging.ClearScreen()
|
||||||
|
logging.Error("Ungültige eingabe")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return choice, false
|
||||||
|
}
|
||||||
58
code/golang/internal/menus/menus_type.go
Normal file
58
code/golang/internal/menus/menus_type.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package menus
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* TYPES
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
type MenuOption struct {
|
||||||
|
Label string
|
||||||
|
SubLabel string
|
||||||
|
Submenu *Menu
|
||||||
|
Action func() (bool, error) // NOTE: in go, this is automatically a pointer type
|
||||||
|
}
|
||||||
|
|
||||||
|
type Menu struct {
|
||||||
|
IsRoot bool
|
||||||
|
ForceReturn bool
|
||||||
|
Path []string
|
||||||
|
PromptMessages []string
|
||||||
|
Options [][]MenuOption
|
||||||
|
Default int
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* TYPES - prompt
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Usage
|
||||||
|
|
||||||
|
- Name: Variablenname
|
||||||
|
|
||||||
|
- Description: Kurze Beschreibung der Variablen
|
||||||
|
|
||||||
|
- Type: Beschreiben des erwarteten Types der Variablen.
|
||||||
|
|
||||||
|
- Requirements: Liste von Anforderungen.
|
||||||
|
|
||||||
|
- Response: Ptr zur Struct, d. h. &responseType{}, wobei responseType eine struct der folgenden Form ist:
|
||||||
|
|
||||||
|
type responseType struct { Response #### `yaml:"response"` }
|
||||||
|
|
||||||
|
wobei #### = ein Typ
|
||||||
|
*/
|
||||||
|
type PromptValueQuery struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
Type string
|
||||||
|
ValidExamples *[]string
|
||||||
|
Requirements *[]string
|
||||||
|
// Response muss ein Ptr auf eine Struct sein:
|
||||||
|
Response interface{}
|
||||||
|
}
|
||||||
@@ -5,9 +5,12 @@ package cli
|
|||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/akamensky/argparse"
|
"github.com/akamensky/argparse"
|
||||||
|
|
||||||
"ads/internal/types"
|
"ads/internal/types"
|
||||||
|
"ads/pkg/re"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
@@ -26,17 +29,30 @@ var optionsQuiet = argparse.Options{
|
|||||||
Default: false,
|
Default: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var optionsChecks = argparse.Options{
|
||||||
|
Help: "Ob vor und nach Ausführung von Algorithmen Checks auf Inputs/Outputs ausgeführt werden sollen.",
|
||||||
|
Required: false,
|
||||||
|
// NOTE: no `Boolean` option available!
|
||||||
|
Default: "false",
|
||||||
|
}
|
||||||
|
|
||||||
var optionsDebug = 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 das Programm im interaktiven Modus.",
|
||||||
Required: false,
|
Required: false,
|
||||||
Default: false,
|
Default: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
var optionsColour = argparse.Options{
|
var optionsColour = argparse.Options{
|
||||||
Help: "Ob Logging färblich angezeigt wird (default=true).",
|
Help: "Ob Logging färblich angezeigt wird.",
|
||||||
Required: false,
|
Required: false,
|
||||||
// NOTE: no `Boolean` option available!
|
// NOTE: no `Boolean` option available!
|
||||||
Default: "true",
|
Default: "false",
|
||||||
}
|
}
|
||||||
|
|
||||||
var optionsConfigFile = argparse.Options{
|
var optionsConfigFile = argparse.Options{
|
||||||
@@ -49,18 +65,30 @@ var optionsConfigFile = argparse.Options{
|
|||||||
* METHODS parse cli
|
* METHODS parse cli
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// Parst cli flags.
|
||||||
func ParseCli(args []string) (*types.CliArguments, error) {
|
func ParseCli(args []string) (*types.CliArguments, error) {
|
||||||
var err 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{
|
arguments := types.CliArguments{
|
||||||
Help: Parser.NewCommand("help", ""),
|
ModeHelp: Parser.NewCommand("help", "Hilfsanleitung anzeigen"),
|
||||||
Version: Parser.NewCommand("version", "Ruft Endpunkt auf, der die Version anzeigt."),
|
ModeVersion: Parser.NewCommand("version", "Version anzeigen."),
|
||||||
Run: Parser.NewCommand("run", "Ruft Endpunkt auf, der die Algorithmen laufen lässt."),
|
ModeRun: Parser.NewCommand("run", "Algorithmen ausführen."),
|
||||||
Quiet: Parser.Flag("q", "quiet", &optionsQuiet),
|
Quiet: Parser.Flag("q", "quiet", &optionsQuiet),
|
||||||
Debug: Parser.Flag("", "debug", &optionsDebug),
|
Debug: Parser.Flag("", "debug", &optionsDebug),
|
||||||
Colour: Parser.String("", "colour", &optionsColour),
|
Interactive: Parser.Flag("", "it", &optionsInteractive),
|
||||||
ConfigFile: Parser.String("", "config", &optionsConfigFile),
|
Checks: Parser.String("", "checks", &optionsChecks),
|
||||||
|
Colour: Parser.String("", "colour", &optionsColour),
|
||||||
|
ConfigFile: Parser.String("", "config", &optionsConfigFile),
|
||||||
}
|
}
|
||||||
err = Parser.Parse(args)
|
err = Parser.Parse(args)
|
||||||
return &arguments, err
|
return &arguments, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prüft, ob der Parser nur deshalb fehlschlägt, weil ein Command fehlt.
|
||||||
|
func ParseCliCommandMissing(err error) bool {
|
||||||
|
// FIXME: unschöne Lösung. Leider ist Error-Typ im Package versteckt
|
||||||
|
return re.Matches(`(?i)(command required)`, fmt.Sprintf("%v", err))
|
||||||
|
}
|
||||||
|
|||||||
56
code/golang/internal/setup/setup_appconfig.go
Normal file
56
code/golang/internal/setup/setup_appconfig.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package setup
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"ads/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
var AppConfig = types.AppConfig{}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS getters
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// Extrahiert Inhalte einer YAML Config und parset dies als Struktur
|
||||||
|
func AppConfigInitialise() error {
|
||||||
|
contents := AppConfigYaml()
|
||||||
|
err := yaml.Unmarshal([]byte(contents), &AppConfig)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppConfigFancyMode() bool {
|
||||||
|
return AppConfig.Options.Display
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppConfigShowMetrics() bool {
|
||||||
|
return AppConfig.Options.Metrics
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppConfigPerformChecks() bool {
|
||||||
|
return AppConfig.Options.Checks
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS setters
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func SetAppConfigFancyMode(value bool) {
|
||||||
|
AppConfig.Options.Display = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetAppConfigShowMetrics(value bool) {
|
||||||
|
AppConfig.Options.Metrics = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetAppConfigPerformChecks(value bool) {
|
||||||
|
AppConfig.Options.Checks = value
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ func ReadAsset(key string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* METHODS templates
|
* METHODS assets
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
func Help() string {
|
func Help() string {
|
||||||
@@ -54,3 +54,7 @@ func Logo() string {
|
|||||||
func Version() string {
|
func Version() string {
|
||||||
return strings.Trim(ReadAsset("version"), "\n")
|
return strings.Trim(ReadAsset("version"), "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AppConfigYaml() string {
|
||||||
|
return strings.Trim(ReadAsset("appconfig"), "\n")
|
||||||
|
}
|
||||||
|
|||||||
130
code/golang/internal/setup/setup_display.go
Normal file
130
code/golang/internal/setup/setup_display.go
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package setup
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD display case start/end
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func DisplayStartOfCase(index int, descr *string) {
|
||||||
|
DisplayBar(80)
|
||||||
|
if descr == nil || *descr == "" {
|
||||||
|
logging.Plain("\033[92;1mCASE %[1]v\033[0m.", index)
|
||||||
|
} else {
|
||||||
|
logging.Plain("\033[92;1mCASE %[1]v\033[0m (\033[1;2m%[2]s\033[0m).", index, *descr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayStartOfCaseBlank() {
|
||||||
|
DisplayBar(80)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayEndOfCase() {
|
||||||
|
DisplayBar(80)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD display value
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func RepresentValue(value interface{}) interface{} {
|
||||||
|
switch reflect.TypeOf(value).Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
obj := reflect.ValueOf(value)
|
||||||
|
if obj.IsNil() {
|
||||||
|
return fmt.Sprintf("%v", nil)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("&%v", RepresentValue(obj.Elem().Interface()))
|
||||||
|
}
|
||||||
|
case reflect.Slice:
|
||||||
|
obj := reflect.ValueOf(value)
|
||||||
|
n := obj.Len()
|
||||||
|
values := []interface{}{}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
x := RepresentValue(obj.Index(i).Interface())
|
||||||
|
values = append(values, x)
|
||||||
|
}
|
||||||
|
if n > 10 {
|
||||||
|
values = append(append(values[:3], "..."), values[n-2:]...)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v", values)
|
||||||
|
case reflect.Map:
|
||||||
|
obj := reflect.ValueOf(value)
|
||||||
|
n := obj.Len()
|
||||||
|
iter := obj.MapRange()
|
||||||
|
m := map[interface{}]interface{}{}
|
||||||
|
parts := []string{}
|
||||||
|
for iter.Next() {
|
||||||
|
key := iter.Key().Interface()
|
||||||
|
x := RepresentValue(iter.Value().Interface())
|
||||||
|
m[key] = x
|
||||||
|
parts = append(parts, fmt.Sprintf("%[1]v: %[2]v", key, x))
|
||||||
|
}
|
||||||
|
if n > 4 {
|
||||||
|
parts = append(append(parts[:3], "..."), parts[n-2:]...)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("{%s}", strings.Join(parts, ", "))
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD display algorithm start/end
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func DisplayStartOfAlgorithm(name string, inputs map[string]interface{}) {
|
||||||
|
logging.Plain("Ausführung vom Algorithmus: \033[92;1m%[1]s\033[0m", name)
|
||||||
|
logging.Plain("INPUTS")
|
||||||
|
for varname, value := range inputs {
|
||||||
|
logging.Plain(" - %[1]s = %[2]v", varname, RepresentValue(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayEndOfAlgorithm(outputs map[string]interface{}) {
|
||||||
|
logging.Plain("OUTPUTS:")
|
||||||
|
for varname, value := range outputs {
|
||||||
|
logging.Plain(" - %[1]s = %[2]v", varname, RepresentValue(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayMetrics() {
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS Verschiedenes
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func DisplayBar(options ...int) {
|
||||||
|
n := 80
|
||||||
|
if len(options) > 0 {
|
||||||
|
n = options[0]
|
||||||
|
}
|
||||||
|
logging.Plain("+%[1]s+", strings.Repeat("-", n))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func displayCost(cost int) string {
|
||||||
|
if cost > 0 {
|
||||||
|
return fmt.Sprintf("%v", cost)
|
||||||
|
}
|
||||||
|
return "-"
|
||||||
|
}
|
||||||
31
code/golang/internal/setup/setup_userconfig.go
Normal file
31
code/golang/internal/setup/setup_userconfig.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package setup
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
"ads/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
// Erstellt eine Struktur, die die Infos aus der Config-Datei erfasst
|
||||||
|
func NewUserConfig() types.UserConfig {
|
||||||
|
return types.UserConfig{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extrahiert Inhalte einer YAML Config und parset dies als Struktur
|
||||||
|
func GetUserConfig(path string, config *types.UserConfig) error {
|
||||||
|
contents, err := ioutil.ReadFile(path)
|
||||||
|
if err == nil {
|
||||||
|
err = yaml.Unmarshal(contents, config)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
27
code/golang/internal/types/types_appconfig.go
Normal file
27
code/golang/internal/types/types_appconfig.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* YAML SCHEMES
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
type AppConfig struct {
|
||||||
|
Info *AppConfigInfo `yaml:"info"`
|
||||||
|
Options *AppConfigOptions `yaml:"options"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppConfigInfo struct {
|
||||||
|
Title *string `yaml:"title"`
|
||||||
|
Description *string `yaml:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppConfigOptions struct {
|
||||||
|
Display bool `yaml:"display"`
|
||||||
|
Checks bool `yaml:"checks"`
|
||||||
|
Metrics bool `yaml:"metrics"`
|
||||||
|
}
|
||||||
109
code/golang/internal/types/types_basic.go
Normal file
109
code/golang/internal/types/types_basic.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD convert basic types to pointers
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/****
|
||||||
|
* NOTE: these cannot be replaced by inline variants, e.g.
|
||||||
|
* var x string
|
||||||
|
* var xx *string = &x
|
||||||
|
* as then the values are tied.
|
||||||
|
* These methods create addresses to clones of the original variables,
|
||||||
|
* and do not coincide with the addresses of the original variables.
|
||||||
|
****/
|
||||||
|
|
||||||
|
func StructToPtr(x struct{}) *struct{} {
|
||||||
|
var value = x
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
func InterfaceToPtr(x interface{}) *interface{} {
|
||||||
|
var value = x
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
func BoolToPtr(x bool) *bool {
|
||||||
|
var value = x
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringToPtr(x string) *string {
|
||||||
|
var value = x
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
func IntToPtr(x int) *int {
|
||||||
|
var value = x
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD get value from ptr with default
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func ExpandPtrToBool(p *bool) interface{} {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func PtrToBool(p *bool, Default bool) bool {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
return Default
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExpandPtrToString(p *string) interface{} {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func PtrToString(p *string, Default string) string {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
return Default
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExpandPtrToInt(p *int) interface{} {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func PtrToInt(p *int, Default int) int {
|
||||||
|
if p != nil {
|
||||||
|
return *p
|
||||||
|
}
|
||||||
|
return Default
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD interface to (ptr to) array
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func InterfaceToArray(x interface{}) *[]interface{} {
|
||||||
|
if reflect.TypeOf(x).Kind() == reflect.Slice {
|
||||||
|
var xSlice []interface{} = []interface{}{}
|
||||||
|
var xConverted = reflect.ValueOf(x)
|
||||||
|
for i := 0; i < xConverted.Len(); i++ {
|
||||||
|
xSlice = append(xSlice, xConverted.Index(i).Interface())
|
||||||
|
}
|
||||||
|
return &xSlice
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -5,11 +5,9 @@ package types
|
|||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/akamensky/argparse"
|
"github.com/akamensky/argparse"
|
||||||
|
|
||||||
"ads/pkg/re"
|
"ads/internal/core/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
@@ -17,29 +15,41 @@ import (
|
|||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
type CliArguments struct {
|
type CliArguments struct {
|
||||||
Help *argparse.Command
|
ModeHelp *argparse.Command
|
||||||
Version *argparse.Command
|
ModeVersion *argparse.Command
|
||||||
Run *argparse.Command
|
ModeRun *argparse.Command
|
||||||
Quiet *bool
|
Quiet *bool
|
||||||
Debug *bool
|
Debug *bool
|
||||||
Colour *string
|
Interactive *bool
|
||||||
ConfigFile *string
|
Checks *string
|
||||||
|
Colour *string
|
||||||
|
ConfigFile *string
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* METHODS convert string option to boolean
|
* METHODS convert string option to boolean
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
func IsTrue(text string) bool {
|
func (arguments CliArguments) QuietModeOn() bool {
|
||||||
text = strings.TrimSpace(text)
|
return *arguments.Quiet
|
||||||
return re.Matches(`(?i)(^(true|t|yes|y|1|\+|\+1)$)`, text)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsFalse(text string) bool {
|
func (arguments CliArguments) DebugModeOn() bool {
|
||||||
text = strings.TrimSpace(text)
|
return *arguments.Debug
|
||||||
return re.Matches(`(?i)(^(false|f|no|n|0|-|-1)$)`, text)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (arguments *CliArguments) ShowColour() bool {
|
func (arguments CliArguments) InteractiveMode() bool {
|
||||||
return !IsFalse(*arguments.Colour)
|
return *arguments.Interactive
|
||||||
|
}
|
||||||
|
|
||||||
|
func (arguments CliArguments) ShowChecks() bool {
|
||||||
|
return !utils.IsFalse(*arguments.Checks)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (arguments CliArguments) ShowColour() bool {
|
||||||
|
return !utils.IsFalse(*arguments.Colour)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (arguments CliArguments) GetConfigFile() string {
|
||||||
|
return *arguments.ConfigFile
|
||||||
}
|
}
|
||||||
|
|||||||
56
code/golang/internal/types/types_counter.go
Normal file
56
code/golang/internal/types/types_counter.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* TYPE Counter
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
type Counter struct {
|
||||||
|
nr int
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CLASS METHODS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func NewCounter() Counter {
|
||||||
|
c := Counter{}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Counter) String() string {
|
||||||
|
return fmt.Sprintf("%[1]v", self.nr)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
n = options[0]
|
||||||
|
}
|
||||||
|
self.nr += n
|
||||||
|
}
|
||||||
72
code/golang/internal/types/types_timer.go
Normal file
72
code/golang/internal/types/types_timer.go
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* TYPE Timer
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
type Timer struct {
|
||||||
|
time_elapsed time.Duration
|
||||||
|
time_current time.Time
|
||||||
|
running bool
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CLASS METHODS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func NewTimer() Timer {
|
||||||
|
c := Timer{}
|
||||||
|
c.Reset()
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Timer) String() string {
|
||||||
|
return fmt.Sprintf("%[1]v", self.time_elapsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Timer) CurrentTime() time.Time {
|
||||||
|
return self.time_current
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Timer) ElapsedTime() time.Duration {
|
||||||
|
return self.time_elapsed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Timer) Start() {
|
||||||
|
self.time_current = time.Now()
|
||||||
|
self.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Timer) Stop() {
|
||||||
|
if self.running {
|
||||||
|
t0 := self.time_current
|
||||||
|
t1 := time.Now()
|
||||||
|
delta := t1.Sub(t0)
|
||||||
|
self.time_current = t1
|
||||||
|
self.time_elapsed += delta
|
||||||
|
}
|
||||||
|
self.running = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Timer) Reset() {
|
||||||
|
t := time.Now()
|
||||||
|
delta := t.Sub(t) // d. h. 0
|
||||||
|
self.time_current = t
|
||||||
|
self.time_elapsed = delta
|
||||||
|
self.running = false
|
||||||
|
}
|
||||||
38
code/golang/internal/types/types_userconfig.go
Normal file
38
code/golang/internal/types/types_userconfig.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* YAML SCHEMES
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
type UserConfig struct {
|
||||||
|
Info *UserConfigInfo `yaml:"info"`
|
||||||
|
Parts *UserConfigParts `yaml:"parts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserConfigInfo struct {
|
||||||
|
Title *string `yaml:"title"`
|
||||||
|
Description *string `yaml:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserConfigParts struct {
|
||||||
|
Cases *([]UserConfigCase) `yaml:"cases"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserConfigCase struct {
|
||||||
|
Command *string `yaml:"command"`
|
||||||
|
Description *string `yaml:"description"`
|
||||||
|
Inputs *UserConfigInputs `yaml:"inputs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserConfigInputs struct {
|
||||||
|
List *[]int `yaml:"L"`
|
||||||
|
SearchRank *int `yaml:"i"`
|
||||||
|
SearchValue *int `yaml:"x"`
|
||||||
|
JumpSize *int `yaml:"m"`
|
||||||
|
}
|
||||||
@@ -9,10 +9,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"ads/internal/core/logging"
|
"ads/internal/core/logging"
|
||||||
"ads/internal/endpoints"
|
|
||||||
"ads/internal/setup"
|
"ads/internal/setup"
|
||||||
"ads/internal/setup/cli"
|
"ads/internal/setup/cli"
|
||||||
"ads/internal/types"
|
"ads/internal/types"
|
||||||
|
|
||||||
|
endpoints_print "ads/internal/endpoints/print"
|
||||||
|
endpoints_run "ads/internal/endpoints/run"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
@@ -24,9 +26,10 @@ var (
|
|||||||
//go:embed assets/*
|
//go:embed assets/*
|
||||||
res embed.FS
|
res embed.FS
|
||||||
assets = map[string]string{
|
assets = map[string]string{
|
||||||
"version": "assets/VERSION",
|
"appconfig": "assets/config.yml",
|
||||||
"logo": "assets/LOGO",
|
"version": "assets/VERSION",
|
||||||
"help": "assets/HELP",
|
"logo": "assets/LOGO",
|
||||||
|
"help": "assets/HELP",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,34 +38,66 @@ var (
|
|||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var err error
|
|
||||||
var arguments *types.CliArguments
|
var arguments *types.CliArguments
|
||||||
|
var (
|
||||||
|
err1 error
|
||||||
|
err2 error
|
||||||
|
err3 error
|
||||||
|
cmdMissing bool
|
||||||
|
showChecks bool
|
||||||
|
)
|
||||||
|
|
||||||
// set assets
|
// assets festlegen
|
||||||
setup.Res = res
|
setup.Res = res
|
||||||
setup.Assets = assets
|
setup.Assets = assets
|
||||||
|
|
||||||
// parse cli arguments
|
// cli arguments parsen
|
||||||
arguments, err = cli.ParseCli(os.Args)
|
arguments, err1 = cli.ParseCli(os.Args)
|
||||||
|
cmdMissing = cli.ParseCliCommandMissing(err1)
|
||||||
|
|
||||||
// initialise logging options
|
// Programmeinstellungen initialisieren
|
||||||
if err == nil {
|
showChecks = false
|
||||||
logging.SetQuietMode(*arguments.Quiet)
|
if err1 == nil {
|
||||||
logging.SetDebugMode(*arguments.Debug)
|
if !(arguments.ModeRun.Happened() && arguments.InteractiveMode()) {
|
||||||
logging.SetAnsiMode(arguments.ShowColour())
|
logging.SetQuietMode(arguments.QuietModeOn())
|
||||||
}
|
logging.SetDebugMode(arguments.DebugModeOn())
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
if arguments.Version.Happened() {
|
|
||||||
endpoints.Version()
|
|
||||||
} else if arguments.Run.Happened() {
|
|
||||||
err = endpoints.Run(*arguments.ConfigFile)
|
|
||||||
} else { // } else if arguments.Help.Happened() {
|
|
||||||
endpoints.Help()
|
|
||||||
}
|
}
|
||||||
|
logging.SetAnsiMode(arguments.ShowColour())
|
||||||
|
showChecks = arguments.ShowChecks()
|
||||||
}
|
}
|
||||||
|
err2 = setup.AppConfigInitialise()
|
||||||
|
setup.SetAppConfigPerformChecks(showChecks)
|
||||||
|
|
||||||
if err != nil {
|
// Fehler melden (fatal)
|
||||||
logging.LogFatal(err)
|
if err1 != nil && !cmdMissing {
|
||||||
|
logging.Fatal(err1)
|
||||||
|
}
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
code/golang/pkg/algorithms/search/binary/binary.go
Normal file
54
code/golang/pkg/algorithms/search/binary/binary.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package binary
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM binary search
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
|
|
||||||
|
Annahme: L sei aufsteigend sortiert.
|
||||||
|
|
||||||
|
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.Debug("x nicht in L.")
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
m := int(len(L) / 2)
|
||||||
|
if L[m] == x {
|
||||||
|
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.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.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 == -1 {
|
||||||
|
return -1 // wenn nicht gefunden
|
||||||
|
}
|
||||||
|
return index + (m + 1) // NOTE: muss Indexwert kompensieren
|
||||||
|
}
|
||||||
|
}
|
||||||
106
code/golang/pkg/algorithms/search/binary/binary_fancy.go
Normal file
106
code/golang/pkg/algorithms/search/binary/binary_fancy.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package binary
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func preChecks(L []int, _ ...interface{}) error {
|
||||||
|
if !utils.IsSortedListInt(L) {
|
||||||
|
return fmt.Errorf("Ungültiger Input: L muss aufsteigend sortiert sein!")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, x int, index int, _ ...interface{}) error {
|
||||||
|
if utils.ArrayContains(L, x) {
|
||||||
|
if !(index >= 0) {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte nicht -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
if L[index] != x {
|
||||||
|
return fmt.Errorf("Der Algorithmus hat den falschen Index bestimmt.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if index != -1 {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM binary search + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyBinarySearch(input_L []int, input_x int) (int, error) {
|
||||||
|
var name = "Binärsuchalgorithmus"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"x": input_x,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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, input_x)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_index = BinarySearch(input_L, input_x)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
67
code/golang/pkg/algorithms/search/interpol/interpol.go
Normal file
67
code/golang/pkg/algorithms/search/interpol/interpol.go
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package interpol
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM interpolation
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
|
|
||||||
|
Annahme: L sei aufsteigend sortiert.
|
||||||
|
|
||||||
|
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.Debug("Liste L leer, also x nicht in L")
|
||||||
|
return -1
|
||||||
|
} else if !(L[u] <= x && x <= L[v]) {
|
||||||
|
logging.Debug("x liegt außerhalb der Grenzen von L")
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
p := getSuchposition(L, x, u, v)
|
||||||
|
if L[p] == x {
|
||||||
|
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.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.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM interpolation
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
||||||
|
|
||||||
|
Outputs: Interpolierte Position, um Suchinterval ausgeglichen aufzuteilen.
|
||||||
|
*/
|
||||||
|
func getSuchposition(L []int, x int, u int, v int) int {
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
r := float64(x-L[u]) / float64(L[v]-L[u])
|
||||||
|
p := int(math.Floor(float64(u) + r*float64(v-u)))
|
||||||
|
return p
|
||||||
|
}
|
||||||
108
code/golang/pkg/algorithms/search/interpol/interpol_fancy.go
Normal file
108
code/golang/pkg/algorithms/search/interpol/interpol_fancy.go
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
package interpol
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func preChecks(L []int, _ ...interface{}) error {
|
||||||
|
if !utils.IsSortedListInt(L) {
|
||||||
|
return fmt.Errorf("Ungültiger Input: L muss aufsteigend sortiert sein!")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, x int, index int, _ ...interface{}) error {
|
||||||
|
if utils.ArrayContains(L, x) {
|
||||||
|
if !(index >= 0) {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte nicht -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
if L[index] != x {
|
||||||
|
return fmt.Errorf("Der Algorithmus hat den falschen Index bestimmt.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if index != -1 {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM interpolation + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyInterpolationSearch(input_L []int, input_x int, input_u int, input_v int) (int, error) {
|
||||||
|
var name = "Interpolationssuchalgorithmus"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"x": input_x,
|
||||||
|
"u": input_u,
|
||||||
|
"v": input_v,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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, input_x, input_u, input_v)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_index = InterpolationSearch(input_L, input_x, input_u, input_v)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
94
code/golang/pkg/algorithms/search/ith_element/ith_element.go
Normal file
94
code/golang/pkg/algorithms/search/ith_element/ith_element.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package ith_element
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find ith smallest
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, i = Ordinalzahl
|
||||||
|
|
||||||
|
Annahmen:
|
||||||
|
|
||||||
|
- L enthält keine Duplikate.
|
||||||
|
- L enthält mindestens i Elemente.
|
||||||
|
|
||||||
|
Outputs: Wert des i. kleinste Element in L.
|
||||||
|
Beachte 1.kleinstes <==> Minimum.
|
||||||
|
*/
|
||||||
|
func FindIthSmallest(L []int, i int) int {
|
||||||
|
n := len(L)
|
||||||
|
// extrahiere Wert + Index des Minimums - bedarf n Schritte
|
||||||
|
metrics.AddTimeCost(n)
|
||||||
|
index := utils.ArgMinInt(L)
|
||||||
|
minValue := L[index]
|
||||||
|
// Falls i = 1, dann wird das Minimum gesucht, sonst Minimum entfernen und nach i-1. Element suchen
|
||||||
|
if i == 1 {
|
||||||
|
logging.Debug("Das i. kleinste Element wurde gefunden.")
|
||||||
|
return minValue
|
||||||
|
} else {
|
||||||
|
logging.Debug("Entferne Minimum: %[1]v.", minValue)
|
||||||
|
i = i - 1
|
||||||
|
L_ := utils.PopIndexListInt(L, index) // entferne Element mit Index = index
|
||||||
|
return FindIthSmallest(L_, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find ith smallest (D & C)
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, i = Ordinalzahl
|
||||||
|
|
||||||
|
Annahmen:
|
||||||
|
|
||||||
|
- L enthält keine Duplikate.
|
||||||
|
|
||||||
|
- L enthält mindestens i Elemente.
|
||||||
|
|
||||||
|
Outputs: Wert des i. kleinste Element in L.
|
||||||
|
Beachte 1.kleinstes <==> Minimum.
|
||||||
|
*/
|
||||||
|
func FindIthSmallestDC(L []int, i int) int {
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
p := L[len(L)-1] // NOTE: Pivotelement kann beliebig gewählt werden
|
||||||
|
// Werte in L in linke und rechte Teillisten um das Pivotelement aufteilen:
|
||||||
|
Ll := []int{} // wird alle Elemente in L < p enthalten
|
||||||
|
Lr := []int{} // wird alle Elemente in L > p enthalten
|
||||||
|
for i := 0; i < len(L); i++ {
|
||||||
|
x := L[i]
|
||||||
|
if x < p {
|
||||||
|
Ll = append(Ll, x)
|
||||||
|
} else if x > p {
|
||||||
|
Lr = append(Lr, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallunterscheidung:
|
||||||
|
if len(Ll) == i-1 {
|
||||||
|
logging.Debug("Es gibt i-1 Elemente vor p=%[1]v. ==> i. kleinste Element = p", p)
|
||||||
|
return p
|
||||||
|
} else if len(Ll) >= i {
|
||||||
|
logging.Debug("Es gibt >= i Elemente vor p=%[1]v. ==> Suche in linker Hälfte!", p)
|
||||||
|
return FindIthSmallestDC(Ll, i)
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package ith_element
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func preChecks(L []int, i int, _ ...interface{}) error {
|
||||||
|
if !(1 <= i && i <= len(L)) {
|
||||||
|
return fmt.Errorf("Der Wert von i muss zw. %[1]v und %[2]v liegen.", 1, len(L))
|
||||||
|
} else if !utils.ContainsNoDuplicatesListInt(L) {
|
||||||
|
return fmt.Errorf("Ungültiger Input: L darf keine Duplikate enthalten!")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, i int, value int, _ ...interface{}) error {
|
||||||
|
L_ := make([]int, len(L))
|
||||||
|
copy(L_, L)
|
||||||
|
sort.Ints(L_)
|
||||||
|
if !(L_[i-1] == value) {
|
||||||
|
return fmt.Errorf("Das i=%[1]v. kleinste Element ist %[2]v und nicht %[3]v.", i, L_[i-1], value)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find ith smallest + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyFindIthSmallest(input_L []int, input_i int) (int, error) {
|
||||||
|
var name = "Auswahlproblem (i. kleinstes Element)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"i": input_i,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_value 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, input_i)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_value = FindIthSmallest(input_L, input_i)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"value": output_value,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_i, output_value)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find ith smallest (D & C) + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyFindIthSmallestDC(input_L []int, input_i int) (int, error) {
|
||||||
|
var name = "Auswahlproblem (i. kleinstes Element, D & C)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"i": input_i,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_value 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, input_i)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_value = FindIthSmallestDC(input_L, input_i)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"value": output_value,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_i, output_value)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_value, err
|
||||||
|
}
|
||||||
96
code/golang/pkg/algorithms/search/jump/jump.go
Normal file
96
code/golang/pkg/algorithms/search/jump/jump.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package jump
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/pkg/algorithms/search/sequential"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM jump search
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
|
||||||
|
|
||||||
|
Annahmen:
|
||||||
|
- L sei aufsteigend sortiert.
|
||||||
|
- Idealerweise: L enthält keine Duplikate.
|
||||||
|
- Idealerweise: Abstände zw. Elementen nicht uniform.
|
||||||
|
|
||||||
|
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
||||||
|
*/
|
||||||
|
func JumpSearchLinear(L []int, x int, m int) int {
|
||||||
|
i0 := 0
|
||||||
|
i1 := m
|
||||||
|
// ACHTUNG: dies ist eine while-Schleife ist golang:
|
||||||
|
for i0 < len(L) {
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
if i1 > len(L) {
|
||||||
|
i1 = len(L)
|
||||||
|
}
|
||||||
|
block := L[i0:i1]
|
||||||
|
elementAfterBlock := block[len(block)-1] + 1
|
||||||
|
if x < elementAfterBlock {
|
||||||
|
logging.Debug("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1)
|
||||||
|
index := sequential.SequentialSearch(block, x)
|
||||||
|
if index == -1 {
|
||||||
|
return -1 // wenn nicht gefunden
|
||||||
|
}
|
||||||
|
return index + i0 // NOTE: muss wegen Offset kompensieren
|
||||||
|
}
|
||||||
|
logging.Debug("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1)
|
||||||
|
i0 = i1
|
||||||
|
i1 += m
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM jump search - exponentiell
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
|
|
||||||
|
Annahmen:
|
||||||
|
- L sei aufsteigend sortiert.
|
||||||
|
- L enthält keine Duplikate.
|
||||||
|
|
||||||
|
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
||||||
|
*/
|
||||||
|
func JumpSearchExponentiell(L []int, x int) int {
|
||||||
|
i0 := 0
|
||||||
|
i1 := 1
|
||||||
|
// ACHTUNG: dies ist eine while-Schleife ist golang:
|
||||||
|
for i0 < len(L) {
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
if i1 > len(L) {
|
||||||
|
i1 = len(L)
|
||||||
|
}
|
||||||
|
block := L[i0:i1]
|
||||||
|
elementAfterBlock := block[len(block)-1] + 1
|
||||||
|
if x < elementAfterBlock {
|
||||||
|
logging.Debug("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1)
|
||||||
|
index := sequential.SequentialSearch(block, x)
|
||||||
|
if index == -1 {
|
||||||
|
return -1 // wenn nicht gefunden
|
||||||
|
}
|
||||||
|
return index + i0 // NOTE: muss wegen Offset kompensieren
|
||||||
|
}
|
||||||
|
logging.Debug("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1)
|
||||||
|
i0 = i1
|
||||||
|
i1 *= 2
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
168
code/golang/pkg/algorithms/search/jump/jump_fancy.go
Normal file
168
code/golang/pkg/algorithms/search/jump/jump_fancy.go
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
package jump
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func preChecks(L []int, _ ...interface{}) error {
|
||||||
|
if !utils.IsSortedListInt(L) {
|
||||||
|
return fmt.Errorf("Ungültiger Input: L muss aufsteigend sortiert sein!")
|
||||||
|
}
|
||||||
|
// NOTE: nicht prüfen, ob Duplikate existieren. Das ist nur eine erwünschte aber keine notwendige Annahme.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, x int, index int, _ ...interface{}) error {
|
||||||
|
if utils.ArrayContains(L, x) {
|
||||||
|
if !(index >= 0) {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte nicht -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
if L[index] != x {
|
||||||
|
return fmt.Errorf("Der Algorithmus hat den falschen Index bestimmt.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if index != -1 {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM jump search + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyJumpSearchLinear(input_L []int, input_x int, input_m int) (int, error) {
|
||||||
|
var name = "Sprungsuche"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"x": input_x,
|
||||||
|
"m": input_m,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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, input_x, input_m)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_index = JumpSearchLinear(input_L, input_x, input_m)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM jump search - exponentiell + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyJumpSearchExponentiell(input_L []int, input_x int) (int, error) {
|
||||||
|
var name = "Sprungsuche (exponentiell)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"x": input_x,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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, input_x)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_index = JumpSearchExponentiell(input_L, input_x)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
171
code/golang/pkg/algorithms/search/poison/poison.go
Normal file
171
code/golang/pkg/algorithms/search/poison/poison.go
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
package poison
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find poison
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
||||||
|
|
||||||
|
Annahme: Genau ein Getränk sei vergiftet.
|
||||||
|
|
||||||
|
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.Debug("Bereite Vorkoster vor")
|
||||||
|
n := len(L)
|
||||||
|
testers := [][]int{}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
metrics.AddSpaceCost()
|
||||||
|
logging.Debug("Füge Vorkoster hinzu, der nur Getränk %[1]v testet.", i)
|
||||||
|
testers = append(testers, []int{i})
|
||||||
|
}
|
||||||
|
logging.Debug("Warte auf Effekte")
|
||||||
|
effects := waitForEffects(L, testers)
|
||||||
|
logging.Debug("Effekte auswerten, um vergiftete Getränke zu lokalisieren.")
|
||||||
|
poisened := evaluateEffects(testers, effects)
|
||||||
|
if len(poisened) > 0 {
|
||||||
|
return poisened[0]
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find poison fast
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
||||||
|
|
||||||
|
Annahme: Genau ein Getränk sei vergiftet.
|
||||||
|
|
||||||
|
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.Debug("Bereite Vorkoster vor")
|
||||||
|
n := len(L)
|
||||||
|
p := utils.LengthOfBinary(n)
|
||||||
|
testers := [][]int{}
|
||||||
|
// Für jedes Bit i=0 bis p-1 ...
|
||||||
|
for i := 0; i < p; i++ {
|
||||||
|
tester0 := []int{}
|
||||||
|
tester1 := []int{}
|
||||||
|
for k := 0; k < n; k++ {
|
||||||
|
if utils.NthBit(k, i) == 0 {
|
||||||
|
tester0 = append(tester0, k)
|
||||||
|
} else {
|
||||||
|
tester1 = append(tester1, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* NOTE: tester1 ist virtuell: aus den Effekten auf tester0 und den Annahmen
|
||||||
|
* lassen sich die Effekte auf tester0 erschließen.
|
||||||
|
* Darum zählen wir nicht 2 sondern 1 Vorkoster.
|
||||||
|
*/
|
||||||
|
metrics.AddSpaceCost(1)
|
||||||
|
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.Debug("Warte auf Effekte")
|
||||||
|
effects := waitForEffects(L, testers)
|
||||||
|
logging.Debug("Effekte auswerten, um vergiftete Getränke zu lokalisieren.")
|
||||||
|
poisened := evaluateEffects(testers, effects)
|
||||||
|
if len(poisened) > 0 {
|
||||||
|
return poisened[0]
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* AUXILIARY METHOD wait for effects, evaluate effects
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs:
|
||||||
|
|
||||||
|
- L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
||||||
|
|
||||||
|
- testers = Liste von Vorkostern. Jeder Vorkoster kostet eine 'Teilliste' der Getränke.
|
||||||
|
|
||||||
|
Outputs: effects = eine Liste, die jedem Vorkoster zuordnet, wie viele vergiftete Getränke er konsumiert hat.
|
||||||
|
*/
|
||||||
|
func waitForEffects(L []int, testers [][]int) []int {
|
||||||
|
m := len(testers)
|
||||||
|
effects := make([]int, m)
|
||||||
|
for i, tester := range testers {
|
||||||
|
effect := 0
|
||||||
|
for _, k := range tester {
|
||||||
|
effect += L[k]
|
||||||
|
}
|
||||||
|
effects[i] = effect
|
||||||
|
}
|
||||||
|
return effects
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs:
|
||||||
|
|
||||||
|
- testers = Liste von Vorkostern. Jeder Vorkoster kostet eine 'Teilliste' der Getränke.
|
||||||
|
|
||||||
|
- effects = eine Liste, die jedem Vorkoster zuordnet, wie viele vergiftete Getränke er konsumiert hat.
|
||||||
|
|
||||||
|
Annahmen: Vorkoster wurden so angewiesen, dass es garantiert ist, vergiftete Getränke zu finden, wenn es die gibt.
|
||||||
|
|
||||||
|
Outputs: Liste der Indexes aller vergifteten Getränke.
|
||||||
|
*/
|
||||||
|
func evaluateEffects(testers [][]int, effects []int) []int {
|
||||||
|
var states = map[int]bool{}
|
||||||
|
var poisened = []int{}
|
||||||
|
|
||||||
|
// Werte Effekte aus, um Gift zu lokalisieren:
|
||||||
|
// Zuerst die Indexes der Getränke bei allen vergifteten Tester zusammenführen:
|
||||||
|
for i, tester := range testers {
|
||||||
|
// wenn Tester positiv testet, dann ist eines der von ihm probierten Getränks vergiftet
|
||||||
|
if effects[i] > 0 {
|
||||||
|
// markiere alle vom Tester probierten Getränke
|
||||||
|
for _, k := range tester {
|
||||||
|
states[k] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// jetzt eliminieren wir alle Getränke, die von nicht vergifteten Testern konsumiert wurden:
|
||||||
|
for i, tester := range testers {
|
||||||
|
// wenn Tester negativ testet, dann ist KEINES der von ihm probierten Getränks vergiftet
|
||||||
|
if effects[i] == 0 {
|
||||||
|
// schließe alle vom Tester probierten Getränke aus
|
||||||
|
for _, k := range tester {
|
||||||
|
states[k] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// was übrig bleibt sind die vergifteten Getränke, vorausgesetzt genug Vorkoster wurden ausgewählt
|
||||||
|
for k, state := range states {
|
||||||
|
if state {
|
||||||
|
poisened = append(poisened, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return poisened
|
||||||
|
}
|
||||||
160
code/golang/pkg/algorithms/search/poison/poison_fancy.go
Normal file
160
code/golang/pkg/algorithms/search/poison/poison_fancy.go
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
package poison
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
func preChecks(L []int, _ ...interface{}) error {
|
||||||
|
s := utils.SumListInt(L)
|
||||||
|
if !(s > 0) {
|
||||||
|
return fmt.Errorf("Mindestens ein Getränk muss vergiftet sein!")
|
||||||
|
} else if !(s <= 1) {
|
||||||
|
return fmt.Errorf("Höchstens ein Getränk darf vergiftet sein!")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, index int, _ ...interface{}) error {
|
||||||
|
if !(index >= 0) {
|
||||||
|
return fmt.Errorf("Der Algorithmus hat kein vergiftetes Getränk gefunden, obwohl per Annahme eines existiert.")
|
||||||
|
} else if !(L[index] > 0) {
|
||||||
|
return fmt.Errorf("Der Algorithmus hat das vergiftete Getränk nicht erfolgreich bestimmt.")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find poison + Display
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
func FancyFindPoison(input_L []int) (int, error) {
|
||||||
|
var name = "Giftsuche (O(n) Vorkoster)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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()
|
||||||
|
output_index = FindPoison(input_L)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM find poison fast + Display
|
||||||
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||||
|
|
||||||
|
func FancyFindPoisonFast(input_L []int) (int, error) {
|
||||||
|
var name = "Giftsuche (O(log(n)) Vorkoster)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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()
|
||||||
|
output_index = FindPoisonFast(input_L)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
37
code/golang/pkg/algorithms/search/sequential/sequential.go
Normal file
37
code/golang/pkg/algorithms/search/sequential/sequential.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package sequential
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM sequential search
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
|
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
||||||
|
*/
|
||||||
|
func SequentialSearch(L []int, x int) int {
|
||||||
|
n := len(L)
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
if L[i] == x {
|
||||||
|
logging.Debug("Element in Position %[1]v gefunden.", i)
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
logging.Debug("Element nicht in Position %[1]v.", i)
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
104
code/golang/pkg/algorithms/search/sequential/sequential_fancy.go
Normal file
104
code/golang/pkg/algorithms/search/sequential/sequential_fancy.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package sequential
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func preChecks(L []int, _ ...interface{}) error {
|
||||||
|
// Keine Checks!
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, x int, index int, _ ...interface{}) error {
|
||||||
|
if utils.ArrayContains(L, x) {
|
||||||
|
if !(index >= 0) {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte nicht -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
if L[index] != x {
|
||||||
|
return fmt.Errorf("Der Algorithmus hat den falschen Index bestimmt.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if index != -1 {
|
||||||
|
return fmt.Errorf("Der Algorithmus sollte -1 zurückgeben.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD sequential search + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancySequentialSearch(input_L []int, input_x int) (int, error) {
|
||||||
|
var name = "Sequenziellsuchalgorithmus"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
"x": input_x,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_index 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, input_x)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
metrics.ResetMetrics()
|
||||||
|
metrics.StartMetrics()
|
||||||
|
output_index = SequentialSearch(input_L, input_x)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
167
code/golang/pkg/algorithms/sum/maxsubsum/maxsubsum.go
Normal file
167
code/golang/pkg/algorithms/sum/maxsubsum/maxsubsum.go
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
package maxsubsum
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/core/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM max sub sum
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
|
||||||
|
- maxSum = Wert der maximalen Summe einer Teilliste aufeinanderfolgender Elemente
|
||||||
|
|
||||||
|
- u, v = Indexes so dass die Teilliste [L[u], L[u+1], ..., L[v]] die maximale Summe aufweist
|
||||||
|
*/
|
||||||
|
func MaxSubSum(L []int) (int, int, int) {
|
||||||
|
maxSum := 0
|
||||||
|
u := 0
|
||||||
|
v := -1
|
||||||
|
for i := 0; i < len(L); i++ {
|
||||||
|
// Bestimme maximale Teilsumme der linken Rände der Liste ab Index i {
|
||||||
|
maxSum_, _, k := lRandSum(L[i:])
|
||||||
|
if maxSum_ > maxSum {
|
||||||
|
k += i // NOTE: muss wegen Offset kompensieren
|
||||||
|
maxSum, u, v = maxSum_, i, k
|
||||||
|
logging.Debug("max Teilsumme aktualisiert: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxSum, u, v
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM max sub sum (D & C)
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
|
||||||
|
- maxSum = Wert der maximalen Summe einer Teilliste aufeinanderfolgender Elemente
|
||||||
|
|
||||||
|
- u, v = Indexes so dass die Teilliste [L[u], L[u+1], ..., L[v]] die maximale Summe aufweist
|
||||||
|
*/
|
||||||
|
func MaxSubSumDC(L []int) (int, int, int) {
|
||||||
|
maxSum := 0
|
||||||
|
u := 0
|
||||||
|
v := -1
|
||||||
|
if len(L) == 1 {
|
||||||
|
// wenn Liste aus 1 Element besteht, nicht teilen:
|
||||||
|
if L[0] > maxSum {
|
||||||
|
v = 0
|
||||||
|
maxSum = L[0]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u = utils.Ceil(float64(len(L)) / 2)
|
||||||
|
Ll := L[:u]
|
||||||
|
Lr := L[u:]
|
||||||
|
// berechnet maximale Teilsumme der linken Hälfte:
|
||||||
|
maxSum1, u1, v1 := MaxSubSumDC(Ll)
|
||||||
|
// berechnet maximale Teilsumme der rechten Hälfte:
|
||||||
|
maxSum2, u2, v2 := MaxSubSumDC(Lr)
|
||||||
|
u2, v2 = u2+len(Ll), v2+len(Ll) // offsets kompensieren
|
||||||
|
// berechnet maximale Teilsumme mit Überschneidung zw. den Hälften:
|
||||||
|
maxSum3, u3, v3 := lrRandSum(Ll, Lr)
|
||||||
|
// bestimme Maximum der 3 Möglichkeiten:
|
||||||
|
maxSum = utils.MaxInt(maxSum1, maxSum2, maxSum3)
|
||||||
|
if maxSum == maxSum1 {
|
||||||
|
maxSum, u, v = maxSum1, u1, v1
|
||||||
|
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.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.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
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* AUXILIARY METHODS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bestimmt maximale Teilsumme einer Teiliste einer Liste,
|
||||||
|
wobei die Liste in zwei Intervalle partitioniert ist
|
||||||
|
und die Teilliste beide überschneidet.
|
||||||
|
|
||||||
|
Inputs: Ll, Lr = eine Partition einer Liste von Zahlen in zwei Intervalle
|
||||||
|
|
||||||
|
Outputs: maxSum, u=0, v
|
||||||
|
*/
|
||||||
|
func lrRandSum(Ll []int, Lr []int) (int, int, int) {
|
||||||
|
maxSumL, u, _ := rRandSum(Ll)
|
||||||
|
maxSumR, _, v := lRandSum(Lr)
|
||||||
|
maxSum := maxSumL + maxSumR
|
||||||
|
v += len(Ll) // offsets kompensieren
|
||||||
|
return maxSum, u, v
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bestimmt maximale Teilsumme aller nicht leeren linken Segmente einer Liste.
|
||||||
|
|
||||||
|
Inputs: L = Liste von Zahlen
|
||||||
|
|
||||||
|
Outputs: maxSum, u(=0), v
|
||||||
|
*/
|
||||||
|
func lRandSum(L []int) (int, int, int) {
|
||||||
|
n := len(L)
|
||||||
|
// berechne kumulative Summen (vorwärts)
|
||||||
|
metrics.AddTimeCost(n)
|
||||||
|
total := L[0]
|
||||||
|
maxSum := total
|
||||||
|
u := 0
|
||||||
|
v := 0
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
total += L[i]
|
||||||
|
if total > maxSum {
|
||||||
|
v = i
|
||||||
|
maxSum = total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxSum, u, v
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Bestimmt maximale Teilsumme aller nicht leeren rechten Segmente einer Liste.
|
||||||
|
|
||||||
|
Inputs: L = Liste von Zahlen
|
||||||
|
|
||||||
|
Outputs: maxSum, u, v(=len(L)-1)
|
||||||
|
*/
|
||||||
|
func rRandSum(L []int) (int, int, int) {
|
||||||
|
n := len(L)
|
||||||
|
// berechne kumulative Summen (rückwärts)
|
||||||
|
metrics.AddTimeCost(n)
|
||||||
|
total := L[n-1]
|
||||||
|
maxSum := total
|
||||||
|
u := n - 1
|
||||||
|
v := n - 1
|
||||||
|
for i := n - 2; i >= 0; i-- {
|
||||||
|
total += L[i]
|
||||||
|
if total > maxSum {
|
||||||
|
u = i
|
||||||
|
maxSum = total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxSum, u, v
|
||||||
|
}
|
||||||
160
code/golang/pkg/algorithms/sum/maxsubsum/maxsubsum_fancy.go
Normal file
160
code/golang/pkg/algorithms/sum/maxsubsum/maxsubsum_fancy.go
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
package maxsubsum
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* CHECKS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func preChecks(L []int, _ ...interface{}) error {
|
||||||
|
if !(len(L) > 0) {
|
||||||
|
return fmt.Errorf("Liste darf nicht leer sein.")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func postChecks(L []int, _ ...interface{}) error {
|
||||||
|
// TODO
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHOD Algorithm + Display
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyMaxSubSum(input_L []int) (int, int, int, error) {
|
||||||
|
var name = "MaxSubSum (Maximale Teilsumme)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_maxSum int
|
||||||
|
output_indexFrom int
|
||||||
|
output_indexTo 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()
|
||||||
|
output_maxSum, output_indexFrom, output_indexTo = MaxSubSum(input_L)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"maxSum": output_maxSum,
|
||||||
|
"index_from": output_indexFrom,
|
||||||
|
"index_to": output_indexTo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, output_maxSum, output_indexFrom, output_indexTo)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_maxSum, output_indexFrom, output_indexTo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM max sub sum (D & C)
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func FancyMaxSubSumDC(input_L []int) (int, int, int, error) {
|
||||||
|
var name = "MaxSubSum (Maximale Teilsumme mit D & C)"
|
||||||
|
var inputs = map[string]interface{}{
|
||||||
|
"L": input_L,
|
||||||
|
}
|
||||||
|
var outputs map[string]interface{}
|
||||||
|
var (
|
||||||
|
output_maxSum int
|
||||||
|
output_indexFrom int
|
||||||
|
output_indexTo 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()
|
||||||
|
output_maxSum, output_indexFrom, output_indexTo = MaxSubSumDC(input_L)
|
||||||
|
metrics.StopMetrics()
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"maxSum": output_maxSum,
|
||||||
|
"index_from": output_indexFrom,
|
||||||
|
"index_to": output_indexTo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metriken anzeigen
|
||||||
|
if setup.AppConfigShowMetrics() {
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
}
|
||||||
|
|
||||||
|
// End Message
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
if setup.AppConfigPerformChecks() {
|
||||||
|
err = postChecks(input_L, output_maxSum, output_indexFrom, output_indexTo)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_maxSum, output_indexFrom, output_indexTo, err
|
||||||
|
}
|
||||||
81
code/golang/pkg/data_structures/queues/queues.go
Normal file
81
code/golang/pkg/data_structures/queues/queues.go
Normal 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:]
|
||||||
|
}
|
||||||
81
code/golang/pkg/data_structures/stacks/stacks.go
Normal file
81
code/golang/pkg/data_structures/stacks/stacks.go
Normal 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)]
|
||||||
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
github.com/akamensky/argparse@v1.3.1
|
github.com/akamensky/argparse@v1.3.1
|
||||||
github.com/lithammer/dedent@v1.1.0
|
github.com/lithammer/dedent@v1.1.0
|
||||||
github.com/slongfield/pyfmt@v0.0.0-20180124071345-020a7cb18bca
|
|
||||||
github.com/stretchr/testify@v1.7.0
|
github.com/stretchr/testify@v1.7.0
|
||||||
golang.org/x/tools
|
|
||||||
gopkg.in/yaml.v3@v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3@v3.0.0-20210107192922-496545a6307b
|
||||||
|
|||||||
38
code/python/.gitignore
vendored
Normal file
38
code/python/.gitignore
vendored
Normal 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
27
code/python/Makefile
Normal 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
78
code/python/README.md
Normal 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. 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. 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. 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
3
code/python/assets/LOGO
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
+--------------------+
|
||||||
|
| \033[32;1mAlgoDat I\033[0m |
|
||||||
|
+--------------------+
|
||||||
1
code/python/assets/VERSION
Normal file
1
code/python/assets/VERSION
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.0.0
|
||||||
7
code/python/assets/config.yml
Normal file
7
code/python/assets/config.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
info:
|
||||||
|
title: "App für ADS1"
|
||||||
|
description: "Interne Configurationsdatei"
|
||||||
|
options:
|
||||||
|
display: true
|
||||||
|
checks: false
|
||||||
|
metrics: true
|
||||||
@@ -17,6 +17,7 @@ import sys;
|
|||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), '..')));
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), '..')));
|
||||||
|
|
||||||
from src.setup.cli import *;
|
from src.setup.cli import *;
|
||||||
|
from src.endpoints.exports import *;
|
||||||
from src.main import enter;
|
from src.main import enter;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -24,10 +25,18 @@ from src.main import enter;
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.tracebacklimit = 0;
|
|
||||||
sys.tracebacklimit = 0;
|
sys.tracebacklimit = 0;
|
||||||
try:
|
try:
|
||||||
args = GetArgumentsFromCli(sys.argv[1:]);
|
args = GetArgumentsFromCli(*sys.argv[1:]);
|
||||||
except:
|
except:
|
||||||
|
endpoint_help();
|
||||||
exit(1);
|
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,
|
||||||
|
);
|
||||||
|
|||||||
@@ -6,4 +6,5 @@
|
|||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
from src.algorithms.search.exports import *;
|
from src.algorithms.search.exports import *;
|
||||||
|
from src.algorithms.stacks.exports import *;
|
||||||
from src.algorithms.sum.exports import *;
|
from src.algorithms.sum.exports import *;
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
import functools;
|
import functools
|
||||||
|
|
||||||
from src.core.log import *;
|
from src.core.log import *;
|
||||||
|
from src.setup import appconfig;
|
||||||
|
from src.core.metrics import *;
|
||||||
from src.setup.display import *;
|
from src.setup.display import *;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -37,14 +39,12 @@ nonnestedAlgorithms = OneShot();
|
|||||||
|
|
||||||
def algorithmInfos(
|
def algorithmInfos(
|
||||||
name: str,
|
name: str,
|
||||||
checks: bool = True,
|
outputnames: List[str] = ['result'],
|
||||||
metrics: bool = None,
|
|
||||||
outputnames: Union[str, Tuple[str]] = 'result',
|
|
||||||
preChecks: Any = None,
|
preChecks: Any = None,
|
||||||
postChecks: Any = None
|
postChecks: Any = None
|
||||||
):
|
):
|
||||||
'''
|
'''
|
||||||
Decorator für Algorthmen, der Folgendes macht:
|
Decorator für Algorithmen, der Folgendes macht:
|
||||||
|
|
||||||
- Zeigt vorm Start Console-Messages mit Namen des Algorithmus + Inputs.
|
- Zeigt vorm Start Console-Messages mit Namen des Algorithmus + Inputs.
|
||||||
- Zeit am Ende optional Metriken (bspw. Zeitkosten).
|
- Zeit am Ende optional Metriken (bspw. Zeitkosten).
|
||||||
@@ -65,27 +65,30 @@ def algorithmInfos(
|
|||||||
if state:
|
if state:
|
||||||
# Initialisierung
|
# Initialisierung
|
||||||
DisplayStartOfAlgorithm(name, **inputs);
|
DisplayStartOfAlgorithm(name, **inputs);
|
||||||
RestartCounter();
|
|
||||||
# Prechecks
|
# Prechecks
|
||||||
if checks and callable(preChecks):
|
if appconfig.AppConfigPerformChecks() and callable(preChecks):
|
||||||
preChecks(**inputs);
|
preChecks(**inputs);
|
||||||
# Ausführung des Algorithmus:
|
# Metriken initialisieren + starten
|
||||||
|
ResetMetrics();
|
||||||
|
StartMetrics();
|
||||||
|
# Ausführung des Algorithmus:
|
||||||
nonnestedRecursion.trigger();
|
nonnestedRecursion.trigger();
|
||||||
nonnestedAlgorithms.trigger();
|
nonnestedAlgorithms.trigger();
|
||||||
outputs = func(*[], **inputs);
|
outputs = func(*[], **inputs);
|
||||||
nonnestedAlgorithms.state = state1;
|
nonnestedAlgorithms.state = state1;
|
||||||
nonnestedRecursion.state = state2;
|
nonnestedRecursion.state = state2;
|
||||||
if state:
|
if state:
|
||||||
|
# Metriken anhalten
|
||||||
|
StopMetrics();
|
||||||
# benenne Outputs:
|
# benenne Outputs:
|
||||||
outputs_ = outputs if isinstance(outputs, tuple) else tuple([outputs]);
|
outputs_ = outputs if isinstance(outputs, tuple) else tuple([outputs]);
|
||||||
outputnames_ = outputnames if isinstance(outputnames, tuple) else tuple([outputnames]);
|
outputsNamed = { outputnames[k]: value for k, value in enumerate(outputs_) };
|
||||||
outputsNamed = { outputnames_[k]: value for k, value in enumerate(outputs_) };
|
|
||||||
# Letzte Messages
|
# Letzte Messages
|
||||||
if metrics:
|
if appconfig.AppConfigShowMetrics():
|
||||||
DisplayMetrics();
|
DisplayMetrics();
|
||||||
DisplayEndOfAlgorithm(**outputsNamed);
|
DisplayEndOfAlgorithm(**outputsNamed);
|
||||||
# Postchecks
|
# Postchecks
|
||||||
if checks and callable(postChecks):
|
if appconfig.AppConfigPerformChecks() and callable(postChecks):
|
||||||
postChecks(**inputs, **outputsNamed);
|
postChecks(**inputs, **outputsNamed);
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
nonnestedAlgorithms.state = state1;
|
nonnestedAlgorithms.state = state1;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
|
|||||||
# ALGORITHM binary search
|
# 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:
|
def BinarySearch(L: List[int], x: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, x = Zahl.
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
@@ -49,7 +49,7 @@ def BinarySearch(L: List[int], x: int) -> int:
|
|||||||
if len(L) == 0:
|
if len(L) == 0:
|
||||||
logDebug('x nicht in L');
|
logDebug('x nicht in L');
|
||||||
return -1;
|
return -1;
|
||||||
AddToCounter();
|
AddTimeCost();
|
||||||
m = math.floor(len(L)/2);
|
m = math.floor(len(L)/2);
|
||||||
if L[m] == x:
|
if L[m] == x:
|
||||||
logDebug('x in Position m gefunden');
|
logDebug('x in Position m gefunden');
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
|
|||||||
# ALGORITHM interpolation
|
# 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:
|
def InterpolationSearch(L: List[int], x: int, u: int, v: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
||||||
@@ -66,7 +66,7 @@ def getSuchposition(L: List[int], x: int, u: int, v: int) -> int:
|
|||||||
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
Inputs: L = Liste von Zahlen, x = Zahl, [u, v] = Suchinterval.
|
||||||
Outputs: Interpolierte Position, um Suchinterval ausgeglichen aufzuteilen.
|
Outputs: Interpolierte Position, um Suchinterval ausgeglichen aufzuteilen.
|
||||||
'''
|
'''
|
||||||
AddToCounter();
|
AddTimeCost();
|
||||||
r = (x - L[u])/(L[v]-L[u]);
|
r = (x - L[u])/(L[v]-L[u]);
|
||||||
p = math.floor(u + r*(v-u))
|
p = math.floor(u + r*(v-u))
|
||||||
return p;
|
return p;
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ def postChecks(L: List[int], i: int, value: int, **_):
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# ALGORITHM jump search
|
# 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:
|
def FindIthSmallest(L: List[int], i: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, i = Ordinalzahl
|
Inputs: L = Liste von Zahlen, i = Ordinalzahl
|
||||||
@@ -51,7 +51,7 @@ def FindIthSmallest(L: List[int], i: int) -> int:
|
|||||||
'''
|
'''
|
||||||
index = 0;
|
index = 0;
|
||||||
minValue = L[0];
|
minValue = L[0];
|
||||||
AddToCounter(len(L));
|
AddTimeCost(len(L));
|
||||||
for i_ in range(1, len(L)):
|
for i_ in range(1, len(L)):
|
||||||
if L[i_] < minValue:
|
if L[i_] < minValue:
|
||||||
index = i_;
|
index = i_;
|
||||||
@@ -65,10 +65,10 @@ def FindIthSmallest(L: List[int], i: int) -> int:
|
|||||||
return FindIthSmallest(L=L[:index] + L[(index+1):], i=i);
|
return FindIthSmallest(L=L[:index] + L[(index+1):], i=i);
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# ALGORITHM jump search (D & C)
|
# 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:
|
def FindIthSmallestDC(L: List[int], i: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, i = Ordinalzahl
|
Inputs: L = Liste von Zahlen, i = Ordinalzahl
|
||||||
@@ -81,7 +81,7 @@ def FindIthSmallestDC(L: List[int], i: int) -> int:
|
|||||||
Outputs: Wert des i. kleinste Element in L.
|
Outputs: Wert des i. kleinste Element in L.
|
||||||
Beachte 1.kleinstes <==> Minimum.
|
Beachte 1.kleinstes <==> Minimum.
|
||||||
'''
|
'''
|
||||||
AddToCounter();
|
AddTimeCost();
|
||||||
p = L[len(L)-1]; # NOTE: Pivotelement kann beliebig gewählt werden
|
p = L[len(L)-1]; # NOTE: Pivotelement kann beliebig gewählt werden
|
||||||
Ll = [ x for x in L if x < p ];
|
Ll = [ x for x in L if x < p ];
|
||||||
Lr = [ x for x in L if x > p ];
|
Lr = [ x for x in L if x > p ];
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from src.algorithms.methods import *;
|
|||||||
|
|
||||||
def preChecks(L: List[int], **_):
|
def preChecks(L: List[int], **_):
|
||||||
assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!';
|
assert L == sorted(L), 'Ungültiger Input: L muss aufsteigend sortiert sein!';
|
||||||
assert L == sorted(list(set(L))), 'Ungültiger Input: L darf keine Duplikate enthalten!';
|
## NOTE: nicht prüfen, ob Duplikate existieren. Das ist nur eine erwünschte aber keine notwendige Annahme.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def postChecks(L: List[int], x: int, index: int, **_):
|
def postChecks(L: List[int], x: int, index: int, **_):
|
||||||
@@ -39,20 +39,21 @@ def postChecks(L: List[int], x: int, index: int, **_):
|
|||||||
# ALGORITHM jump search
|
# 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:
|
def JumpSearchLinear(L: List[int], x: int, m: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
|
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
|
||||||
|
|
||||||
Annahmen:
|
Annahmen:
|
||||||
- L sei aufsteigend sortiert.
|
- L sei aufsteigend sortiert.
|
||||||
- L enthält keine Duplikate.
|
- Idealerweise: L enthält keine Duplikate.
|
||||||
|
- Idealerweise: Abstände zw. Elementen nicht uniform.
|
||||||
|
|
||||||
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
||||||
'''
|
'''
|
||||||
i = 0;
|
i = 0;
|
||||||
while i*m < len(L):
|
while i*m < len(L):
|
||||||
AddToCounter();
|
AddTimeCost();
|
||||||
offset = i*m;
|
offset = i*m;
|
||||||
block = L[offset:][:m];
|
block = L[offset:][:m];
|
||||||
elementAfterBlock = block[-1] + 1;
|
elementAfterBlock = block[-1] + 1;
|
||||||
@@ -70,21 +71,22 @@ def JumpSearchLinear(L: List[int], x: int, m: int) -> int:
|
|||||||
# ALGORITHM jump search - exponentiell
|
# 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:
|
def JumpSearchExponentiell(L: List[int], x: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, x = Zahl.
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
|
|
||||||
Annahmen:
|
Annahmen:
|
||||||
- L sei aufsteigend sortiert.
|
- L sei aufsteigend sortiert.
|
||||||
- L enthält keine Duplikate.
|
- Idealerweise: L enthält keine Duplikate.
|
||||||
|
- Idealerweise: Abstände zw. Elementen nicht uniform.
|
||||||
|
|
||||||
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
Outputs: Position von x in L, sonst −1 wenn x nicht in L.
|
||||||
'''
|
'''
|
||||||
i0 = 0;
|
i0 = 0;
|
||||||
i1 = 1;
|
i1 = 1;
|
||||||
while i0 < len(L):
|
while i0 < len(L):
|
||||||
AddToCounter();
|
AddTimeCost();
|
||||||
block = L[i0:i1];
|
block = L[i0:i1];
|
||||||
elementAfterBlock = block[-1] + 1;
|
elementAfterBlock = block[-1] + 1;
|
||||||
if x < elementAfterBlock:
|
if x < elementAfterBlock:
|
||||||
|
|||||||
@@ -21,23 +21,25 @@ from src.algorithms.methods import *;
|
|||||||
# CHECKS
|
# CHECKS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def preChecks(L: List[bool], **_):
|
def preChecks(L: List[int], **_):
|
||||||
assert sum(L) > 0, 'Mindestens ein Getränk muss vergiftet sein!';
|
s = sum(L);
|
||||||
assert sum(L) == 1, 'Höchstens ein Getränk darf vergiftet sein!';
|
assert s > 0, 'Mindestens ein Getränk muss vergiftet sein!';
|
||||||
|
assert s <= 1, 'Höchstens ein Getränk darf vergiftet sein!';
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def postChecks(L: List[bool], index: int, **_):
|
def postChecks(L: List[int], index: int, **_):
|
||||||
assert L[index] == True, 'Der Algorithmus hat das vergiftete Getränk nicht erfolgreich bestimmt.';
|
assert index >= 0, 'Der Algorithmus hat kein vergiftetes Getränk gefunden, obwohl per Annahme eines existiert.';
|
||||||
|
assert L[index] > 0, 'Der Algorithmus hat das vergiftete Getränk nicht erfolgreich bestimmt.';
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# ALGORITHM find poison
|
# 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[bool]) -> int:
|
def FindPoison(L: List[int]) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
Inputs: L = Liste von Getränken: durch 0-1 Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
||||||
Annahme: Genau ein Getränk sei vergiftet.
|
Annahme: Genau ein Getränk sei vergiftet.
|
||||||
Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1.
|
Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1.
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ def FindPoison(L: List[bool]) -> int:
|
|||||||
n = len(L);
|
n = len(L);
|
||||||
testers = [];
|
testers = [];
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
AddToCounter();
|
AddSpaceCost();
|
||||||
logDebug('Füge Vorkoster hinzu, der nur Getränk {i} testet.'.format(i=i))
|
logDebug('Füge Vorkoster hinzu, der nur Getränk {i} testet.'.format(i=i))
|
||||||
testers.append([i]);
|
testers.append([i]);
|
||||||
logDebug('Warte auf Effekte');
|
logDebug('Warte auf Effekte');
|
||||||
@@ -62,10 +64,10 @@ def FindPoison(L: List[bool]) -> int:
|
|||||||
# ALGORITHM find poison fast
|
# 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[bool]) -> List[int]:
|
def FindPoisonFast(L: List[int]) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
Inputs: L = Liste von Getränken: durch 0-1 Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
||||||
Annahme: Genau ein Getränk sei vergiftet.
|
Annahme: Genau ein Getränk sei vergiftet.
|
||||||
Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1.
|
Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1.
|
||||||
|
|
||||||
@@ -81,7 +83,7 @@ def FindPoisonFast(L: List[bool]) -> List[int]:
|
|||||||
tester1 = [ k for k in range(n) if not (k in tester0) ];
|
tester1 = [ k for k in range(n) if not (k in tester0) ];
|
||||||
# NOTE: tester1 ist virtuell: aus den Effekten auf tester0 und den Annahmen lassen sich die Effekte auf tester0 erschließen.
|
# NOTE: tester1 ist virtuell: aus den Effekten auf tester0 und den Annahmen lassen sich die Effekte auf tester0 erschließen.
|
||||||
# Darum zählen wir nicht 2 sondern 1 Vorkoster.
|
# Darum zählen wir nicht 2 sondern 1 Vorkoster.
|
||||||
AddToCounter(1);
|
AddSpaceCost(1);
|
||||||
logDebug('Füge Vorkoster hinzu, der alle Getränke k testet mit {i}. Bit = 0.'.format(i=i))
|
logDebug('Füge Vorkoster hinzu, der alle Getränke k testet mit {i}. Bit = 0.'.format(i=i))
|
||||||
testers.append(tester0);
|
testers.append(tester0);
|
||||||
testers.append(tester1);
|
testers.append(tester1);
|
||||||
@@ -97,10 +99,10 @@ def FindPoisonFast(L: List[bool]) -> List[int]:
|
|||||||
# AUXILIARY METHOD wait for effects, evaluate effects
|
# AUXILIARY METHOD wait for effects, evaluate effects
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def waitForEffects(L: List[bool], testers: List[List[int]]) -> List[int]:
|
def waitForEffects(L: List[int], testers: List[List[int]]) -> List[int]:
|
||||||
'''
|
'''
|
||||||
Inputs:
|
Inputs:
|
||||||
- L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
- L = Liste von Getränken: durch 0-1 Werte wird dargestellt, ob ein Getränk vergiftet ist.
|
||||||
- testers = Liste von Vorkostern. Jeder Vorkoster kostet eine 'Teilliste' der Getränke.
|
- testers = Liste von Vorkostern. Jeder Vorkoster kostet eine 'Teilliste' der Getränke.
|
||||||
|
|
||||||
Outputs: effects = eine Liste, die jedem Vorkoster zuordnet, wie viele vergiftete Getränke er konsumiert hat.
|
Outputs: effects = eine Liste, die jedem Vorkoster zuordnet, wie viele vergiftete Getränke er konsumiert hat.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ def postChecks(L: List[int], x: int, index: int, **_):
|
|||||||
# ALGORITHM sequential search
|
# 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:
|
def SequentialSearch(L: List[int], x: int) -> int:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen, x = Zahl.
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
||||||
@@ -45,7 +45,7 @@ def SequentialSearch(L: List[int], x: int) -> int:
|
|||||||
'''
|
'''
|
||||||
n = len(L);
|
n = len(L);
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
AddToCounter();
|
AddTimeCost();
|
||||||
if L[i] == x:
|
if L[i] == x:
|
||||||
logDebug('Element in Position {} gefunden.'.format(i));
|
logDebug('Element in Position {} gefunden.'.format(i));
|
||||||
return i;
|
return i;
|
||||||
|
|||||||
0
code/python/src/algorithms/stacks/__init__.py
Normal file
0
code/python/src/algorithms/stacks/__init__.py
Normal file
8
code/python/src/algorithms/stacks/exports.py
Normal file
8
code/python/src/algorithms/stacks/exports.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# EXPORTS
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
from src.algorithms.stacks.next_greater_element import NextGreaterElement;
|
||||||
91
code/python/src/algorithms/stacks/next_greater_element.py
Normal file
91
code/python/src/algorithms/stacks/next_greater_element.py
Normal 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;
|
||||||
@@ -33,7 +33,7 @@ def postChecks(L: List[int], **_):
|
|||||||
# ALGORITHM max sub sum
|
# 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]:
|
def MaxSubSum(L: List[float]) -> Tuple[float, int, int]:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen
|
Inputs: L = Liste von Zahlen
|
||||||
@@ -58,7 +58,7 @@ def MaxSubSum(L: List[float]) -> Tuple[float, int, int]:
|
|||||||
# ALGORITHM max sub sum (D & C)
|
# 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]:
|
def MaxSubSumDC(L: List[float]) -> Tuple[float, int, int]:
|
||||||
'''
|
'''
|
||||||
Inputs: L = Liste von Zahlen
|
Inputs: L = Liste von Zahlen
|
||||||
@@ -127,7 +127,7 @@ def lRandSum(L: List[float]) -> Tuple[float, int, int]:
|
|||||||
'''
|
'''
|
||||||
n = len(L);
|
n = len(L);
|
||||||
## berechne kumulative Summen (vorwärts)
|
## berechne kumulative Summen (vorwärts)
|
||||||
AddToCounter(n);
|
AddTimeCost(n);
|
||||||
total = L[0];
|
total = L[0];
|
||||||
maxSum = total;
|
maxSum = total;
|
||||||
u = 0;
|
u = 0;
|
||||||
@@ -148,7 +148,7 @@ def rRandSum(L: List[float]) -> Tuple[float, int, int]:
|
|||||||
'''
|
'''
|
||||||
n = len(L);
|
n = len(L);
|
||||||
## berechne kumulative Summen (rückwärts)
|
## berechne kumulative Summen (rückwärts)
|
||||||
AddToCounter(n);
|
AddTimeCost(n);
|
||||||
total = L[n-1];
|
total = L[n-1];
|
||||||
maxSum = total;
|
maxSum = total;
|
||||||
u = n-1;
|
u = n-1;
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ from src.local.misc import *;
|
|||||||
from src.local.system import *;
|
from src.local.system import *;
|
||||||
from src.local.typing import *;
|
from src.local.typing import *;
|
||||||
|
|
||||||
from datetime import timedelta;
|
from src.core.utils import StripAnsi;
|
||||||
|
|
||||||
from src.core.metrics import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# GLOBAL VARIABLES
|
# GLOBAL VARIABLES
|
||||||
@@ -20,8 +18,8 @@ from src.core.metrics import *;
|
|||||||
|
|
||||||
_logging_prefix: str = '';
|
_logging_prefix: str = '';
|
||||||
_quietmode: bool = False;
|
_quietmode: bool = False;
|
||||||
_debugmode: bool = False;
|
_debugmode: bool = True;
|
||||||
_ctr: Counter = Counter();
|
_ansimode: bool = False;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# METHOD get/set quiet mode, logging depth, timer
|
# METHOD get/set quiet mode, logging depth, timer
|
||||||
@@ -43,24 +41,14 @@ def SetDebugMode(mode: bool):
|
|||||||
_debugmode = mode;
|
_debugmode = mode;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def RestartCounter():
|
def GetAnsiMode() -> bool:
|
||||||
global _ctr;
|
return _ansimode;
|
||||||
_ctr.reset();
|
|
||||||
|
def SetAnsiMode(mode: bool):
|
||||||
|
global _ansimode;
|
||||||
|
_ansimode = mode;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def AddToCounter(n: int = 1):
|
|
||||||
global _ctr;
|
|
||||||
_ctr.add(n);
|
|
||||||
return;
|
|
||||||
|
|
||||||
def NumberOfSteps() -> int:
|
|
||||||
return _ctr.numberOfStep;
|
|
||||||
|
|
||||||
def TimeElapsed() -> timedelta:
|
|
||||||
global _ctr;
|
|
||||||
_ctr.stop();
|
|
||||||
return _ctr.elapsedTime;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# Logging
|
# Logging
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -71,7 +59,10 @@ def logGeneric(tag: str, *lines: Any, file: io.TextIOWrapper, force: bool = Fals
|
|||||||
tag = '' if tag == '' else tag + ' ';
|
tag = '' if tag == '' else tag + ' ';
|
||||||
file = file or sys.stdout;
|
file = file or sys.stdout;
|
||||||
for line in lines:
|
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:
|
if not tag_all:
|
||||||
tag = '';
|
tag = '';
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -5,49 +5,141 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
from __future__ import annotations;
|
||||||
from datetime import datetime;
|
from datetime import datetime;
|
||||||
from datetime import timedelta;
|
from datetime import timedelta;
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# GLOBAL VARIABLES
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
_ctr_time = None;
|
||||||
|
_ctr_space = None;
|
||||||
|
_tmr = None;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# CLASS counter
|
# CLASS counter
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
class Counter(object):
|
class Counter(object):
|
||||||
_nr_steps: int;
|
value: int;
|
||||||
_timeelapsed: timedelta;
|
|
||||||
_timecurrent: datetime;
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reset();
|
self.reset();
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return str(self._nr_steps);
|
return str(self.value);
|
||||||
|
|
||||||
@property
|
def add(self, n: int = 1):
|
||||||
def numberOfStep(self) -> int:
|
self.value += n;
|
||||||
return self._nr_steps;
|
return self;
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.value = 0;
|
||||||
|
return self;
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# CLASS timer
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class Timer(object):
|
||||||
|
_time_elapsed: timedelta;
|
||||||
|
_time_current: datetime;
|
||||||
|
_running: bool
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.reset();
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return str(self._time_elapsed);
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def elapsedTime(self) -> timedelta:
|
def elapsedTime(self) -> timedelta:
|
||||||
return self._timeelapsed;
|
return self._time_elapsed;
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self._timecurrent = datetime.now();
|
self._time_current = datetime.now();
|
||||||
|
self._running = True
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
t0 = self._timecurrent;
|
if self._running:
|
||||||
t1 = datetime.now();
|
t0 = self._time_current;
|
||||||
self._timecurrent = t1;
|
t1 = datetime.now();
|
||||||
self._timeelapsed += (t1 - t0);
|
delta = t1 - t0;
|
||||||
return self;
|
self._time_current = t1;
|
||||||
|
self._time_elapsed += delta;
|
||||||
def add(self, n: int = 1):
|
self._running = False
|
||||||
self._nr_steps += n;
|
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
t = datetime.now();
|
t = datetime.now();
|
||||||
self._timeelapsed = t - t;
|
delta = t - t;
|
||||||
self._nr_steps = 0;
|
self._time_current = t;
|
||||||
self._timecurrent = t;
|
self._time_elapsed = delta;
|
||||||
|
self._running = False
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
|
## Initialisierung:
|
||||||
|
_ctr_time = Counter();
|
||||||
|
_ctr_moves = Counter();
|
||||||
|
_ctr_space = Counter();
|
||||||
|
_tmr = Timer();
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# METHODS
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
def StartMetrics():
|
||||||
|
_tmr.start()
|
||||||
|
return;
|
||||||
|
|
||||||
|
def StopMetrics():
|
||||||
|
_tmr.stop()
|
||||||
|
return;
|
||||||
|
|
||||||
|
def AddTimeCost(n: int = 1):
|
||||||
|
global _ctr_time;
|
||||||
|
_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.value;
|
||||||
|
|
||||||
|
def GetMovesCost() -> int:
|
||||||
|
return _ctr_moves.value;
|
||||||
|
|
||||||
|
def GetSpaceCost() -> int:
|
||||||
|
return _ctr_space.value;
|
||||||
|
|
||||||
|
def GetTimeElapsed() -> timedelta:
|
||||||
|
global _tmr;
|
||||||
|
_tmr.stop();
|
||||||
|
return _tmr.elapsedTime;
|
||||||
|
|||||||
40
code/python/src/core/utils.py
Normal file
40
code/python/src/core/utils.py
Normal 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;
|
||||||
0
code/python/src/data_structures/__init__.py
Normal file
0
code/python/src/data_structures/__init__.py
Normal file
52
code/python/src/data_structures/queues.py
Normal file
52
code/python/src/data_structures/queues.py
Normal 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]);
|
||||||
52
code/python/src/data_structures/stacks.py
Normal file
52
code/python/src/data_structures/stacks.py
Normal 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]);
|
||||||
0
code/python/src/endpoints/__init__.py
Normal file
0
code/python/src/endpoints/__init__.py
Normal file
11
code/python/src/endpoints/exports.py
Normal file
11
code/python/src/endpoints/exports.py
Normal 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;
|
||||||
25
code/python/src/endpoints/print.py
Normal file
25
code/python/src/endpoints/print.py
Normal 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;
|
||||||
74
code/python/src/endpoints/run.py
Normal file
74
code/python/src/endpoints/run.py
Normal 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;
|
||||||
@@ -8,80 +8,64 @@
|
|||||||
import os;
|
import os;
|
||||||
import sys;
|
import sys;
|
||||||
|
|
||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..')));
|
_path_to_python_project = os.path.abspath(os.path.join(os.path.abspath(__file__), '..', '..'));
|
||||||
os.chdir(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.log import *;
|
||||||
from src.core.config import *;
|
|
||||||
from src.setup.display import *;
|
|
||||||
from src.setup.cli import *;
|
from src.setup.cli import *;
|
||||||
from src.algorithms.exports import *;
|
from src.setup import appconfig;
|
||||||
|
from src.endpoints.exports import *;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# GLOBAL VARIABLES/CONSTANTS
|
# GLOBAL VARIABLES/CONSTANTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
PATH_TO_CONFIG: str = 'code/config.yml';
|
PATH_TO_CONFIG: str = '../config.yml';
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# MAIN PROCESS
|
# MAIN PROCESS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
def enter(quiet: bool, debug: bool, mode: str, path: Any, **_):
|
def enter(
|
||||||
SetQuietMode(quiet);
|
mode: Union[str, None],
|
||||||
SetDebugMode(debug);
|
it: bool,
|
||||||
configpath = path if isinstance(path, str) else PATH_TO_CONFIG;
|
quiet: bool,
|
||||||
if mode in 'run':
|
debug: bool,
|
||||||
LoopThroughCases(path=configpath);
|
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:
|
else:
|
||||||
DisplayHelpMessage();
|
endpoint_runInteractive();
|
||||||
return;
|
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();
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -91,7 +75,16 @@ def LoopThroughCases(path: str):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.tracebacklimit = 0;
|
sys.tracebacklimit = 0;
|
||||||
try:
|
try:
|
||||||
args = GetArgumentsFromCli(sys.argv[1:]);
|
args = GetArgumentsFromCli(*sys.argv[1:]);
|
||||||
except:
|
except Exception as e:
|
||||||
|
endpoint_help();
|
||||||
exit(1);
|
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,
|
||||||
|
);
|
||||||
|
|||||||
66
code/python/src/setup/appconfig.py
Normal file
66
code/python/src/setup/appconfig.py
Normal 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;
|
||||||
38
code/python/src/setup/assets.py
Normal file
38
code/python/src/setup/assets.py
Normal 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;
|
||||||
@@ -5,9 +5,13 @@
|
|||||||
# IMPORTS
|
# IMPORTS
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
from argparse import ArgumentError
|
||||||
from src.local.typing import *;
|
from src.local.typing import *;
|
||||||
|
|
||||||
from src.core.log 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
|
# GLOBAL VARIABLES
|
||||||
@@ -24,18 +28,37 @@ def GetArgumentParser() -> argparse.ArgumentParser:
|
|||||||
if not isinstance(parser, argparse.ArgumentParser):
|
if not isinstance(parser, argparse.ArgumentParser):
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog='code/main.py',
|
prog='code/main.py',
|
||||||
description=dedent('''
|
description=DedentIgnoreFirstLast('''
|
||||||
\033[93;1mBeschreibung:\033[0m
|
\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,
|
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('mode',
|
||||||
parser.add_argument('--path', nargs=1, type=str, help='Pfad zur alternativen Configdatei.');
|
nargs='?',
|
||||||
parser.add_argument('--debug', action='store_true', help='Debugging Messages stummschalten.')
|
choices=['version', 'help', 'run'],
|
||||||
parser.add_argument('-q', '--quiet', action='store_true', help='Alle console-messages bis auf Errors stummschalten.')
|
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;
|
return parser;
|
||||||
|
|
||||||
def GetArgumentsFromCli(cli_args: List[str]) -> argparse.Namespace:
|
def GetArgumentsFromCli(*cli_args: str) -> argparse.Namespace:
|
||||||
parser = GetArgumentParser();
|
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;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
from src.local.typing import *;
|
from src.local.typing import *;
|
||||||
|
|
||||||
from src.core.log import *;
|
from src.core.log import *;
|
||||||
|
from src.core.metrics import *;
|
||||||
from src.setup.cli import GetArgumentParser;
|
from src.setup.cli import GetArgumentParser;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -67,8 +68,10 @@ def DisplayEndOfAlgorithm(*_: Any, **outputs: Any):
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
def DisplayMetrics():
|
def DisplayMetrics():
|
||||||
logPlain('Dauer der Ausführung: t = \033[1m{}\033[0m'.format(TimeElapsed()));
|
logPlain('Dauer der Ausführung: t = \033[1m{}\033[0m'.format(GetTimeElapsed()));
|
||||||
logPlain('Anzahl der Schritte: T(n) = \033[1m{}\033[0m'.format(NumberOfSteps()));
|
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;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -78,3 +81,6 @@ def DisplayMetrics():
|
|||||||
def DisplayBar(n: int = 80):
|
def DisplayBar(n: int = 80):
|
||||||
logPlain('+{}+'.format('-'*n));
|
logPlain('+{}+'.format('-'*n));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
def displayCost(cost: int) -> str:
|
||||||
|
return str(cost) if cost > 0 else '-';
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ Inhaltsverzeichnis
|
|||||||
- [Vorlesungswoche 2](./woche2.md)
|
- [Vorlesungswoche 2](./woche2.md)
|
||||||
- [Vorlesungswoche 3](./woche3.md)
|
- [Vorlesungswoche 3](./woche3.md)
|
||||||
- [Vorlesungswoche 4](./woche4.md)
|
- [Vorlesungswoche 4](./woche4.md)
|
||||||
- [Vorlesungswoche 5](./woche4.md)
|
- [Vorlesungswoche 5](./woche5.md)
|
||||||
- [Vorlesungswoche 6](./woche4.md)
|
- [Vorlesungswoche 6](./woche6.md)
|
||||||
- [Vorlesungswoche 7](./woche4.md)
|
- [Vorlesungswoche 7](./woche7.md)
|
||||||
- [Vorlesungswoche 8](./woche4.md)
|
- [Vorlesungswoche 8](./woche8.md)
|
||||||
- [Vorlesungswoche 9](./woche4.md)
|
- [Vorlesungswoche 9](./woche9.md)
|
||||||
- [Vorlesungswoche 10](./woche10.md)
|
- [Vorlesungswoche 10](./woche10.md)
|
||||||
- [Vorlesungswoche 11](./woche11.md)
|
- [Vorlesungswoche 11](./woche11.md)
|
||||||
- [Vorlesungswoche 12](./woche12.md)
|
- [Vorlesungswoche 12](./woche12.md)
|
||||||
|
|||||||
@@ -2,13 +2,26 @@
|
|||||||
|
|
||||||
## Agenda ##
|
## 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 ##
|
## Nächste Woche ##
|
||||||
|
|
||||||
-
|
- Sortierungsalgorithmen
|
||||||
|
- Bäume
|
||||||
|
|
||||||
### TODOs (Studierende) ###
|
### 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
|
||||||
|
|||||||
@@ -2,13 +2,41 @@
|
|||||||
|
|
||||||
## Agenda ##
|
## 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 ##
|
## Nächste Woche ##
|
||||||
|
|
||||||
-
|
- Ab VL5 + Blatt 6.
|
||||||
|
|
||||||
### TODOs (Studierende) ###
|
### TODOs (Studierende) ###
|
||||||
|
|
||||||
-
|
- VL-Inhalte aus Wochen 4 + 5 durchgehen
|
||||||
|
- freiwillige ÜB 5 + Pflichtserie 3.
|
||||||
|
|||||||
@@ -2,13 +2,10 @@
|
|||||||
|
|
||||||
## Agenda ##
|
## Agenda ##
|
||||||
|
|
||||||
- [ ]
|
- [x] Mergesort, inkl. Pseudo-Code
|
||||||
- [ ]
|
- [x] natürliches Mergesort, inkl. Aspekte
|
||||||
|
- [x] k-Wege Mergesort
|
||||||
## Nächste Woche ##
|
|
||||||
|
|
||||||
-
|
|
||||||
|
|
||||||
### TODOs (Studierende) ###
|
### TODOs (Studierende) ###
|
||||||
|
|
||||||
-
|
- weiter an Pflichtserie3 arbeiten.
|
||||||
|
|||||||
@@ -2,13 +2,19 @@
|
|||||||
|
|
||||||
## Agenda ##
|
## 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) ###
|
### TODOs (Studierende) ###
|
||||||
|
|
||||||
-
|
- weiter an Pflichtserie3 arbeiten und vor der Frist abgeben.
|
||||||
|
|||||||
Reference in New Issue
Block a user