Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,37 @@
shared void run() {
value numerals = map {
'I' -> 1,
'V' -> 5,
'X' -> 10,
'L' -> 50,
'C' -> 100,
'D' -> 500,
'M' -> 1000
};
function toHindu(String roman) {
variable value total = 0;
for(i->c in roman.indexed) {
assert(exists currentValue = numerals[c]);
/* Look at the next letter to see if we're looking
at a IV or CM or whatever. If so subtract the
current number from the total. */
if(exists next = roman[i + 1],
exists nextValue = numerals[next],
currentValue < nextValue) {
total -= currentValue;
} else {
total += currentValue;
}
}
return total;
}
assert(toHindu("I") == 1);
assert(toHindu("II") == 2);
assert(toHindu("IV") == 4);
assert(toHindu("MDCLXVI") == 1666);
assert(toHindu("MCMXC") == 1990);
assert(toHindu("MMVIII") == 2008);
}

View file

@ -0,0 +1,18 @@
MapChar(STRING1 c) := CASE(c,'M'=>1000,'D'=>500,'C'=>100,'L'=>50,'X'=>10,'V'=>5,'I'=>1,0);
RomanDecode(STRING s) := FUNCTION
dsS := DATASET([{s}],{STRING Inp});
R := { INTEGER2 i; };
R Trans1(dsS le,INTEGER pos) := TRANSFORM
SELF.i := MapChar(le.Inp[pos]) * IF ( MapChar(le.Inp[pos]) < MapChar(le.Inp[pos+1]), -1, 1 );
END;
RETURN SUM(NORMALIZE(dsS,LENGTH(TRIM(s)),Trans1(LEFT,COUNTER)),i);
END;
RomanDecode('MCMLIV'); //1954
RomanDecode('MCMXC'); //1990
RomanDecode('MMVIII'); //2008
RomanDecode('MDCLXVI'); //1666
RomanDecode('MDLXVI'); //1566

View file

