Old Russian measure of length

From Rosetta Code
Task
Old Russian measure of length
You are encouraged to solve this task according to the task description, using any language you may know.
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



11l

Translation of: Python

Run as:

commandname <value> <unit>
V unit2mult = [‘arshin’ = 0.7112, ‘centimeter’ = 0.01,     ‘diuym’   = 0.0254,
               ‘fut’    = 0.3048, ‘kilometer’  = 1000.0,   ‘liniya’  = 0.00254,
               ‘meter’  = 1.0,    ‘milia’      = 7467.6,   ‘piad’    = 0.1778,
               ‘sazhen’ = 2.1336, ‘tochka’     = 0.000254, ‘vershok’ = 0.04445,
               ‘versta’ = 1066.8]

:start:
assert(:argv.len == 3, ‘ERROR. Need two arguments - number then units’)
Float value
X.try
   value = Float(:argv[1])
X.catch
   exit(‘ERROR. First argument must be a (float) number’)
V unit = :argv[2]
assert(unit C unit2mult, ‘ERROR. Only know the following units: ’unit2mult.keys().join(‘ ’))

print(‘#. #. to:’.format(value, unit))
L(unt, mlt) sorted(unit2mult.items())
   print(‘  #10: #.’.format(unt, value * unit2mult[unit] / mlt))
Output:
1 meter to:
      arshin: 1.406074241
  centimeter: 100
       diuym: 39.37007874
         fut: 3.280839895
   kilometer: 0.001
      liniya: 393.700787402
       meter: 1
       milia: 0.000133912
        piad: 5.624296963
      sazhen: 0.468691414
      tochka: 3937.007874016
     vershok: 22.497187852
      versta: 0.000937383

Action!

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
Output:

Screenshot from Atari 8-bit computer

Get value: 1
1-arshins 2-centimeters 3-kilometers 4-meters 5-sazhens 6-vershoks 7-versts
Get unit (1-7): 4

  1.40607424 arshins
  100 centimeters
  1.0E-03 kilometers
  1 meters
  .4686914135 sazhens
  22.49718785 vershoks
  9.37382827E-04 versts

Get value: 10
1-arshins 2-centimeters 3-kilometers 4-meters 5-sazhens 6-vershoks 7-versts
Get unit (1-7): 7

  15000 arshins
  1066800 centimeters
  10.668 kilometers
  10668 meters
  5000 sazhens
  240000 vershoks
  10 versts

ALGOL 68

BEGIN # convert Old Russian units to/from metric                             #
    # mode to hold details of the units - value is in meters                 #
    MODE UNIT = STRUCT( STRING name, REAL value );
    # gets a UNIT from the standard input                                    #
    PROC read unit = UNIT:
         BEGIN
            UNIT r;
            read( ( value OF r, name OF r, newline ) );
            # trim leading and trailing spaces from the name                 #
            INT f pos := LWB name OF r;
            WHILE IF f pos <= UPB name OF r THEN ( name OF r )[ f pos ] = " " ELSE FALSE FI
            DO
                f pos +:= 1
            OD;
            INT b pos := UPB name OF r;
            WHILE IF b pos >= LWB name OF r THEN ( name OF r )[ b pos ] = " " ELSE FALSE FI
            DO
                b pos -:= 1
            OD;
            IF f pos > b pos THEN
                # no name                                                    #
                name OF r := ""
            ELIF ( name OF r )[ b pos ] = "s" THEN
                # the user entered a plural - remove the "S"                 #
                name OF r := ( name OF r )[ f pos : b pos - 1 ]
            ELSE
                # non-blank, non-plural name                                 #
                name OF r := ( name OF r )[ f pos : b pos     ]
            FI;
            r
         END # read unit # ;
    # units and their value in meters                                        #
    []UNIT units = ( ( "arshin",  0.7112 ), ( "centimeter", 0.01     ), ( "diuym",   0.0254  )
                   , ( "fut",     0.3048 ), ( "kilometer",  1000.0   ), ( "liniya",  0.00254 )
                   , ( "meter",   1.0    ), ( "milia",      7467.6   ), ( "piad",    0.1778  )
                   , ( "sazhen",  2.1336 ), ( "tochka",     0.000254 ), ( "vershok", 0.04445 )
                   , ( "versta",  1066.8 )
                   );
    WHILE # prompt for units and show their conversions                      #
        print( ( "Enter the unit to convert - value followed by unit name (or 0 to quit): " ) );
        UNIT r := read unit;
        value OF r /= 0
    DO
        # find the unit name in the table of valid units                     #
        INT u pos := LWB units - 1;
        FOR i FROM LWB units TO UPB units WHILE u pos < LWB units DO
            IF name OF r = name OF units[ i ] THEN
                u pos := i
            FI
        OD;
        IF u pos < LWB units THEN
            # didn't find the units                                          #
            print( ( "Unknown units - please enter one of:", newline, "    " ) );
            FOR i FROM LWB units TO UPB units DO
                print( ( name OF units[ i ], IF i = UPB units THEN newline ELSE ", " FI ) )
            OD
        ELSE
            # found the units - show the values in the other units           #
            UNIT u = units[ u pos ];
            print( ( fixed( value OF r, -12, 6 ), " ", name OF u, " is:", newline ) );
            FOR i FROM LWB units TO UPB units DO
                IF i /= u pos THEN
                    print( ( fixed( ( value OF r * value OF u )/ value OF units[ i ], -16, 6 )
                           , " ", name OF units[ i ], newline
                           )
                         )
                FI
            OD
        FI
    OD
END
Output:
Enter the unit to convert - value followed by unit name (or 0 to quit): 1 meter
    1.000000 meter is:
        1.406074 arshin
      100.000000 centimeter
       39.370079 diuym
        3.280840 fut
        0.001000 kilometer
      393.700787 liniya
        0.000134 milia
        5.624297 piad
        0.468691 sazhen
     3937.007874 tochka
       22.497188 vershok
        0.000937 versta
Enter the unit to convert - value followed by unit name (or 0 to quit): 3 arshin
    3.000000 arshin is:
      213.360000 centimeter
       84.000000 diuym
        7.000000 fut
        0.002134 kilometer
      840.000000 liniya
        2.133600 meter
        0.000286 milia
       12.000000 piad
        1.000000 sazhen
     8400.000000 tochka
       48.000000 vershok
        0.002000 versta
Enter the unit to convert - value followed by unit name (or 0 to quit): 0

AppleScript

Vanilla

-- General purpose linear measurement converter.
on convertLinear(inputNumber, inputUnitRecord, outputUnitRecord)
    set {inputType, outputType} to {inputUnitRecord's type, outputUnitRecord's type}
    if (inputType is not outputType) then error "Unit type mismatch: " & inputType & ", " & outputType
    -- The |offset| values are only relevant to temperature conversions and default to zero.
    set inputUnit to inputUnitRecord & {|offset|:0}
    set outputUnit to outputUnitRecord & {|offset|:0}
    
    return (inputNumber - (inputUnit's |offset|)) * (inputUnit's coefficient) / (outputUnit's coefficient) ¬
        + (outputUnit's |offset|)
end convertLinear

on program(inputNumber, inputUnitName)
    -- The task description only specifies these seven units, but more can be added if wished.
    -- The coefficients are the equivalent lengths in metres.
    set unitRecords to {{|name|:"metre", type:"length", coefficient:1.0}, ¬
        {|name|:"centimetre", type:"length", coefficient:0.01}, {|name|:"kilometre", type:"length", coefficient:1000.0}, ¬
        {|name|:"vershok", type:"length", coefficient:0.04445}, {|name|:"arshin", type:"length", coefficient:0.7112}, ¬
        {|name|:"sazhen", type:"length", coefficient:2.1336}, {|name|:"versta", type:"length", coefficient:1066.8}}
    
    -- Massage the given input unit name if necessary.
    if (inputUnitName ends with "s") then set inputUnitName to text 1 thru -2 of inputUnitName
    if (inputUnitName ends with "meter") then set inputUnitName to (text 1 thru -3 of inputUnitName) & "re"
    
    -- Get the record with the input unit name from 'unitRecords'.
    set inputUnitRecord to missing value
    repeat with thisRecord in unitRecords
        if (thisRecord's |name| is inputUnitName) then
            set inputUnitRecord to thisRecord's contents
            exit repeat
        end if
    end repeat
    if (inputUnitRecord is missing value) then error "Unrecognised unit name: " & inputUnitName
    
    -- Guess the user's spelling preference from the short-date order configured on their machine.
    tell (current date) to set {Feb1, its day, its month, its year} to {it, 1, 2, 3333}
    set USSpelling to (Feb1's short date string's first word as integer is 2)
    
    -- Convert the input number to its equivalents in all the specified units, rounding to eight decimal
    -- places and getting integer values as AS integers where possible. Pair the results with the unit names.
    set output to {}
    repeat with thisRecord in unitRecords
        set outputNumber to convertLinear(inputNumber, inputUnitRecord, thisRecord)
        set outputNumber to outputNumber div 1 + ((outputNumber * 100000000 mod 100000000) as integer) / 100000000
        if (outputNumber mod 1 is 0) then set outputNumber to outputNumber div 1
        set outputUnitName to thisRecord's |name|
        if ((outputUnitName ends with "metre") and (USSpelling)) then ¬
            set outputUnitName to (text 1 thru -3 of outputUnitName) & "er"
        if (outputNumber is not 1) then set outputUnitName to outputUnitName & "s"
        set end of output to {outputNumber, outputUnitName}
    end repeat
    
    return output -- {{number, unit name}, … }
end program

on demo()
    set output to {}
    set astid to AppleScript's text item delimiters
    repeat with input in {{1, "kilometre"}, {1, "versta"}}
        set {inputNumber, inputUnitName} to input
        set end of output to (inputNumber as text) & space & inputUnitName & " is:"
        set conversions to program(inputNumber, inputUnitName)
        set AppleScript's text item delimiters to space
        repeat with thisConversion in conversions
            set thisConversion's contents to thisConversion as text
        end repeat
        set AppleScript's text item delimiters to ";  "
        set end of output to conversions as text
    end repeat
    set AppleScript's text item delimiters to linefeed
    set output to output as text
    set AppleScript's text item delimiters to astid
    
    return output
end demo

return demo()
Output:
"1 kilometre is:
1000 metres;  100000 centimetres;  1 kilometre;  2.249718785152E+4 vershoks;  1406.07424072 arshins;  468.69141357 sazhens;  0.93738283 verstas
1 versta is:
1066.8 metres;  106680 centimetres;  1.0668 kilometres;  24000 vershoks;  1500 arshins;  500 sazhens;  1 versta"

AppleScriptObjC

use AppleScript version "2.5" -- macOS 10.12 (Sierra) or later. Not 10.11 (El Capitan).
use framework "Foundation"
use scripting additions

property |⌘| : current application

-- Return a custom NSUnit with a linear converter.
on customNSUnit(unitClassName, symbol, coefficient, |offset|)
    set converter to |⌘|'s class "NSUnitConverterLinear"'s alloc()'s initWithCoefficient:(coefficient) |constant|:(|offset|)
    return |⌘|'s class unitClassName's alloc()'s initWithSymbol:(symbol) converter:(converter)
end customNSUnit

on program(inputNumber, inputUnitName)
    -- The task description only specifies these seven units, but more can be added if wished.
    -- The base unit of the NSUnitLength class is 'meters'.
    set unitRecords to {{|name|:"metre", NSUnit:|⌘|'s class "NSUnitLength"'s |meters|()}, ¬
        {|name|:"centimetre", NSUnit:|⌘|'s class "NSUnitLength"'s |centimeters|()}, ¬
        {|name|:"kilometre", NSUnit:|⌘|'s class "NSUnitLength"'s |kilometers|()}, ¬
        {|name|:"vershok", NSUnit:customNSUnit("NSUnitLength", "vershok", 0.04445, 0)}, ¬
        {|name|:"arshin", NSUnit:customNSUnit("NSUnitLength", "arshin", 0.7112, 0)}, ¬
        {|name|:"sazhen", NSUnit:customNSUnit("NSUnitLength", "sazhen", 2.1336, 0)}, ¬
        {|name|:"versta", NSUnit:customNSUnit("NSUnitLength", "versta", 1066.8, 0)}}
    
    -- Massage the given input unit name if necessary.
    if (inputUnitName ends with "s") then set inputUnitName to text 1 thru -2 of inputUnitName
    if (inputUnitName ends with "meter") then set inputUnitName to (text 1 thru -3 of inputUnitName) & "re"
    
    -- Get the record with the input unit name from 'unitRecords'.
    set filter to |⌘|'s class "NSPredicate"'s predicateWithFormat_("name == %@", inputUnitName)
    set filteredList to ((|⌘|'s class "NSArray"'s arrayWithArray:(unitRecords))'s filteredArrayUsingPredicate:(filter)) as list
    if (filteredList is {}) then error "Unrecognised unit name: " & inputUnitName
    set inputUnitRecord to beginning of filteredList
    
    -- Set up an NSMeasurement using the input number and the NSUnit from the record.
    set inputMeasurement to |⌘|'s class "NSMeasurement"'s alloc()'s ¬
        initWithDoubleValue:(inputNumber) unit:(inputUnitRecord's NSUnit)
    
    -- Get equivalent NSMeasurements in all the specified units and format them as text using an NSMeasurementFormatter
    -- configured to use the measurements' own units instead of local equivalents and, in the case of the three preset units,
    -- to include the full words, localised and pluralised as appropriate, instead of the symbols "m", "cm", or "km".
    set output to {}
    set measurementFormatter to |⌘|'s class "NSMeasurementFormatter"'s new()
    tell measurementFormatter to setUnitOptions:(|⌘|'s NSMeasurementFormatterUnitOptionsProvidedUnit)
    tell measurementFormatter to setUnitStyle:(|⌘|'s NSFormattingUnitStyleLong)
    repeat with thisRecord in unitRecords
        set outputMeasurement to (inputMeasurement's measurementByConvertingToUnit:(thisRecord's NSUnit))
        set formattedMeasurement to (measurementFormatter's stringFromMeasurement:(outputMeasurement)) as text
        if not ((outputMeasurement's doubleValue() is 1) or (thisRecord's |name| ends with "metre")) then ¬
            set formattedMeasurement to formattedMeasurement & "s"
        set end of output to formattedMeasurement
    end repeat
    
    return output -- {formatted text, … }
end program

on demo()
    considering numeric strings
        if ((system info)'s system version < "10.12") then ¬
            error "El Capitan doesn't support the Foundation framework's Units and Measurement system"
    end considering
    set output to {}
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ";  "
    repeat with input in {{1, "kilometre"}, {1, "versta"}}
        set {inputNumber, inputUnitName} to input
        set end of output to (inputNumber as text) & space & inputUnitName & " is:"
        set end of output to program(inputNumber, inputUnitName) as text
    end repeat
    set AppleScript's text item delimiters to linefeed
    set output to output as text
    set AppleScript's text item delimiters to astid
    
    return output
end demo

return demo()
Output:
"1 kilometre is:
1,000 metres;  100,000 centimetres;  1 kilometre;  22,497.188 vershoks;  1,406.074 arshins;  468.691 sazhens;  0.937 verstas
1 versta is:
1,066.8 metres;  106,680 centimetres;  1.067 kilometres;  24,000 vershoks;  1,500 arshins;  500 sazhens;  1 versta"

AWK

# syntax: GAWK -f OLD_RUSSIAN_MEASURE_OF_LENGTH.AWK
BEGIN {
    units = "kilometer meter centimeter tochka liniya diuym vershok piad fut arshin sazhen versta milia"
    values = "1000.0 1.0 0.01 0.000254 0.00254 0.0254 0.04445 0.1778 0.3048 0.7112 2.1336 1066.8 7467.6"
    u_leng = split(units,u_arr," ")
    v_leng = split(values,v_arr," ")
    if (u_leng != v_leng) {
      print("error: lengths of units & values are unequal")
      exit(1)
    }
    print("enter length & measure or C/R to exit")
}
{   if ($0 == "") {
      exit(0)
    }
    measure = tolower($2)
    sub(/s$/,"",measure)
    for (i=1; i<=u_leng; i++) {
      if (u_arr[i] == measure) {
        for (j=1; j<=u_leng; j++) {
          str = sprintf("%.8f",$1*v_arr[i]/v_arr[j])
          sub(/0+$/,"",str)
          printf("%10s %s\n",u_arr[j],str)
        }
        print("")
        next
      }
    }
    printf("error: invalid measure; choose from: %s\n\n",units)
}
Output:
enter length & measure or C/R to exit
1 meter
 kilometer 0.001
     meter 1.
centimeter 100.
    tochka 3937.00787402
    liniya 393.7007874
     diuym 39.37007874
   vershok 22.49718785
      piad 5.62429696
       fut 3.2808399
    arshin 1.40607424
    sazhen 0.46869141
    versta 0.00093738
     milia 0.00013391

1 milia
 kilometer 7.4676
     meter 7467.6
centimeter 746760.
    tochka 29400000.
    liniya 2940000.
     diuym 294000.
   vershok 168000.
      piad 42000.
       fut 24500.
    arshin 10500.
    sazhen 3500.
    versta 7.
     milia 1.

BASIC

BASIC256

arraybase 1
dim units = {"tochka", "liniya", "dyuim", "vershok", "piad", "fut", "arshin", "sazhen", "versta", "milia", "centimeter", "meter", "kilometer"}
# all expressed in centimeters
dim convs = {0.0254, 0.254, 2.54, 4.445, 17.78, 30.48, 71.12, 213.36, 10668, 74676, 1, 100, 10000}

do
	cls
	print
	for i = 1 to units[?]
		print rjust(string(i),2); " "; units[i]
	next
	print
	do
		input "Please choose a unit 1 to 13 : ", unit
	until unit >= 1 and unit <= 13
	print
	do
		input "Now enter a value in that unit : ", value
	until value >= 0
	print
	print "The equivalent in the remaining units is : "
	print
	for i = 1 to units[?]
		if i = unit then continue for
		print " "; units[i], " : "; value * convs[unit] / convs[i]
	next
	print
	do
		input "Do another one y/n : ", yn
		yn = lower(yn)
	until yn = "y" or yn = "n"
until yn = "n"
Output:
Same as Run BASIC entry.

BBC BASIC

REM >oldrussian
@% = &90E
PROColdrus(1, "meter")
PRINT
PROColdrus(10, "arshin")
END
:
DEF PROColdrus(length, unit$)
LOCAL units$(), values(), unit%, i%
DIM units$(12)
DIM values(12)
units$() = "kilometer", "meter", "centimeter", "milia", "versta", "sazhen", "arshin", "fut", "piad", "vershok", "diuym", "liniya", "tochka"
values() = 1000, 1, 0.01, 7467.6, 1066.8, 2.1336, 0.7112, 0.3048, 0.1778, 0.04445, 0.0254, 0.00254, 0.000254
unit% = -1
FOR i% = 0 TO 12
  IF units$(i%) = unit$ THEN unit% = i%
NEXT
IF unit% = -1 THEN
  PRINT "Unknown unit '"; unit$; "'"
ELSE
  PRINT; length; " "; unit$; " ="
  FOR i% = 0 TO 12
    IF i% <> unit% THEN PRINT length / values(i%) * values(unit%); " "; units$(i%)
  NEXT
ENDIF
ENDPROC
Output:
1 meter =
         0.001 kilometer
           100 centimeter
0.000133911832 milia
0.000937382827 versta
   0.468691414 sazhen
    1.40607424 arshin
     3.2808399 fut
    5.62429696 piad
    22.4971879 vershok
    39.3700787 diuym
    393.700787 liniya
    3937.00787 tochka

10 arshin =
      0.007112 kilometer
         7.112 meter
         711.2 centimeter
0.000952380952 milia
 0.00666666667 versta
    3.33333333 sazhen
    23.3333333 fut
            40 piad
           160 vershok
           280 diuym
          2800 liniya
         28000 tochka


FreeBASIC

' FB 1.05.0 Win64

Dim units(1 To 13) As String = {"tochka", "liniya", "dyuim", "vershok", "piad", "fut", _
                                "arshin", "sazhen", "versta", "milia", _
                                "centimeter", "meter", "kilometer"}

' all expressed in centimeters
Dim convs(1 To 13) As Single = {0.0254, 0.254, 2.54, 4.445, 17.78, 30.48, _
                                71.12, 213.36, 10668, 74676, _
                                1, 100, 10000}
Dim unit As Integer
Dim value As Single
Dim yn As String

Do
  Shell("cls")
  Print 
  For i As Integer = 1 To 13
    Print Using "##"; i;
    Print " "; units(i)
  Next
  Print
  Do
    Input "Please choose a unit 1 to 13 : "; unit
  Loop Until unit >= 1 AndAlso unit <= 13  
  Print
  Do
    Input "Now enter a value in that unit : "; value
  Loop Until value >= 0 
  Print
  Print "The equivalent in the remaining units is : "
  Print
  For i As Integer = 1 To 13
    If i = unit Then Continue For
    Print " "; units(i), " : "; value * convs(unit) / convs(i)
  Next
  Print
  Do
    Input "Do another one y/n : "; yn
    yn = LCase(yn)
  Loop Until yn = "y" OrElse yn = "n"
Loop Until yn = "n"
     
End

Sample input/output:

Output:

 1 tochka
 2 liniya
 3 dyuim
 4 vershok
 5 piad
 6 fut
 7 arshin
 8 sazhen
 9 versta
10 milia
11 centimeter
12 meter
13 kilometer

Please choose a unit 1 to 13 : ? 13

Now enter a value in that unit : ? 1

The equivalent in the remaining units is :

 tochka        :  393700.8
 liniya        :  39370.08
 dyuim         :  3937.008
 vershok       :  2249.719
 piad          :  562.4297
 fut           :  328.084
 arshin        :  140.6074
 sazhen        :  46.86914
 versta        :  0.9373828
 milia         :  0.1339118
 centimeter    :  10000
 meter         :  100

Do another one y/n : ? n

Gambas

Public Sub Main() 
  
  Dim units As String[] = ["tochka", "liniya", "dyuim", "vershok", "piad", "fut", "arshin", "sazhen", "versta", "milia", "centimeter", "meter", "kilometer"]
  
  ' all expressed in centimeters
  Dim convs As Single[] = [0.254, 0.254, 2.54, 4.445, 17.78, 30.48, 71.12, 213.36, 10668, 74676, 1, 100, 10000] 
  Dim i, unit As Integer
  Dim value As Single 
  Dim yn As String 
  
  Do 
    Shell("clear") 
    Print  
    For i = 1 To units.count
      Print Format$(i, "##"); " "; units[i - 1] 
    Next 
    Print "\nPlease choose a unit 1 to 13 : "
    Do 
      Input unit 
    Loop Until unit >= 1 And unit <= 13   
    Print "\nNow enter a value in that unit : "
    Do 
      Input value 
    Loop Until value >= 0  
    Print "\nThe equivalent in the remaining units is : \n" 
    For i = 0 To units.count - 1
      If i = unit - 1 Then Continue 'For 
      Print units[i]; Space$(10 - Len(units[i])); 
      Print " : "; value * convs[unit - 1] / convs[i] 
    Next 
    Print "\nDo another one y/n : "
    Do 
      Input yn 
      yn = LCase(yn) 
    Loop Until yn = "y" Or yn = "n" 
  Loop Until yn = "n"
  
End
Output:
Similar as FreeBASIC entry.

QBasic

Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
DIM units(1 TO 13) AS STRING
FOR i = LBOUND(units) TO UBOUND(units)
READ units(i)
NEXT i
DATA "tochka", "liniya", "dyuim", "vershok", "piad", "fut", "arshin", "sazhen", "versta", "milia", "centimeter", "meter", "kilometer"

' all expressed in centimeters
DIM convs(1 TO 13) AS SINGLE
FOR i = 1 TO 13
READ convs(i)
NEXT i
DATA 0.0254, 0.254, 2.54, 4.445, 17.78, 30.48, 71.12, 213.36, 10668, 74676, 1, 100, 10000
DIM unit AS INTEGER
DIM value AS SINGLE
DIM yn AS STRING

DO
    CLS
    PRINT
    FOR i = 1 TO 13
        PRINT USING "## "; i;
        PRINT units(i)
    NEXT i
    PRINT
    DO
        INPUT "Please choose a unit 1 to 13 : ", unit
    LOOP UNTIL unit >= 1 AND unit <= 13
    PRINT
    DO
        INPUT "Now enter a value in that unit : ", value
    LOOP UNTIL value >= 0
    PRINT
    PRINT "The equivalent in the remaining units is : "
    PRINT
    FOR i = 1 TO 13
        IF i <> unit THEN PRINT " "; units(i), " : "; value * convs(unit) / convs(i)
    NEXT i
    PRINT
    DO
        INPUT "Do another one y/n : ", yn
        yn = LCASE$(yn)
    LOOP UNTIL yn = "y" OR yn = "n"
LOOP UNTIL yn = "n"
Output:
Same as FreeBASIC entry.

True BASIC

DIM units$(1 TO 13)
FOR i = LBOUND(units$) TO UBOUND(units$)
    READ units$(i)
NEXT i
DATA "tochka", "liniya", "dyuim", "vershok", "piad", "fut", "arshin", "sazhen", "versta", "milia", "centimeter", "meter", "kilometer"

! all expressed in centimeters
DIM convs(1 TO 13)
FOR i = 1 TO 13
    READ convs(i)
NEXT i
DATA 0.0254, 0.254, 2.54, 4.445, 17.78, 30.48, 71.12, 213.36, 10668, 74676, 1, 100, 10000

DO
   CLEAR
   PRINT
   FOR i = 1 TO 13
       PRINT USING "## ": i;
       PRINT units$(i)
   NEXT i
   PRINT
   DO
      INPUT prompt "Please choose a unit 1 to 13 : ": unit
   LOOP UNTIL unit >= 1 AND unit <= 13
   PRINT
   DO
      INPUT prompt "Now enter a value! in that unit : ": value
   LOOP UNTIL value >= 0
   PRINT
   PRINT "The equivalent in the remaining units is : "
   PRINT
   FOR i = 1 TO 13
       IF i <> unit THEN PRINT " "; units$(i), " : "; value*convs(unit)/convs(i)
   NEXT i
   PRINT
   DO
      INPUT prompt "Do another one y/n : ": yn$
      LET yn$ = LCASE$(yn$)
   LOOP UNTIL yn$ = "y" OR yn$ = "n"
LOOP UNTIL yn$ = "n"
END
Output:
Same as FreeBASIC entry.

XBasic

Works with: Windows XBasic
PROGRAM	"progname"
VERSION	"0.0000"

DECLARE FUNCTION Entry ()

FUNCTION Entry ()

DIM units$[14]
units$[1]  = "tochka    " : units$[2]  = "liniya    " : units$[3]  = "dyuim     "
units$[4]  = "vershok   " : units$[5]  = "piad      " : units$[6]  = "fut       "
units$[7]  = "arshin    " : units$[8]  = "sazhen    " : units$[9]  = "versta    "
units$[10] = "milia     " : units$[11] = "centimeter" : units$[12] = "meter     "
units$[13] = "kilometer "

' all expressed in centimeters
DIM convs![14]
convs![1]  = 0.0254 : convs![2] = 0.254 : convs![3]  = 2.54
convs![4]  = 4.445 : convs![5]  = 17.78 : convs![6]  = 30.48
convs![7]  = 71.12 : convs![8]  = 213.36 : convs![9] = 10668
convs![10] = 74676 : convs![11] = 1 : convs![12] = 100 : convs![13] = 10000

DO
    PRINT
    FOR i = 1 TO 13
        PRINT FORMAT$("##",i); " "; units$[i]
    NEXT i
    DO
        unit = UBYTE(INLINE$("\nPlease choose a unit 1 to 13 : "))
    LOOP UNTIL unit >= 1 AND unit <= 13
    DO
        value = USHORT(INLINE$("\nNow enter a value in that unit : "))
    LOOP UNTIL value >= 0

    PRINT
    PRINT "The equivalent in the remaining units is : "
    PRINT
    FOR i = 1 TO 13
        IF i <> unit THEN PRINT " "; units$[i], " : "; value * convs![unit] / convs![i]
    NEXT i
    DO
        yn$ = LCASE$(INLINE$("\nDo another one y/n : "))
    LOOP UNTIL (yn$ = "y") OR (yn$ = "n")
 LOOP UNTIL yn$ = "n"

END FUNCTION
END PROGRAM
Output:
Similar as FreeBASIC entry.

uBasic/4tH

This program uses a command prompt. It will accept queries as long as the order "quantity, from unit, to unit" is preserved. EXIT will leave the program. Note all arithmetic is done in fixed point math, so some rounding errors are unavoidable.

Do                                     ' get in command loop
  t := ""                              ' no token
  n = Info ("nil")                     ' units are undefined
  f = _Fmul                            ' first, a multiplication
  o = Ask("> ")                        ' show the prompt
                                       ' strip trailing spaces
  For x = Len (o) While Peek(o, Set(x, x-1)) = Ord(" ") : o = Clip(o, 1) : Next

  Do While Len (o)                     ' if there is something left to parse
    t = FUNC(_Parse (" "))             ' get the token
    If Val (t) # Info ("nil") Then n = FUNC (_Ntof (Val (t)))
    l = Name (t)                       ' is it a number, set it
    If Line (l) Then n = FUNC (l (f, n)) : f = _Fdiv
  Loop                                 ' if it's a function, execute it
Until n = Info ("nil")                 ' display the result
  Print Show (Str ("+?.####", FUNC(_Ftoi (n))));" ";Show (t)
Loop

End

_Parse                                 ' parse string and get token
  Param (1)
  Local (3)

  Do                                   ' get only complete tokens
    If Set(b@, Find(o, a@)) < 0 Then
      c@ := o : o := ""                ' last token, we're done
    Else                               ' get the next token
      c@ = Clip (o, Len(o) - b@) : o = Chop (o, b@+1)
    EndIf
  Until Len (c@) : Loop

Return (c@)                            ' return token

Rem 'arshin' = 0.7112, 'centimeter' = 0.01,     'diuym'   = 0.0254,
Rem 'fut'    = 0.3048, 'kilometer'  = 1000.0,   'liniya'  = 0.00254,
Rem 'meter'  = 1.0,    'milia'      = 7467.6,   'piad'    = 0.1778,
Rem 'sazhen' = 2.1336, 'tochka'     = 0.000254, 'vershok' = 0.04445,
Rem 'versta' = 1066.8

_arshin Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (711200)))))
_centimeter Param (2) : Return (FUNC(a@(b@, FUNC(_Ntof (1)))))
_diuym Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (25400)))))
_fut Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (304800)))))
_kilometer Param (2) : Return (FUNC(a@(b@, FUNC(_Ntof (100000)))))
_liniya Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (2540)))))
_meter Param (2) : Return (FUNC(a@(b@, FUNC(_Ntof (100)))))
_milia Param (2) : Return (FUNC(a@(b@, FUNC(_Ntof (746760)))))
_piad Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (177800)))))
_sazhen Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (2133600)))))
_tochka Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (254)))))
_vershok Param (2) : Return (FUNC(a@(b@, FUNC(_Itof (44450)))))
_versta Param (2) : Return (FUNC(a@(b@, FUNC(_Ntof (106680)))))
_exit Param (2) : Return (Info ("nil"))

