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