Dec2Rome() »»» Dezimalzahlen in römische Zahlen umwandeln

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Dec2Rome() »»» Dezimalzahlen in römische Zahlen umwandeln

Beitrag von AND51 »

[Beitrag komplett überarbeitet]


Hallo!

Mein Weihnachtsgeschenk an euch: Einen funktionierenden Code, der arabische Dezimalsazahlen >=1 in römische Zahlen umwandelt.
Funktioniert garantiert richtig!

Würde mich freuen, wenn dieser Thread wieder auflebt und ihr vielleicht performantere Versionen postet!
Die Handhabung ist denkbar einfach: Oben steckt man einen positiven Quad rein, unten kommt die zahl in römischer Schreibweise wieder heraus. <)

Code: Alles auswählen

Procedure.s Dec2Rome(number.q) ; AND51 / Dec-2007
	Protected result.s, temp=number/1000
	If temp > 0 ;{ thounsand's
		result=Space(temp)
		ReplaceString(result, " ", "M", 2)
		number-temp*1000
	EndIf ;}
	While number > 99 ;{ hundred's
		temp=number/100
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "C", 2)
			Case 4
				result+"CD"
			Case 5 To 8
				result+"D"
				temp=5
			Case 9
				result+"CM"
		EndSelect
		number-temp*100
	Wend ;}
	While number > 9 ;{ ten's
		temp=number/10
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "X", 2)
			Case 4
				result+"XL"
			Case 5 To 8
				result+"L"
				temp=5
			Case 9
				result+"XC"
		EndSelect
		number-temp*10
	Wend ;}
	While number ;{ one's
		temp=number
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "I", 2)
			Case 4
				result+"IV"
			Case 5 To 8
				result+"V"
				temp=5
			Case 9
				result+"IX"
		EndSelect
		number-temp
	Wend ;}
	ProcedureReturn result
EndProcedure


For n=30 To 230 Step 21
	Debug Str(n)+" to rome: "+Dec2Rome(n)
Nextt
Viel Spaß damit! :allright:
Zuletzt geändert von AND51 am 24.12.2007 03:39, insgesamt 1-mal geändert.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
D@nte
Beiträge: 324
Registriert: 24.04.2007 15:33
Wohnort: Berlin

Beitrag von D@nte »

OMFG AND -.-

Setzen (IX - IV + I)

4 = IV (5 - 1)
9 = IX (10 - 1)

Nette Idee aber in dem Fall noch stark verbesserungswürdig das gilt nämlich noch für'n paar Zahlen mehr...

90 = XC (100 - 10) etc pp
Da haste nen Umrechner ;p

In diesem Sinne
Errare humanum est
oder
veni, vidi, amitti
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Ja, du hast Recht! Danke für deinen Beitrag!!
Ich habe gerade eine Webseite gefunden, die das sher gut erklärt.
Jetzt habe ich es (hoffentlich) verstanden. Bis dahin dürft ihr aber ruhig auch was posten! :allright:

// Edit: Lese gerade auf Wikipedia, dass meine Darstellung doch korrekt ist. Die von D@nte angesprochene Schreibweise ist lediglich eine verkürzende Schreibweise; dennoch ist beides möglich: Wikipedia - Römische Zahlen
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

AND51 hat geschrieben:// Edit: Lese gerade auf Wikipedia, dass meine Darstellung doch korrekt ist. Die von D@nte angesprochene Schreibweise ist lediglich eine verkürzende Schreibweise; dennoch ist beides möglich: Wikipedia - Römische Zahlen
OMFG

...meine güte... wer hat denn diesen beitrag geschrieben...
das ist ja ein riesen-sermon...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Laurin
Beiträge: 1639
Registriert: 23.09.2004 18:04
Wohnort: /dev/eth0

Beitrag von Laurin »

Jepp und die reden laufend von Etruskern und Griechen. Das hätte man besser in einen extra Abschnitt untergebracht.
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
Benutzeravatar
D@nte
Beiträge: 324
Registriert: 24.04.2007 15:33
Wohnort: Berlin

Beitrag von D@nte »

ok, ich werd jetzt aber nicht sagen:
"ich nehm alles zurück und behaupte das Gegenteil"