_Fmul Param (2) : Return ((a@*b@)/16384)
_Fdiv Param (2) : Return ((a@*16384)/b@)
_Ftoi Param (1) : Return ((10000*a@)/16384)
_Itof Param (1) : Return ((16384*a@)/10000)
_Ntof Param (1) : Return (a@*16384)
Output:
> convert 1 meter to fut
3.2808 fut
> convert 10 diuym to centimeter
25.3997 centimeter
> how much is 1 fut in diuym
12.0000 diuym
> 20 diuym in tochka
2000.7211 tochka
> 1 milia = versta
7.0000 versta
> exit

0 OK, 0:1014 

Yabasic

dim units$(14)
units$(1) = "tochka" : units$(2) = "liniya" : units$(3) = "dyuim"
units$(4) = "vershok" : units$(5) = "piad" : units$(6) = "fut"
units$(7) = "arshin" : units$(8) = "sazhen" : units$(9) = "versta"
units$(10) = "milia" : units$(11) = "centimeter" : units$(12) = "meter"
units$(13) = "kilometer"

// all expressed in centimeters
dim convs(14) 
convs(1) = 0.0254 : convs(2) = 0.254 : convs(3) = 2.54
convs(4) = 4.445 : convs(5) = 17.78 : convs(6) = 30.48
convs(7) = 71.12 : convs(8) = 213.36 : convs(9) = 10668
convs(10) = 74676 : convs(11) = 1 : convs(12) = 100 : convs(13) = 10000

