Fischer-Bayern.de
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen   RegistrierenRegistrieren 
 ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Römische und arabische Zahlen

 
Neues Thema eröffnen   Neue Antwort erstellen    Fischer-Bayern.de Foren-Übersicht -> OS X-Snippets
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 26.07.2007 - 21:44    Titel: Römische und arabische Zahlen Antworten mit Zitat

Hallo zusammen,

nachdem das Niveau in diesem Forum in letzter Zeit ziemlich gesunken ist (will ja nicht rumätzen oder mich über etwas stellen, aber ich frage mich wirklich, ob das sein muß und was das und vor allem wem das dienlich sein soll...!), stelle ich mal was neues ein.

Habe mich heute gefragt, wie wohl Programme wie XPress und InDesign bei der Seitenpaginierung intern vorgehen, wenn der Nutzer römische Paginierung auswählt.
Ausgangspunkt war, daß ich die Dateien eines Prospektes spaßeshalber römisch paginieren wollte (nur acht Seiten), es dann aber doch arabisch (also Hilfspagina) gelassen habe, da der Renamer4Mac interessanter Weise keine römischen Zahlen kann (wohl aber A, B, C...). Ob so ein Algorithmus schwierig war?

Nach diverser Internetrecherche und nur wenigen Ansätzen, die laut Bekunden alle kompliziert sind, habe ich es selbst neu versucht und finde, eine vor allem kurze und sehr effektive Methode gefunden zu haben.

Folgende zwei Handler habe ich erstellt:

Code:
on arab2rom(zahl, minomax) -- © Copyright 26.7.2007 by Martin Wolter, martin_wolter@gmx.de
   set romzahl to ""
   if minomax is false then
      set romliste to {"m", 1000, "d", 500, "c", 100, "l", 50, "x", 10, "v", 5, "i", 1}
   else
      set romliste to {"M", 1000, "D", 500, "C", 100, "L", 50, "X", 10, "V", 5, "I", 1}
   end if
   repeat with i from 1 to (count items of romliste) by 2
      set zeichen to item i of romliste
      set wert to item (i + 1) of romliste
      repeat until zahl < wert
         set romzahl to romzahl & zeichen
         set zahl to zahl - wert
      end repeat
   end repeat
   if minomax is false then
      set romzahl to do shell script "echo " & romzahl & " | sed -e 's/dcccc/cm/g' -e 's/cccc/cd/g' -e 's/lxxxx/xc/g' -e 's/xxxx/xl/g' -e 's/viiii/ix/g' -e 's/iiii/iv/g'"
   else
      set romzahl to do shell script "echo " & romzahl & " | sed -e 's/DCCCC/CM/g' -e 's/CCCC/CD/g' -e 's/LXXXX/XC/g' -e 's/XXXX/XL/g' -e 's/VIIII/IX/g' -e 's/IIII/IV/g'"
   end if
   return romzahl
end arab2rom


und das Gegenstück, zur Rückwandlung:

Code:
on rom2arab(romzahl) -- © Copyright 26.7.2007 by Martin Wolter, martin_wolter@gmx.de
   set zahl to 0
   set romzahl to do shell script "echo " & romzahl & " | sed -e 'y/mdclxvi/MDCLXVI/' -e 's/CM/DCCCC/g' -e 's/CD/CCCC/g' -e 's/XC/LXXXX/g' -e 's/XL/XXXX/g' -e 's/IX/VIIII/g' -e 's/IV/IIII/g'"
   set romliste to {"M", 1000, "D", 500, "C", 100, "L", 50, "X", 10, "V", 5, "I", 1}
   repeat with i from 1 to (count items of romliste) by 2
      set my text item delimiters to (item i of romliste)
      set zahl to zahl + ((count of text items of romzahl) - 1) * (item (i + 1) of romliste)
   end repeat
   return zahl
end rom2arab


Was meint Ihr? Geht es noch kürzer oder hättet Ihr es anders gemacht?

Ich bin damit nach ausgiebigen Tests erstmal sehr zufrieden.
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Skeeve
•---->
•---->


Anmeldedatum: 20.04.2006
Beiträge: 1068

BeitragVerfasst am: 30.07.2007 - 22:23    Titel: Antworten mit Zitat

Mit reinem AppleScript (Hin-Richtung)
Zitat:
on arab2rom(zahl, lower)
   if lower then
      set rom_chr to characters of "ivxlcdm"
   else
      set rom_chr to characters of "IVXLCDM"
   end if
   set rom_pat to {"0", "00", "000", "01", "1", "10", "100", "1000", "02"}
   set rom to ""
   set d to 1000
   set f to zahl div d
   set zahl to zahl - f * d
   repeat while f > 0
      set rom to rom & item 7 of rom_chr
      set f to f - 1
   end repeat
   set i to 5
   repeat while d > 1
      set d to d / 10
      set f to zahl div d
      if f > 0 then
         set zahl to zahl - f * d
         repeat with o in every character of item f of rom_pat
            set rom to rom & item (i + o) of rom_chr
         end repeat
      end if
      set i to i - 2
   end repeat
   return rom
