Převod římských čísel na arabská a naopak

Předobrazem tohoto tématu úplně poprvé v dějinách stránek RPNmania není předchozí řešení pro nějaký RPN kalkulátor. Tentokrát se jedná o RPL program napsaný z voleje pro HP-50g.



Zdrojový text

  

Upřímně řečeno, tak úplně z voleje to není. Popis prvního zde zveřejněného RPL programu totiž naznačuje, že srozumitelnost RPL kódu není zrovna nejvyšší. Další v pořadí si vypomáhá zdrojovým kódem v "Céčku". A protože osvědčené postupy by se neměly měnit, i zde je na vysvětlenou krátký program v jazyku C. Celý je obsažen v jediném modulu roman.c. (Eventuálním čtenářům se prudce doporučuje zevrubná prohlídka tohoto souboru před započetím studia objektu ROMAN. V dalším povídání je se znalostí zmíněného programového modulu počítáno.)

Zde již výpis RPL kódu:

ROMAN
« DUP TYPE
  IF DUP 28. ==
  THEN DROP I→R
    IF DUPDUP 1. < SWAP 3999. > OR
    THEN "Bad Range: " SWAP →STR + DOERR
    END 0.
  ELSE
    CASE DUP 2. ==
      THEN
      END DUP 6. ==
      THEN SWAP →STR DUP SIZE 1. - 2. SWAP SUB SWAP
      END DROP "Bad Argument: " SWAP + DOERR
    END
  END "IVXLCDM" → sromt
  «
    IF
    THEN { 1. 5. 10. 50. 100. 500. 1000. } { } → svalt result
      «
        DO DUP HEAD sromt SWAP POS DUP
          IF NOT
          THEN DROP "Unknown Digit: " SWAP + DOERR
          END svalt SWAP GET → cval
          « 'result' cval STO+ result 1.
            « ABS cval <
            » DOLIST 0. + ∑LIST DUP
            IF 2. ≥
            THEN DROP "Unexpected Digit: " SWAP + DOERR
            END
            IF
            THEN 'result' result SIZE 1. - DUP2 GET NEG PUT
            END
          »
        UNTIL TAIL DUP SIZE NOT
        END DROP result 0. + ∑LIST R→I
      »
    ELSE 1000. sromt SIZE "" → divisor sidx result
      «
        DO DUP divisor / IP DUP UNROT divisor * - SWAP
          IF DUPDUP 4. == SWAP 9. == OR
          THEN 'result' sromt sidx DUP SUB STO+ 'result' sromt ROT 9. == 1. + sidx + DUP SUB STO+
          ELSE
            WHILE DUP
            REPEAT sidx OVER
              IF 5. ≥
              THEN 1. + SWAP 4. - SWAP
              END DUP sromt UNROT SUB 'result' SWAP STO+ 1. -
            END DROP
          END 'sidx' 2. STO-
        UNTIL divisor 10. / IP DUP 'divisor' STO NOT
        END DROP result
      »
    END
  »
»

Zajímavosti v řešení

  

Podrobně rozebírat program zabírající několik řádků textu je určitě zbytečné. Přesto obsahuje dvě finesy (první je docela pěkná, ta druhá fakt hodně blbá; obě v části převodu římských čísel na arabská), na které stojí za to poukázat.

  1. V řešení v jazyku C je pomocná funkce roman_prevlessnum() sloužící ke spočítání předchozích číslic s menší hodnotou, než má číslice aktuálně vyhodnocovaná. Funkce "měří" dvacet řádků, není tedy rozsahem zanedbatelná. Totéž, co tato funkce, v notaci RPL provádí sekvence result 1. « ABS cval < » DOLIST 0. + ∑LIST.
  2. Výskytům příkazu ∑LIST vždy předchází 0. +. Je to divná berlička nahrazující neschopnost spočítat součet prvků seznamu, obsahuje-li tento pouze jeden prvek. Není to nic moc, ale asi to stojí menší "sádlo", než sekvence IF DUP SIZE 1. > THEN ∑LIST ELSE 1. GET END.


Použití programu

  

Stejně jako v minulém případě nemá smyslu ztrácet čas povídáním. Stačí zadat jednu ze dvou možných hodnot:

Stisk Soft KEY ROMAN (po předchozím VAR v adresáři obsahujícím proměnnou ROMAN) má za následek vložení převedené hodnoty na stack, nebo hlášení indikující chybné zadání.

Pozn.: Vysvětlivky k barvám podkladu Soft KEYs jsou opět zde.


Pár hodnot na vyzkoušení

  

Nejprve důležité dějinné události...

Letopočet Událost
1492 MCDXCII Objevení Ameriky
1789 MDCCLXXXIX Francouzská buržoazní revoluce
1878 MDCCCLXXVIIINarození Jana Łukasiewicze
1919 MCMXIX Založena Kominterna
1939 MCMXXXIX Založení společnosti Hewlett-Packard
1969 MCMLXIX Apollo 11 přistálo na měsíci
1984 MCMLXXXIV "Narození" RPL

...potom data vzniku některých kalkulátorů.

Letopočet Model
1968 MCMLXVIII HP-9100A
1972 MCMLXXII HP-35
1976 MCMLXXVI HP-9825A
1979 MCMLXXIX HP-41C
1982 MCMLXXXII HP-15C
1987 MCMLXXXVII HP-28C
1988 MCMLXXXVIIIHP-42S
1991 MCMXCI HP-32sII
2006 MMVI HP-50g
2007 MMVII HP-35s

Download

  

Textový tvar Binární forma Zdrojový text C
ROMAN ROMAN.hp roman.c