Deine Darstellung der 4 als IIII ist auch richtig, hab zwar im Internet keine Quelle ausser wiki gefunden die 4 als IIII und nicht als IV darstellt gefunden, aber mein alte Wanduhr im Keller hat auch die IIII als 4. ;)
Allerdings wird auch in der Schule gelehrt das die römische Ziffer(nfolge) IV für 4 steht, deshalb hab ich auch nit weiter drüber nachgedacht als ich gepostet hab. Dementsprechend ist m.E. nach IV die einzige richtige Schreibweise für 4...

Könntest das Programm natürlich für nervensäge wie mich um die zwei anderen römischen Schreibweisen erweitern...
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> aber mein alte Wanduhr im Keller hat auch die IIII als 4.

das kenne ich auch, aber da bin ich davon ausgegangen, dass es deshalb ist,
weil die VI (&) meist auf dem kopf steht, damit man die beiden nicht verwechselt.

...die 9 wird ja grundsätzlich auf der uhr als IX geschrieben, nicht als VIIII, obwohl die XI auch dabei ist...

also, vorn un hinne inkonsistent, typisch mensch.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Hallo!

Als Weihnachtsgeschenk an euch alle ein garantiert funktionierender Code, der jegliche, positive Quad-Zahl in römischer Schreibweise ausgibt:

Code: Alles auswählen

Procedure.s Dec2Rome(number.q) ; AND51 / Dec-2007
	Protected result.s, temp=number/1000
	If temp > 0 ;{ thounsand's
		result=Space(temp)
		ReplaceString(result, " ", "M", 2)
		number-temp*1000
	EndIf ;}
	While number > 99 ;{ hundred's
		temp=number/100
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "C", 2)
			Case 4
				result+"CD"
			Case 5 To 8
				result+"D"
				temp=5
			Case 9
				result+"CM"
		EndSelect
		number-temp*100
	Wend ;}
	While number > 9 ;{ ten's
		temp=number/10
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "X", 2)
			Case 4
				result+"XL"
			Case 5 To 8
				result+"L"
				temp=5
			Case 9
				result+"XC"
		EndSelect
		number-temp*10
	Wend ;}
	While number ;{ one's
		temp=number
		Select temp
			Case 1 To 3
				result+Space(temp)
				ReplaceString(result, " ", "I", 2)
			Case 4
				result+"IV"
			Case 5 To 8
				result+"V"
				temp=5
			Case 9
				result+"IX"
		EndSelect
		number-temp
	Wend ;}
	ProcedureReturn result
EndProcedure

For n=30 To 230 Step 21
	Debug Str(n)+" to rome: "+Dec2Rome(n)
Next
Viel Spaß damit! :allright:
Würde mich freuen, wenn optimiertere/performantere Versionen hier auftauchen würden!

@ Andre:
Könnte man diesen Code vielleicht ins CodeArchiv aufnehmen?
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

Hier mal meine Versionen ...

Meine war ja auch vor ANDy51s fertig :mrgreen:

Da es im römischen anscheinend nur 3999 Zahlen gibt, könnte man auch eine Tabelle erzeugen, vielleicht sogar per Hand und je nach dem, welche Zahl der Benutzer gern haben möchte, wird einfach an der Stelle in der Tabelle geschaut. :mrgreen:

Mit Anleitung. Prozeduren müsst ihr selbst draus machen :D

Funktionen für
arabisch zu römisch und
römisch zu arabisch

Das meiste an dem Code sind die Kommentare

Code: Alles auswählen

;/ Folker Linstedt
;/ 2007|12|23
;/ arabische Zahlen in römische Zahlen umwandeln


; I = 1, II = 2, III = 3, IV = 4, V = 5, VI = 6, VII = 7, VIII = 8, 9 = IX, 10 = X,
; XI = 11, XII = 12, ... 19 = XIX aber nicht IXX

; XXXIX = 39

;/ Regeln:
; - 5er können nicht addiert werden. 
; - 1er können maximal drei addiert werden! Beachte 39, 390, 3900
; - 1er kann höchstens einer abgezogen werden
; - es können einer nur von 5er gleicher Ordnung oder 1ern einer Ordnung höher abgezogen werden
; - es können gleichzeitig keine 1er addiert und subtraiert werden (entweder oder)

;/ maximale Zahl: MMMCMXCIX - 3999

;/ oft verwendete Zahl : MCMXCIX - 1999 (Jahr-2000-Problem Y2K)

;           1 = I
;  5 = V,  10 = X
; 50 = L, 100 = C,
;500 = D,1000 = M,    

;/ http://www.mathematische-basteleien.de/roemisch.htm


;/ 


