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
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
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
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
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
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
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
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
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
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
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
// 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
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.
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)
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
≪ { "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 STEP ≫ ELSE 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
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
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
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
- Programming Tasks
- Solutions by Programming Task
- 11l
- Action!
- Action! Real Math
- ALGOL 68
- AppleScript
- AWK
- BASIC
- BASIC256
- BBC BASIC
- FreeBASIC
- Gambas
- QBasic
- True BASIC
- XBasic
- UBasic/4tH
- Yabasic
- C
- C++
- D
- Delphi
- System.SysUtils
- EasyLang
- Elena
- Factor
- Fortran
- Forth
- Frink
- Go
- Haskell
- J
- Java
- Jq
- Julia
- Kotlin
- M2000 Interpreter
- Mathematica
- Wolfram Language
- МК-61/52
- Nim
- Perl
- Phix
- Python
- Racket
- Raku
- REXX
- Ring
- RPL
- Ruby
- Rust
- Scala
- Sidef
- Tcl
- Wren
- Wren-fmt
- Wren-str
- XPL0