repeat
    clear screen
    print 
    for i = 1 to arraysize(units$(), 1) - 1
        print i using ("##"), " ", units$(i)
    next
    print
    repeat
        input "Please choose a unit 1 to 13 : " unit
    until unit >= 1 and unit <= 13  
    print
    repeat
        input "Now enter a value in that unit : " value
    until value >= 0 
    
    print "\nThe equivalent in the remaining units is : \n"
    
    for i = 1 to 13
        if i = unit  continue 
        print " ", units$(i), "\t : ", value * convs(unit) / convs(i)
    next
    print
    repeat
        input "Do another one y/n : " yn$
        yn$ = lower$(yn$)
    until yn$ = "y" or yn$ = "n"
until yn$ = "n"
end
Output:
Same as FreeBASIC entry.

C

Accepts length and unit as input, prints out length in all other units. Usage printed on incorrect invocation.

#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdio.h>

#define UNITS_LENGTH 13

int main(int argC,char* argV[])
{
	int i,reference;
	char *units[UNITS_LENGTH] = {"kilometer","meter","centimeter","tochka","liniya","diuym","vershok","piad","fut","arshin","sazhen","versta","milia"};
    double factor, values[UNITS_LENGTH] = {1000.0,1.0,0.01,0.000254,0.00254,0.0254,0.04445,0.1778,0.3048,0.7112,2.1336,1066.8,7467.6};
	
	if(argC!=3)
		printf("Usage : %s followed by length as <value> <unit>");
	else{
		for(i=0;argV[2][i]!=00;i++)
			argV[2][i] = tolower(argV[2][i]);
		
		for(i=0;i<UNITS_LENGTH;i++){
			if(strstr(argV[2],units[i])!=NULL){
				reference = i;
				factor = atof(argV[1])*values[i];
				break;
			}
		}
		
		printf("%s %s is equal in length to : \n",argV[1],argV[2]);
		
		for(i=0;i<UNITS_LENGTH;i++){
			if(i!=reference)
				printf("\n%lf %s",factor/values[i],units[i]);
		}
	}
	
	return 0;
}

Output :

C:\rosettaCode>metricRussian.exe 1 meter
1 meter is equal in length to :

0.001000 kilometer
100.000000 centimeter
3937.007874 tochka
393.700787 liniya
39.370079 diuym
22.497188 vershok
5.624297 piad
3.280840 fut
1.406074 arshin
0.468691 sazhen
0.000937 versta
0.000134 milia
C:\rosettaCode>metricRussian.exe 3 arshin
3 arshin is equal in length to :

0.002134 kilometer
2.133600 meter
213.360000 centimeter
8400.000000 tochka
840.000000 liniya
84.000000 diuym
48.000000 vershok
12.000000 piad
7.000000 fut
1.000000 sazhen
0.002000 versta
0.000286 milia

C++

#include <iostream>
#include <iomanip>
//-------------------------------------------------------------------------------------------
using namespace std;

//-------------------------------------------------------------------------------------------
class ormConverter
{
public:
    ormConverter() :  AR( 0.7112f ), CE( 0.01f ), DI( 0.0254f ), FU( 0.3048f ), KI( 1000.0f ), LI( 0.00254f ), ME( 1.0f ),
		      MI( 7467.6f ), PI( 0.1778f ), SA( 2.1336f ), TO( 0.000254f ), VE( 0.04445f ), VR( 1066.8f ) {}
    void convert( char c, float l )
    {
	system( "cls" );
	cout << endl << l;
	switch( c )
	{
	    case 'A': cout << " Arshin to:";     l *= AR; break;
	    case 'C': cout << " Centimeter to:"; l *= CE; break;
	    case 'D': cout << " Diuym to:";      l *= DI; break;
	    case 'F': cout << " Fut to:";        l *= FU; break;
	    case 'K': cout << " Kilometer to:";  l *= KI; break;
	    case 'L': cout << " Liniya to:";     l *= LI; break;
	    case 'M': cout << " Meter to:";      l *= ME; break;
	    case 'I': cout << " Milia to:";      l *= MI; break;
	    case 'P': cout << " Piad to:";       l *= PI; break;
	    case 'S': cout << " Sazhen to:";     l *= SA; break;
	    case 'T': cout << " Tochka to:";     l *= TO; break;
	    case 'V': cout << " Vershok to:";    l *= VE; break;
	    case 'E': cout << " Versta to:";     l *= VR;
	}

	float ar = l / AR, ce = l / CE, di = l / DI, fu = l / FU, ki = l / KI, li = l / LI, me = l / ME,
	      mi = l / MI, pi = l / PI, sa = l / SA, to = l / TO, ve = l / VE, vr = l / VR;
	cout << left << endl << "=================" << endl
	     << setw( 12 ) << "Arshin:" << ar << endl << setw( 12 ) << "Centimeter:" << ce << endl
	     << setw( 12 ) << "Diuym:" << di << endl << setw( 12 ) << "Fut:" << fu << endl
	     << setw( 12 ) << "Kilometer:" << ki << endl << setw( 12 ) << "Liniya:" << li << endl
	     << setw( 12 ) << "Meter:" << me << endl << setw( 12 ) << "Milia:" << mi << endl
	     << setw( 12 ) << "Piad:" << pi << endl << setw( 12 ) << "Sazhen:" << sa << endl
	     << setw( 12 ) << "Tochka:" << to << endl << setw( 12 ) << "Vershok:" << ve << endl
	     << setw( 12 ) << "Versta:" << vr << endl << endl << endl;
    }
private:
    const float AR, CE, DI, FU, KI, LI, ME, MI, PI, SA, TO, VE, VR;
};
//-------------------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
    ormConverter c;
    char s; float l;
    while( true )
    {
	cout << "What unit:\n(A)rshin, (C)entimeter, (D)iuym, (F)ut\n(K)ilometer, (L)iniya, (M)eter, m(I)lia, (P)iad\n(S)azhen, (T)ochka, (V)ershok, v(E)rsta, (Q)uit\n";
	cin >> s; if( s & 32 ) s ^= 32; if( s == 'Q' ) return 0;
	cout << "Length (0 to Quit): "; cin >> l; if( l == 0 ) return 0;
	c.convert( s, l ); system( "pause" ); system( "cls" );
    }
    return 0;
}
//-------------------------------------------------------------------------------------------

Output:

1 Milia to:
=================
Arshin:     10500
Centimeter: 746760
Diuym:      294000
Fut:        24500
Kilometer:  7.4676
Liniya:     2.94e+006
Meter:      7467.6
Milia:      1
Piad:       42000
Sazhen:     3500
Tochka:     2.94e+007
Vershok:    168000
Versta:     7

1 Meter to:
=================
Arshin:     1.40607
Centimeter: 100
Diuym:      39.3701
Fut:        3.28084
Kilometer:  0.001
Liniya:     393.701
Meter:      1
Milia:      0.000133912
Piad:       5.6243
Sazhen:     0.468691
Tochka:     3937.01
Vershok:    22.4972
Versta:     0.000937383

D

Translation of: Raku
import std.stdio, std.string, std.algorithm, std.conv;

void main(in string[] args) {
    auto factor = ["arshin":         0.7112,
                   "centimeter":     0.01,
                   "diuym":          0.0254,
                   "fut":            0.3048,
                   "kilometer":  1_000.0,
                   "liniya":         0.00254,
                   "meter":          1.0,
                   "milia":      7_467.6,
                   "piad":           0.1778,
                   "sazhen":         2.1336,
                   "tochka":         0.000254,
                   "vershok":        0.04445,
                   "versta":     1_066.8];

    if (args.length != 3 || !isNumeric(args[1]) || args[2] !in factor)
        return writeln("Please provide args Value and Unit.");

    immutable magnitude = args[1].to!double;
    immutable meters = magnitude * factor[args[2]];
    writefln("%s %s to:\n", args[1], args[2]);
    foreach (immutable key; factor.keys.schwartzSort!(k => factor[k]))
       writefln("%10s: %s", key, meters / factor[key]);
}
Output:
1 meter to:

    tochka: 3937.01
    liniya: 393.701
centimeter: 100
     diuym: 39.3701
   vershok: 22.4972
      piad: 5.6243
       fut: 3.28084
    arshin: 1.40607
     meter: 1
    sazhen: 0.468691
 kilometer: 0.001
    versta: 0.000937382
     milia: 0.000133911

1 milia to:

    tochka: 2.94e+07
    liniya: 2.94e+06
centimeter: 746760
     diuym: 294000
   vershok: 168000
      piad: 42000
       fut: 24500
    arshin: 10500
     meter: 7467.6
    sazhen: 3500
 kilometer: 7.4676
    versta: 7
     milia: 1

Delphi

Translation of: Go
program Old_Russian_measure_of_length;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

const
  units: array[0..12] of string = ('tochka', 'liniya', 'dyuim', 'vershok',
    'piad', 'fut', 'arshin', 'sazhen', 'versta', 'milia', 'centimeter', 'meter',
    'kilometer');
  convs: array[0..12] of double = (0.0254, 0.254, 2.54, 4.445, 17.78, 30.48,
    71.12, 213.36, 10668, 74676, 1, 100, 10000);

function ReadInt(): integer;
var
  data: string;
begin
  Readln(data);
  Result := StrToIntDef(data, -1);
end;

function ReadFloat(): Double;
var
  data: string;
begin
  Readln(data);
  Result := StrToFloatDef(data, -1);
end;

var
  yn, u: string;
  i, unt: integer;
  value: Double;