end arab2rom

_________________
"All problems are solved in slightly less than half an hour" (Chumbawamba, "Hey Hey We're The Junkies")
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Wolle-77
•--->
•--->


Anmeldedatum: 25.02.2003
Beiträge: 447
Wohnort: Geldern

BeitragVerfasst am: 28.02.2008 - 15:00    Titel: Die Wiederentdeckung des reinen AppleScript's Antworten mit Zitat

So, nach langer Zeit habe ich heute tatsächlich mal meinen handler gebrauch, es ging darum, ein kleines Werk umzupaginieren.

Und die DTP ist dann zu mir gekommen, da der Renamer4Mac diese Funktion nicht bietet.

Während das Werk ruckzuck damit bearbeitet war (aber was heißt schon ruckzuck…?), habe ich noch etwas über den handler nachgedacht und da ich auch schon dem Entwickler von Renamer4Mac diesen geschickt habe und der sich aber nicht gemeldet habe, meinte mein Kollege nur, daß er für den Renamer evtl. zu langsam ist – und mit einem Test von 7.000 Durchläufen kam ich auch auf unglaublich lange 57 Sekunden (nicht repräsentativ, iMac 24 ").

Das ist echt zu lange. Und der Kollege meinte auch nur, als C-Programm wäre sowas rasend schnell und ein Klacks; selbst bei 100.000 Durchläufen (damit bin ich angefangen und habe aber auf 7.000 reduziert, da es einfach zu lange dauerte).

Dann hat er tatsächlich eine kleine C-Routine gefunden (499 Byte), die mit gcc kompiliert zu einem 16 KB kleinen Shell-Programm auch via do shell script aufrufbar war.

Und die große Überraschung (zu meiner Genugtuung, erstmal): Es dauerte ganze 8 Sekunden länger, nämlich 65 Sekunden.

Und eine Kupplung zu do shell habe ich ja auch drin in meinem obigen Originalhandler. Also was dauert es soviel länger?


Naja, aber der Kern der Sache ist, in der C-Routine war ein anderer Ansatz: Anstatt erstmal mit den 7 eigentlichen Zahlen (M, D, C, L, X, V, I) zu verfahren und anschließend diese noch um die Sonderfälle CM, CD, XC, XL, IX und IV zu reduzieren, wurde dort direkt das gleiche Prinzip der so-lange-Reduzierens-bis-der-Wert-kleiner-als-die-noch-verbliebene-Zahl-ist-Methode angewendet.

Also: Warum brauche ich da noch die shell, um sed zum Such-Tausch zu benutzen?

So gerne ich diese in den letzten Monaten benutze und fast ohne nicht mehr auskam, so habe ich mir meinen handler noch einmal vorgenommen.


Hier das Ergebnis:

Code:
on arab2rom(zahl) -- © Copyright 26.7.2007 by Martin Wolter, martin_wolter@gmx.de
   set romzahl to ""
   set romliste to {"M", 1000, "CM", 900, "D", 500, "CD", 400, "C", 100, "XC", 90, "L", 50, "XL", 40, "X", 10, "IX", 9, "V", 5, "IV", 4, "I", 1}
   repeat with i from 1 to 26 by 2
      set zeichen to item i of romliste
      set wert to item (i + 1) of romliste
      if zahl is greater than or equal to wert then
         repeat until zahl < wert
            set romzahl to romzahl & zeichen
            set zahl to zahl - wert
         end repeat
      end if
   end repeat
   return romzahl
end arab2rom


Voilá! Extrem kurz vom Quellcode und die 7000 Durchläufe schafft er in ca. 1 Sekunde! Also, äh, @Skeeve: Deinen damals als Antwort geposteten handler verstehe ich erstens nicht so richtig und zweitens braucht der 8 Sekunden…

Sehr schön!

Man könnte die if-Abfrage im ersten repeat auch noch weglassen, aber ich glaube, damit kann man auch bestimmte Zahlen wie 10001 noch schneller abarbeiten, da ja gar nicht erst geprüft wird, ob die 900 abgezogen werden kann oder so.
_________________
Martin Wolter
--
Apple rocks the planet!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Skeeve
•---->
•---->


Anmeldedatum: 20.04.2006
Beiträge: 1068

BeitragVerfasst am: 28.02.2008 - 19:04    Titel: Antworten mit Zitat

Hier mal mit Erläuterungen:
Zitat:
arab2rom(1998, false)

on arab2rom(zahl, lower)
   -- legen den "Zeichensatz" fest
   if lower then
      set rom_chr to characters of "ivxlcdm"
   else
      set rom_chr to characters of "IVXLCDM"
   end if
   -- Definiere "Muster" für die Ziffern 1-9
   -- item of ZIFFER liefert das Muster
   -- Das gibt an, welches römische Zeichen zu nehmen ist
   -- 0= das aktuelle
   -- 1= das nächste (also rechts davon)
   -- 2= das übernächste
   set rom_pat to {"0", "00", "000", "01", "1", "10", "100", "1000", "02"}
   -- römische Zahl initialisieren
   set rom to ""
   -- 1000 ist die größte römische Zahl, wenn wir nicht
   -- mit "Strichen" arbeiten wollen oder können.
   -- 4000 wird also zu MMMM
   set d to 1000
   
   -- Ermittle wieviele 1000er vorkommen
   set f to zahl div d
   -- und merk Dir den Rest, also 1998 -> 998
   set zahl to zahl - f * d
   -- Einfache Schleife um soviele Ms hintereinander
   -- zu hängen, bis wir genug haben
   (* alt
repeat while f > 0
set rom to rom & item 7 of rom_chr
set f to f - 1
end repeat
*)
   -- neu
   set rom_zif to item 7 of rom_chr
   repeat f times
      set rom to rom & rom_zif
   end repeat
   -- alles kleiner 1000 also den rest) abarbeiten
   -- Grundzeichen festlegen.
   -- wir starten also mit "C"
   set i to 5
   repeat while d > 1
      -- damit wird die Stelle um eins nach rechts
      -- verschoben.
      -- Wir arbeiten also erst die 100er ab,
      -- dann die 10er und zuletzt die 1er
      set d to d div 10
      -- hier wieder die Ziffer holen wie
      set f to zahl div d
      -- wenn es eine Ziffer von 0-9 ist
      if f > 0 then
         -- ermittle den Rest
         set zahl to zahl - f * d
         -- und hole Dir das Muster
         -- Arbeite jedes Zeichen des Musters ab
         repeat with o in every character of item f of rom_pat
            -- hänge einfach das Grundzeichen
            -- (item i) hinten an. Es wird
            -- zum Grundzeichen noch der Offset (o)
            -- addiert. Der ist 0, 1 oder 2
            set rom to rom & item (i + o) of rom_chr
         end repeat
      end if
      -- Grundzeichen verschieben
      set i to i - 2
   end repeat
   -- das war's
   return rom
