Compare commits

...

23 Commits

Author SHA1 Message Date
RLogik
14f59eeb63 master > master: protokoll - woche 7 2021-11-26 17:30:07 +01:00
RLogik
a6cce9626c master > master: protokoll - woche 7 2021-11-26 14:47:24 +01:00
RLogik
8d726bf344 master > master: protokolle - woche 6+7 2021-11-25 18:52:38 +01:00
RLogik
04eecdb444 master > master: protokolle - Woche6 2021-11-22 08:49:26 +01:00
RLogik
60c47c20c5 master > master: protokoll - woche 5 (minor Anmerkung) 2021-11-13 18:30:32 +01:00
RLogik
89499f524f master > master: README.md 2021-11-13 16:55:57 +01:00
RLogik
e55d8708a7 master > master: protokoll - woche5 (minor) 2021-11-13 16:54:48 +01:00
RLogik
ea7dfc5bef master > mater: protokolle - woche4 + woche5 2021-11-13 09:01:35 +01:00
RLogik
18ece75b67 master > master: code - minor 2021-11-08 13:21:03 +01:00
RLogik
6541a5246d master > mater: code - nextGreaterElement, auxiliary methods entfernt 2021-11-07 18:56:49 +01:00
RLogik
3505401c7f master > master: minor 2021-11-07 18:52:46 +01:00
RLogik
b193d1d61e master > master: protokoll - woche4 2021-11-07 18:50:05 +01:00
RLogik
ae459547c2 master > master: code - umgang mit cli args vereinheitlicht 2021-11-07 18:17:31 +01:00
RLogik
0f1b426f94 master > master: config - fügte Daten aus Aufgabe + nicht trivialen Fall hinzu 2021-11-07 08:55:29 +01:00
RLogik
cccc6a14ba master > master: code - next greater element messages leicht verbessert 2021-11-07 08:54:54 +01:00
RLogik
8d2de4fa2b master > master: code - stacks + queues data structures überarbeitet 2021-11-07 08:49:52 +01:00
RLogik
5c13f8d4cd master > master: Makefiles - defaults für Windows leicht angepasst 2021-11-06 20:48:28 +01:00
fe93d96584 master > master: code - Kommentare 2021-11-06 18:27:40 +01:00
580cc97387 master > master: code - nextGreaterEl alg für python, vereinfachte Algorithmus für py + go 2021-11-06 18:22:17 +01:00
ef833533f6 master > master: code - metrics für moves 2021-11-06 18:21:37 +01:00
ab38c181c9 master > master: code go - logging debug dunkel 2021-11-06 18:15:35 +01:00
972027ce41 master > master: assets - VERSION 2021-11-06 18:15:10 +01:00
2d91e98904 master > master: .gitignore 2021-11-06 18:14:58 +01:00
37 changed files with 640 additions and 208 deletions

View File

@@ -88,4 +88,8 @@ parts:
- command: 'algorithm-stacks-next-greater-element'
description: 'Seminarblatt Woche 4, Aufgabe 1'
inputs:
L: [4, 2, 1, 100, 6, 3, 16]
L: [4, 6, 3, 16]
- command: 'algorithm-stacks-next-greater-element'
description: 'Seminarblatt Woche 4, Aufgabe 1 mit anderen Daten'
inputs:
L: [20, 10, 10, 2, 1, 5, 30, 3, 16]

View File

@@ -18,9 +18,10 @@
!/assets/LOGO
!/assets/config.yml
!/internal
!/pkg
!/**/*.go
!/internal
!/*/**/
!/*/**/*.go
!/go.mod
!/go.sum

View File

@@ -1,9 +1,15 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# LOCAL ARGUMENTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PATH_TO_ARTEFACT:=../../dist/ads
PATH_TO_CONFIG:=../config.yml
COLOUR:=true# <- auf false stellen, falls es Probleme gibt
PATH_TO_CONFIG:=../config.yml#<- kann durch Pfad zur eigenen yml-Datei ersetzt werden
PATH_TO_ARTEFACT:=../../dist/ads#<- kann beliebiger Pfad sein
COLOUR:=true
## für Windows weichen Defaultsettings leicht ab:
ifeq ($(OS),Windows_NT)
PATH_TO_ARTEFACT:=${PATH_TO_ARTEFACT}.exe
COLOUR:=false# <- man kann als 'true' setzen, aber in Windows funktioniert es möglicherweise nicht
endif
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TARGETS

