Compare commits
4 Commits
15c2c37213
...
7f5f3e9541
Author | SHA1 | Date | |
---|---|---|---|
7f5f3e9541 | |||
f563c8e6e9 | |||
a38f18ee81 | |||
2c23f4c728 |
19
README.md
19
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:
|
||||||
|
|
||||||
@ -28,8 +30,10 @@ In diesem Repository findet man:
|
|||||||
Im Unterordner [`code`](./code) kann man Codeprojekte in Python und Golang finden, in denen verschiedene Algorithmen implementiert werden
|
Im Unterordner [`code`](./code) kann man Codeprojekte in Python und Golang finden, in denen verschiedene Algorithmen implementiert werden
|
||||||
(siehe insbes. [`code/python/src/algorithms`](./code/python//src/algorithms)
|
(siehe insbes. [`code/python/src/algorithms`](./code/python//src/algorithms)
|
||||||
und [`code/golang/pkg/algorithms`](./code/golang/pkg/algorithms)).
|
und [`code/golang/pkg/algorithms`](./code/golang/pkg/algorithms)).
|
||||||
Man kann gerne den Code benutzen, in einer eigenen Repository verändern,
|
|
||||||
und mit den in dem Kurs präsentierten Algorithmen herumexperimentieren.
|
Gerne kann man den Code benutzen, in einem eigenen Repository verändern, und mit den im Kurs präsentierten Algorithmen **herumexperimentieren**.
|
||||||
|
|
||||||
|
**HINWEIS:** _Bei meiner Implementierung kann es zu leichten Abweichungen kommen. Bitte **stets** an dem Material im VL-Skript sich orientieren. Der Hauptzweck der Code-Projekte besteht darin, dass Wissbegierige die Algorithmen konkret ausprobieren können. Alle theoretischen Aspekte werden jedoch im Skript und in den Übungen ausführlicher erklärt._
|
||||||
|
|
||||||
### Systemvoraussetzungen ###
|
### Systemvoraussetzungen ###
|
||||||
|
|
||||||
@ -54,7 +58,7 @@ usw. in der Bash-Console ausführen.
|
|||||||
|
|
||||||
#### Für das Golang-Projekt ####
|
#### 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
|
Man braucht [go](https://golang.org/dl/) Version **1.17.x**. (Man kann bestimmt bei späteren Releases höhere Versionen benutzen. Man muss lediglich dann in [`./code/golang/go.mod`](./code/golang/go.mod) die Version hochstellen und die Requirements nochmals installieren lassen.) Und einige Packages werden benötigt. Letztere lassen sich mittels
|
||||||
```bash
|
```bash
|
||||||
./scripts/build.sh --lang go --mode setup
|
./scripts/build.sh --lang go --mode setup
|
||||||
```
|
```
|
||||||
@ -64,10 +68,9 @@ installieren.
|
|||||||
|
|
||||||
Python version 3.x.x (idealerweise zumindest 3.9.5) plus einige Module (siehe [code/requirements](./code/requirements)). Letztere lassen sich mittels
|
Python version 3.x.x (idealerweise zumindest 3.9.5) plus einige Module (siehe [code/requirements](./code/requirements)). Letztere lassen sich mittels
|
||||||
```bash
|
```bash
|
||||||
|
# Benutze die Option `--venv true`, um mit virtuellem Env zu arbeiten:
|
||||||
./scripts/build.sh --lang python --mode setup
|
./scripts/build.sh --lang python --mode setup
|
||||||
## mit virtuellem Env:
|
## oder:
|
||||||
./scripts/build.sh --lang python --venv true --mode setup
|
|
||||||
## alternative:
|
|
||||||
python3 -m pip install -r code/requirements; # linux, osx
|
python3 -m pip install -r code/requirements; # linux, osx
|
||||||
py -3 -m pip install -r code/requirements; # Windows
|
py -3 -m pip install -r code/requirements; # Windows
|
||||||
```
|
```
|
||||||
@ -105,7 +108,7 @@ py -3 main.py run [--debug]; # Windows
|
|||||||
|
|
||||||
popd; ## <- zum vorherigen Pfad zurückwechseln
|
popd; ## <- zum vorherigen Pfad zurückwechseln
|
||||||
```
|
```
|
||||||
Oder man erstelle einen bash Skript wie `run.sh`, trage die Befehle da ein und führe
|
Oder man erstelle ein bash Skript wie `run.sh`, trage die Befehle da ein und führe
|
||||||
```bash
|
```bash
|
||||||
chmod +x run.sh; # nur einmalig nötig
|
chmod +x run.sh; # nur einmalig nötig
|
||||||
./run.sh
|
./run.sh
|
||||||
|
@ -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
|
||||||
|
53
code/golang/internal/algorithms/search/binary/binary.go
Normal file
53
code/golang/internal/algorithms/search/binary/binary.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package binary
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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.LogDebug(fmt.Sprintf("x nicht in L"))
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
m := int(len(L) / 2)
|
||||||
|
if L[m] == x {
|
||||||
|
logging.LogDebug(fmt.Sprintf("x in Position m gefunden"))
|
||||||
|
return m
|
||||||
|
} else if x < L[m] {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Suche in linker Hälfte fortsetzen."))
|
||||||
|
index := BinarySearch(L[:m], x)
|
||||||
|
return index
|
||||||
|
} else { // } else if x > L[m] {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Suche in rechter Hälfte fortsetzen."))
|
||||||
|
index := BinarySearch(L[m+1:], x)
|
||||||
|
if index >= 0 {
|
||||||
|
index += (m + 1) // NOTE: muss Indexwert kompensieren
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_x)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = BinarySearch(input_L, input_x)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
69
code/golang/internal/algorithms/search/interpol/interpol.go
Normal file
69
code/golang/internal/algorithms/search/interpol/interpol.go
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package interpol
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"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.LogDebug(fmt.Sprintf("Liste L leer, also x nicht in L"))
|
||||||
|
return -1
|
||||||
|
} else if !(L[u] <= x && x <= L[v]) {
|
||||||
|
logging.LogDebug(fmt.Sprintf("x liegt außerhalb der Grenzen von L"))
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
metrics.AddTimeCost()
|
||||||
|
p := getSuchposition(L, x, u, v)
|
||||||
|
logging.LogDebug(fmt.Sprintf("Interpolante von x in (u, v)=(%[1]v, %[2]v) ist p = %[3]v.", u, v, p))
|
||||||
|
if L[p] == x {
|
||||||
|
logging.LogDebug(fmt.Sprintf("x in Position p gefunden"))
|
||||||
|
return p
|
||||||
|
} else if x < L[p] {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Suche in linker Hälfte fortsetzen."))
|
||||||
|
return InterpolationSearch(L, x, u, p-1)
|
||||||
|
} else { // } else if x > L[p] {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Suche in rechter Hälfte fortsetzen."))
|
||||||
|
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
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_x, input_u, input_v)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = InterpolationSearch(input_L, input_x, input_u, input_v)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package ith_element
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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.LogDebug("Das i. kleinste Element wurde gefunden.")
|
||||||
|
return minValue
|
||||||
|
} else {
|
||||||
|
logging.LogDebug(fmt.Sprintf("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.LogDebug(fmt.Sprintf("Es gibt i-1 Elemente vor p=%[1]v. ==> i. kleinste Element = p", p))
|
||||||
|
return p
|
||||||
|
} else if len(Ll) >= i {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Es gibt >= i Elemente vor p=%[1]v. ==> Suche in linker Hälfte!", p))
|
||||||
|
return FindIthSmallestDC(Ll, i)
|
||||||
|
} else {
|
||||||
|
logging.LogDebug(fmt.Sprintf("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,139 @@
|
|||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_i)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_value = FindIthSmallest(input_L, input_i)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"value": output_value,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_i)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_value = FindIthSmallestDC(input_L, input_i)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"value": output_value,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, input_i, output_value)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_value, err
|
||||||
|
}
|
91
code/golang/internal/algorithms/search/jump/jump.go
Normal file
91
code/golang/internal/algorithms/search/jump/jump.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package jump
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/algorithms/search/sequential"
|
||||||
|
"ads/internal/core/logging"
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* ALGORITHM jump search
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inputs: L = Liste von Zahlen, x = Zahl, m = lineare Sprunggröße.
|
||||||
|
|
||||||
|
Annahmen:
|
||||||
|
- L sei aufsteigend sortiert.
|
||||||
|
- L enthält keine Duplikate.
|
||||||
|
|
||||||
|
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()
|
||||||
|
block := L[i0:i1]
|
||||||
|
elementAfterBlock := block[len(block)-1] + 1
|
||||||
|
if x < elementAfterBlock {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1))
|
||||||
|
index := sequential.SequentialSearch(block, x)
|
||||||
|
if index >= 0 {
|
||||||
|
index += i0 // NOTE: muss wegen Offset kompensieren
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
logging.LogDebug(fmt.Sprintf("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()
|
||||||
|
block := L[i0:i1]
|
||||||
|
elementAfterBlock := block[len(block)-1] + 1
|
||||||
|
if x < elementAfterBlock {
|
||||||
|
logging.LogDebug(fmt.Sprintf("Element muss sich im Block [%[1]v, %[2]v) befinden.", i0, i1))
|
||||||
|
index := sequential.SequentialSearch(block, x)
|
||||||
|
if index >= 0 {
|
||||||
|
index += i0 // NOTE: muss wegen Offset kompensieren
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
logging.LogDebug(fmt.Sprintf("Element befindet sich nicht im Block [%[1]v, %[2]v).", i0, i1))
|
||||||
|
i0 = i1
|
||||||
|
i1 *= 2
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
143
code/golang/internal/algorithms/search/jump/jump_fancy.go
Normal file
143
code/golang/internal/algorithms/search/jump/jump_fancy.go
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
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!")
|
||||||
|
}
|
||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_x, input_m)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = JumpSearchLinear(input_L, input_x, input_m)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_x)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = JumpSearchExponentiell(input_L, input_x)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
173
code/golang/internal/algorithms/search/poison/poison.go
Normal file
173
code/golang/internal/algorithms/search/poison/poison.go
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
package poison
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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.LogDebug("Bereite Vorkoster vor")
|
||||||
|
n := len(L)
|
||||||
|
testers := [][]int{}
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
metrics.AddSpaceCost()
|
||||||
|
logging.LogDebug(fmt.Sprintf("Füge Vorkoster hinzu, der nur Getränk %[1]v testet.", i))
|
||||||
|
testers = append(testers, []int{i})
|
||||||
|
}
|
||||||
|
logging.LogDebug("Warte auf Effekte")
|
||||||
|
effects := waitForEffects(L, testers)
|
||||||
|
logging.LogDebug("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.LogDebug("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.LogDebug(fmt.Sprintf("Füge Vorkoster hinzu, der alle Getränke k testet mit %[1]v. Bit von k = 0.", i))
|
||||||
|
testers = append(testers, tester0)
|
||||||
|
testers = append(testers, tester1)
|
||||||
|
}
|
||||||
|
logging.LogDebug("Warte auf Effekte")
|
||||||
|
effects := waitForEffects(L, testers)
|
||||||
|
logging.LogDebug("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
|
||||||
|
}
|
136
code/golang/internal/algorithms/search/poison/poison_fancy.go
Normal file
136
code/golang/internal/algorithms/search/poison/poison_fancy.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = FindPoison(input_L)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = FindPoisonFast(input_L)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package sequential
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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.LogDebug(fmt.Sprintf("Element in Position %[1]v gefunden.", i))
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
logging.LogDebug(fmt.Sprintf("Element nicht in Position %[1]v.", i))
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L, input_x)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_index = SequentialSearch(input_L, input_x)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"index": output_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, input_x, output_index)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_index, err
|
||||||
|
}
|
169
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum.go
Normal file
169
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum.go
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
package maxsubsum
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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.LogDebug(fmt.Sprintf("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.LogDebug(fmt.Sprintf("max Teilsumme kommt in linker Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||||
|
} else if maxSum == maxSum3 {
|
||||||
|
maxSum, u, v = maxSum3, u3, v3
|
||||||
|
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in Überschneidung vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||||
|
} else { // } else if maxSum == maxSum2 {
|
||||||
|
maxSum, u, v = maxSum2, u2, v2
|
||||||
|
logging.LogDebug(fmt.Sprintf("max Teilsumme kommt in rechter Partition vor: Summe L[i] von i=%[1]v .. %[2]v = %[3]v", u, v, maxSum))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
136
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum_fancy.go
Normal file
136
code/golang/internal/algorithms/sum/maxsubsum/maxsubsum_fancy.go
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
package maxsubsum
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"ads/internal/core/metrics"
|
||||||
|
"ads/internal/setup"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* 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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_maxSum, output_indexFrom, output_indexTo = MaxSubSum(input_L)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"maxSum": output_maxSum,
|
||||||
|
"index_from": output_indexFrom,
|
||||||
|
"index_to": output_indexTo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
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
|
||||||
|
setup.DisplayStartOfAlgorithm(name, inputs)
|
||||||
|
metrics.RestartMetrics()
|
||||||
|
|
||||||
|
// Prechecks:
|
||||||
|
err = preChecks(input_L)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ausführung des Algorithmus:
|
||||||
|
output_maxSum, output_indexFrom, output_indexTo = MaxSubSumDC(input_L)
|
||||||
|
outputs = map[string]interface{}{
|
||||||
|
"maxSum": output_maxSum,
|
||||||
|
"index_from": output_indexFrom,
|
||||||
|
"index_to": output_indexTo,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Letzte Messages:
|
||||||
|
setup.DisplayMetrics()
|
||||||
|
setup.DisplayEndOfAlgorithm(outputs)
|
||||||
|
|
||||||
|
// Postchecks:
|
||||||
|
err = postChecks(input_L, output_maxSum, output_indexFrom, output_indexTo)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_maxSum, output_indexFrom, output_indexTo, err
|
||||||
|
}
|
50
code/golang/internal/core/metrics/metrics.go
Normal file
50
code/golang/internal/core/metrics/metrics.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package metrics
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"ads/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
var _ctr_time = types.NewCounter()
|
||||||
|
var _ctr_space = types.NewCounter()
|
||||||
|
var _tmr = types.NewTimer()
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func RestartMetrics() {
|
||||||
|
_tmr.Reset()
|
||||||
|
_ctr_time.Reset()
|
||||||
|
_ctr_space.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddTimeCost(options ...int) {
|
||||||
|
_ctr_time.Add(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddSpaceCost(options ...int) {
|
||||||
|
_ctr_space.Add(options...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTimeCost() int {
|
||||||
|
return _ctr_time.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSpaceCost() int {
|
||||||
|
return _ctr_space.Size()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetTimeElapsed() time.Duration {
|
||||||
|
_tmr.Stop()
|
||||||
|
return _tmr.ElapsedTime()
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
@ -5,16 +5,148 @@ package endpoints
|
|||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"ads/internal/core/logging"
|
|
||||||
"ads/internal/setup"
|
"ads/internal/setup"
|
||||||
|
"ads/internal/types"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
algorithm_search_binary "ads/internal/algorithms/search/binary"
|
||||||
|
algorithm_search_interpol "ads/internal/algorithms/search/interpol"
|
||||||
|
algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
|
||||||
|
algorithm_search_jump "ads/internal/algorithms/search/jump"
|
||||||
|
algorithm_search_poison "ads/internal/algorithms/search/poison"
|
||||||
|
algorithm_search_sequential "ads/internal/algorithms/search/sequential"
|
||||||
|
algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
|
||||||
|
"ads/internal/core/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ---------------------------------------------------------------- *
|
/* ---------------------------------------------------------------- *
|
||||||
* ENDPOINT run
|
* ENDPOINT run
|
||||||
* ---------------------------------------------------------------- */
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
func Run(fnameConfig string) error {
|
// Liest Config Datei ein und führt Algorithmen auf Fälle durch
|
||||||
|
func Run(path string) error {
|
||||||
|
var err error
|
||||||
|
var err_case error
|
||||||
|
|
||||||
logging.LogPlain(setup.Logo())
|
logging.LogPlain(setup.Logo())
|
||||||
logging.LogWarn("Die Go-Implementierung ist noch unter Arbeit.")
|
|
||||||
|
// extrahiere user config
|
||||||
|
config := setup.NewUserConfig()
|
||||||
|
err = setup.GetUserConfig(path, &config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fälle extrahieren
|
||||||
|
cases := []types.CaseConfig{}
|
||||||
|
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.InputsConfig{}
|
||||||
|
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-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.LogError(err_case)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setup.DisplayEndOfCase()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
116
code/golang/internal/setup/setup_display.go
Normal file
116
code/golang/internal/setup/setup_display.go
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
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.LogPlain(fmt.Sprintf("\033[92;1mCASE %[1]v\033[0m.", index))
|
||||||
|
} else {
|
||||||
|
logging.LogPlain(fmt.Sprintf("\033[92;1mCASE %[1]v\033[0m (\033[1;2m%[2]s\033[0m).", index, *descr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.LogPlain(fmt.Sprintf("Ausführung vom Algorithmus: \033[92;1m%[1]s\033[0m", name))
|
||||||
|
logging.LogPlain("INPUTS")
|
||||||
|
for varname, value := range inputs {
|
||||||
|
logging.LogPlain(fmt.Sprintf(" - %[1]s = %[2]v", varname, RepresentValue(value)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayEndOfAlgorithm(outputs map[string]interface{}) {
|
||||||
|
logging.LogPlain("OUTPUTS:")
|
||||||
|
for varname, value := range outputs {
|
||||||
|
logging.LogPlain(fmt.Sprintf(" - %[1]s = %[2]v", varname, RepresentValue(value)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DisplayMetrics() {
|
||||||
|
logging.LogPlain(fmt.Sprintf("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsed()))
|
||||||
|
logging.LogPlain(fmt.Sprintf("Kosten (Zeit): T(n) = \033[1m%[1]v\033[0m", metrics.GetTimeCost()))
|
||||||
|
logging.LogPlain(fmt.Sprintf("Kosten (Platz): S(n) = \033[1m%[1]v\033[0m", metrics.GetSpaceCost()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* METHODS Verschiedenes
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
func DisplayBar(options ...int) {
|
||||||
|
n := 80
|
||||||
|
if len(options) > 0 {
|
||||||
|
n = options[0]
|
||||||
|
}
|
||||||
|
logging.LogPlain(fmt.Sprintf("+%[1]s+", strings.Repeat("-", n)))
|
||||||
|
return
|
||||||
|
}
|
30
code/golang/internal/setup/setup_userconfig.go
Normal file
30
code/golang/internal/setup/setup_userconfig.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package setup
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ads/internal/types"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* 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
|
||||||
|
}
|
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
|
||||||
|
}
|
52
code/golang/internal/types/types_counter.go
Normal file
52
code/golang/internal/types/types_counter.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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) Add(options ...int) {
|
||||||
|
n := 1
|
||||||
|
if len(options) > 0 {
|
||||||
|
n = options[0]
|
||||||
|
}
|
||||||
|
self.nr += n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Counter) Reset() {
|
||||||
|
self.nr = 0
|
||||||
|
}
|
66
code/golang/internal/types/types_timer.go
Normal file
66
code/golang/internal/types/types_timer.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* IMPORTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* GLOBAL VARIABLES/CONSTANTS
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* TYPE Timer
|
||||||
|
* ---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
type Timer struct {
|
||||||
|
time_elapsed time.Duration
|
||||||
|
time_current time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------- *
|
||||||
|
* 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Timer) Stop() {
|
||||||
|
t0 := self.time_current
|
||||||
|
t1 := time.Now()
|
||||||
|
delta := t1.Sub(t0)
|
||||||
|
self.time_current = t1
|
||||||
|
self.time_elapsed += delta
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Timer) Reset() {
|
||||||
|
t := time.Now()
|
||||||
|
delta := t.Sub(t) // d. h. 0
|
||||||
|
self.time_current = t
|
||||||
|
self.time_elapsed = delta
|
||||||
|
}
|
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 *InfoConfig `yaml:"info"`
|
||||||
|
Parts *PartsConfig `yaml:"parts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InfoConfig struct {
|
||||||
|
Title *string `yaml:"title"`
|
||||||
|
Description *string `yaml:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PartsConfig struct {
|
||||||
|
Cases *([]CaseConfig) `yaml:"cases"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CaseConfig struct {
|
||||||
|
Command *string `yaml:"command"`
|
||||||
|
Description *string `yaml:"description"`
|
||||||
|
Inputs *InputsConfig `yaml:"inputs"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InputsConfig struct {
|
||||||
|
List *[]int `yaml:"L"`
|
||||||
|
SearchRank *int `yaml:"i"`
|
||||||
|
SearchValue *int `yaml:"x"`
|
||||||
|
JumpSize *int `yaml:"m"`
|
||||||
|
}
|
@ -8,6 +8,7 @@
|
|||||||
import functools;
|
import functools;
|
||||||
|
|
||||||
from src.core.log import *;
|
from src.core.log import *;
|
||||||
|
from src.core.metrics import *;
|
||||||
from src.setup.display import *;
|
from src.setup.display import *;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -39,12 +40,12 @@ def algorithmInfos(
|
|||||||
name: str,
|
name: str,
|
||||||
checks: bool = True,
|
checks: bool = True,
|
||||||
metrics: bool = None,
|
metrics: bool = None,
|
||||||
outputnames: Union[str, Tuple[str]] = 'result',
|
outputnames: List[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,7 +66,7 @@ def algorithmInfos(
|
|||||||
if state:
|
if state:
|
||||||
# Initialisierung
|
# Initialisierung
|
||||||
DisplayStartOfAlgorithm(name, **inputs);
|
DisplayStartOfAlgorithm(name, **inputs);
|
||||||
RestartCounter();
|
RestartMetrics();
|
||||||
# Prechecks
|
# Prechecks
|
||||||
if checks and callable(preChecks):
|
if checks and callable(preChecks):
|
||||||
preChecks(**inputs);
|
preChecks(**inputs);
|
||||||
@ -78,8 +79,7 @@ def algorithmInfos(
|
|||||||
if state:
|
if state:
|
||||||
# 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 metrics:
|
||||||
DisplayMetrics();
|
DisplayMetrics();
|
||||||
|
@ -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'], checks=True, metrics=True, 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'], checks=True, metrics=True, 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'], checks=True, metrics=True, 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'], checks=True, metrics=True, 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 ];
|
||||||
|
@ -39,7 +39,7 @@ 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'], checks=True, metrics=True, 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.
|
||||||
@ -52,7 +52,7 @@ def JumpSearchLinear(L: List[int], x: int, m: int) -> int:
|
|||||||
'''
|
'''
|
||||||
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,7 +70,7 @@ 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'], checks=True, metrics=True, 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.
|
||||||
@ -84,7 +84,7 @@ def JumpSearchExponentiell(L: List[int], x: int) -> int:
|
|||||||
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'], checks=True, metrics=True, 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'], checks=True, metrics=True, 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'], checks=True, metrics=True, 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;
|
||||||
|
@ -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'], checks=True, metrics=True, 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'], checks=True, metrics=True, 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,10 +10,6 @@ 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.metrics import *;
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# GLOBAL VARIABLES
|
# GLOBAL VARIABLES
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -21,7 +17,6 @@ from src.core.metrics import *;
|
|||||||
_logging_prefix: str = '';
|
_logging_prefix: str = '';
|
||||||
_quietmode: bool = False;
|
_quietmode: bool = False;
|
||||||
_debugmode: bool = False;
|
_debugmode: bool = False;
|
||||||
_ctr: Counter = Counter();
|
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# METHOD get/set quiet mode, logging depth, timer
|
# METHOD get/set quiet mode, logging depth, timer
|
||||||
@ -43,24 +38,6 @@ def SetDebugMode(mode: bool):
|
|||||||
_debugmode = mode;
|
_debugmode = mode;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
def RestartCounter():
|
|
||||||
global _ctr;
|
|
||||||
_ctr.reset();
|
|
||||||
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
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -5,17 +5,24 @@
|
|||||||
# 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;
|
_nr_steps: int;
|
||||||
_timeelapsed: timedelta;
|
|
||||||
_timecurrent: datetime;
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reset();
|
self.reset();
|
||||||
@ -27,27 +34,87 @@ class Counter(object):
|
|||||||
def numberOfStep(self) -> int:
|
def numberOfStep(self) -> int:
|
||||||
return self._nr_steps;
|
return self._nr_steps;
|
||||||
|
|
||||||
@property
|
|
||||||
def elapsedTime(self) -> timedelta:
|
|
||||||
return self._timeelapsed;
|
|
||||||
def start(self):
|
|
||||||
self._timecurrent = datetime.now();
|
|
||||||
return self;
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
t0 = self._timecurrent;
|
|
||||||
t1 = datetime.now();
|
|
||||||
self._timecurrent = t1;
|
|
||||||
self._timeelapsed += (t1 - t0);
|
|
||||||
return self;
|
|
||||||
|
|
||||||
def add(self, n: int = 1):
|
def add(self, n: int = 1):
|
||||||
self._nr_steps += n;
|
self._nr_steps += n;
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
t = datetime.now();
|
|
||||||
self._timeelapsed = t - t;
|
|
||||||
self._nr_steps = 0;
|
self._nr_steps = 0;
|
||||||
self._timecurrent = t;
|
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# CLASS timer
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class Timer(object):
|
||||||
|
_time_elapsed: timedelta;
|
||||||
|
_time_current: datetime;
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.reset();
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return str(self._time_elapsed);
|
||||||
|
|
||||||
|
@property
|
||||||
|
def elapsedTime(self) -> timedelta:
|
||||||
|
return self._time_elapsed;
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self._time_current = datetime.now();
|
||||||
|
return self;
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
t0 = self._time_current;
|
||||||
|
t1 = datetime.now();
|
||||||
|
delta = t1 - t0;
|
||||||
|
self._time_current = t1;
|
||||||
|
self._time_elapsed += delta;
|
||||||
|
return self;
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
t = datetime.now();
|
||||||
|
delta = t - t;
|
||||||
|
self._time_current = t;
|
||||||
|
self._time_elapsed = delta;
|
||||||
|
return self;
|
||||||
|
|
||||||
|
## Initialisierung:
|
||||||
|
_ctr_time = Counter();
|
||||||
|
_ctr_space = Counter();
|
||||||
|
_tmr = Timer();
|
||||||
|
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
# METHODS
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
def RestartMetrics():
|
||||||
|
global _ctr_time;
|
||||||
|
global _ctr_space;
|
||||||
|
global _tmr;
|
||||||
|
|
||||||
|
_ctr_time.reset();
|
||||||
|
_ctr_space.reset();
|
||||||
|
_tmr.reset();
|
||||||
|
return;
|
||||||
|
|
||||||
|
def AddTimeCost(n: int = 1):
|
||||||
|
global _ctr_time;
|
||||||
|
_ctr_time.add(n);
|
||||||
|
return;
|
||||||
|
|
||||||
|
def AddSpaceCost(n: int = 1):
|
||||||
|
global _ctr_space;
|
||||||
|
_ctr_space.add(n);
|
||||||
|
return;
|
||||||
|
|
||||||
|
def GetTimeCost() -> int:
|
||||||
|
return _ctr_time.numberOfStep;
|
||||||
|
|
||||||
|
def GetSpaceCost() -> int:
|
||||||
|
return _ctr_space.numberOfStep;
|
||||||
|
|
||||||
|
def GetTimeElapsed() -> timedelta:
|
||||||
|
global _tmr;
|
||||||
|
_tmr.stop();
|
||||||
|
return _tmr.elapsedTime;
|
||||||
|
@ -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,9 @@ 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(GetTimeCost()));
|
||||||
|
logPlain('Kosten (Platz): S(n) = \033[1m{}\033[0m'.format(GetSpaceCost()));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Loading…
x
Reference in New Issue
Block a user