end arab2rom


Ein Beispiellauf:
Code:

rom_chr:I, V, X, L, C, D, M
rom_pat:0, 00, 000, 01, 1, 10, 100, 1000, 02
rom:
d:1000
f:1
zahl:998
rom_zif:M
repeat:1
   rom:M
i:5
repeat:1000
   d:100
   f:9
   i:5
   zahl:98
   o:0
      rom:MC
   o:2
      rom:MCM
i:3
repeat:100
   d:10
   f:9
   i:3
   zahl:8
   o:0
      rom:MCMX
   o:2
      rom:MCMXC
i:1
repeat:10
   d:1
   f:8
   i:1
   zahl:0
   o:1
      rom:MCMXCV
   o:0
      rom:MCMXCVI
   o:0
      rom:MCMXCVII
   o:0
      rom:MCMXCVIII
i:-1

_________________
"All problems are solved in slightly less than half an hour" (Chumbawamba, "Hey Hey We're The Junkies")


Zuletzt bearbeitet von Skeeve am 28.02.2008 - 19:25, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Skeeve
•---->
•---->


Anmeldedatum: 20.04.2006
Beiträge: 1068

BeitragVerfasst am: 28.02.2008 - 19:20    Titel: Antworten mit Zitat

Du hast eine if Abfrage zuviel.

Hier aber mal 2 überarbeitete Varianten Deines Handlers. Teste doch mal unter gleichen Bedingungen.

Variante 1 mit zerissenen Listen hat Folgendes geschrieben:
arab2rom(1998)
on arab2rom(zahl)
   set romzahl to ""
   set romliste to {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
   set romwerte to {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
   set i to 1
   repeat with zeichen in romliste
      set wert to item i of romwerte
      repeat until zahl < wert
         set romzahl to romzahl & zeichen
         set zahl to zahl - wert
      end repeat
      set i to i + 1
   end repeat
   return romzahl
end arab2rom


Variante 2 mit tupeln hat Folgendes geschrieben:
arab2rom(1998)
on arab2rom(zahl)
   set romzahl to ""
   set romliste to {{"M", 1000}, {"CM", 900}, {"D", 500}, {"CD", 400}, {"C", 100}, {"XC", 90}, {"L", 50}, {"XL", 40}, {"X", 10}, {"IX", 9}, {"V", 5}, {"IV", 4}, {"I", 1}}
   repeat with tupel in romliste
      set {zeichen, wert} to tupel
      repeat until zahl < wert
         set romzahl to romzahl & zeichen
         set zahl to zahl - wert
      end repeat
   end repeat
   return romzahl
end arab2rom

_________________
"All problems are solved in slightly less than half an hour" (Chumbawamba, "Hey Hey We're The Junkies")
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Fischer-Bayern.de Foren-Übersicht -> OS X-Snippets Alle Zeiten sind GMT + 2 Stunden
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2002 phpBB Group
Deutsche Übersetzung von phpBB.de


AppleScript für absolute Starter