Compare commits

...

5 Commits

23 changed files with 347 additions and 24 deletions

View File

@ -85,3 +85,7 @@ parts:
- command: 'algorithm-search-interpolation'
description: 'Seminarblatt Woche 3, Aufgabe 1'
inputs: *ref_inputs_sem3_1
- command: 'algorithm-stacks-next-greater-element'
description: 'Seminarblatt Woche 4, Aufgabe 1'
inputs:
L: [4, 2, 1, 100, 6, 3, 16]

View File

@ -4,8 +4,8 @@
Dieses Projekt ist erneut kein nötiger Bestandteil des Kurses,
sondern nur für Wissbegierige gedacht.
Zunächst bietet sich an, sich die Algorithmen im Unterordner [`internal/algorithms`](./internal/algorithms) anzuschauen,
z. B. [`internal/algorithms/search/binary/binary.go`](./internal/algorithms/search/binary/binary.go) für den Binärsuchalgorithmus,
Zunächst bietet sich an, sich die Algorithmen im Unterordner [`pkg/algorithms`](./pkg/algorithms) anzuschauen,
z. B. [`pkg/algorithms/search/binary/binary.go`](./pkg/algorithms/search/binary/binary.go) für den Binärsuchalgorithmus,
ohne irgendetwas installieren zu müssen.
**HINWEIS 1:** _Bei meiner Implementierung kann es zu leichten Abweichungen kommen. Bitte **stets** an dem Material im VL-Skript sich orientieren. Der Hauptzweck der Code-Projekte besteht darin, dass Wissbegierige die Algorithmen konkret ausprobieren können. Alle theoretischen Aspekte werden jedoch im Skript und in den Übungen ausführlicher erklärt._

View File

