# Locking System



## syntaxError404 (11. Jun 2021)

Hey miteinander  ich bräuchte etwas hilfe und zwar:

es geht um schliesßanlagen. 
Eine Schließanlage besteht aus mehreren Riegel ( n-viele ).
Die einzelnen Riegel können entweder OFFEN oder ZU sein
Die Schließanlage ist dann offen wenn alle Riegel offen sind und dann zu wenn alle Riegel zu sind.
Die Riegel lassen sich jetzt nun nicht so leicht öffnen oder schließen (bewegen) , es gibt 4 Regeln:
1- R1 (erstes Riegel) kann immer bewegt werden.
2- R2 kann nur bewegt werden wenn R1 offen ist.
3- Jeder andere Riegel kann genau dann bewegt werden, wenn der Riegel mit der nächst kleineren
Nummer offen ist und alle mit noch kleineren Nummern zu sind.
4- Der Riegel n kann außerdem noch bewegt werden, wenn alle Riegel 1 bis n- 1 zu sind.

man bekommt am anfang eine Liste mit n - Riegeln die alle zufällig offen oder zu sind.

Jetzt ist dat ding dass ich ne Methode fürs öffnen des Schlosses und eine fürs Schließen schreiben soll. Mir ist klar wie das auf Papier funktioniert aber ich bekomms einfach nicht programmiert :// 

Worte können kaum beschreiben wie dankbar ich für jede Hilfe bin.

Gruß


----------



## mihe7 (11. Jun 2021)

syntaxError404 hat gesagt.:


> Mir ist klar wie das auf Papier funktioniert aber ich bekomms einfach nicht programmiert ://


Beschreib es doch erstmal in Worten.


----------



## syntaxError404 (11. Jun 2021)

zum schließen:
man checkt Rn ab ob es zu ist, wenn ja dann Rn-1 usw.
Wenn’s offen ist schaut man den Riegel vorher an ob der geöffnet ist (Notw. Bed.). Ist dieser geöffnet dann schaut man immer einen Riegel weiter ob dieser geschlossen ist. Ist dies nicht der Fall. Wird dieser Riegel zum neuen Index(Also der zum ändernden Riegel) und man fängt von vorne an (also ab dem neuen index).
Bis man dann einen Riegel geschlossen hat. Und dann fängt man wieder ganz von vorne an. Wenn Rn geschlossen ist, wird wieder alles durchgelaufen ab Rn-1

zum öffnen:
Im Grunde dasselbe aber halt das man jetzt nicht schließen sondern öffnen möchte


----------



## mihe7 (11. Jun 2021)

syntaxError404 hat gesagt.:


> Wenn’s offen ist schaut man den Riegel vorher an ob der geöffnet ist (Notw. Bed.).


Was ist mit Bedingung 4? 

Ansonsten ist die Beschreibung schon gar nicht verkehrt, wobei Du noch berücksichtigen musst, dass R2 sich nur ändern lässt, wenn R1 offen ist.

Ich würde mir mal in der umgekehrten Reihenfolge überlegen: was ist bei einem Riegel zu tun? was ist bei zwei Riegeln zu tun? Was ist bei mehr als zwei Riegeln zu tun?


----------



## syntaxError404 (11. Jun 2021)

mihe7 hat gesagt.:


> Was ist mit Bedingung 4?
> 
> Ansonsten ist die Beschreibung schon gar nicht verkehrt, wobei Du noch berücksichtigen musst, dass R2 sich nur ändern lässt, wenn R1 offen ist.
> 
> Ich würde mir mal in der umgekehrten Reihenfolge überlegen: was ist bei einem Riegel zu tun? was ist bei zwei Riegeln zu tun? Was ist bei mehr als zwei Riegeln zu tun?


Da Bedingung 4 kein muss ist habe ich das mal weggelassen, denn das ist ja nur "mehr arbeit" das noch zu berücksichtigen. Prinzipiell habe ich das ja verstanden wie man das mit derselben Methode immer auf und zu kriegt, jedoch schaffe ich es einfach nicht als Code umzusetzen :/


