Problem statement:
Write a program that converts all given temperatures from a given input temperature scale to a given output temperature scale. The temperature scales to be supported are Kelvin, Celsius, Fahrenheit, Rankine, Delisle, Newton, Rømer, Réaumur.
Synopsis: tempconv INPUT_SCALE OUTPUT_SCALE [TEMPERATURE]...
The INPUT_SCALE
and OUTPUT_SCALE
shall be given as follows:
K
for KelvinC
for CelsiusF
for FahrenheitR
for RankineD
for DelisleN
for NewtonRø
for RømerRé
for Réaumur.
Example:
tempconv K C 0 273.15 373.15
-273.15
0.0
100.0
My solution in Java:
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.DoubleUnaryOperator;
import java.util.stream.Stream;
import static java.util.Map.entry;
import static java.util.stream.Collectors.toUnmodifiableMap;
enum TemperatureConverter {
KELVIN (kelvin -> kelvin, kelvin -> kelvin, "K", "k"),
CELSIUS (celsius -> celsius + 273.15, kelvin -> kelvin - 273.15, "°C", "C", "c"),
DELISLE (delisle -> 373.15 - delisle * 2 / 3, kelvin -> (373.15 - kelvin) * 3 / 2, "°De", "De", "DE", "de"),
FAHRENHEIT(fahrenheit -> (fahrenheit + 459.67) * 5 / 9, kelvin -> kelvin * 9 / 5 - 459.67, "°F", "F", "f"),
NEWTON (newton -> newton * 100 / 33 + 273.15, kelvin -> (kelvin - 273.15) * 33 / 100, "°N", "N", "n"),
RANKINE (rankine -> rankine * 5 / 9, kelvin -> kelvin * 9 / 5, "°R", "R", "r"),
RÉAUMUR (réaumur -> réaumur * 5 / 4 + 273.15, kelvin -> (kelvin - 273.15) * 4 / 5, "°Ré", "°Re", "Ré", "RÉ", "ré", "Re", "RE", "re"),
RØMER (rømer -> (rømer - 7.5) * 40 / 21 + 273.15, kelvin -> (kelvin - 273.15) * 21 / 40 + 7.5, "°Rø", "°Ro", "Rø", "RØ", "rø", "Ro", "RO", "ro"),
;
private static final Map<String, TemperatureConverter> converters =
Stream.of(values())
.flatMap(tc -> tc.names.stream().map(name -> entry(name, tc)))
.collect(toUnmodifiableMap(e -> e.getKey(), e -> e.getValue()));
private final Set<String> names;
final DoubleUnaryOperator toKelvin;
final DoubleUnaryOperator fromKelvin;
TemperatureConverter(final DoubleUnaryOperator toKelvin, final DoubleUnaryOperator fromKelvin, final String... names) {
this.toKelvin = toKelvin;
this.fromKelvin = fromKelvin;
this.names = Set.of(names);
}
public static TemperatureConverter get(final String name) {
return converters.get(name);
}
public static void main(final String... args) {
var toKelvin = TemperatureConverter.get(args[0]).toKelvin;
var fromKelvin = TemperatureConverter.get(args[1]).fromKelvin;
Stream
.of(args)
.skip(2)
.mapToDouble(Double::parseDouble)
.map(toKelvin)
.map(fromKelvin)
.forEach(System.out::println);
}
}
Note: I'm aware that the lines that define the enum constants are a bit long. In this case, I prefer to sacrifice a bit of line length to retain a tabular format.