View File

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

View File

@@ -5,6 +5,7 @@ package logging
* ---------------------------------------------------------------- */
import (
"fmt"
"os"
)
@@ -24,7 +25,7 @@ func Debug(line interface{}, args ...interface{}) {
if !debugmode {
return
}
logGeneric(os.Stdout, "[\033[96;1mDEBUG\033[0m]", line, args...)
logGeneric(os.Stdout, "\033[2m[\033[96;1mDEBUG\033[0m\033[2m]\033[0m", fmt.Sprintf("\033[2m%v\033[0m", line), args...)
}
func Warn(line interface{}, args ...interface{}) {

View File

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

View File

@@ -68,7 +68,10 @@ var optionsConfigFile = argparse.Options{
// Parst cli flags.
func ParseCli(args []string) (*types.CliArguments, error) {
var err error
Parser = argparse.NewParser("cli parser", "Liest Optionen + Flags von Kommandozeile.")
Parser = argparse.NewParser(
"cli parser",
"\033[93;2mEin Programm zur Ausführung verschiedener Algorithmen aus dem Kurs AlgoDat I.\033[0m",
)
arguments := types.CliArguments{
ModeHelp: Parser.NewCommand("help", "Hilfsanleitung anzeigen"),
ModeVersion: Parser.NewCommand("version", "Version anzeigen."),

View File

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

View File

@@ -104,6 +104,7 @@ func DisplayMetrics() {
// logging.Plain("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsed())
logging.Plain("Dauer der Ausführung: t = \033[1m%[1]v\033[0m", metrics.GetTimeElapsedLongFormat())
logging.Plain("Kosten (Zeit): T(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetTimeCost()))
logging.Plain("Kosten (#Züge): M(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetMovesCost()))
logging.Plain("Kosten (Platz): S(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetSpaceCost()))
return
}

View File

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

View File

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

View File

@@ -14,94 +14,68 @@ import (
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
var _output_list [][2]int
//
/* ---------------------------------------------------------------- *
* ALGORITHM next greater element
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen, x = Zahl.
Inputs: L = Liste von Zahlen.
Outputs: Liste von Paaren von Elementen und ihrem nächsten größeren Element
*/
func NextGreaterElement(L []int) [][2]int {
clearOutput()
if len(L) == 0 {
return output()
}
output := [][2]int{}
S := stacks.CREATE()
S.INIT()
for i := 0; i < len(L); i++ {
logging.Debug("Lies Element L[%v] ein", i)
logging.Debug("Stack S | %v", S)
logging.Debug("Nächstes List-Element L[%v] = %v betrachten", i, L[i])
nextElement := L[i]
logging.Debug("Stack S | %v", S)
if !S.EMPTY() {
logging.Debug("Entferne alle top Elemente vom Stack bis >= nextElement")
logging.Debug("Alle top Elemente vom Stack, die < nextElement sind, mit L[i] paaren")
// Führe aus, bis top Element >= nextElement oder Stack leer ist.
for !S.EMPTY() { // ACHTUNG: schreibe 'while' im Pseudocode, denn dies ist eine while-Schleife in golang
element := S.TOP()
if element < nextElement {
// falls top Element < next Element, zum Output hinzufügen und vom Stack entfernen
logging.Debug("Stack S | %v; top Element < nextElement; ==> pop und Paar zum Output hinzufügen", S)
output = append(output, [2]int{element, nextElement})
S.POP()
metrics.AddTimeCost()
/*
Entferne kleinere Elemente vom Stack
Aktuelles Element ist jeweils größerer rechter Partner
*/
for element < nextElement {
metrics.AddMovesCost()
logging.Debug("Stack S | %v", S)
addToOutput(element, nextElement)
if S.EMPTY() {
} else if element > nextElement {
// falls top Element > next Element, auf Stack lassen und Schleife abbrechen.
break
} else {
// falls top Element == next Element, vom Stack entfernen und Schleife abbrechen.
S.POP()
metrics.AddMovesCost()
break
}
element = S.TOP()
S.POP()
metrics.AddTimeCost()
}
// lege letztes Element zurück
if element > nextElement {
logging.Debug("Element >= nextElement zurücklegen")
S.PUSH(element)
metrics.AddTimeCost()
}
logging.Debug("Stack S | %v", S)
}
S.PUSH(nextElement)
metrics.AddTimeCost()
logging.Debug("L[%v] auf Stack legen", i)
logging.Debug("Stack S | %v", S)
S.PUSH(nextElement)
metrics.AddMovesCost()
}
logging.Debug("Stack S | %v", S)
// was übrig bleibt hat kein größeres Element
logging.Debug("Alles übrige auf Stack hat kein nächstes größeres Element")
for !S.EMPTY() {
metrics.AddTimeCost()
for !S.EMPTY() { // ACHTUNG: schreibe 'while' im Pseudocode, denn dies ist eine while-Schleife in golang
logging.Debug("Stack S | %v", S)
element := S.TOP()
output = append(output, [2]int{element, -1})
S.POP()
addToOutput(element, -1)
metrics.AddMovesCost()
}
logging.Debug("Stack S | %v", S)
return output()
}
/* ---------------------------------------------------------------- *
* AUXILIARY METHODS
* ---------------------------------------------------------------- */
func clearOutput() {
_output_list = [][2]int{}
}
func addToOutput(m int, n int) {
_output_list = append(_output_list, [2]int{m, n})
}
func output() [][2]int {
var output = make([][2]int, len(_output_list))
copy(output, _output_list)
clearOutput()
return output
}

View File

@@ -34,7 +34,7 @@ func postChecks(L []int, pairs [][2]int, _ ...interface{}) error {
* ---------------------------------------------------------------- */
func FancyNextGreaterElement(input_L []int) ([][2]int, error) {
var name = "Binärsuchalgorithmus"
var name = "Next Greater Element"
var inputs = map[string]interface{}{
"L": input_L,
}

View File

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

View File

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

View File

@@ -1,15 +1,16 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# LOCAL ARGUMENTS
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PATH_TO_CONFIG:=../config.yml
COLOUR:=true# <- auf false stellen, falls es Probleme gibt
PATH_TO_CONFIG:=../config.yml#<- kann durch Pfad zur eigenen yml-Datei ersetzt werden
COLOUR:=true
PYTHON:=python3
PIP:=python3 -m pip
## für Windows weichen Defaultsettings leicht ab:
ifeq ($(OS),Windows_NT)
PYTHON:=py -3
PIP:=py -3 -m pip
else
PYTHON:=python3
PIP:=python3 -m pip
COLOUR:=false# <- man kann als 'true' setzen, aber in Windows funktioniert es möglicherweise nicht
PYTHON:=py -3
PIP:=py -3 -m pip
endif
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,17 +6,14 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
from src.core.log import *;
from src.setup.cli import GetArgumentsFromCli;
from src.setup.cli import GetArgumentParser;
from src.setup import assets;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ENDPOINT version
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def version():
with open('assets/VERSION', 'r') as fp:
version = ('\n'.join(fp.readlines())).strip();
logPlain(version);
logPlain(assets.Version());
return;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -24,6 +21,5 @@ def version():
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def help():
parser = GetArgumentParser();
parser.print_help();
logPlain(assets.Help());
return;

View File

@@ -8,6 +8,7 @@
from src.core.log import *;
from src.core.config import *;
from src.setup.display import *;
from src.setup import assets;
from src.algorithms.exports import *;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -18,6 +19,7 @@ def runInteractive():
'''
Startet Programm im interaktiven Modus (Konsole).
'''
logPlain(assets.Logo());
logWarn('Interaktiver Modus noch nicht implementiert.');
return;
@@ -31,6 +33,7 @@ def runNonInteractive(path: str):
'''
config = ReadConfigFile(path);
cases = GetAttribute(config, 'parts', 'cases', expectedtype=list, default=[]);
logPlain(assets.Logo());
for caseindex, case in enumerate(cases):
command = GetAttribute(case, 'command', expectedtype=str, default='');
descr = GetAttribute(case, 'description', expectedtype=str, default='');
@@ -39,11 +42,7 @@ def runNonInteractive(path: str):
DisplayStartOfCase(caseindex, descr);
try:
if command == 'algorithm-sum-maxsub':
MaxSubSum(L=inputs['L']);
elif command == 'algorithm-sum-maxsub-dc':
MaxSubSumDC(L=inputs['L']);
elif command == 'algorithm-search-sequential':
if command == 'algorithm-search-sequential':
SequentialSearch(L=inputs['L'], x=inputs['x']);
elif command == 'algorithm-search-binary':
BinarySearch(L=inputs['L'], x=inputs['x']);
@@ -61,6 +60,12 @@ def runNonInteractive(path: str):
FindPoison(L=inputs['L']);
elif command == 'algorithm-search-poison-fast':
FindPoisonFast(L=inputs['L']);
elif command == 'algorithm-stacks-next-greater-element':
NextGreaterElement(L=inputs['L']);
elif command == 'algorithm-sum-maxsub':
MaxSubSum(L=inputs['L']);
elif command == 'algorithm-sum-maxsub-dc':
MaxSubSumDC(L=inputs['L']);
else:
raise ValueError('Command \033[1m{}\033[0m nicht erkannt'.format(command));
except Exception as e:

View File

@@ -13,8 +13,6 @@ sys.path.insert(0, _path_to_python_project);
os.chdir(_path_to_python_project);
from src.core.log import *;
from src.core.utils import IsTrue;
from src.core.utils import IsFalse;
from src.setup.cli import *;
from src.setup import appconfig;
from src.endpoints.exports import *;
@@ -30,14 +28,16 @@ PATH_TO_CONFIG: str = '../config.yml';
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def enter(
mode: str,
mode: Union[str, None],
it: bool,
quiet: bool,
debug: bool,
checks: bool,
colour: bool,
config: Any, **_
config: Union[str, None],
**_
):
# Programmeinstellungen initialisieren
if not (mode == 'run' and it):
SetQuietMode(quiet);
SetDebugMode(debug);
@@ -46,7 +46,15 @@ def enter(
config = config if isinstance(config, str) else PATH_TO_CONFIG;
if mode == 'version':
# Wenn der Artefakt ohne Argument aufgerufen wird, keinen Fehler melden, sondern im it-Modus ausführen
if mode is None:
endpoint_runInteractive();
return;
# Sonst Commands behandeln
if mode == 'help':
endpoint_help();
return;
elif mode == 'version':
endpoint_version();
return;
elif mode == 'run':
@@ -54,8 +62,9 @@ def enter(
endpoint_runInteractive();
else:
endpoint_runNonInteractive(path=config);
else: # elif mode
endpoint_help();
return;
else:
endpoint_runInteractive();
return;
return;
@@ -71,11 +80,11 @@ if __name__ == '__main__':
endpoint_help();
exit(1);
enter(
mode=args.mode[0],
mode=args.mode,
it=args.it,
quiet=args.quiet,
debug=args.debug,
checks=IsTrue(args.checks[0]),
colour=IsTrue(args.colour[0]),
checks=args.checks,
colour=args.colour,
config=args.config,
);

View File

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

View File

@@ -10,6 +10,8 @@ from src.local.typing import *;
from src.core.log import *;
from src.core.utils import DedentIgnoreFirstLast;
from src.core.utils import IsTrue;
from src.core.utils import IsFalse;
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# GLOBAL VARIABLES
@@ -28,12 +30,12 @@ def GetArgumentParser() -> argparse.ArgumentParser:
prog='code/main.py',
description=DedentIgnoreFirstLast('''
\033[93;1mBeschreibung:\033[0m
\033[93;2mEin Programm, das verschiedene Algorithmen aus dem Kurs AlgoDat I testet.\033[0m
\033[93;2mEin Programm zur Ausführung verschiedener Algorithmen aus dem Kurs AlgoDat I.\033[0m
'''),
formatter_class=argparse.RawTextHelpFormatter,
);
parser.add_argument('mode',
nargs=1,
nargs='?',
choices=['version', 'help', 'run'],
help=DedentIgnoreFirstLast('''
help = Hilfsanleitung anzeigen.
@@ -56,4 +58,7 @@ def GetArgumentParser() -> argparse.ArgumentParser:
def GetArgumentsFromCli(*cli_args: str) -> argparse.Namespace:
parser = GetArgumentParser();
return parser.parse_args(cli_args);
args = parser.parse_args(cli_args);
args.checks=IsTrue(args.checks[0]);
args.colour=IsTrue(args.colour[0]);
return args;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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