----------



## mihe7 (11. Jun 2021)

syntaxError404 hat gesagt.:


> Da Bedingung 4 kein muss ist habe ich das mal weggelassen, denn das ist ja nur "mehr arbeit" das noch zu berücksichtigen.


Bedingung 3 und 4 werden zu: jeder andere Riegel n kann bewegt werden, wenn die Riegel n-2 geschlossen sind. Der Riegel n-1 kann offen (Bed. 3) oder zu (Bed. 4) sein.



syntaxError404 hat gesagt.:


> jedoch schaffe ich es einfach nicht als Code umzusetzen :/


Du kannst entweder direkt das, was Du beschrieben hast, umsetzen oder Dir eben die umgekehrte Reihenfolge überlegen, um den Spaß rekursiv zu lösen.


----------



## syntaxError404 (12. Jun 2021)

mihe7 hat gesagt.:


> Bedingung 3 und 4 werden zu: jeder andere Riegel n kann bewegt werden, wenn die Riegel n-2 geschlossen sind. Der Riegel n-1 kann offen (Bed. 3) oder zu (Bed. 4) sein.
> 
> 
> Du kannst entweder direkt das, was Du beschrieben hast, umsetzen oder Dir eben die umgekehrte Reihenfolge überlegen, um den Spaß rekursiv zu lösen.


ja habs jetzt rekursiv gelöst, klappt


----------



## Programmierbot (13. Jun 2021)

syntaxError404 hat gesagt.:


> ja habs jetzt rekursiv gelöst, klappt


Hey, ich muss diese Aufgabe auch machen und habe noch keine richtige Idee, könntest du mir evtl. einen Tipp geben?
Ich habe die open()-Methode schon ein paar Mal geschrieben, aber es war nichts richtig (auch mit Rekursion). 
Den Vorgang auf Papier verstehe ich schon, aber ich weiß nicht wie ich es für beliebige Riegel als Code umsetzten kann.
Danke und LG


----------



## mihe7 (13. Jun 2021)

Die Idee ist: 
1. eine Schließanlage hat mindestens 1 Riegel,
2. eine Schließanlage mit n (n > 1) Riegeln ist eine Schließanlage mit n-1 Riegeln plus eines weiteren Riegels.

Soll nun der n-te Riegel geschlossen werden, dann gibt es offensichtlich verschiedene Fälle zu berücksichtigen. Schreib Dir einfach mal auf, wie es sich bei Riegel 1, 2 und n (n > 2) verhält, d. h. was im Fall einer Schließanlage mit 1 Riegel, mit 2 Riegeln und mit n Riegeln (n > 2) getan werden muss. Dabei kannst Du auf die Schließen-Funktion zurückgreifen, die Du gerade beschreibst (Rekursion) und genau das lässt sich unmittelbar in Code gießen. Um die Formulierungen zu vereinfachen, kannst Du z. B. festlegen, dass die Riegel 1 bis n-1 als "restliche Riegel" bezeichnet werden.


----------



## Programmierbot (13. Jun 2021)

Ich glaube ich habe es verstanden: Ich muss zuerst "nur" den letzten bzw. den n-ten Riegel schließen und alle anderen öffnen, dann rufe ich die gleiche Methode für n-1 auf, d.h. dann schließe ich den n-1-ten Riegel und alle drunter öffne ich usw. bis ich an den Basisfall n = 5 komme weil für n = 5 bekomme ich in 12 Schritten alle zu.
Natürlich muss ich auch für alle Fälle n Riegel < 5 bestimmen aber das ist nicht schwer. (mit n Riegel meine ich hier die Anzahl der gesamten Riegel)
Konntest du es verstehen und auch bestätigen oder habe ich doch einen Denkfehler?


----------



## mihe7 (13. Jun 2021)

Programmierbot hat gesagt.:


> Ich glaube ich habe es verstanden: Ich muss zuerst "nur" den letzten bzw. den n-ten Riegel schließen und alle anderen öffnen, dann rufe ich die gleiche Methode für n-1 auf, d.h. dann schließe ich den n-1-ten Riegel und alle drunter öffne ich usw. bis ich an den Basisfall n = 5 komme weil für n = 5 bekomme ich in 12 Schritten alle zu.
> Natürlich muss ich auch für alle Fälle n Riegel < 5 bestimmen aber das ist nicht schwer. (mit n Riegel meine ich hier die Anzahl der gesamten Riegel)
> Konntest du es verstehen und auch bestätigen oder habe ich doch einen Denkfehler?


Du musst nicht alle anderen öffnen. Nach Regel 4 kannst Du den Riegen n ja nur bewegen, wenn die Riegel 1 bis n-1 zu sind (außer die Angabe in Kommentar #1 war falsch). Und Du brauchst nicht alle Fälle < 5 berücksichtigen. Nur die Fälle n=1 und n=2 benötigen eine Sonderbehandlung (entsprichend der Regeln 1 und 2), für den Rest läuft alles gleich ab.


----------



## Barista (13. Jun 2021)

Die Frage ist sicher auch, arbeitet man stur, also ausprobieren oder intelligent, also ein Lösungsprinzip gefunden.
(implizit in den anderen Postings bereits für die intelligente Variante entschieden).

Wenn man intelligent arbeitet, stellt sich die Frage:

Überprüft man die Einhaltung der Regeln bei jeder Änderung an den Riegel-Stellungen oder geht man davon aus, dass nicht gegen die Regeln verstossen wird?


----------



## Programmierbot (14. Jun 2021)

mihe7 hat gesagt.:


> Du musst nicht alle anderen öffnen. Nach Regel 4 kannst Du den Riegen n ja nur bewegen, wenn die Riegel 1 bis n-1 zu sind (außer die Angabe in Kommentar #1 war falsch). Und Du brauchst nicht alle Fälle < 5 berücksichtigen. Nur die Fälle n=1 und n=2 benötigen eine Sonderbehandlung (entsprichend der Regeln 1 und 2), für den Rest läuft alles gleich ab.


Nein die war richtig.
Mir ist es auch aufgefallen, dass nur n = 1 und n = 2 eine Sonderbehandlung brauchen, es gibt mehrere Möglichkeiten, die Riegel zu öffnen, wie auch @Barista gesagt hat, war meine vorherige nicht nach einem Prinzip, sondern ich habe eine Möglichkeit ausprobiert.
Aber zu dem ersten Teil den ich geschrieben habe: Ist es ein Lösungsprinzip, zuerst den n-ten Riegel zu schließen und dann den n-1-ten usw. bis ich beim ersten bin?
Ich denke, dann habe ich es verstanden, ich muss es nur noch als Code aufschreiben.



Barista hat gesagt.:


> Wenn man intelligent arbeitet, stellt sich die Frage:
> 
> Überprüft man die Einhaltung der Regeln bei jeder Änderung an den Riegel-Stellungen oder geht man davon aus, dass nicht gegen die Regeln verstossen wird?


Wie genau meinst Du das? Bzw. Warum sollte nicht gegen die Regeln verstoßen werden?


----------



## mihe7 (14. Jun 2021)

Programmierbot hat gesagt.:


> Aber zu dem ersten Teil den ich geschrieben habe: Ist es ein Lösungsprinzip, zuerst den n-ten Riegel zu schließen und dann den n-1-ten usw. bis ich beim ersten bin?


Wenn es um die rekursiven Aufrufe geht: man kann beim Schließen sowohl von Riegel 1 nach n, als auch von Riegel n nach 1 gehen.

Falls die Methoden getrennt sein dürfen, ist das iterativ ja leicht umzusetzen. Das Schließen:

1. öffne Riegel 1, schließe Riegel 2, schließe Riegel 1 (Regeln #1 und #2)
2. Für alle Riegel r von 3 bis n: schließe Riegel r (Regel #4)

Das geht auch rekursiv:

1. Falls n = 1, schließe Riegel 1 (Regel #1)
2. Falls n = 2, öffne Riegel 1, schließe Riegel 2, schließe Riegel 1 (Regel #2)
3. Falls n > 2, müssen erst mal alle "kleineren" Riegel geschlossen werden (rekursiver Aufruf), dann kann der letzte Riegel geschlossen werden (Regel #4)

Will man ausschließlich Regel #3 umsetzen, wird es komplizierter. Das überlasse ich Euch.


----------



## Barista (14. Jun 2021)

Programmierbot hat gesagt.:


> Warum sollte nicht gegen die Regeln verstoßen werden?


Weil die Lösung dann nicht korrekt ist.


----------



## Barista (14. Jun 2021)

Ich würde als Erstes ein Modell programmieren, welches den Status des Schlosses abbildet und die möglichen Operationen anbietet.

Das könnte ein Array mit einer Anzahl statischer Methoden oder eine Klasse mit gekapseltem Array sein.

`boolean canClose(int riegelNumber)`

`boolean canOpen(int riegelNumber)`

`void close(int riegelNumber) throws IllegalRiegelOperation`

`void open(int riegelNumber) throws IllegalRiegelOperation`

Am besten die verändernden Methoden als clone-Methoden, also unveränderliches Modell.

In der sturen Variante würde ich jeden Status in rekursivem Code in einem Stack halten.

Abbruch-Bedingung 'gescheitert' ist das Erreichen eines Status, den es im Stack schon gibt.

Also `equals(Object other)` korrekt implementieren, für Array-Vergleich Methode aus java.util.Arrays.

Abbruch-Bedingung 'erfolgreich' ist das Erreichen des gewünschten Zielzustandes 'Offen' bzw. 'Geschlossen'.

Beim Erreichen des gewünschten Zielzustandes ist der Stack die Historie der Operationen, die zum Erfolg geführt haben.

Also Stack nicht Abbauen, sondern Vermerken.

In der sturen Variante würde ich jede Operation (Riegel-Nummer und Schliessen vs. Öffnen) auf erlaubt-sein prüfen und dann im Stack rekursiv weiter ablaufen lassen.

Bei Scheitern die nächste mögliche Operation ausführen.

Drum herum als Test Schlösser auf Basis Zufallsgenerator erzeugen (Seed vermerken zur Wiederholung nicht erfolreicher Tests).

Alternativ Erzeugung Schlösser auf Basis Permutationen.


----------



## Barista (14. Jun 2021)

Barista hat gesagt.:


> In der sturen Variante würde ich jede Operation (Riegel-Nummer und Schliessen vs. Öffnen) auf erlaubt-sein prüfen und dann im Stack rekursiv weiter ablaufen lassen.


In der sturen Variante würde ich jede Operation (Riegel-Nummer und Schliessen vs. Öffnen) auf erlaubt-sein prüfen, *ausführen* und dann im Stack rekursiv weiter ablaufen lassen.


----------



## mihe7 (14. Jun 2021)

@Barista, wo bleibt die Testsuite?


----------



## Barista (14. Jun 2021)

mihe7 hat gesagt.:


> wo bleibt die Testsuite?


Was bedeutet dieses Posting?

Soll ich eine Testsuite schreiben?

Hätte ich in meinen Gedanken-Stichpunkten eine Testsuite erwähnen sollen?


----------



## mihe7 (14. Jun 2021)

Barista hat gesagt.:


> Soll ich eine Testsuite schreiben?


So war das gemeint, ja


----------



## Programmierbot (14. Jun 2021)

Sorry, dass ich mich lange nicht gemeldet habe, ich war die ganze Zeit am Programmieren...
Letzten Endes habe ich es doch geschafft und ihr hattet einen großen Anteil daran.
Deswegen möchte ich mich recht herzlich bei euch bedanken👍


----------

