Task

Write a program to perform a conversion of the old Russian measures of length to the metric system   (and vice versa).



It is an example of a linear transformation of several variables.



The program should accept a single value in a selected unit of measurement, and convert and return it to the other units:

vershoks, arshins, sazhens, versts, meters, centimeters and kilometers.



Also see

   Old Russian measure of length


INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
DEFINE PTR="CARD"
DEFINE UNIT_COUNT="10"
 
PTR ARRAY
  names(UNIT_COUNT),
  values(UNIT_COUNT)
BYTE count=[0]
 
PROC Append(CHAR ARRAY name REAL POINTER value)
  names(count)=name
  values(count)=value
  count==+1
RETURN
 
PROC Init()
  REAL
    arshin,centimeter,kilometer,meter,
    sazhen,vershok,versta
 
  ValR("0.7112",arshin)   Append("arshins",arshin)
  ValR("0.01",centimeter) Append("centimeters",centimeter)
  ValR("1000",kilometer)  Append("kilometers",kilometer)
  ValR("1",meter)         Append("meters",meter)
  ValR("2.1336",sazhen)   Append("sazhens",sazhen)
  ValR("0.04445",vershok) Append("vershoks",vershok)
  ValR("1066.8",versta)   Append("versts",versta)
RETURN
 
BYTE FUNC GetUnit()
  BYTE i,res
 
  FOR i=1 TO count
  DO
    PrintF("%B-%S",i,names(i-1))
    IF i<count THEN Put(32) FI
  OD
  PutE()
  DO
    PrintF("Get unit (1-%B): ",count)
    res=InputB()
  UNTIL res>=1 AND res<=count
  OD
RETURN (res-1)
 
PROC PrintResult(REAL POINTER value BYTE unit)
  BYTE i
  REAL res,tmp
 
  PutE()
  FOR i=0 TO count-1
  DO
    IF i=unit THEN
      RealAssign(value,res)
    ELSE
      RealMult(value,values(unit),tmp)
      RealDiv(tmp,values(i),res)
    FI
    Print("  ") PrintR(res)
    PrintF(" %S%E",names(i))
  OD
  PutE()
RETURN
 
PROC Main()
  BYTE unit
  REAL value
 
  Put(125) PutE() ;clear screen
  Init()
 
  DO
    Print("Get value: ")
    InputR(value)
    unit=GetUnit()
    PrintResult(value,unit)
  OD
RETURN