BPS #7: Viele Wege führen nach Rom - Auswertung

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Xeres

Moderator

Betreff: BPS #7: Viele Wege führen nach Rom - Auswertung

BeitragSa, Mai 07, 2011 22:46
Antworten mit Zitat
Benutzer-Profile anzeigen
So, wer kann veni vidi vici von sich behaupten?

Das war die Aufgabe

Postet hier eure Ergebnisse, Codes, Gedanken. Lernt von den anderen, seht euch deren Quelltext an und versucht euren eigenen zu verbessern.

Diskussion
Postet zu euren Codes stets eine kurze Erklärung mit euren Gedanken in denen ihr simpel gesagt die Frage "Wieso habe ich XY auf diese Art gelöst?" beantwortet. Beiträge, die nur den Code enthalten werden wir aus dem Thread entfernen.

Nächste Aufgabe
In drei Tagen, am 10. Mai, wird die Musterlösung nach editiert und die nächste Aufgabe eingestellt.

Viel Spaß & viel Erfolg!

Musterlösung:

Im Folgenden je eine längere und gekürzte Variante:
BlitzBasic: [AUSKLAPPEN]
; Römische Zahlen mittels der Einfachen Umrechnung:

Graphics(256,256,0,2)
Const M = 1000, D = 500, C = 100, L = 50, X = 10, V = 5, I = 1

Local z
For z=1 To 10
Print(RomanNumeral(z))
Next
Print(RomanNumeral(1999))
Print(RomanNumeral(2011))

WaitKey()
End

Function RomanNumeral$(zahl%)
;* Die Funktion muss mit einem $ versehen werden, damit sie einen String
;* Zurück geben kann!
;* Es gilt: M = 1000, D = 500, C = 100, L = 50, X = 10, V = 5, I = 1


;* Für die Einfache Umrechnung wird mit dem höchsten Wert begonnen:

If zahl <= 0 Then Return "N"

Local output$ = ""

Local Mz% = zahl / M ;* Wie oft passt 1000 in die Zahl?
zahl = zahl - (Mz*M) ;* Glatte tausender entfernen
output=output+String("M",Mz)

Local Dz% = zahl / D
zahl = zahl - (Dz*D)
output=output+String("D",Dz)

Local Cz% = zahl / C
zahl = zahl - (Cz*C)
output=output+String("C",Cz)

Local Lz% = zahl / L
zahl = zahl - (Lz*L)
output=output+String("L",Lz)

Local Xz% = zahl / X
zahl = zahl - (Xz*X)
output=output+String("X",Xz)

Local Vz% = zahl/ V
zahl = zahl - (Vz*V)
output=output+String("V",Vz)

Local Iz% = zahl / I
zahl = zahl - (Iz*I)
output=output+String("I",Iz)

Return output

End Function

BlitzBasic: [AUSKLAPPEN]
; Römische Zahlen mittels der Einfachen Umrechnung:

Graphics(256,256,0,2)
Dim RomSymbol$(6)
RomSymbol(0) = "I"
RomSymbol(1) = "V"
RomSymbol(2) = "X"
RomSymbol(3) = "L"
RomSymbol(4) = "C"
RomSymbol(5) = "D"
RomSymbol(6) = "M"
Dim RomNumber(6)
RomNumber(0) = 1
RomNumber(1) = 5
RomNumber(2) = 10
RomNumber(3) = 50
RomNumber(4) = 100
RomNumber(5) = 500
RomNumber(6) = 1000

Local z
For z=1 To 10
Print(RomanNumeral(z))
Next
Print(RomanNumeral(1999))
Print(RomanNumeral(2011))

WaitKey()
End

Function RomanNumeral$(zahl%)
;* Die Funktion muss mit einem $ versehen werden, damit sie einen String
;* Zurück geben kann!

;* Das selbe Verfahren nur etwas kondensierter:

If zahl <= 0 Then Return "N"

Local z, output$=""
For z=6 To 0 Step -1
Local A% = zahl / RomNumber(z)
zahl = zahl - (A*RomNumber(z))
output=output+String(RomSymbol(z),A)
Next

Return output
End Function
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
  • Zuletzt bearbeitet von Xeres am Fr, Mai 13, 2011 11:36, insgesamt einmal bearbeitet

darth

BeitragSo, Mai 08, 2011 0:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ziemlich interessante Aufgabe. Könnte einem vielleicht allg. etwas über Zahlensysteme beibringen. Allerdings hat das Römische noch einige Sonderheiten die einem üble Fallen stellen, von daher keine schlechte Wahl.

Zum Programm selber:
Ich habe einen globalen Array mit den römischen Zeichen definiert von 1-1000, und einen dezimalen der dazu gehört. Den zweiten könnte man sich theoretisch sparen, aber es wird so einfacher lesbar, deshalb hab ich das so gemacht. Man könnte die Liste ziemlich einfach auf höhere Werte ergänzen, wenn ich die Zeichen dazu kennen würde :>