@ -0,0 +1,41 @@
IMPORT STD;
RomanDecode(STRING s) := FUNCTION
SetWeights := [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
SetSymbols := ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
ProcessRec := RECORD
UNSIGNED val;
STRING Roman;
END;
dsSymbols := DATASET(13,TRANSFORM(ProcessRec,SELF.Roman := s, SELF := []));
RECORDOF(dsSymbols) XF(dsSymbols L, dsSymbols R, INTEGER C) := TRANSFORM
ThisRoman := IF(C=1,R.Roman,L.Roman);
IsDone := ThisRoman = '';
Repeatable := C IN [1,5,9,13];
SymSize := IF(C % 2 = 0, 2, 1);
IsNext := STD.Str.StartsWith(ThisRoman,SetSymbols[C]);
SymLen := IF(IsNext,
IF(NOT Repeatable,
SymSize,
MAP(NOT IsDone AND ThisRoman[1] = ThisRoman[2] AND ThisRoman[1] = ThisRoman[3] => 3,
NOT IsDone AND ThisRoman[1] = ThisRoman[2] => 2,
NOT IsDone => 1,
0)),
0);
SymbolWeight(STRING s) := IF(NOT Repeatable,
SetWeights[C],
CHOOSE(LENGTH(s),SetWeights[C],SetWeights[C]*2,SetWeights[C]*3,0));
SELF.Roman := IF(IsDone,ThisRoman,ThisRoman[SymLen+1..]);
SELF.val := IF(IsDone,L.val,L.Val + IF(IsNext,SymbolWeight(ThisRoman[1..SymLen]),0));
END;
i := ITERATE(dsSymbols,XF(LEFT,RIGHT,COUNTER));
RETURN i[13].val;
END;
RomanDecode('MCMLIV'); //1954
RomanDecode('MCMXC'); //1990
RomanDecode('MMVIII'); //2008
RomanDecode('MDCLXVI'); //1666
RomanDecode('MDLXVI'); //1566

View file

@ -0,0 +1,29 @@
PROGRAM ROMAN2ARAB
DIM R%[7]
PROCEDURE TOARAB(ROMAN$->ANS%)
LOCAL I%,J%,P%,N%
FOR I%=LEN(ROMAN$) TO 1 STEP -1 DO
J%=INSTR("IVXLCDM",MID$(ROMAN$,I%,1))
IF J%=0 THEN
ANS%=-9999 ! illegal character
EXIT PROCEDURE
END IF
IF J%>=P% THEN
N%+=R%[J%]
ELSE
N%-=R%[J%]
END IF
P%=J%
END FOR
ANS%=N%
END PROCEDURE
BEGIN
R%[]=(0,1,5,10,50,100,500,1000)
TOARAB("MCMXCIX"->ANS%) PRINT(ANS%)
TOARAB("MMXII"->ANS%) PRINT(ANS%)
TOARAB("MDCLXVI"->ANS%) PRINT(ANS%)
TOARAB("MMMDCCCLXXXVIII"->ANS%) PRINT(ANS%)
END PROGRAM

View file

@ -0,0 +1,62 @@
' FB 1.05.0 Win64
Function romanDecode(roman As Const String) As Integer
If roman = "" Then Return 0 '' zero denotes invalid roman number
Dim roman1(0 To 2) As String = {"MMM", "MM", "M"}
Dim roman2(0 To 8) As String = {"CM", "DCCC", "DCC", "DC", "D", "CD", "CCC", "CC", "C"}
Dim roman3(0 To 8) As String = {"XC", "LXXX", "LXX", "LX", "L", "XL", "XXX", "XX", "X"}
Dim roman4(0 To 8) As String = {"IX", "VIII", "VII", "VI", "V", "IV", "III", "II", "I"}
Dim As Integer i, value = 0, length = 0
Dim r As String = UCase(roman)
For i = 0 To 2
If Left(r, Len(roman1(i))) = roman1(i) Then
value += 1000 * (3 - i)
length = Len(roman1(i))
r = Mid(r, length + 1)
length = 0
Exit For
End If
Next
For i = 0 To 8
If Left(r, Len(roman2(i))) = roman2(i) Then
value += 100 * (9 - i)
length = Len(roman2(i))
r = Mid(r, length + 1)
length = 0
Exit For
End If
Next
For i = 0 To 8
If Left(r, Len(roman3(i))) = roman3(i) Then
value += 10 * (9 - i)
length = Len(roman3(i))
r = Mid(r, length + 1)
length = 0
Exit For
End If
Next
For i = 0 To 8
If Left(r, Len(roman4(i))) = roman4(i) Then
value += 9 - i
length = Len(roman4(i))
Exit For
End If
Next
' Can't be a valid roman number if there are any characters left
If Len(r) > length Then Return 0
Return value
End Function
Dim a(2) As String = {"MCMXC", "MMVIII" , "MDCLXVI"}
For i As Integer = 0 To 2
Print a(i); Tab(8); " =>"; romanDecode(a(i))
Next
Print
Print "Press any key to quit"
Sleep

View file

@ -0,0 +1,28 @@
local fn RomantoDecimal( roman as Str15 ) as short
dim as short i, n, preNum, num
preNum = 0 : num = 0
for i = roman[0] to 1 step -1
n = 0
if roman[i] = _"M" then n = 1000
if roman[i] = _"D" then n = 500
if roman[i] = _"C" then n = 100
if roman[i] = _"L" then n = 50
if roman[i] = _"X" then n = 10
if roman[i] = _"V" then n = 5
if roman[i] = _"I" then n = 1
if n < preNum then num = num - n else num = num + n
preNum = n
next
end fn = num
print " MCMXC ="; fn RomantoDecimal( "MCMXC" )
print " MMVIII ="; fn RomantoDecimal( "MMVIII" )
print " MMXVI ="; fn RomantoDecimal( "MMXVI" )
print "MDCLXVI ="; fn RomantoDecimal( "MDCLXVI" )
print " MCMXIV ="; fn RomantoDecimal( "MCMXIV" )
print " DXIII ="; fn RomantoDecimal( "DXIII" )
print " M ="; fn RomantoDecimal( "M" )
print " DXIII ="; fn RomantoDecimal( "DXIII" )
print " XXXIII ="; fn RomantoDecimal( "XXXIII" )

View file

@ -0,0 +1,23 @@
define br => '\r'
//decode roman
define decodeRoman(roman::string)::integer => {
local(ref = array('M'=1000, 'CM'=900, 'D'=500, 'CD'=400, 'C'=100, 'XC'=90, 'L'=50, 'XL'=40, 'X'=10, 'IX'=9, 'V'=5, 'IV'=4, 'I'=1))
local(out = integer)
while(#roman->size) => {
// need to use neset while instead of query expr to utilize loop_abort
while(loop_count <= #ref->size) => {
if(#roman->beginswith(#ref->get(loop_count)->first)) => {
#out += #ref->get(loop_count)->second
#roman->remove(1,#ref->get(loop_count)->first->size)
loop_abort
}
}
}
return #out
}
'MCMXC as integer is '+decodeRoman('MCMXC')
br
'MMVIII as integer is '+decodeRoman('MMVIII')
br
'MDCLXVI as integer is '+decodeRoman('MDCLXVI')

View file

@ -0,0 +1,13 @@
require! 'prelude-ls': {fold, sum}
# String → Number
decimal_of_roman = do
# [Number, Number] → String → [Number, Number]
_convert = ([acc, last_value], ch) ->
current_value = { M:1000 D:500 C:100 L:50 X:10 V:5 I:1 }[ch] ? 0
op = if last_value < current_value then (-) else (+)
[op(acc, last_value), current_value]
# fold the string and sum the resulting tuple (array)
fold(_convert, [0, 0]) >> sum
{[rom, decimal_of_roman rom] for rom in <[ MCMXC MMVII MDCLXVII MMMCLIX MCMLXXVII MMX ]>}

View file

@ -0,0 +1,12 @@
import tables
let rdecode = {'M': 1000, 'D': 500, 'C': 100, 'L': 50, 'X': 10, 'V': 5, 'I': 1}.toTable
proc decode(roman): int =
for i in 0 .. <roman.high:
let (rd, rd1) = (rdecode[roman[i]], rdecode[roman[i+1]])
result += (if rd < rd1: -rd else: rd)
result += rdecode[roman[roman.high]]
for r in ["MCMXC", "MMVIII", "MDCLXVI"]:
echo r, " ", decode(r)

View file

@ -0,0 +1,13 @@
constant romans = "MDCLXVI",
decmls = {1000,500,100,50,10,5,1}
function romanDec(string s)
integer n, prev = 0, res = 0
for i=length(s) to 1 by -1 do
n = decmls[find(s[i],romans)]
if n<prev then n = 0-n end if
res += n
prev = n
end for
return res
end function

View file

@ -0,0 +1,18 @@
Red [
Purpose: "Arabic <-> Roman numbers converter"
Author: "Didier Cadieu"
Date: "07-Oct-2016"
]
table-r2a: reverse [1000 "M" 900 "CM" 500 "D" 400 "CD" 100 "C" 90 "XC" 50 "L" 40 "XL" 10 "X" 9 "IX" 5 "V" 4 "IV" 1 "I"]
roman-to-arabic: func [r [string!] /local a b e] [
a: 0
parse r [any [b: ["I" ["V" | "X" | none] | "X" ["L" | "C" | none] | "C" ["D" | "M" | none] | "V" | "L" | "D" | "M"] e: (a: a + select table-r2a copy/part b e)]]
a
]
; Example usage:
print roman-to-arabic "XXXIII"
print roman-to-arabic "MDCCCLXXXVIII"
print roman-to-arabic "MMXVI"

View file

@ -0,0 +1,21 @@
symbols = "MDCLXVI"
weights = [1000,500,100,50,10,5,1]
see "MCMXCIX = " + romanDec("MCMXCIX") + nl
see "MDCLXVI =" + romanDec("MDCLXVI") + nl
see "XXV = " + romanDec("XXV") + nl
see "CMLIV = " + romanDec("CMLIV") + nl
see "MMXI = " + romanDec("MMXI") + nl
func romanDec roman
n = 0
lastval = 0
arabic = 0
for i = len(roman) to 1 step -1
n = substr(symbols,roman[i])
if n > 0 n = weights[n] ok
if n < lastval arabic = arabic - n
else arabic = arabic + n ok
lastval = n
next
return arabic

View file

@ -0,0 +1,28 @@
func roman2arabic(roman) {
var arabic = 0;
var last_digit = 1000;
static m = Hash.new(
I => 1,
V => 5,
X => 10,
L => 50,
C => 100,
D => 500,
M => 1000,
);
roman.uc.split('').map{m{_} \\ 0}.each { |digit|
last_digit < digit && (
arabic -= (2 * last_digit);
);
arabic += (last_digit = digit);
}
return arabic;
}
%w(MCMXC MMVIII MDCLXVI).each { |roman_digit|
"%-10s == %d\n".printf(roman_digit, roman2arabic(roman_digit));
}

View file

@ -0,0 +1,21 @@
func roman2arabic(digit) {
digit.uc.trans([
:M: '1000+',
:CM: '900+',
:D: '500+',
:CD: '400+',
:C: '100+',
:XC: '90+',
:L: '50+',
:XL: '40+',
:X: '10+',
:IX: '9+',
:V: '5+',
:IV: '4+',
:I: '1+',
]).split('+').map{.to_i}.sum;
}
%w(MCMXC MMVIII MDCLXVI).each { |roman_num|
say "#{roman_num}\t-> #{roman2arabic(roman_num)}";
}

View file

@ -0,0 +1,28 @@
func rtoa(var str: String) -> Int {
var result = 0
for (value, letter) in
[( 1000, "M"),
( 900, "CM"),
( 500, "D"),
( 400, "CD"),
( 100, "C"),
( 90, "XC"),
( 50, "L"),
( 40, "XL"),
( 10, "X"),
( 9, "IX"),
( 5, "V"),
( 4, "IV"),
( 1, "I")]
{
while str.hasPrefix(letter) {
result += value
str = str[advance(str.startIndex, count(letter)) ..< str.endIndex]
}
}
return result
}
println(rtoa("MDCLXVI")) // 1666

View file

@ -0,0 +1,33 @@
func rtoa(var str: String) -> Int {
var result = 0
for (value, letter) in
[ ( 1000, "M"),
( 900, "CM"),
( 500, "D"),
( 400, "CD"),
( 100, "C"),
( 90, "XC"),
( 50, "L"),
( 40, "XL"),
( 10, "X"),
( 9, "IX"),
( 5, "V"),
( 4, "IV"),
( 1, "I")]
{
while str.hasPrefix(letter) {
let first = str.startIndex
let count = letter.characters.count
str.removeRange(first ..< first.advancedBy(count))
result += value
}
}
return result
}
print(rtoa("MDCLXVI")) // 1666

View file

@ -0,0 +1,10 @@
(defun decode (r)
(define roman '((#\m 1000) (#\d 500) (#\c 100) (#\l 50) (#\x 10) (#\v 5) (#\i 1)))
(defun to-arabic (rn rs a)
(cond
((null rn) a)
((eqv? (car rn) (caar rs)) (to-arabic (cdr rn) roman (if (and (not (eqv? (car rn) (cadr rn))) (< (cadar rs) (to-arabic (cdr rn) roman 0)))
(- a (cadar rs))
(+ a (cadar rs)) ) ) )
(t (to-arabic rn (cdr rs) a)) ) )
(to-arabic (string->list r) roman 0) )

View file

@ -0,0 +1,3 @@
[1] (mapcar decode '("mcmxc" "mmviii" "mdclxvi"))
(1990 2008 1666)

View file

@ -0,0 +1,20 @@
def fromRoman:
def addRoman(n):
if length == 0 then n
elif startswith("M") then .[1:] | addRoman(1000 + n)
elif startswith("CM") then .[2:] | addRoman(900 + n)
elif startswith("D") then .[1:] | addRoman(500 + n)
elif startswith("CD") then .[2:] | addRoman(400 + n)
elif startswith("C") then .[1:] | addRoman(100 + n)
elif startswith("XC") then .[2:] | addRoman(90 + n)
elif startswith("L") then .[1:] | addRoman(50 + n)
elif startswith("XL") then .[2:] | addRoman(40 + n)
elif startswith("X") then .[1:] | addRoman(10 + n)
elif startswith("IX") then .[2:] | addRoman(9 + n)
elif startswith("V") then .[1:] | addRoman(5 + n)
elif startswith("IV") then .[2:] | addRoman(4 + n)
elif startswith("I") then .[1:] | addRoman(1 + n)
else
error("invalid Roman numeral: " + tostring)
end;
addRoman(0);

View file

@ -0,0 +1 @@
[ "MCMXC", "MMVIII", "MDCLXVI" ] | map("\(.) => \(fromRoman)") | .[]

View file

@ -0,0 +1,4 @@
$ jq -n -f -r fromRoman.jq
MCMXC => 1990
MMVIII => 2008
MDCLXVI => 1666