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