Die Zahl wird Schritt für Schritt abgehaupt, dabei werden verschiedene Fälle betrachtet:
4*x hat Platz -> (x-1)x, Bsp: IV
x+4*x, Bsp: VIV -> IX
x hat Platz: I
Die eingesetzte Zahl wird abgezogen und dem String der römischen Zahl hinzugefügt.

Die Umkehrung dessen ist ziemlich straight forward. Einfach alle Zeichen auf das Resultat addieren, falls das Zeichen danach "grösser" ist, muss man subtrahieren, et voila.

BlitzBasic: [AUSKLAPPEN]
Const nSigns = 7

Global roman$[nSigns]
roman[6] = "M"
roman[5] = "D"
roman[4] = "C"
roman[3] = "L"
roman[2] = "X"
roman[1] = "V"
roman[0] = "I"

Global dec[nSigns]

dec[6] = 1000
dec[5] = 500
dec[4] = 100
dec[3] = 50
dec[2] = 10
dec[1] = 5
dec[0] = 1

Function toRoman$(n)
Local r$ = ""

Local i = nSigns -1

While i >= 0
If n >= 4 * dec[i]
If i = nSigns -1
Return "NaN"
Else
If Right(r, 1) = roman[i + 1]
; 9 -> 5 + (5 - 1) = VIV -> IX
r = Left(r, Len(r) - 1) + roman[i] + roman[i + 2]
Else
; 4 -> 5 - 1 = IV
r = r + roman[i] + roman[i + 1]
EndIf
EndIf

n = n - 4 * dec[i]
ElseIf n >= dec[i]
r = r + roman[i]

n = n - dec[i]
Else
i = i - 1
EndIf
Wend

Return r
End Function

Function toDecimal(r$)
Local n = 0

Local c1$, c2$
Local i1, i2

For j = 1 To Len(r)
c1 = Mid(r, j, 1)

For i1 = 0 To nSigns -1
If c1 = roman[i1]
Exit
EndIf
Next

If j < Len(r)
c2 = Mid(r, j+1, 1)

For i2 = 0 To nSigns -1
If c2 = roman[i2]
Exit
EndIf
Next

If i1 < i2
; IX -> -1 + 9
n = n - dec[i1]
Else
; XI -> 10 + 1
n = n + dec[i1]
EndIf
Else
; I -> +1
n = n + dec[i1]
EndIf
Next

Return n
End Function

Print toRoman(1394)
WaitKey()
Diese Signatur ist leer.
 

Tigerass

BeitragSo, Mai 08, 2011 15:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

Da ich nun wirklich ein blutiger Anfänger in Blitz bin, habe ich das Problem so gelöst:

Ich schaue, wie oft die Römische Zahl, die die lateinische Zahl ersetzten soll, in diese Passt.
Der Code sieht dann so aus:

[code]Global output$ , toconvert

gegeben=Input ("Zahl eingeben: ")
convert(gegeben) ;Aufruf der Funktion

Print (gegeben+" ist in Römischer Schreibweise:")
Print (output$)

WaitKey()
End()

;-----------------------------------------------------------
Function convert(latein)

toconvert=latein

calculate("M",1000,toconvert) ;jeden 1000er durch M ersetzen
calculate("D",500,toconvert) ;jeden 500er durch D ersetzten
calculate("C",100,toconvert) ;...
calculate("L",50,toconvert)
calculate("X",10,toconvert)
calculate("V",5,toconvert)

printoutput("I",toconvert) ;Den Rest kann man so in den Output schreiben, da kleiner als 4

End Function
;-----------------------------------------------------------
Function calculate(char$,amount,latein)