begin

  repeat
    for i := 0 to High(units) do
    begin
      u := units[i];
      Writeln(format('%2d %s', [i + 1, u]));
    end;
    Writeln;

    unt := 0;
    repeat
      Writeln('Please choose a unit 1 to 13 : ');
      unt := ReadInt();
    until (unt >= 1) and (unt <= 13);

    dec(unt);

    repeat
      Writeln('Now enter a value in that unit : ');
      value := ReadFloat();
    until value >= 0;

    Writeln(#10'The equivalent in the remaining units is:'#10);

    for i := 0 to High(units) do
    begin
      u := units[i];
      if i = unt then
        Continue;
      Writeln(format(' %10s : %g', [u, value * convs[unt] / convs[i]]));
    end;

    Writeln;

    yn := '';
    Writeln('Do another one y/n : ');
    readln(yn);
  until yn.toLower = 'n';
end.

EasyLang

Translation of: Gambas
units$[] = [ "tochka" "liniya" "dyuim" "vershok" "piad" "fut" "arshin" "sazhen" "versta" "milia" "centimeter" "meter" "kilometer" ]
convs[] = [ 0.254 0.254 2.54 4.445 17.78 30.48 71.12 213.36 10668 74676 1 100 10000 ]
for i to len units$[]
   print i & ") " & units$[i]
.
print ""
write "Please choose a unit (1 to 13): "
repeat
   unit = number input
   until unit >= 1 and unit <= 13
.
print unit
write "Now enter a value in that unit: "
repeat
   value = -1
   value = number input
   print value
   until value >= 0
.
print value
print ""
print value & " " & units$[unit] & " are"
print ""
for i to len units$[]
   if i <> unit
      print value * convs[unit] / convs[i] & " " & units$[i]
   .
.

Elena

Translation of: Julia

ELENA 6.x:

import system'collections;
import system'routines;
import extensions;

unit2mult = new Map<string, real>()
    .setAt("arshin",     0.7112r)
    .setAt("centimeter", 0.01r)     
    .setAt("diuym",      0.0254r)
    .setAt("fut",        0.3048r)
    .setAt("kilometer",  1000.0r)   
    .setAt("liniya",     0.00254r)
    .setAt("meter",      1.0r)
    .setAt("milia",      7467.6r)
    .setAt("piad",       0.1778r)
    .setAt("sazhen",     2.1336r)
    .setAt("tochka",     0.000254r) 
    .setAt("vershok",    0.04445r)
    .setAt("versta",     1066.8r);

public program()
{
    if (program_arguments.Length != 3)
        { console.writeLine("need two arguments - number then units"); AbortException.raise() };
        
    real value := program_arguments[1].toReal();    
    string unit := program_arguments[2];
    ifnot (unit2mult.containsKey(unit))
    {
        console.printLine("only following units are supported:",
            unit2mult.selectBy::(x=>x.Item1).asEnumerable());
            
        AbortException.raise()
    };
    
    console.printLine(value," ",unit," to:");

    unit2mult.forEach::(u,mlt)
    {
        console.printPaddingLeft(30, u, ":").printLine(value * unit2mult[unit] / mlt)
    }    
}
Output:
2.3 meter to:
                       arshin:3.233970753656
                   centimeter:230.0
                        diuym:90.55118110236
                          fut:7.54593175853
                    kilometer:0.0023
                       liniya:905.5118110236
                        meter:2.3
                        milia:0.0003079972146
                         piad:12.93588301462
                       sazhen:1.077990251219
                       tochka:9055.118110236
                      vershok:51.74353205849
                       versta:0.0021559805024

Factor

This solution makes use of Factor's rather robust units vocabulary. Units may be defined in terms of any unit and converted to any unit through the power of inverse functions (via the inverse vocabulary). This means that we also have access to a variety of units defined in units.si, units.imperial, etc.

USING: formatting inverse io kernel math prettyprint quotations
sequences units.imperial units.si vocabs ;
IN: rosetta-code.units.russian

: arshin  ( n -- d ) 2+1/3 * feet ;
: tochka  ( n -- d ) 1/2800 * arshin ;
: liniya  ( n -- d ) 1/280 * arshin ;
: dyuim   ( n -- d ) 1/28 * arshin ;
: vershok ( n -- d ) 1/16 * arshin ;
: ladon   ( n -- d ) 7+1/2 * cm ;
: piad    ( n -- d ) 1/4 * arshin ;
: fut     ( n -- d ) 3/7 * arshin ;
: lokot   ( n -- d ) 45 * cm ;
: shag    ( n -- d ) 71 * cm ;
: sazhen  ( n -- d ) 3 * arshin ;
: versta  ( n -- d ) 1,500 * arshin ;
: milya   ( n -- d ) 10,500 * arshin ;

<PRIVATE

: convert ( quot -- )
    [ unparse rest rest but-last write "to:" print ] [ call ] bi
    "rosetta-code.units.russian" vocab-words { cm m km } append
    [ dup "%8u : " printf 1quotation [undo] call( x -- x ) . ]
    with each nl ; inline

: main ( -- )
    [ 6 m ] [ 1+7/8 milya ] [ 2 furlongs ] [ convert ] tri@ ;

PRIVATE>

MAIN: main
Output:
6 m to:
  versta : 5/889
 vershok : 134+874/889
    shag : 8+32/71
  tochka : 23622+6/127
     fut : 19+87/127
   ladon : 80
    piad : 33+663/889
  sazhen : 2+722/889
   lokot : 13+1/3
   milya : 5/6223
   dyuim : 236+28/127
  liniya : 2362+26/127
  arshin : 8+388/889
      cm : 600
       m : 6
      km : 3/500

1+7/8 milya to:
  versta : 13+1/8
 vershok : 315000
    shag : 19720+55/71
  tochka : 55125000
     fut : 45937+1/2
   ladon : 186690
    piad : 78750
  sazhen : 6562+1/2
   lokot : 31115
   milya : 1+7/8
   dyuim : 551250
  liniya : 5512500
  arshin : 19687+1/2
      cm : 1400175
       m : 14001+3/4
      km : 14+7/4000

2 furlongs to:
  versta : 66/175
 vershok : 9051+3/7
    shag : 566+238/355
  tochka : 1584000
     fut : 1320
   ladon : 5364+12/25
    piad : 2262+6/7
  sazhen : 188+4/7
   lokot : 894+2/25
   milya : 66/1225
   dyuim : 15840
  liniya : 158400
  arshin : 565+5/7
      cm : 40233+3/5
       m : 402+42/125
      km : 12573/31250

Fortran

PROGRAM RUS
 IMPLICIT NONE
 REAL, PARAMETER:: E_m = 1.
 REAL, PARAMETER:: E_mm = 1.E-3
 REAL, PARAMETER:: E_km = 1.E+3
 REAL, PARAMETER:: E_cm = 1.E-2
 REAL, PARAMETER:: E_arshin = 71.12 * E_cm
 REAL, PARAMETER:: E_fut = 3./7. * E_arshin
 REAL, PARAMETER:: E_piad = 1./4. * E_arshin
 REAL, PARAMETER:: E_vershok = 1./16. * E_arshin
 REAL, PARAMETER:: E_dyuim = 1./28. * E_arshin
 REAL, PARAMETER:: E_liniya = 1./280. * E_arshin
 REAL, PARAMETER:: E_tochka = 1./2800. * E_arshin
 REAL, PARAMETER:: E_ladon = 7.5 * E_cm
 REAL, PARAMETER:: E_lokot = 45 * E_cm
 REAL, PARAMETER:: E_sazhen = 3. * E_arshin
 REAL, PARAMETER:: E_versta = 1500. * E_arshin
 REAL, PARAMETER:: E_milya = 10500. * E_arshin
 INTEGER, PARAMETER:: N = 16
 CHARACTER(LEN=7), DIMENSION(N):: nam = (/&
  &'m      ', 'mm     ', 'km     ', 'cm     ',&
  &'arshin ', 'fut    ', 'piad   ', 'vershok',&
  &'dyuim  ', 'liniya ', 'tochka ', 'ladon  ',&
  &'lokot  ', 'sazhen ', 'versta ', 'milya  ' /)
 REAL, DIMENSION(N):: wert = (/ &
  &1., E_mm, E_km, E_cm,&
  &E_arshin, E_fut, E_piad, E_vershok,&
  &E_dyuim, E_liniya, E_tochka, E_ladon,&
  &E_lokot, E_sazhen, E_versta, E_milya /)
 CHARACTER(LEN=7):: RD_U
 REAL:: RD_V
 INTEGER:: I, J
 DO I=1, N
  WRITE(*, '(A, " ")', ADVANCE='NO')  nam(I)
 END DO
 WRITE (*, *)
 WRITE(*, '(A)', ADVANCE='NO') 'value unit -> '
 READ(*, *) RD_V, RD_U
 RD_U = ADJUSTL(RD_U)
 J = 1
 DO WHILE (NAM(J) .NE. RD_U)
  J = J + 1
  IF (J .GT. N) STOP "Unit not known: "//RD_U
 END DO
 RD_V = RD_V * wert(J)
 DO I=1, N
  J = J + 1
  IF (J .GT. N) J = 1
  WRITE (*, '(F20.3, " ", A)') RD_V / wert(J), nam(J)
 END DO
END PROGRAM RUS
Output:
m       mm      km      cm      arshin  fut     piad    vershok dyuim   liniya  tochka  ladon   lokot   sazhen  versta  milya   
value unit -> 1 m
            1000.000 mm     
               0.001 km     
             100.000 cm     
               1.406 arshin 
               3.281 fut    
               5.624 piad   
              22.497 vershok
              39.370 dyuim  
             393.701 liniya 
            3937.008 tochka 
              13.333 ladon  
               2.222 lokot  
               0.469 sazhen 
               0.001 versta 
               0.000 milya  
               1.000 m 

m       mm      km      cm      arshin  fut     piad    vershok dyuim   liniya  tochka  ladon   lokot   sazhen  versta  milya   
value unit -> 10 arshin
              23.333 fut    
              40.000 piad   
             160.000 vershok
             280.000 dyuim  
            2800.000 liniya 
           28000.002 tochka 
              94.827 ladon  
              15.804 lokot  
               3.333 sazhen 
               0.007 versta 
               0.001 milya  
               7.112 m      
            7112.000 mm     
               0.007 km     
             711.200 cm     
              10.000 arshin

Forth

Tested with GForth.

create units s" kilometer" 2, s" meter" 2, s" centimeter" 2, s" tochka" 2, s" liniya" 2, s" diuym" 2, s" vershok" 2, s" piad" 2, s" fut" 2, s" arshin" 2, s" sazhen" 2, s" versta" 2, s" milia" 2,
create values 1000.0e f, 1.0e f, 0.01e f, 0.000254e f, 0.00254e f, 0.0254e f, 0.04445e f, 0.1778e f, 0.3048e f, 0.7112e f, 2.1336e f, 1066.8e f, 7467.6e f,
: unit ( u1 -- caddr u1 )
    units swap 2 cells * + 2@ ;
: myval ( u1 -- caddr u1 )
    values swap 1 cells * + f@ ;
: 2define create 0 , 0 , ;

2define ch_u 
variable mlt
variable theunit
: show ( chosen_unit chosen_mutliplier -- )
    ch_u 2!
    mlt f!
    13 0 DO 
    ch_u 2@ i unit compare if  
    else mlt f@ f. i unit type cr ." ==========="  cr
        i myval theunit f!
        13 0 DO 
            ." 	" i unit type ." : " theunit f@ i myval f/ mlt f@ f* f. cr 
        LOOP
    then
    LOOP cr ;
1e s" meter" show
20e s" versta" show
10e s" milia" show
Output:
1. meter
===========
	kilometer: 0.001 
	meter: 1. 
	centimeter: 100. 
	tochka: 3937.00787401575 
	liniya: 393.700787401575 
	diuym: 39.3700787401575 
	vershok: 22.4971878515186 
	piad: 5.62429696287964 
	fut: 3.28083989501312 
	arshin: 1.40607424071991 
	sazhen: 0.468691413573303 
	versta: 0.000937382827146607 
	milia: 0.000133911832449515 

20. versta
===========
	kilometer: 21.336 
	meter: 21336. 
	centimeter: 2133600. 
	tochka: 84000000. 
	liniya: 8400000. 
	diuym: 840000. 
	vershok: 480000. 
	piad: 120000. 
	fut: 70000. 
	arshin: 30000. 
	sazhen: 10000. 
	versta: 20. 
	milia: 2.85714285714286 

10. milia
===========
	kilometer: 74.676 
	meter: 74676. 
	centimeter: 7467600. 
	tochka: 294000000. 
	liniya: 29400000. 
	diuym: 2940000. 
	vershok: 1680000. 
	piad: 420000. 
	fut: 245000. 
	arshin: 105000. 
	sazhen: 35000. 
	versta: 70. 
	milia: 10. 


Frink

One of Frink's unique features is tracking units of measure through all calculations. It is easy to add new units of measure and allow them to be automatically converted between any existing units. Frink's standard data file contains 642 units of length (not including prefixes) that this program can convert between.

arshin  := (2 + 1/3) ft
vershok := 1/16 arshin
sazhen  := 3 arshin
verst   := 1500 arshin
versta  := verst

do
{
   valstr = input["Enter unit of measure: ", "1 arshin"]
   val = eval[valstr]
   if ! (val conforms length)
      println["$valstr is not a unit of length."]
} until val conforms length

println["$valstr = "]
println["     " + (val -> "arshin")]
println["     " + (val -> "vershok")]
println["     " + (val -> "sazhen")]
println["     " + (val -> "verst")]
println["     " + (val -> "feet")]
println["     " + (val -> "meters")]
println["     " + (val -> "centimeters")]
println["     " + (val -> "kilometers")]
Output:
Enter unit of measure:  [1 arshin] 
1 arshin = 
     1 arshin
     16 vershok
     1/3 (approx. 0.33333333333333333) sazhen
     1/1500 (approx. 0.00066666666666666667) verst
     7/3 (approx. 2.3333333333333333) feet
     889/1250 (exactly 0.7112) meters
     1778/25 (exactly 71.12) centimeters
     889/1250000 (exactly 0.0007112) kilometers

Go

Translation of: Kotlin
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    units := []string{
        "tochka", "liniya", "dyuim", "vershok", "piad", "fut",
        "arshin", "sazhen", "versta", "milia",
        "centimeter", "meter", "kilometer",
    }

    convs := []float32{
        0.0254, 0.254, 2.54, 4.445, 17.78, 30.48,
        71.12, 213.36, 10668, 74676,
        1, 100, 10000,
    }

    scanner := bufio.NewScanner(os.Stdin)
    for {
        for i, u := range units {
            fmt.Printf("%2d %s\n", i+1, u)
        }
        fmt.Println()
        var unit int
        var err error
        for {
            fmt.Print("Please choose a unit 1 to 13 : ")
            scanner.Scan()
            unit, err = strconv.Atoi(scanner.Text())
            if err == nil && unit >= 1 && unit <= 13 {
                break
            }
        }
        unit--
        var value float64
        for {
            fmt.Print("Now enter a value in that unit : ")
            scanner.Scan()
            value, err = strconv.ParseFloat(scanner.Text(), 32)
            if err == nil && value >= 0 {
                break
            }
        }
        fmt.Println("\nThe equivalent in the remaining units is:\n")
        for i, u := range units {
            if i == unit {
                continue
            }
            fmt.Printf(" %10s : %g\n", u, float32(value)*convs[unit]/convs[i])
        }
        fmt.Println()
        yn := ""
        for yn != "y" && yn != "n" {
            fmt.Print("Do another one y/n : ")
            scanner.Scan()
            yn = strings.ToLower(scanner.Text())
        }
        if yn == "n" {
            return
        }
    }
}
Output:

Sample input/output:

 1 tochka
 2 liniya
 3 dyuim
 4 vershok
 5 piad
 6 fut
 7 arshin
 8 sazhen
 9 versta
10 milia
11 centimeter
12 meter
13 kilometer

Please choose a unit 1 to 13 : 13
Now enter a value in that unit : 1

The equivalent in the remaining units is:

     tochka : 393700.78
     liniya : 39370.08
      dyuim : 3937.0078
    vershok : 2249.7188
       piad : 562.4297
        fut : 328.08398
     arshin : 140.60742
     sazhen : 46.86914
     versta : 0.9373828
      milia : 0.13391183
 centimeter : 10000
      meter : 100

Do another one y/n : n

Haskell

module Main where

import Text.Printf (printf)
import System.Environment (getArgs, getProgName)

tochka     = ("tochka"    , 0.000254)
liniya     = ("liniya"    , 0.00254)
centimeter = ("centimeter", 0.01)
diuym      = ("diuym"     , 0.0254)
vershok    = ("vershok"   , 0.04445)
piad       = ("piad"      , 0.1778)
fut        = ("fut"       , 0.3048)
arshin     = ("arshin"    , 0.7112)
meter      = ("meter"     , 1.0)
sazhen     = ("sazhen"    , 2.1336)
kilometer  = ("kilometer" , 1000.0)
versta     = ("versta"    , 1066.8)
milia      = ("milia"     , 7467.6)

units :: [(String, Double)]
units = [tochka, liniya, centimeter, diuym, vershok, piad, fut, arshin, meter, sazhen, kilometer, versta, milia]


convert :: Double -> Double -> IO ()
convert num factor = mapM_ (\(unit, fac) -> printf "| %-10s | %-22f|\n" unit  (num * factor / fac)) units

main :: IO ()
main = do
  args <- getArgs
  case args of
    [x,y] | [(num, "")]   <- reads x :: [(Double, String)]
          , (Just factor) <- lookup y units -> convert num factor
    (_) -> do
      name <- getProgName
      printf "Arguments were wrong - please use ./%s <number> <unit>\n" name

Output:


./ruslen 8 meter

| tochka     | 31496.062992125986    |
| liniya     | 3149.606299212598     |
| centimeter | 800.0                 |
| diuym      | 314.96062992125985    |
| vershok    | 179.97750281214846    |
| piad       | 44.994375703037115    |
| fut        | 26.246719160104984    |
| arshin     | 11.248593925759279    |
| meter      | 8.0                   |
| sazhen     | 3.749531308586427     |
| kilometer  | 0.008                 |
| versta     | 0.0074990626171728535 |
| milia      | 0.0010712946595961218 |

./ruslen 1 arshin

| tochka     | 2800.0000000000005    |
| liniya     | 280.0                 |
| centimeter | 71.12                 |
| diuym      | 28.000000000000004    |
| vershok    | 16.0                  |
| piad       | 4.0                   |
| fut        | 2.3333333333333335    |
| arshin     | 1.0                   |
| meter      | 0.7112                |
| sazhen     | 0.33333333333333337   |
| kilometer  | 0.0007112             |
| versta     | 0.0006666666666666668 |
| milia      | 0.00009523809523809524|

./ruslen 8 notaunit

Arguments were wrong - please use ./ruslen <number> <unit>


./ruslen notanumber meter

Arguments were wrong - please use ./ruslen <number> <unit>

J

Translation of python.