@ -11,13 +11,14 @@ import (
"ads/internal/setup"
"ads/internal/types"
algorithm_search_binary "ads/internal/algorithms/search/binary"
algorithm_search_interpol "ads/internal/algorithms/search/interpol"
algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
algorithm_search_jump "ads/internal/algorithms/search/jump"
algorithm_search_poison "ads/internal/algorithms/search/poison"
algorithm_search_sequential "ads/internal/algorithms/search/sequential"
algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
algorithm_search_binary "ads/pkg/algorithms/search/binary"
algorithm_search_interpol "ads/pkg/algorithms/search/interpol"
algorithm_search_ith_element "ads/pkg/algorithms/search/ith_element"
algorithm_search_jump "ads/pkg/algorithms/search/jump"
algorithm_search_poison "ads/pkg/algorithms/search/poison"
algorithm_search_sequential "ads/pkg/algorithms/search/sequential"
algorithm_stacks_next_greater_element "ads/pkg/algorithms/stacks/next_greater_element"
algorithm_sum_maxsubsum "ads/pkg/algorithms/sum/maxsubsum"
)
/* ---------------------------------------------------------------- *
@ -138,6 +139,13 @@ func RunNonInteractive(path string) error {
} else {
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
}
case "algorithm-stacks-next-greater-element":
L := inputs.List
if L != nil {
_, err_case = algorithm_stacks_next_greater_element.FancyNextGreaterElement(*L)
} else {
err_case = fmt.Errorf("Fehlende Inputs für Befehl '%[1]s'.", *problem.Command)
}
case "algorithm-sum-maxsub":
L := inputs.List
if L != nil {

View File

@ -8,17 +8,18 @@ import (
"ads/internal/core/logging"
"ads/internal/setup"
algorithm_search_binary "ads/internal/algorithms/search/binary"
algorithm_search_interpol "ads/internal/algorithms/search/interpol"
algorithm_search_ith_element "ads/internal/algorithms/search/ith_element"
algorithm_search_jump "ads/internal/algorithms/search/jump"
algorithm_search_poison "ads/internal/algorithms/search/poison"
algorithm_search_sequential "ads/internal/algorithms/search/sequential"
algorithm_sum_maxsubsum "ads/internal/algorithms/sum/maxsubsum"
algorithm_search_binary "ads/pkg/algorithms/search/binary"
algorithm_search_interpol "ads/pkg/algorithms/search/interpol"
algorithm_search_ith_element "ads/pkg/algorithms/search/ith_element"
algorithm_search_jump "ads/pkg/algorithms/search/jump"
algorithm_search_poison "ads/pkg/algorithms/search/poison"
algorithm_search_sequential "ads/pkg/algorithms/search/sequential"
algorithm_stacks_next_greater_element "ads/pkg/algorithms/stacks/next_greater_element"
algorithm_sum_maxsubsum "ads/pkg/algorithms/sum/maxsubsum"
)
/* ---------------------------------------------------------------- *
* ACTIONS - Algorithmen
* ACTIONS algorithmen - search
* ---------------------------------------------------------------- */
func actionAlgorithmSearchBinary() (bool, error) {
@ -202,6 +203,28 @@ func actionAlgorithmSearchSequential() (bool, error) {
return cancel, nil
}
/* ---------------------------------------------------------------- *
* ACTIONS algorithmen - stacks
* ---------------------------------------------------------------- */
func actionAlgorithmStacksNextGreaterElement() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {
return cancel, err
}
setup.DisplayStartOfCaseBlank()
_, err = algorithm_stacks_next_greater_element.FancyNextGreaterElement(input_L)
if err != nil {
logging.Error(err)
}
setup.DisplayEndOfCase()
return cancel, nil
}
/* ---------------------------------------------------------------- *
* ACTIONS algorithmen - sum
* ---------------------------------------------------------------- */
func actionAlgorithmSumMaxsub() (bool, error) {
input_L, cancel, err := promptInputListOfInt("L", "Liste von Werten", []string{})
if cancel || err != nil {

View File

@ -27,6 +27,7 @@ var menuMain = menus.Menu{
}, {
{Label: "Suchalgorithmen", Submenu: &menuSearchAlgorithms},
{Label: "Summenalgorithmen", Submenu: &menuSumAlgorithms},
{Label: "Algorithmen mit Stacks und Queues", Submenu: &menuStacksQueuesAlgorithms},
},
},
Default: -1,
@ -117,6 +118,19 @@ var menuSearchAlgorithms = menus.Menu{
Default: -1,
}
var menuStacksQueuesAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Algorithmen mit Stacks und Queues"},
PromptMessages: []string{
"Algorithmus wählen",
},
Options: [][]menus.MenuOption{
{
{Label: "'Next Greater Element' mit Stacks", Action: actionAlgorithmStacksNextGreaterElement},
},
},
Default: -1,
}
var menuSumAlgorithms = menus.Menu{
Path: []string{"Hauptmenü", "Summenalgorithmen"},
PromptMessages: []string{

View File

@ -103,8 +103,8 @@ func DisplayEndOfAlgorithm(outputs map[string]interface{}) {
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", metrics.GetTimeCost())
logging.Plain("Kosten (Platz): S(n) = \033[1m%[1]v\033[0m", metrics.GetSpaceCost())
logging.Plain("Kosten (Zeit): T(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetTimeCost()))
logging.Plain("Kosten (Platz): S(n) = \033[1m%[1]v\033[0m", displayCost(metrics.GetSpaceCost()))
return
}
@ -120,3 +120,10 @@ func DisplayBar(options ...int) {
logging.Plain("+%[1]s+", strings.Repeat("-", n))
return
}
func displayCost(cost int) string {
if cost > 0 {
return fmt.Sprintf("%v", cost)
}
return "-"
}

View File

@ -38,15 +38,14 @@ func InterpolationSearch(L []int, x int, u int, v int) int {
}
metrics.AddTimeCost()
p := getSuchposition(L, x, u, v)
logging.Debug("Interpolante von x in (u, v)=(%[1]v, %[2]v) ist p = %[3]v.", u, v, p)
if L[p] == x {
logging.Debug("x in Position p gefunden")
logging.Debug("Interpolante in (%[1]v, %[2]v) ist p = %[3]v; L[p] == x; ===> Element gefunden", u, v, p)
return p
} else if x < L[p] {
logging.Debug("Suche in linker Hälfte fortsetzen.")
logging.Debug("Interpolante in (%[1]v, %[2]v) ist p = %[3]v; L[p] > x; ===> suche in linker Hälfte", u, v, p)
return InterpolationSearch(L, x, u, p-1)
} else { // } else if x > L[p] {
logging.Debug("Suche in rechter Hälfte fortsetzen.")
logging.Debug("Interpolante in (%[1]v, %[2]v) ist p = %[3]v; L[p] < x; ===> suche in rechter Hälfte", u, v, p)
return InterpolationSearch(L, x, p+1, v)
}
}

View File

@ -5,9 +5,9 @@ package jump
* ---------------------------------------------------------------- */
import (
"ads/internal/algorithms/search/sequential"
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/pkg/algorithms/search/sequential"
)
/* ---------------------------------------------------------------- *

View File

@ -0,0 +1,107 @@
package next_greater_element
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"ads/internal/core/logging"
"ads/internal/core/metrics"
"ads/pkg/data_structures/stacks"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
var _output_list [][2]int
/* ---------------------------------------------------------------- *
* ALGORITHM next greater element
* ---------------------------------------------------------------- */
/*
Inputs: L = Liste von Zahlen, x = Zahl.
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()
}
S := stacks.CREATE()
for i := 0; i < len(L); i++ {
logging.Debug("Lies Element L[%v] ein", i)
nextElement := L[i]
logging.Debug("Stack S | %v", S)
if !S.EMPTY() {
logging.Debug("Entferne alle top Elemente vom Stack bis >= nextElement")
element := S.TOP()
S.POP()
metrics.AddTimeCost()
/*
Entferne kleinere Elemente vom Stack
Aktuelles Element ist jeweils größerer rechter Partner
*/
for element < nextElement {
logging.Debug("Stack S | %v", S)
addToOutput(element, nextElement)
if S.EMPTY() {
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)
}
// 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()
logging.Debug("Stack S | %v", S)
element := S.TOP()
S.POP()
addToOutput(element, -1)
}
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

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

View File

@ -0,0 +1,72 @@
package stacks
/* ---------------------------------------------------------------- *
* IMPORTS
* ---------------------------------------------------------------- */
import (
"fmt"
"strings"
)
/* ---------------------------------------------------------------- *
* GLOBAL VARIABLES/CONSTANTS
* ---------------------------------------------------------------- */
//
/* ---------------------------------------------------------------- *
* TYPE
* ---------------------------------------------------------------- */
type StackInt struct {
values []int
}
/* ---------------------------------------------------------------- *
* METHODS stacks
* ---------------------------------------------------------------- */
func CREATE() StackInt {
return StackInt{
values: []int{},
}
}
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
}
func (S StackInt) String() string {
if len(S.values) == 0 {
return "-"
}
values := []string{}
for _, value := range S.values {
values = append(values, fmt.Sprintf("%v", value))
}
return fmt.Sprintf(strings.Join(values, ", "))
}