div# = latein / amount ;Zahlen teilen und dann die Vorkommazahl verwenden
nummer = (Asc(div#) - 48) ;dafür gibt es sicherlich einen besseren Befehl
printoutput(char$, nummer) ;Römische zahlen x mal in den Output schreiben
toconvert = toconvert - (amount * nummer) ;Menge von der übersetzten Römischen Zahl abziehen

End Function
;-----------------------------------------------------------
Function printoutput(char$,amount)

For n = 1 To amount
output$ = output$ + char$ ;Römische Zahl an den Output anhängen
Next

End Function
;-----------------------------------------------------------[/code]

Sicher nicht das beste und es funktioniert nur bis zu den Zahlen 9999 wegen Asc.

Xeres

Moderator

BeitragDi, Mai 10, 2011 10:13
Antworten mit Zitat
Benutzer-Profile anzeigen
@Tigerass: Leider kann man in BlitzBasic Funktionen nicht verschachteln, aber ich hätte die Verwendung von Return statt einer Globalen Variable besser gefunden.

Auch fände ich es bei beiden Lösungen nett, die Probe-Zahlen nicht komplett zu unterschlagen.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

darth

BeitragDi, Mai 10, 2011 11:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

*seufz*, wie pingelig..
Aber bitte, ich will ja nicht böse sein Smile

BlitzBasic: [AUSKLAPPEN]
; TEST

For i = 1 To 10
Print i +" -> "+ toRoman(i)
Next

Print 1999 +" -> "+toRoman(1999)
Print 2011 +" -> "+toRoman(2011)

WaitKey()


Tadaaaa..

MfG,
Darth
Diese Signatur ist leer.

Dice of Darkness

BeitragDi, Mai 10, 2011 21:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo zusammen,

ist zwar schon etwas später, aber ich wollte meine Lösung auch noch einmal präsentieren:

Code: [AUSKLAPPEN]
AppTitle "BPS 7 - Römische Zahlendarstellung"

Graphics 800,600,16,2
;SetBuffer BackBuffer()

Dim roemische_zahlen(13)   ;13 verschiedene Werte, siehe unten

roemische_zahlen(0) = 1
roemische_zahlen(1) = 4      ;subtraktiv: IV (eins vor fünf)
roemische_zahlen(2) = 5
roemische_zahlen(3) = 9      ;subtraktiv: IX (eins vor zehn)
roemische_zahlen(4) = 10
roemische_zahlen(5) = 40   ;subtraktiv: XL (zehn vor fünfzig)
roemische_zahlen(6) = 50
roemische_zahlen(7) = 90   ;subtraktiv: XC (zehn vor hundert)
roemische_zahlen(8) = 100
roemische_zahlen(9) = 400   ;subtraktiv: CD (hundert vor fünfhundert)
roemische_zahlen(10) = 500
roemische_zahlen(11) = 900   ;subtraktiv: CM (hundert vor tausend)
roemische_zahlen(12) = 1000


Dim roemisches_zeichen$(12)     ;die zu den 13 römischen Zahlen gehörigen Zeichen

roemisches_zeichen$(0) = "I"
roemisches_zeichen$(1) = "IV"
roemisches_zeichen$(2) = "V"
roemisches_zeichen$(3) = "IX"
roemisches_zeichen$(4) = "X"
roemisches_zeichen$(5) = "XL"
roemisches_zeichen$(6) = "L"
roemisches_zeichen$(7) = "XC"
roemisches_zeichen$(8) = "C"
roemisches_zeichen$(9) = "CD"
roemisches_zeichen$(10) = "D"
roemisches_zeichen$(11) = "CM"
roemisches_zeichen$(12) = "M"


;Zahlen in Dezimalschreibweise, die wir umrechnen lassen wollen
Dim dezimalzahlen(11)

dezimalzahlen(0) = 1
dezimalzahlen(1) = 2
dezimalzahlen(2) = 3
dezimalzahlen(3) = 4
dezimalzahlen(4) = 5
dezimalzahlen(5) = 6
dezimalzahlen(6) = 7
dezimalzahlen(7) = 8
dezimalzahlen(8) = 9
dezimalzahlen(9) = 10
dezimalzahlen(10) = 1999
dezimalzahlen(11) = 2011

;alle Zahlen als römische Zahlen ausgeben lassen
For i=0 To 11
   BerechneRoemischeZahl(dezimalzahlen(i))
Next

WaitKey()
End


Function BerechneRoemischeZahl(parameter)
   
   Local roemischerString$                     ;ein String, der am Ende das fertige Zahlzeichen beinhaltet
   Local parameterFuerAlgorithmus = parameter      ;mit dem übergebenen Parameter müssen wir rechnen
   
   ;Wir können nur Zahlen zwischen 1 und 3999 umwandeln!
   If parameter < 1 Or parameter > 3999 Then
      Print "Ungültiger Wert! Bitte eine Zahl zwischen 1 und 3999 zur Umrechnung wählen!"
      Return   ;abbrechen
   EndIf
   
   ; Wir benutzen einen "gierigen Algorithmus", um alle benötigten Zahlzeichen zu ermitteln.
   ; Das heißt, wir betrachten die Zahl und gucken, welches der höchste Wert aus unserem Array
   ; "roemische_zahlen" ist, der kleiner oder gleich groß ist wie der Funktions-Parameter.
   ; Diesen Wert "addieren" wir als String auf "roemischerString" drauf und ziehen den Zahlenwert
   ; vom Algorithmus-Parameter ab. Das ganze wiederholen wir so lange, bis dieser Parameter null wird.
   While parameterFuerAlgorithmus > 0
      
      For x=12 To 0 Step -1                                    ;Rückwärts, da wir beim höchsten möglichen Wert anfangen müssen
         If parameterFuerAlgorithmus >= roemische_zahlen(x) Then
            roemischerString$=roemischerString$+roemisches_zeichen$(x)      ;Zeichen in den String einbauen
            parameterFuerAlgorithmus = parameterFuerAlgorithmus - roemische_zahlen(x)
            Exit
         EndIf
      Next
      
   Wend
   
   Print "Die Zahl "+parameter+" sieht in römischer Schreibweise wie folgt aus: "+roemischerString
   
End Function


Man könnte sagen, ich habe ein wenig "geschummelt", weil ich einfach die Zahlen mit subtraktiver Darstellung als einen ganzen String verwendet habe und es mir somit ersparen konnte, eine eigene Funktion dafür zu schreiben^^. Eigentlich wollte ich noch eine Eingabe-Funktion machen, dass man beliebige Dezimalwerte eintippen und umrechnen lassen kann, aber das hab ich nicht mehr geschafft.


MfG, Dice
Gratis Spiele, Musik, Tools

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group