#!/usr/bin/ijconsole
UNIT2MULT=: |:_2 (; ".)&;/\;:'arshin 0.7112 centimeter 0.01 diuym 0.0254 fut 0.3048 kilometer 1000.0 liniya 0.00254 meter 1.0 milia 7467.6 piad 0.1778 sazhen 2.1336 tochka 0.000254 vershok 0.04445 versta 1066.8'

conv=: UNIT2MULT 1 : 0 
 if. 2 ~: # y do. 'ERROR. Need two arguments - number then units'
 else.
  'VALUE UNIT'=. (;~ _&".)&;~/y
  if. _ = VALUE do. 'ERROR. First argument must be a (float) number'
  else.
   try. 
     scale=. ({::~ i.&(<UNIT))~/m
     ((":;:inv y),' to:'),":({.m),.({:m)*L:0 VALUE%scale
   catch.
     'ERROR. Only know the following units: ',;:inv{.m
   end.
  end.
 end.
)

NB. for use from os command line only:
exit echo conv }.ARGV

If this were named ormol

$ ormol 8 meter
8 meter to:
┌──────────┬──────────┐
│arshin    │11.2486   │
├──────────┼──────────┤
│centimeter│800       │
├──────────┼──────────┤
│diuym     │314.961   │
├──────────┼──────────┤
│fut       │26.2467   │
├──────────┼──────────┤
│kilometer │0.008     │
├──────────┼──────────┤
│liniya    │3149.61   │
├──────────┼──────────┤
│meter     │8         │
├──────────┼──────────┤
│milia     │0.00107129│
├──────────┼──────────┤
│piad      │44.9944   │
├──────────┼──────────┤
│sazhen    │3.74953   │
├──────────┼──────────┤
│tochka    │31496.1   │
├──────────┼──────────┤
│vershok   │179.978   │
├──────────┼──────────┤
│versta    │0.00749906│
└──────────┴──────────┘

The same display can be achieved from the J comand line using the expression conv ;:'8 meter'. However, this is only possible if the exit line is omitted, since the exit command would exit the J session. If dual use was desired, the code could be packaged as a shell script (see the native shebang task) and the exit line could be made conditional on the name of that shell script (which would appear as the first element in ARGV).

Java

public class OldRussianMeasures {

    final static String[] keys = {"tochka", "liniya", "centimeter", "diuym",
        "vershok", "piad", "fut", "arshin", "meter", "sazhen", "kilometer",
        "versta", "milia"};

    final static double[] values = {0.000254, 0.00254, 0.01,0.0254,
        0.04445, 0.1778, 0.3048, 0.7112, 1.0, 2.1336, 1000.0,
        1066.8, 7467.6};

    public static void main(String[] a) {
        if (a.length == 2 && a[0].matches("[+-]?\\d*(\\.\\d+)?")) {
            double inputVal = lookup(a[1]);
            if (!Double.isNaN(inputVal)) {
                double magnitude = Double.parseDouble(a[0]);
                double meters = magnitude * inputVal;
                System.out.printf("%s %s to: %n%n", a[0], a[1]);
                for (String k: keys)
                    System.out.printf("%10s: %g%n", k, meters / lookup(k));
                return;
            }
        }
        System.out.println("Please provide a number and unit");

    }

    public static double lookup(String key) {
        for (int i = 0; i < keys.length; i++)
            if (keys[i].equals(key))
                return values[i];
        return Double.NaN;
    }
}
1 meter to: 

    tochka: 3937,01
    liniya: 393,701
centimeter: 100,000
     diuym: 39,3701
   vershok: 22,4972
      piad: 5,62430
       fut: 3,28084
    arshin: 1,40607
     meter: 1,00000
    sazhen: 0,468691
 kilometer: 0,00100000
    versta: 0,000937383
     milia: 0,000133912

1 milia to: 

    tochka: 2,94000e+07
    liniya: 2,94000e+06
centimeter: 746760
     diuym: 294000
   vershok: 168000
      piad: 42000,0
       fut: 24500,0
    arshin: 10500,0
     meter: 7467,60
    sazhen: 3500,00
 kilometer: 7,46760
    versta: 7,00000
     milia: 1,00000

jq

Works with: jq
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;

def Units: {
  "arshin"    : 0.7112,
  "centimeter": 0.01,
  "diuym"     : 0.0254,
  "fut"       : 0.3048,
  "kilometer" : 1000.0,
  "liniya"    : 0.00254,
  "meter"     : 1.0,
  "milia"     : 7467.6,
  "piad"      : 0.1778,
  "sazhen"    : 2.1336,
  "tochka"    : 0.000254,
  "vershok"   : 0.04445,
  "versta"    : 1066.8
};

def cyrillic: {
  "arshin"    : "арши́н",
  "centimeter": "сантиметр",
  "diuym"     : "дюйм",
  "fut"       : "фут",
  "kilometer" : "километр",
  "liniya"    : "ли́ния",
  "meter"     : "метр",
  "milia"     : "ми́ля",
  "piad"      : "пядь",
  "sazhen"    : "саже́нь",
  "tochka"    : "то́чка",
  "vershok"   : "вершо́к",
  "versta"    : "верста́"
};

def request:
  def explain: "number and unit of measurement expected vs \(.)" | error;
  def check:
    $ARGS.positional
    | if length >= 2
      then (try (.[0] | tonumber) catch false) as $n
      | (.[1] | sub("s$";"")) as $u
      | if $n and Units[$u] then [$n, $u]
        else explain
        end
      else explain
      end;
  check ;

# Input: a number
# Delete unhelpful digits
def humanize($n):
   tostring
   | ( capture("^(?<head>[0-9]*)[.](?<zeros>0*)(?<tail>[0-9]*)$")
       | (.head|length) as $hl
       | if $hl > $n then .head + "."
         elif .head | (. == "" or . == "0")
         then .head + "." + .zeros + .tail[:1 + $n - $hl]
         else .head + "." + (.zeros + .tail)[:1 + $n - $hl]
         end ) // .;

def display:
  Units
  | . as $Units
  | request as [$n, $unit]
  | "\($n) \($unit)\(if $n == 1 then "" else "s" end) ::",
    (to_entries[]
     | "\(.key|lpad(10)) : \(($n * $Units[$unit] / .value) | humanize(5)) \(cyrillic[.key])"),
    "" ;

display

Invocation example

jq -nr -f old-russian-measure-of-length.jq --args 2.3 meter
Output:
2.3 meters ::
    arshin : 3.23397 арши́н
centimeter : 229.999 сантиметр
     diuym : 90.5511 дюйм
       fut : 7.54593 фут
 kilometer : 0.0023 километр
    liniya : 905.511 ли́ния
     meter : 2.3 метр
     milia : 0.00030799 ми́ля
      piad : 12.9358 пядь
    sazhen : 1.07799 саже́нь
    tochka : 9055.11 то́чка
   vershok : 51.7435 вершо́к
    versta : 0.0021559 верста́

Julia

Works with: Julia version 0.6
Translation of: Python
using DataStructures

const unit2mult = Dict(
    "arshin" => 0.7112, "centimeter" => 0.01,     "diuym"   => 0.0254,
    "fut"    => 0.3048, "kilometer"  => 1000.0,   "liniya"  => 0.00254,
    "meter"  => 1.0,    "milia"      => 7467.6,   "piad"    => 0.1778,
    "sazhen" => 2.1336, "tochka"     => 0.000254, "vershok" => 0.04445,
    "versta" => 1066.8)

@assert length(ARGS) == 2 "need two arguments - number then units"

global value
try value = parse(Float64, ARGS[1])
catch error("first argument must be a (float) number") end

if isnull(value) error("first argument must be a (float) number") end
unit = ARGS[2]
@assert unit  keys(unit2mult) "only know the following units:\n" * join(keys(unit2mult), ", ")

println("$value $unit to:")
for (unt, mlt) in sort(unit2mult)
    @printf("  %10s: %g\n", unt, value * unit2mult[unit] / mlt)
end
Output:
$ julia Old_Russian_measure_of_length.jl 2.3 meter
2.3 meter to:
      arshin: 3.23397
  centimeter: 230
       diuym: 90.5512
         fut: 7.54593
   kilometer: 0.0023
      liniya: 905.512
       meter: 2.3
       milia: 0.000307997
        piad: 12.9359
      sazhen: 1.07799
      tochka: 9055.12
     vershok: 51.7435
      versta: 0.00215598

Kotlin

Translation of: FreeBASIC
// version 1.0.6

/* clears console on Windows 10 */
fun cls() = ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor()

fun main(args: Array<String>) {
    val units = listOf("tochka", "liniya", "dyuim", "vershok", "piad", "fut",
                       "arshin", "sazhen", "versta", "milia",
                       "centimeter", "meter", "kilometer")
    val convs = arrayOf(0.0254f, 0.254f, 2.54f, 4.445f, 17.78f, 30.48f, 
                        71.12f, 213.36f, 10668.0f, 74676.0f, 
                        1.0f, 100.0f, 10000.0f)
    var unit: Int
    var value: Float
    var yn : String
    do {
        cls()
        println()
        for (i in 0 until units.size) println("${"%2d".format(i + 1)} ${units[i]}")
        println()
        do {
            print("Please choose a unit 1 to 13 : ")
            unit = try { readLine()!!.toInt() } catch (e: NumberFormatException) { 0 }
        }
        while (unit !in 1..13)
        unit--
        do {
            print("Now enter a value in that unit : ")
            value = try { readLine()!!.toFloat() } catch (e: NumberFormatException) { -1.0f }
        }
        while (value < 0.0f)
        println("\nThe equivalent in the remaining units is:\n")
        for (i in 0 until units.size) {
            if (i == unit) continue            
            println(" ${units[i].padEnd(10)} : ${value * convs[unit] / convs[i]}")
        }
        println()
        do {
            print("Do another one y/n : ")
            yn = readLine()!!.toLowerCase()
        }
        while (yn != "y" && yn != "n")            
    }
    while (yn == "y")
}

Sample input/output

Output:

 1 tochka
 2 liniya
 3 dyuim
 4 vershok
 5 piad
 6 fut
 7 arshin
 8 sazhen
 9 versta
10 milia
11 centimeter
12 meter
13 kilometer

Please choose a unit 1 to 13 : 13
Now enter a value in that unit : 1

The equivalent in the remaining units is:

 tochka     : 393700.78
 liniya     : 39370.08
 dyuim      : 3937.0078
 vershok    : 2249.7188
 piad       : 562.4297
 fut        : 328.08398
 arshin     : 140.60742
 sazhen     : 46.86914
 versta     : 0.9373828
 milia      : 0.13391183
 centimeter : 10000.0
 meter      : 100.0

Do another one y/n : n

M2000 Interpreter

module OldRusianMeasureOfLength {
	unit2mult=list:="arshin" := 0.7112, "centimeter" := 0.01, "diuym" := 0.0254, "fut" := 0.3048, "kilometer" := 1000.0, "liniya" := 0.00254, "meter" := 1.0, "milia" := 7467.6,   "piad" := 0.1778, "sazhen" := 2.1336, "tochka":= 0.000254, "vershok" := 0.04445, "versta" := 1066.8
	k=each(unit2mult)
	menu  // empty menu list
	menu + "(exit)"
	while k
		menu + eval$(k!)
	end while
	double v
	do
		Print "Value, Unit";
		input ":", v;
		print " ";
		menu !
		if menu>0 then
			print menu$(menu)			
			if menu$(menu)="(exit)" then exit
			Print v;" ";menu$(menu);" to:"
			v*=unit2mult(menu$(menu))
			k=each(unit2mult)
			while k
				if eval$(k!)=menu$(menu) then continue
				print format$("{0:-12}: {1}",eval$(k!), round(v/eval(k),9))
			end while
		else
			exit
		end if
	always
}
OldRusianMeasureOfLength
Output:
Value, Unit: 1 meter
1 meter to:
      arshin: 1.406074241
  centimeter: 100
       diuym: 39.37007874
         fut: 3.280839895
   kilometer: 0.001
      liniya: 393.700787402
       meter: 1
       milia: 0.000133912
        piad: 5.624296963
      sazhen: 0.468691414
      tochka: 3937.007874016
     vershok: 22.497187852
      versta: 0.000937383

Mathematica / Wolfram Language

These units are built-in to Wolfram Language:

ClearAll[units, ConvertRussianQuantities]
units = {"RussianVershoks", "RussianArshins", "RussianSazhens", "RussianVerstas", "Centimeters", "Meters", "Kilometers"};
ConvertRussianQuantities[q_Quantity] := UnitConvert[q, #] & /@ Select[units, QuantityUnit[q] != # &]
ConvertRussianQuantities[Quantity[1, "Vershoks"]]
ConvertRussianQuantities[Quantity[1, "Arshins"]]
Output:
{1/16 Russian arshins, 1/48 Russian sazhens, 1/24000 Russian versts, 889/200 cm, 889/20000 m, 889/20000000 km}
{16 Russian vershoks, 1/3 Russian sazhens, 1/1500 Russian versts, 1778/25 cm, 889/1250 m, 889/1250000 km}


МК-61/52

П7	1	0	0	*	П8	1	ВП	5	/
П9	ИП7	1	0	6	7	/	П0	5	0
0	*	ПC	3	*	ПA	1	6	*	ПB
С/П	ПB	1	6	/	ПA	3	/	ПC	5
0	0	/	П0	1	0	6	7	/	БП
00

Instruction: l, meters = РX В/О С/П; l, vershoks = БП 3 1 С/П; l, arshins = РX БП 3 5 С/П; l, sazhens = РX БП 3 8 С/П; l, versts = РX БП 4 3 С/П; РX = РB = l, vershoks; РA = l, arshins; РB = l, versts; РC = l, sazhens; Р7 = l, meters; Р8 = l, centimeters; Р9 = l, kilometers.

Example: 100 m = 2249,2971 vershoks = 140,58107 arshins = 46,860366 sazhens = 0,093790712 versts; 3 vershoks = 13,3375 cm; 2 sazhens = 96 vershoks = 6 arshins = 4,268 m; 1 verst = 1,067 km.

Nim

Translation of: Python
import os, strutils, sequtils, tables

const Unit2Mult = {"arshin": 0.7112, "centimeter": 0.01,     "diuym":   0.0254,
                   "fut":    0.3048, "kilometer":  1000.0,   "liniya":  0.00254,
                   "meter":  1.0,    "milia":      7467.6,   "piad":    0.1778,
                   "sazhen": 2.1336, "tochka":     0.000254, "vershok": 0.04445,
                   "versta": 1066.8}.toOrderedTable

if paramCount() != 2:
  raise newException(ValueError, "need two arguments: number then units.")

let value = try: parseFloat(paramStr(1))
            except ValueError:
              raise newException(ValueError, "first argument must be a (float) number.")

let unit = paramStr(2)
if unit notin Unit2Mult:
  raise newException(ValueError,
                     "only know the following units: " & toSeq(Unit2Mult.keys).join(" "))

echo value, ' ', unit, " to:"
for (key, mult) in Unit2Mult.pairs:
  echo key.align(10), ": ", formatFloat(value * Unit2Mult[unit] / mult, ffDecimal, 5)
Output:

Output for command: ./convert 1 meter

1.0 meter to:
    arshin: 1.40607
centimeter: 100.00000
     diuym: 39.37008
       fut: 3.28084
 kilometer: 0.00100
    liniya: 393.70079
     meter: 1.00000
     milia: 0.00013
      piad: 5.62430
    sazhen: 0.46869
    tochka: 3937.00787
   vershok: 22.49719
    versta: 0.00094

Perl

Displaying converted values to 5 significant digits.

Translation of: Raku
sub convert {
    my($magnitude, $unit) = @_;
     my %factor = (
        tochka     => 0.000254,
        liniya     => 0.00254,
        diuym      => 0.0254,
        vershok    => 0.04445,
        piad       => 0.1778,
        fut        => 0.3048,
        arshin     => 0.7112,
        sazhen     => 2.1336,
        versta     => 1066.8,
        milia      => 7467.6,
        centimeter => 0.01,
        meter      => 1.0,
        kilometer  => 1000.0,
    );

    my $base= $magnitude * $factor{$unit};
    my $result .= "$magnitude $unit to:\n";
    for (sort { $factor{$a} <=> $factor{$b} } keys %factor) {
        $result .= sprintf "%10s: %s\n", $_, sigdig($base / $factor{$_}, 5) unless $_ eq $unit
    }
    return $result;
}

sub sigdig {
    my($num,$sig) = @_;
    return $num unless $num =~ /\./;

    $num =~ /([1-9]\d*\.?\d*)/;
    my $prefix = $`;
    my $match  = $&;
    $sig++ if $match =~ /\./;
    my $digits = substr $match, 0, $sig;
    my $nextd  = substr $match, $sig, 1;
    $digits =~ s/(.)$/{1+$1}/e if $nextd > 5;
    return $prefix . $digits;
}

print convert(1,'meter'), "\n\n";
print convert(1,'milia'), "\n";
Output:
    tochka: 3937.0
    liniya: 393.70
centimeter: 100
     diuym: 39.370
   vershok: 22.497
      piad: 5.6243
       fut: 3.2808
    arshin: 1.4061
    sazhen: 0.46869
 kilometer: 0.001
    versta: 0.00093738
     milia: 0.00013391

1 milia to:
    tochka: 29400000
    liniya: 2940000
centimeter: 746760
     diuym: 294000
   vershok: 168000
      piad: 42000
       fut: 24500
    arshin: 10500
     meter: 7467.6
    sazhen: 3500
 kilometer: 7.4676
    versta: 7

Phix

with javascript_semantics 
constant units = {{"-- metric ---",0},
                  {"kilometer",1000},
                  {"km","kilometer"},
                  {"meter",1},
                  {"m","meter"},
                  {"centimeter",0.01},
                  {"cm","centimeter"},
                  {" old russian ",0},
                  {"tochka",0.000254},
                  {"liniya",0.00254},
                  {"diuym",0.0254},
                  {"vershok",0.04445},
                  {"piad",0.1778},
                  {"fut",0.3048},
                  {"arshin",0.7112},
                  {"sazhen",2.1336},
                  {"versta",1066.8},
                  {"milia",7467.6}},
        {names,facts} = columnize(units)
 
function strim(atom v)
    string res = sprintf("%,f",v)
    integer l = length(res)
    while l do
        integer c = res[l]
        if c!='0' then
            l -= 1+(c='.')
            exit
        end if
        l -= 1
    end while
    res = res[1..l+1]
    return res
end function
 
-- Obviously, uncomment these lines for a prompt (not under p2js)
--while true do
--  string input = prompt_string("\nEnter length & measure or CR to exit:")
--  if input="" then exit end if
--  input = lower(trim(input))
    string input = "7.4676 km"
    string fmt = iff(find(' ',input)?"%f %s":"%f%s")
    sequence r = scanf(input,fmt)
    if length(r)!=1 then
        printf(1,"enter eg 1km or 1 kilometer\n")
    else
        {atom v, string name} = r[1]
        integer k = find(name,names)
        if k=0 or facts[k]=0 then
            printf(1,"unrecognised unit: %s\n",{name})
        else
            if string(facts[k]) then
                -- abbreviation, eg cm->centimeter
                k = find(facts[k],names)
            end if
            for i=1 to length(names) do
                object f = facts[i]
                if f=0 then             -- header
                    printf(1,"--------------%s--------------\n",{names[i]})
                elsif atom(facts[i]) then -- not abbrev
                    printf(1,"%20s %s\n",{strim(v*facts[k]/facts[i]),names[i]})
                end if
            end for
        end if
    end if
--end while
Output:
Enter length & measure or CR to exit:7.4676 km
---------------- metric -----------------
              7.4676 kilometer
             7,467.6 meter
             746,760 centimeter
-------------- old russian --------------
          29,400,000 tochka
           2,940,000 liniya
             294,000 diuym
             168,000 vershok
              42,000 piad
              24,500 fut
              10,500 arshin
               3,500 sazhen
                   7 versta
                   1 milia

Enter length & measure or CR to exit:

Python

Run as:

commandname <value> <unit>
from sys import argv
 
unit2mult = {"arshin": 0.7112, "centimeter": 0.01,     "diuym":   0.0254,
             "fut":    0.3048, "kilometer":  1000.0,   "liniya":  0.00254,
             "meter":  1.0,    "milia":      7467.6,   "piad":    0.1778,
             "sazhen": 2.1336, "tochka":     0.000254, "vershok": 0.04445,
             "versta": 1066.8}
 
if __name__ == '__main__':
    assert len(argv) == 3, 'ERROR. Need two arguments - number then units'
    try:
        value = float(argv[1])
    except:
        print('ERROR. First argument must be a (float) number')
        raise
    unit = argv[2]
    assert unit in unit2mult, ( 'ERROR. Only know the following units: ' 
                                + ' '.join(unit2mult.keys()) )

    print("%g %s to:" % (value, unit))
    for unt, mlt in sorted(unit2mult.items()):
        print('  %10s: %g' % (unt, value * unit2mult[unit] / mlt))
Output:
1 meter to:
      arshin: 1.40607
  centimeter: 100
       diuym: 39.3701
         fut: 3.28084
   kilometer: 0.001
      liniya: 393.701
       meter: 1
       milia: 0.000133912
        piad: 5.6243
      sazhen: 0.468691
      tochka: 3937.01
     vershok: 22.4972
      versta: 0.000937383
Output:
1 milia to:
      arshin: 10500
  centimeter: 746760
       diuym: 294000
         fut: 24500
   kilometer: 7.4676
      liniya: 2.94e+06
       meter: 7467.6
       milia: 1
        piad: 42000
      sazhen: 3500
      tochka: 2.94e+07
     vershok: 168000
      versta: 7
Output:

When given a wrong number

ERROR. First argument must be a (float) number
Traceback (most recent call last):
  File "C:\Users\Paddy\Google Drive\Code\old_russian_lengths.py", line 18, in <module>
    value = float(argv[1])
ValueError: could not convert string to float: '1xx'
Output:

When given a wrong unit

Traceback (most recent call last):
  File "C:\Users\Paddy\Google Drive\Code\old_russian_lengths.py", line 24, in <module>
    + ' '.join(unit2mult.keys()) )
AssertionError: ERROR. Only know the following units: kilometer tochka versta fut diuym liniya vershok meter arshin piad centimeter sazhen milia

Racket

Follows the Raku solution, produces similar output.

#lang racket

(define units
  '([tochka        0.000254]
    [liniya        0.00254]
    [diuym         0.0254]
    [vershok       0.04445]
    [piad          0.1778]
    [fut           0.3048]
    [arshin        0.7112]
    [sazhen        2.1336]
    [versta     1066.8]
    [milia      7467.6]
    [centimeter    0.01]
    [meter         1.0]
    [kilometer  1000.0]))

(define (show u)
  (printf "1 ~s to:\n" u)
  (define n (cadr (assq u units)))
  (for ([u2 units] #:unless (eq? u (car u2)))
    (displayln (~a (~a (car u2) #:width 10 #:align 'right) ": "
                   (~r (/ n (cadr u2)) #:precision 4))))
  (newline))

(show 'meter)
(show 'milia)

Raku

(formerly Perl 6)

Works with: rakudo version 2015.12

Fairly straightfoward. Define a hash of conversion factors then apply them. Makes no attempt to do correct pluralization because I have no idea what the correct plurals are and little interest in researching them. Conversion factors from Wikipedia: Obsolete Russian units of measurement.

convert(1, 'meter');

say '*' x 40, "\n";

convert(1, 'milia');

sub convert (Real $magnitude, $unit) {
     my %factor = 
        tochka     => 0.000254,
        liniya     => 0.00254,
        diuym      => 0.0254,
        vershok    => 0.04445,
        piad       => 0.1778,
        fut        => 0.3048,
        arshin     => 0.7112,
        sazhen     => 2.1336,
        versta     => 1066.8,
        milia      => 7467.6,
        centimeter => 0.01,
        meter      => 1.0,
        kilometer  => 1000.0,
    ;

    my $meters = $magnitude * %factor{$unit.lc};

    say "$magnitude $unit to:\n", '_' x 40;

    printf "%10s: %s\n", $_,  $meters / %factor{$_} unless $_ eq $unit.lc
      for %factor.keys.sort:{ +%factor{$_} }
}
1 meter to:
________________________________________
    tochka: 3937.007874
    liniya: 393.700787
centimeter: 100
     diuym: 39.370079
   vershok: 22.497188
      piad: 5.624297
       fut: 3.280840
    arshin: 1.406074
    sazhen: 0.468691
 kilometer: 0.001
    versta: 0.000937
     milia: 0.000134
****************************************

1 milia to:
________________________________________
    tochka: 29400000
    liniya: 2940000
centimeter: 746760
     diuym: 294000
   vershok: 168000
      piad: 42000
       fut: 24500
    arshin: 10500
     meter: 7467.6
    sazhen: 3500
 kilometer: 7.4676
    versta: 7

REXX

Program features:

  •   shows all   other   units of measurements when any unit is specified.
  •   accepts abbreviations of the length units
  •   does rounding so results are more meaningful and recognizable
  •   does error checking on the user input
  •   added other old Russian units of measurements
  •   uses the correct length unit names when not plural
  •   columnarized the output   (instead of a horizontal stream).
/*REXX program converts a   metric  or  old Russian length   to various other lengths.  */
                              numeric digits 200                      /*lots of digits. */
  /*──translation───*/
  /*tip, top        */        vershok  = 22.492971                    /*1.75 inch.      */
  /*palm, quarter   */        piad     = vershok    /   4             /*(also) chetvert.*/
  /*yard            */        arshin   = vershok    /  16
  /*fathom          */        sazhen   = arshin     /   3
  /*turn (of a plow)*/        verst    = sazhen     / 500             /*(also) a versta.*/
  /*mile            */        milia    = verst      /   1.5
  /*inch            */        diuym    = arshin     *  28
  /*foot            */        fut      = diuym      /  12             /*sounds like foot*/
  /*line            */        liniya   = diuym      *  10
  /*point           */        tochka   = diuym      * 100

KM= 1000;           CM=100                       /*define a couple of metric multipliers*/
sw= linesize() -1                                /*get the linesize (screen width)  - 1.*/
parse arg N what _ __                            /*obtain the user's input from the C.L.*/
if N==''               then call  err  'no arguments specified.'
if \datatype(N, 'N')   then call  err  'units not numeric: '    N
if _\==''              then call  err  'too many arguments specified: '   _   __
n= n / 1                                         /*normalize it  (004──►4  7.──►7,  etc.*/
if what==''  then what= 'meters';   whatU= what  /*None specified?  Then assume meters. */
upper whatU                                      /*an uppercase version for ABBREV bif. */
                         select                  /* [↓]  convert the length ───► meters.*/
                         when abbrev('METRES'     , whatU    )  |,
                              abbrev('METERS'     , whatU    )       then  m= N
                         when abbrev('KILOMETRES' , whatU, 2 )  |,
                              abbrev('KILOMETERS' , whatU, 2 )  |,
                              abbrev('KMS'        , whatU,   )       then  m= N * KM
                         when abbrev('CENTIMETRES', whatU, 2 )  |,
                              abbrev('CENTIMETERS', whatU, 2 )  |,
                              abbrev('CMS'        , whatU, 2 )       then  m= N / CM
                         when abbrev('ARSHINS'    , whatU    )       then  m= N / arshin
                         when abbrev('DIUYM'      , whatU    )       then  m= N / diuym
                         when abbrev('FUT'        , whatU    )       then  m= N / fut
                         when abbrev('LINIYA'     , whatU    )       then  m= N / liniya
                         when abbrev('PIADS'      , whatU    )  |,
                              abbrev('CHETVERTS'  , whatU, 2 )       then  m= N / piad
                         when abbrev('SAZHENS'    , whatU    )       then  m= N / sazhen
                         when abbrev('TOCHKA'     , whatU    )       then  m= N / tochka
                         when abbrev('VERSHOKS'   , whatU, 5 )       then  m= N / vershok
                         when abbrev('VERSTAS'    , whatU, 5 )  |,
                              abbrev('VERSTS'     , whatU, 2 )       then  m= N / verst
                         when abbrev('MILIA'      , whatU, 2 )       then  m= N / milia
                         otherwise     call err   'invalid measure name: '        what
                         end   /*select*/
                                             say centre('metric',      sw, "─")
call tell m / KM       ,   'kilometer'
call tell m            ,   'meter'
call tell m * CM       ,   'centimeter'
                                             say centre('old Russian', sw, "─")
call tell m * milia    ,   'milia'
call tell m * verst    ,   'verst'
call tell m * sazhen   ,   'sazhen'
call tell m * arshin   ,   'arshin'
call tell m * fut      ,   'fut'
call tell m * piad     ,   'piad'
call tell m * vershok  ,   'vershok'
call tell m * diuym    ,   'diuym'
call tell m * liniya   ,   'liniya'
call tell m * tochka   ,   'tochka'              /* ◄─── TELL shows eight decimal digits*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
err:  say center(' error ', sw % 2, "*");   do j=1  to arg();  say arg(j);  end;   exit 13
s:    if arg(1)=1  then return arg(3);      return word( arg(2) 's', 1)       /*plurals.*/
tell: parse arg $;  numeric digits 8;  $= $ / 1;  say right($, 40) arg(2)s($);      return/*REXX program converts a   metric  or  old Russian length   to various other lengths.  */
                              numeric digits 200                      /*lots of digits. */
  /*──translation───*/
  /*tip, top        */        vershok  = 22.492971                    /*1.75 inch.      */
  /*palm, quarter   */        piad     = vershok    /   4             /*(also) chetvert.*/
  /*yard            */        arshin   = vershok    /  16
  /*fathom          */        sazhen   = arshin     /   3
  /*turn (of a plow)*/        verst    = sazhen     / 500             /*(also) a versta.*/
  /*mile            */        milia    = verst      /   1.5
  /*inch            */        diuym    = arshin     *  28
  /*foot            */        fut      = diuym      /  12             /*sounds like foot*/
  /*line            */        liniya   = diuym      *  10
  /*point           */        tochka   = diuym      * 100

KM= 1000;           CM=100                       /*define a couple of metric multipliers*/
sw= linesize() -1                                /*get the linesize (screen width)  - 1.*/
parse arg N what _ __                            /*obtain the user's input from the C.L.*/
if N==''               then call  err  'no arguments specified.'
if \datatype(N, 'N')   then call  err  'units not numeric: '    N
if _\==''              then call  err  'too many arguments specified: '   _   __
n= n / 1                                         /*normalize it  (004──►4  7.──►7,  etc.*/
if what==''  then what= 'meters';   whatU= what  /*None specified?  Then assume meters. */
upper whatU                                      /*an uppercase version for ABBREV bif. */
                         select                  /* [↓]  convert the length ───► meters.*/
                         when abbrev('METRES'     , whatU    )  |,
                              abbrev('METERS'     , whatU    )       then  m= N
                         when abbrev('KILOMETRES' , whatU, 2 )  |,
                              abbrev('KILOMETERS' , whatU, 2 )  |,
                              abbrev('KMS'        , whatU,   )       then  m= N * KM
                         when abbrev('CENTIMETRES', whatU, 2 )  |,
                              abbrev('CENTIMETERS', whatU, 2 )  |,
                              abbrev('CMS'        , whatU, 2 )       then  m= N / CM
                         when abbrev('ARSHINS'    , whatU    )       then  m= N / arshin
                         when abbrev('DIUYM'      , whatU    )       then  m= N / diuym
                         when abbrev('FUT'        , whatU    )       then  m= N / fut
                         when abbrev('LINIYA'     , whatU    )       then  m= N / liniya
                         when abbrev('PIADS'      , whatU    )  |,
                              abbrev('CHETVERTS'  , whatU, 2 )       then  m= N / piad
                         when abbrev('SAZHENS'    , whatU    )       then  m= N / sazhen
                         when abbrev('TOCHKA'     , whatU    )       then  m= N / tochka
                         when abbrev('VERSHOKS'   , whatU, 5 )       then  m= N / vershok
                         when abbrev('VERSTAS'    , whatU, 5 )  |,
                              abbrev('VERSTS'     , whatU, 2 )       then  m= N / verst
                         when abbrev('MILIA'      , whatU, 2 )       then  m= N / milia
                         otherwise     call err   'invalid measure name: '        what
                         end   /*select*/
                                             say centre('metric',      sw, "─")
call tell m / KM       ,   'kilometer'
call tell m            ,   'meter'
call tell m * CM       ,   'centimeter'
                                             say centre('old Russian', sw, "─")
call tell m * milia    ,   'milia'
call tell m * verst    ,   'verst'
call tell m * sazhen   ,   'sazhen'
call tell m * arshin   ,   'arshin'
call tell m * fut      ,   'fut'
call tell m * piad     ,   'piad'
call tell m * vershok  ,   'vershok'
call tell m * diuym    ,   'diuym'
call tell m * liniya   ,   'liniya'
call tell m * tochka   ,   'tochka'              /* ◄─── TELL shows eight decimal digits*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
err:  say center(' error ', sw % 2, "*");   do j=1  to arg();  say arg(j);  end;   exit 13
s:    if arg(1)=1  then return arg(3);      return word( arg(2) 's', 1)       /*plurals.*/
tell: parse arg $;  numeric digits 8;  $= $ / 1;  say right($, 40) arg(2)s($);      return

This REXX program makes use of   LINESIZE   REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console).

The   LINESIZE.REX   REXX program is included here   ──►   LINESIZE.REX.

output   when using the input of:     100   metres
────────────────────────────────────metric─────────────────────────────────────
                                     0.1 kilometers
                                     100 meters
                                   10000 centimeters
──────────────────────────────────old Russian──────────────────────────────────
                             0.062480475 milias
                             0.093720713 versts
                               46.860356 sazhens
                               140.58107 arshins
                               328.02249 futs
                               562.32428 piads
                               2249.2971 vershoks
                               3936.2699 diuyms
                               39362.699 liniyas
                               393626.99 tochkas
output   when using the input of:     1.4058107   arshins
────────────────────────────────────metric─────────────────────────────────────
                                   0.001 kilometers
                                       1 meter
                                     100 centimeters
──────────────────────────────────old Russian──────────────────────────────────
                           0.00062480476 milias
                           0.00093720713 versts
                              0.46860357 sazhens
                               1.4058107 arshins
                                3.280225 futs
                               5.6232428 piads
                               22.492971 vershoks
                                 39.3627 diuyms
                                 393.627 liniyas
                                 3936.27 tochkas
output   when using the input of:     -46.860366   sazhens
────────────────────────────────────metric─────────────────────────────────────
                             -0.10000002 kilometers
                              -100.00002 meters
                              -10000.002 centimeters
──────────────────────────────────old Russian──────────────────────────────────
                            -0.062480488 milias
                            -0.093720732 versts
                              -46.860366 sazhens
                               -140.5811 arshins
                              -328.02256 futs
                              -562.32439 piads
                              -2249.2976 vershoks
                              -3936.2707 diuyms
                              -39362.707 liniyas
                              -393627.07 tochkas

Ring

# Project : Old Russian measure of length

decimals(7)
units = ["tochka", "liniya", "dyuim", "vershok", "piad", "fut", 
             "arshin", "sazhen", "versta", "milia", 
             "centimeter", "meter", "kilometer"]
 
convs = [0.0254, 0.254, 2.54, 4.445, 17.78, 30.48, 
             71.12, 213.36, 10668, 74676, 
             1, 100, 10000]
 
yn = "y"
unit = 1
p = 1
while yn != "n"
      for i = 1 to 13
          see "" + i + " " + units[i] + nl
      next
      see nl
      see "please choose a unit 1 to 13 : "
      give unit
      see nl
      see "now enter a value in that unit : "
      give value
      see nl
      see "the equivalent in the remaining units is : "
      see nl
      for i = 1 to 13
          if i = unit
             loop
          ok
          see "" + units[i] + " : " + (value * convs[number(unit)] / convs[i]) + nl
      next
      see nl
      while yn = "y" or yn = "n"
              see "do another one y/n : "
              give yn
              yn = lower(yn)
      end 
end

Output:

1 tochka
2 liniya
3 dyuim
4 vershok
5 piad
6 fut
7 arshin
8 sazhen
9 versta
10 milia
11 centimeter
12 meter
13 kilometer

please choose a unit 1 to 13 : 13

now enter a value in that unit : 1

the equivalent in the remaining units is : 
tochka : 393700.7874016
liniya : 39370.0787402
dyuim : 3937.0078740
vershok : 2249.7187852
piad : 562.4296963
fut : 328.0839895
arshin : 140.6074241
sazhen : 46.8691414
versta : 0.9373828
milia : 0.1339118
centimeter : 10000
meter : 100

RPL

Works with: Halcyon Calc version 4.2.7
≪  { "arshin" 0.7112 "centimeter" 0.01 "diuym" 0.0254 "fut" 0.3048 "kilometer" 1000 "liniya" 0.00254 "meter" 1 
      "milia" 7467.6 "piad" 0.1778 "sazhen" 2.1336 "tochka" 0.000254 "vershok" 0.04445 "versta" 1066.8 } 
    → value unit table
   ≪ IF table unit POS 
      THEN
         LAST 1 + table SWAP GET value * → meters
         ≪   1 table SIZE FOR j
                meters table j 1 + GET / →STR " " + table j GET + "s" +
              2 STEPELSE value unit ": unknown unit" +
      END
≫ ≫ 
'OLDRU' STO
3.14 "fut" OLDRU
Output:
13: "1.34571428571 arshins" 
12: "95.7072 centimeters"
11: "37.68 diuyms""37.68 diuyms"
10: "3.14 futs"
 9: "0.000957072 kilometers"
 8: "376.8 liniyas"
 7: "0.957072 meters"
 6: "1.28163265306E-04 milias"
 5: "5.38285714286 piads"
 4: "0.448571428571 sazhens"
 3: "3768 tochkas"
 2: "21.5314285714 vershoks"
 1: "8.97142857143E-04 verstas"

Ruby

module Distances

  RATIOS = 
  {arshin: 0.7112, centimeter: 0.01,     diuym:   0.0254,
   fut:    0.3048, kilometer:  1000.0,   liniya:  0.00254,
   meter:  1.0,    milia:      7467.6,   piad:    0.1778,
   sazhen: 2.1336, tochka:     0.000254, vershok: 0.04445,
   versta: 1066.8}

  def self.method_missing(meth, arg)
    from, to = meth.to_s.split("2").map(&:to_sym)
    raise NoMethodError, meth if ([from,to]-RATIOS.keys).size > 0
    RATIOS[from] * arg / RATIOS[to]
  end

  def self.print_others(name, num)
    puts "#{num} #{name} ="
    RATIOS.except(name.to_sym).each {|k,v| puts "#{ (1.0 / v*num)} #{k}" }
  end
end

Distances.print_others("meter", 2)
puts
p Distances.meter2centimeter(3)
p Distances.arshin2meter(1)
p Distances.versta2kilometer(20) # en Hoeperdepoep zat op de stoep
# 13*13 = 169 methods supported, but not:
p Distances.mile2piad(1)
Output:
2 meter =
2.8121484814398197 arshin
200.0 centimeter
78.74015748031496 diuym
6.561679790026246 fut
0.002 kilometer
787.4015748031495 liniya
0.00026782366489903046 milia
11.248593925759279 piad
0.9373828271466067 sazhen
7874.0157480314965 tochka
44.994375703037115 vershok
0.0018747656542932134 versta

300.0
0.7112
21.336
distances.rb:12:in `method_missing': mile2piad (NoMethodError)
	from distances.rb:22:in `<main>'

Rust

Run as:

commandname <value> <unit>
use std::env;
use std::process;
use std::collections::HashMap;

fn main() {

	let units: HashMap<&str, f32> = [("arshin",0.7112),("centimeter",0.01),("diuym",0.0254),("fut",0.3048),("kilometer",1000.0),("liniya",0.00254),("meter",1.0),("milia",7467.6),("piad",0.1778),("sazhen",2.1336),("tochka",0.000254),("vershok",0.04445),("versta",1066.8)].iter().cloned().collect();

	let args: Vec<String> = env::args().collect();
	if args.len() < 3 {
		eprintln!("A correct use is oldrus [amount] [unit].");
		process::exit(1);
	};

	let length_float;
	length_float = match args[1].parse::<f32>() {
		Ok(length_float) =>  length_float,
		Err(..) => 1 as f32,
	};

	let unit: &str = &args[2];
	if ! units.contains_key(unit) {
		let mut keys: Vec<&str> = Vec::new();
		for i in units.keys() {
			keys.push(i)
		};
		eprintln!("The correct units are: {}.", keys.join(", "));
		process::exit(1);
	};

	println!("{} {} to:", length_float, unit);
	for (lunit, length) in &units {
		println!("	{}: {:?}", lunit,  length_float * units.get(unit).unwrap() / length);
	};


}
$ ./oldrus test
A correct use is oldrus [amount] [unit].
$ ./oldrus test test
The correct units are: meter, sazhen, vershok, fut, diuym, kilometer, tochka, arshin, liniya, piad, versta, milia, centimeter.
$ ./oldrus 1 meter
1 meter to:
	kilometer: 0.001
	liniya: 393.70078
	diuym: 39.37008
	centimeter: 100.0
	fut: 3.28084
	arshin: 1.4060743
	piad: 5.624297
	tochka: 3937.0076
	versta: 0.0009373828
	meter: 1.0
	sazhen: 0.4686914
	vershok: 22.497189
	milia: 0.00013391183
$ ./oldrus 5 versta
5 versta to:
	versta: 5.0
	arshin: 7500.0
	kilometer: 5.334
	diuym: 210000.0
	centimeter: 533400.0
	sazhen: 2500.0
	liniya: 2100000.0
	piad: 30000.0
	tochka: 20999998.0
	vershok: 120000.0
	fut: 17500.0
	milia: 0.71428573
	meter: 5334.0

Scala

import scala.collection.immutable.HashMap

object OldRussianLengths extends App {

  private def measures = HashMap("tochka" -> 0.000254,
    "liniya"-> 0.000254, "centimeter"-> 0.01,    "diuym"-> 0.0254, "vershok"-> 0.04445,
    "piad"  -> 0.1778,   "fut"       -> 0.3048, "arshin"-> 0.7112, "meter"  -> 1.0,
    "sazhen"-> 2.1336,   "kilometer" -> 1000.0, "versta"-> 1066.8, "milia"  -> 7467.6
  ).withDefaultValue(Double.NaN)

  if (args.length == 2 && args(0).matches("[+-]?\\d*(\\.\\d+)?")) {
    val inputVal = measures(args(1))

    def meters = args(0).toDouble * inputVal

    if (!java.lang.Double.isNaN(inputVal)) {
      printf("%s %s to: %n%n", args(0), args(1))
      for (k <- measures) println(f"${k._1}%10s:  ${meters / k._2}%g")
    }
  } else println("Please provide a number and unit on the command line.")

}

Sidef

Translation of: Raku
func convert (magnitude, unit) {
     var factor = Hash(
        tochka     => 0.000254,
        liniya     => 0.00254,
        diuym      => 0.0254,
        vershok    => 0.04445,
        piad       => 0.1778,
        fut        => 0.3048,
        arshin     => 0.7112,
        sazhen     => 2.1336,
        versta     => 1066.8,
        milia      => 7467.6,
        centimeter => 0.01,
        meter      => 1,
        kilometer  => 1000,
    )

    var meters = (magnitude * factor{unit.lc})
    say("#{magnitude} #{unit} to:\n", '-' * 40)

    for u,f in (factor.sort_by { |_,v| v }) {
        printf("%10s: %s\n", u, meters / f) if (u != unit.lc)
    }
}

convert(1, 'meter')
say('')
convert(1, 'milia')
Output:
1 meter to:
----------------------------------------
    tochka: 3937.007874015748031496062992125984251968503937007874
    liniya: 393.700787401574803149606299212598425196850393700787
centimeter: 100
     diuym: 39.370078740157480314960629921259842519685039370079
   vershok: 22.497187851518560179977502812148481439820022497188
      piad: 5.624296962879640044994375703037120359955005624297
       fut: 3.28083989501312335958005249343832020997375328084
    arshin: 1.406074240719910011248593925759280089988751406074
    sazhen: 0.468691413573303337082864641919760029996250468691
 kilometer: 0.001
    versta: 0.000937382827146606674165729283839520059992500937
     milia: 0.000133911832449515239166532754834217151427500134

1 milia to:
----------------------------------------
    tochka: 29400000
    liniya: 2940000
centimeter: 746760
     diuym: 294000
   vershok: 168000
      piad: 42000
       fut: 24500
    arshin: 10500
     meter: 7467.6
    sazhen: 3500
 kilometer: 7.4676
    versta: 7

Tcl

Tcllib already has a units package which knows about a lot of things, and can be taught more. Since the other examples in this page provide a nicely tabulated conversions for 1 meter, we can copy that directly to get started ...

package require units

set russian_units {
      arshin  1.40607
  centimeter  100
       diuym  39.3701
         fut  3.28084
   kilometer  0.001
      liniya  393.701
       meter  1
       milia  0.000133912
        piad  5.6243
      sazhen  0.468691
      tochka  3937.01
     vershok  22.4972
      versta  0.000937383
}

proc add_russian_units {} {
    foreach {name factor} $::russian_units {
        if {$name eq "meter"} continue
        set factor [expr {1/$factor}]
        units::new $name "$factor meters"   ;# teach units about the new unit
    }
}

proc demo {} {  ;# show some examples
    foreach base {"1 meter" "1 milia"} {
        puts "$base to:"
        foreach {unit _} $::russian_units {
            puts [format " %-12s: %s" $unit [units::convert $base $unit]]
        }
        puts ""
    }
}

add_russian_units
demo
Output:
1 meter to:
 arshin      : 1.40607
 centimeter  : 100.0
 diuym       : 39.3701
 fut         : 3.28084
 kilometer   : 0.001
 liniya      : 393.701
 meter       : 1.0
 milia       : 0.000133912
 piad        : 5.6243
 sazhen      : 0.46869099999999997
 tochka      : 3937.01
 vershok     : 22.4972
 versta      : 0.000937383

1 milia to:
 arshin      : 10499.955194456059
 centimeter  : 746759.065655057
 diuym       : 293999.7909074616
 fut         : 24499.97012963737
 kilometer   : 7.46759065655057
 liniya      : 2939997.909074616
 meter       : 7467.59065655057
 milia       : 1.0
 piad        : 41999.970129637375
 sazhen      : 3499.9925324093433
 tochka      : 29399979.09074616
 vershok     : 167999.8805185495
 versta      : 6.999992532409343

One nice side effect of this implementation is that units can work with more complex dimensions:

% units::convert "1 piad^2" "hectare"
3.1612805858160454e-6
% units::convert "100 km/h" "versta/minute"
1.562305

Wren

Translation of: Go
Library: Wren-fmt
Library: Wren-str
import "io" for Stdin, Stdout
import "./fmt" for Fmt
import "./str" for Str

var units = [
    "tochka", "liniya", "dyuim", "vershok", "piad", "fut",
    "arshin", "sazhen", "versta", "milia",
    "centimeter", "meter", "kilometer"
]

var convs = [
    0.0254, 0.254, 2.54, 4.445, 17.78, 30.48,
    71.12, 213.36, 10668, 74676,
    1, 100, 10000
]

while (true) {
    var i = 0
    for (u in units) {
        Fmt.print("$2d $s", i+1, u)
        i = i + 1
    }
    System.print()
    var unit
    while (true) {
        System.write("Please choose a unit 1 to 13   : ")
        Stdout.flush()
        unit = Num.fromString(Stdin.readLine())
        if (unit.type == Num && unit.isInteger && unit >= 1 && unit <= 13) break
    }
    unit = unit - 1
    var value
    while (true) {
        System.write("Now enter a value in that unit : ")
        Stdout.flush()
        value = Num.fromString(Stdin.readLine())
        if (value.type == Num && value >= 0) break
    }
    System.print("\nThe equivalent in the remaining units is:\n")
    i = 0
    for (u in units) {
        if (i != unit) Fmt.print(" $10s : $15.8g", u, value*convs[unit]/convs[i])
        i = i + 1
    }
    System.print()
    var yn = ""
    while (yn != "y" && yn != "n") {
        System.write("Do another one y/n : ")
        Stdout.flush()
        yn = Str.lower(Stdin.readLine())
    }
    if (yn == "n") break
    System.print()
}
Output:

Sample run (same as Go example):

 1 tochka
 2 liniya
 3 dyuim
 4 vershok
 5 piad
 6 fut
 7 arshin
 8 sazhen
 9 versta
10 milia
11 centimeter
12 meter
13 kilometer

Please choose a unit 1 to 13   : 13
Now enter a value in that unit : 1

The equivalent in the remaining units is:

     tochka : 393700.78740157
     liniya :  39370.07874016
      dyuim :   3937.00787402
    vershok :   2249.71878515
       piad :    562.42969629
        fut :    328.0839895 
     arshin :    140.60742407
     sazhen :     46.86914136
     versta :      0.93738283
      milia :      0.13391183
 centimeter :  10000.0       
      meter :    100.0       

Do another one y/n : n

XPL0

Translation of: Wren
int  Units, Unit, I, YN;
real Convs, Value;

[Units:= ["tochka", "liniya", "dyuim", "vershok", "piad", "fut",
        "arshin", "sazhen", "versta", "milia",
        "centimeter", "meter", "kilometer"];

Convs:= [0.0254, 0.254, 2.54, 4.445, 17.78, 30.48,
        71.12, 213.36, 10668., 74676.,
        1., 100., 10000.];

loop    [for I:= 0 to 13-1 do
                [if I+1 < 10 then ChOut(0, ^ );  IntOut(0, I+1);
                ChOut(0, ^ );  Text(0, Units(I));  CrLf(0);
                ];
        CrLf(0);
        loop    [Text(0, "Please choose a unit 1 to 13   : ");
                OpenI(0);
                Unit:= IntIn(0);
                if Unit >= 1 and Unit <= 13 then quit;
                ];
        Unit:= Unit-1;
        loop    [Text(0, "Now enter a value in that unit : ");
                OpenI(0);
                Value:= RlIn(0);
                if Value >= 1. then quit;
                ];
        Text(0, "^m^jThe equivalent in the remaining units is:^m^j^m^j");
        Format(7, 8);
        for I:= 0 to 13-1 do
            [if I # Unit then
                [RlOut(0, Value*Convs(Unit)/Convs(I));
                Text(0, " : ");  Text(0, Units(I));  CrLf(0);
                ];
            ];
        CrLf(0);
        YN:= ^ ;
        while YN # ^y and YN # ^n do
                [Text(0, "Do another one y/n : ");
                OpenI(0);
                YN:= ChIn(0) or $20;
                ];
        if YN = ^n then quit;
        CrLf(0);
        ];
]
Output:
 1 tochka
 2 liniya
 3 dyuim
 4 vershok
 5 piad
 6 fut
 7 arshin
 8 sazhen
 9 versta
10 milia
11 centimeter
12 meter
13 kilometer

Please choose a unit 1 to 13   : 13
Now enter a value in that unit : 1

The equivalent in the remaining units is:

 393700.78740157 : tochka
  39370.07874016 : liniya
   3937.00787402 : dyuim
   2249.71878515 : vershok
    562.42969629 : piad
    328.08398950 : fut
    140.60742407 : arshin
     46.86914136 : sazhen
      0.93738283 : versta
      0.13391183 : milia
  10000.00000000 : centimeter
    100.00000000 : meter

Do another one y/n : n