Z$="2548" ;/ Beispiel-Zahl

;/ erwartetes Ergebnis: MMDXLVIII

R$="" ;/ römische Zahl

;/ Ansatz 1
; Z=Val(Z$)
; R$=RSet("",Z / 1000 ,"M")

;/ Ansatz 2
Dim R.s(4)

Procedure.s RepStr(R1$="",R2$="L",R3$="C")
  Sx$="I;II;III;IV;V;VI;VII;VIII;IX"
  If R1$
    Sx$=ReplaceString(Sx$,"X",R3$)
    Sx$=ReplaceString(Sx$,"V",R2$)
    Sx$=ReplaceString(Sx$,"I",R1$)
  EndIf
  ProcedureReturn Sx$
EndProcedure


R(1)=RepStr()
R(2)=RepStr("X")
R(3)=RepStr("C","D","M")
R(4)=RepStr("M","Y","K") ;/ geht erstmal nur für "M"

 Z$=InputRequester("Zahl eingeben","arabische Zahl","123")

If Val(Z$)<4000

  ;/ dieser Block erstellt römische Zahlen
  L=Len(Z$)  
  For i=1 to L
     R$+StringField(R(L+1-i),Val(Mid(Z$,i,1)),";")
  Next
  ;/


 MessageRequester("Ausgabe","arabische Zahl: "+Z$+" entspricht römischer Zahl: "+R$)


Else
  MessageRequester("HINWEIS","Diese Zahl ("+Z$+") kann nicht römisch dargestellt werden")
EndIf

;/ umgekehrt ...

Z$=InputRequester("Zahl eingeben","römische Zahl","DCCXXXIX") ; MCMXCIX

;/ Ansatz : Alle Zahlen addieren bzw. Abziehen und das Ergebnis wieder in römische Zahl wandeln und Strings vergleichen.

Z$=Trim(Z$)
;/ Groß-Kleinschreibung-Umwandlung eventuell ...

R$=Z$
Z=0

For h=1 to 4 
  For i=1 to 9
    SxF$=StringField(R(h),10-i,";")
    G=FindString(Z$,SxF$,1) 
    If G
      Z$=ReplaceString(Z$,SxF$,"") 
      Z+Pow(10,(h-1))*(10-i)
      
    EndIf
  Next
Next

Z$=Str(Z)
D$=""
  ;/ dieser Block erstellt römische Zahlen
  L=Len(Z$)  
  For i=1 to L
    D$+StringField(R(L+1-i),Val(Mid(Z$,i,1)),";")
  Next
  ;/
If D$=R$
  MessageRequester("Ausgabe","römische Zahl: "+R$+" entspricht arabischer Zahl: "+Str(Z))
Else
  MessageRequester("Hinweis : Fehler bei der Eingabe!",Str(Z)+" : Ihre Eingabe: "+R$+Chr(10)+" - Mögliches Ergebnis: "+D$) 
EndIf  
:allright: Frohes Weihnachtsfest und guten Rutsch :allright:
Kinder an die Macht http://scratch.mit.edu/
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

> Da es im römischen anscheinend nur 3999 Zahlen gibt
Das konnte ich jetzt nicht nachvollziehen, auch wenn das irgendwo steht. Z. B. eine römische Legion war eine Truppe von 6000 Mann. Wie können die da nur bis 3999 zählen?
Mein Code stellt halt jeder Tausend ein 'M' voran, dann passt das schon - notfalls achtet der Coder eben selbst darauf, dass er keine Zahlen >3999 übergibt.

> könnte man auch eine Tabelle erzeugen
Das würde IMHO zu viel Speicher beanspruchen, sowohl in der EXe als auch zur Laufzeit im Speicher. AUßerdem hat man eben das Problem: Wenn jemand sagt: "Ich will aber Zahlen >3999!", dann kriegt man das mit einer Tabelle (Array) nicht hin, da der Zahlenbereich zu begrenzt ist.

> vielleicht sogar per Hand [erzeugen]
Wieso? Du hast doch meinen Code...

> und je nach dem, welche Zahl der Benutzer gern haben möchte, wird einfach an der Stelle in der Tabelle geschaut.
Das müsste man dann noch nicht einmal in einer Prozedur machen, es reicht auch schon ein globales Array, auf das man im weiteren Programmverlauf zugreift.

> Prozeduren müsst ihr selbst draus machen
Das ist ja eigentlich die Aufgabe des Posters... :D
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Antworten