Entwickler-Ecke
Sonstiges (.NET) - kleine bzw. grosse Strasse
darkangel1208 - Sa 28.11.09 20:04
Titel: kleine bzw. grosse Strasse
die große Straße ist ja nicht so das problem, das ja alle 5 Zahlen fortlaufend sein müssen
1-2-3-4-5 oder
2-3-4-5-6 = 40 Punkte
aber die kleine Straße bereitet mir Kopfzerbrechen. Dort habe ich ja 4 Forlaufende Zahlen und die 5. is egal und kann alles zwicshen 1 und 6 sein.
Zu Anfang lasse ich mir mein array sortieren, dann stehen die zahlen von klein nach gross im array. Daher ist dann auch die grosse Straße kein Problem. Aber bei der kleinen kann die 5. Zahl, die hier wichtig ist, hinten oder in der Reihe stehen
1,2,3,4,6 oder
1,2,2,3,4 = 30 Punkte
ich komme nicht dahinter, wie ich das lösen könnte
Die große Straße habe ich so realisiert.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| public int strasse(int[] wurf) { Array.Sort(wurf); int i, zaehler = 0, zahl = 4;
for (i = 0; i < zahl; i++) { if ((wurf[i] + 1) != (wurf[i + 1])) return 0; } return zahl*10; } |
Moderiert von
Kha: Topic aus WinForms verschoben am Sa 28.11.2009 um 19:23
Kha - Sa 28.11.09 20:30
Du kannst ganz allgemein die "Straßenlänge" über eine Schleife ermitteln:
Am Anfang setzt du sie auf 1 und beginnst mit dem ersten Eintrag. Wenn der jeweils folgende Eintrag um eins größer ist, erhöhst du die Variable um eins, wenn eine noch größere Differenz besteht, brichst du die Schleife ab.
Den Großteil deines Große-Straße-Codes kannst du also übernehmen.
Namenlosnameless - Sa 28.11.09 20:41
Diesmal die Lösung mit for Schleife^^
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| int c; Random rd = new Random(); List<int> Zahlen = new List<int> {}; for(c=0;c<=5;c++) { Zahlen.Add(rd.Next(1, 7)); } Zahlen.Sort();
int zaehler, i, altes_i, neues_i; zaehler = 1;
for (i = 1; i < Zahlen.Count;i++ ) { neues_i = Zahlen[i]; altes_i = Zahlen[i-1]; if (altes_i + 1 != neues_i) { break; } zaehler++; if (zaehler == 4) { Console.WriteLine("Es ist eine kleine Straße vorhanden"); break; } } if (zaehler != 4) { Console.WriteLine("Sie haben keine Straße gewürfelt"); } Console.ReadLine(); |
Edit: Das ist jetzt der, nach den Vorschlägen von Kha, ausgebesserte Code
ohne Bug^^!!!!
Hier habe ich keinen bool genommen da ich ja gleich zaehler nehmen kann und somit keine eigene Variable brauche.
Kha - Sa 28.11.09 21:05
Wirklich? Dann probier deinen Code mal aus :mrgreen: .
Außer dem kleinen Bug hast du - wiedermal - exakt meinen Vorschlag getroffen ;) .
Noch ein paar Kleinigkeiten: Variablen bitte klein schreiben und erst deklarieren, wenn sie gebraucht werden, außerdem solltest du dir mal
break anschauen ;) .
Namenlosnameless - Sa 28.11.09 21:11
Code funktioniert wunderbar!
Also zumindest soweit ich die Zahlen eingegeben hab!
Ich komm auch momentan nicht drauf wo der Fehler liegt.
Kha hat folgendes geschrieben : |
Noch ein paar Kleinigkeiten: Variablen bitte klein schreiben und erst deklarieren, wenn sie gebraucht werden, außerdem solltest du dir mal break anschauen ;) . |
meinst du das ich z.B. neues_i erst in der for-Schleife als int deklarieren soll??
Falls das so ist dann hab ich mir in VBA einen blödsin eingelernt, da stand im Buch ganz fett und mit Rufzeichen versehen, dass mann die Variablen ganz oben deklarieren soll^^
zu break: ohne dass ich jetzt gegoogelt habe, nehme ich an das es der Code ist von dem ich geglaubt habe das es ihn nicht gibt und ich glaube er steigt aus der schleife aus^^
--
Moderiert von
Kha: Beiträge zusammengefügt ---
ohh ich hab gefunden das es nicht ganz korrekt läuft.
Er hat mir bei 2,3,3,3,3 ausgegeben das eine Straße vorhanden ist^^
--
Moderiert von
Kha: Beiträge zusammengefügt ---
Ich hab den Fehler gefunden.
hab vergessen dass die schleife ja einmal noch fertig äuft und dann theoretisch zeahler 4 werden könnte!
darum wohl auch break^^
Kha - Sa 28.11.09 22:21
Namenlosnameless hat folgendes geschrieben : |
| Falls das so ist dann hab ich mir in VBA einen blödsin eingelernt, da stand im Buch ganz fett und mit Rufzeichen versehen, dass mann die Variablen ganz oben deklarieren soll^^ |
Kann dort schon sein, wir sind hier aber nicht bei VBA ;) .
Deinen Code musst du trotzdem noch einmal überdenken, bei mir liefert
{ 1, 2, 2, 3, 4 } "keine Straße" :nixweiss: .
darkangel1208 - Sa 28.11.09 23:36
bei
C#-Quelltext
1: 2: 3: 4:
| if (altes_i + 1 != neues_i) { break; } |
heißt ja nur dass die darauffolgende Zahl nicht um 1 größer ist. Alos bei 1,2,2,3,4
hat man im ersten druchlauf ja
altes_i=1
neues_i=2
1+1!=2 => kein break;
beim nächsten durchlauf dann
altes_i=2
neues_i=2
2+1!=2 => genau, er geht rein und es kommt der break;
Doch was bewirkt der Break hier genau das er aus der aktuellen schleife(hier eine bedinugng) raus geht. Dann landet er hinter dem } vom if undm acht mit zaehler++; weiter.
Aber eins ist ja klar, mir zumindest jetzt
entweder die unnötige Zahl steht am ende und ist somit größer als die Zahlen der Straße
1,2,3,4,6
oder sie steht drinne und kann dann nur die größe seines Vorgängers haben
wäre hier die doppelte 2 die 2, die zuviel ist hat die größe ihres Vorgängers, genau 2
1,2,2,3,4
Also wenn er so ne 2 findet muss er ja nur irgendwie ans ende von dem ganzen und oben wieder anfangen. Sprich diesen einen Durchlauf nicht werten. Break ist schon net falsch, aber wie s telle ich es am besten an....
P.S. wie du ne Straße bei 1,2,2,3,4 bekommst weiß ich net bei mir kommt jedenfalls keine.
Kilianus - Sa 28.11.09 23:47
darkangel1208 hat folgendes geschrieben : |
bei
C#-Quelltext 1: 2: 3: 4:
| if (altes_i + 1 != neues_i) { break; } |
Doch was bewirkt der Break hier genau das er aus der aktuellen schleife(hier eine bedinugng) raus geht. Dann landet er hinter dem } vom if undm acht mit zaehler++; weiter. |
AUTSCH!
Eine Verzweigung ist keine Schleife!
break beendet die innerste Schleife, also hier die for-Schleife.
ADDit:
darkangel1208 hat folgendes geschrieben : |
Also wenn er so ne 2 findet muss er ja nur irgendwie ans ende von dem ganzen und oben wieder anfangen. Sprich diesen einen Durchlauf nicht werten. Break ist schon net falsch, aber wie s telle ich es am besten an....
|
mit "continue;"
Namenlosnameless - Sa 28.11.09 23:57
Kha hat folgendes geschrieben : |
| Deinen Code musst du trotzdem noch einmal überdenken, bei mir liefert { 1, 2, 2, 3, 4 } "keine Straße" :nixweiss: . |
ahh verdammt^^ ich knie mich morgen nochmal dahinter! jetzt bin ich zu 100% nicht mehr fähig auch nur irgendeinen klaren gedanken zu fassen der mir beim proggen weiterhilft...
darum mal gn8. morgen finde ich den fehler und bessere ihn aus^^.!!!!!!!!!!!!!!
darkangel1208 - So 29.11.09 00:51
ich habe das ganze so jetzt gelöst müsste funktionieren oder? in zahl steht ne 3 oder 4
3 = kleine Strasse
4 = grosse Strasse
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| public int strasse(int[] wurf, int zahl) { wurf[0] = 1; wurf[1] = 2; wurf[2] = 2; wurf[3] = 3; wurf[4] = 4;
Array.Sort(wurf); int i, zaehler = 0; if (zahl == 3) { for (i = 0; i < 4; i++) { if (wurf[i] + 1 != wurf[i + 1]) continue; zaehler++; if (zaehler == 3) return zahl * 10; } return 0; } else { for (i = 0; i < 4; i++) { if (wurf[i] + 1 != wurf[i + 1]) return 0; } return zahl * 10; } } |
Kha - So 29.11.09 01:26
Nope, Gegenbeispiel:
{ 1, 2, 3, 5, 6 }.
Mein allgemeiner Ansatz war allerdings auch etwas zu einfach gedacht :|, so scheint es zu funktionieren:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| static int GetStreetNumber(int[] rolls) { int maxNumber = 1; int currentNumber = 1; for (int i = 1; i < rolls.Length; i++) switch (rolls[i] - rolls[i - 1]) { case 1: currentNumber++; break; case 0: break; default: maxNumber = Math.Max(maxNumber, currentNumber); currentNumber = 1; break; }
return Math.Max(maxNumber, currentNumber); } |
jaenicke - So 29.11.09 02:49
Noch eine Idee, die Funktion gibt direkt die Punktanzahl für große und kleine Straßen zurück bzw. 0, wenn es keine ist:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| public int GetStreetPoints(int[] rolls) { int result = 0, value = -100; foreach (int i in rolls.Distinct().OrderBy(n => n)) { result = (value + 1 < i) ? ((result < 4) ? 1 : result) : result + 1; value = i; } return (result == 5) ? 40 : ((result == 4) ? 30 : 0); } |
darkangel1208 - So 29.11.09 03:20
ja den fall hab ich schon wieder übersehen.
- Straße hat man ja wenn sie aufeianderfolgen
4,5
keine Straße wenn:
- 2 doppelte kommen
4,4
- oder, was mir entgangen war, einer dazwischen fehlt. Aber dann kann er sofort raus gehen, dann wird er keine Straße mehr finden, wenn sie vorher nich nicht da war.(bei 1,2,3,4,6 hat er sie ja schon gefunden und geht raus beovr er 4 -6 rechnen kann. Außer bei 1,3,4,5,6)
4,6
Hab das jetzt umgeändert. Jetzt müsste es wie die Lösung von Kha sein, wobei ich den default-teil von dir noch net verstehe. Aber das kann ich ja morgen mir nochma angucken, was der dort macht
@ jaenicke ääääää wie biste denn auf diese Lösung gekommen. Die finde ich auf den ersten Blick ja schon sehr abstrackt. Die Verstehe ich so jetzt erstmal auf Anhieb nicht. Vorallem die Zeilen 4,6 und 9 verstehe ich nicht. Da ich noch nie ein ? oder : beim Programmieren gesehen habe.
jaenicke - So 29.11.09 03:35
Das nennt sich trinärer Operator. Wenn die Bedingung vor dem Fragezeichen wahr ist, wird der Wert direkt nach dem Fragezeichen benutzt, sonst der nach dem Doppelpunkt. Also:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| result = a ? b : c; if (a) result = b; else result = c; |
Was ich mache ist, das Array zu sortieren nachdem ich doppelte Werte mit Distinct entfernt habe. Dann merke ich mir den aktuellen Wert und setze result auf 1, wenn die Differenz größer als 1 ist (wie beim ersten Durchlauf), sonst erhöhe ich result nur.
Dadurch habe ich nach der Schleife die Anzahl der aufeinanderfolgenden Zahlen. Wobei mir auffällt, dass die Abbruchbedingung bei einer bereits gefundenen Straße fehlt, das habe ich direkt ergänzt, dann wird result nicht verändert.
// EDIT:
Ach ja: die lesbarere Variante ist sicher
Khas. Aber so siehts doch schön aus. :mrgreen:
darkangel1208 - So 29.11.09 04:04
ok danke für die Erklärung. Ich werde es dann morgen (oder bessergesagt in 6 stunden) studieren. Heute schafft das mein Hirn nicht mehr.
Klaro ist deins schöner :mrgreen: Nur muss ich für den Lehrer JEDE Zeile kommentieren und das wird dann schlecht wenn ich net versteh was dort steht :P . Leichter für mich erstmal zu verstehen ist das von Kha.
Ich werde ganz neidisch jaenicke. So toll würd ich auch gerne Proggen können :zustimm:
Namenlosnameless - So 29.11.09 10:25
So für den Fall das du Kha's und jaenicke's verion nicht ganz verständlich findest:
Diesmal funktioniert der Code!! ich habe ihn eingehend getestet.
Er mag vlt länger ausschauen als Kha's aber ich hab mir angewöhnt auch bei einzeiligen if's und schleifen die Klammern zu setzen.
Darum wirk mein Code etwas gigantisch gegenüber den anderen.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| int zaehler, i, altes_i, neues_i; zaehler = 1; List<int> Zahlen = new List<int> {1,2,2,3,4 };
for (i = 1; i < Zahlen.Count; i++) { neues_i = Zahlen[i]; altes_i = Zahlen[i - 1]; if ((altes_i + 1 != neues_i)&&(altes_i!=neues_i)) { break; } if (altes_i != neues_i) { zaehler++; } if (zaehler == 4) { Console.WriteLine("Es ist eine kleine Straße vorhanden"); break; } } if (zaehler != 4) { Console.WriteLine("Sie haben keine Straße gewürfelt"); } |
Kha - So 29.11.09 11:16
*Spaßbremse bin* :mrgreen:
Dieses Mal hast du meinen ersten Vorschlag wirklich exakt umgesetzt. Allerdings war der wie gesagt eben nicht ganz korrekt...
{ 1, 3, 4, 5, 6 }
@
jaenicke: :shock: Auf genau solchen Code habe ich in diesen Threads bewusst verzichtet :P .
Nun, wenn wir Higher Order Functions zulassen, würde ich meine Methode so umschreiben:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| static int GetStreetNumber(IEnumerable<int> rolls) { return rolls.Distinct().OrderBy(r => r) .Select((r, i) => r - i) .GroupBy(r => r) .Max(g => g.Count()); } |
Und für Christian noch in
Point-Free Style [
http://en.wikipedia.org/wiki/Point-free_programming] :D :
C#-Quelltext
1: 2:
| let streetNo : int seq -> int = Seq.distinct >> Seq.sort >> Seq.mapi (-) >> Seq.countBy id >> Seq.map snd >> Seq.max |
darkangel1208 - So 29.11.09 11:33
Ich glaube ich habs nun kapiert
das müsste das dann sein.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| public int strasse(int[] wurf, int art) { wurf.Distinct(); Array.Sort(wurf); int i, zaehler = 0; for (i = 0; i < 4; i++) zaehler = (wurf[i] + 1 < wurf[i + 1]) ? ((zaehler < 3) ? 0 : zaehler) : zaehler + 1 return (art == 3) ? ((zaehler > 2) ? art * 10 : 0) : ((zaehler == 4) ? art * 10 : 0); } |
wobei dann
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| zaehler = (wurf[i] + 1 < wurf[i + 1]) ? ((zaehler < 3) ? 0 : zaehler) : zaehler + 1; if (wurf[i] + 1 < wurf[i + 1]) { if (zaehler < 3) zaehler = 0; } else zaehler++; |
und
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| return (art == 3) ? ((zaehler > 2) ? art * 10 : 0) : ((zaehler == 4) ? art * 10 : 0); if (art == 3) { if (zaehler > 2) return art * 10; else return 0; } else { if (zaehler == 4) return art * 10; else return 0; } |
darkangel1208 - So 29.11.09 11:41
@ Kha
nix für ungut aber das Versteh ich ja noch weniger und dam ir die Zeit im Nacken sitzt guck ich mir das dann frühestens Mittwoch genauer an.
Denn unser Lehrer kam auf die geniale Idee allen Projekte zuzuweisen und ich soll mal in 2 Wcohen ein Kniffel proggen. Wohl gemerkt ist unsere 1. Anwendung in C# mit Forms und Klassen. Vorher gabs halt nur Konsolenanwendung und basta.
Ich arme Sau muss bis Dienstag das Teil fertig bekommen, ne Dokumentation, Bedienungsanleitung und Struktogramm erstellen. ( mal noch von den ganzen Klassenarbeiten abgesehen, die sich auch net alleine mit gut oder besser schreiben)
Und ich habe noch son paar Baustellen.
Trotzdem danke für eure Hilfe und das ihr euch soviel Zeit genommen habt :)
P.S. Ich habe noch genug andere Fragen, womit ihr euch beschäftigen könnt, wenn ihr wollt
Namenlosnameless - So 29.11.09 12:28
Du kannst gerne fragen. Ich versuch dir zu helfen -falls ich selber nicht ganz zu blöd bin-, Kha wird sicher gerne bereitstehen meine Code's zu verbessern :mrgreen: :mrgreen:
aber mach eigene Thread's dafür auf
mfg Christoph
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!