##F#, 128 bytes##
let s(v:string)=Seq.mapFoldBack(fun r i->i*Seq.sumBy(fun c->match c with|'<'->10|'T'->1|_->0)r,i*60)(v.Split ' ')1|>fst|>Seq.sum
Try it online!
Ungolfed it would look like this:
let s (v:string) =
Seq.mapFoldBack(fun r i ->
i * Seq.sumBy(fun c ->
match c with
| '<' -> 10
| 'T' ->1
| _ -> 0
) r,
i * 60) (v.Split ' ') 1
|> fst
|> Seq.sum
Seq.mapFoldBack
combines Seq.map
and Seq.foldBack
. Seq.mapFoldBack
iterates through the sequence backwards, and threads an accumulator value through the sequence (in this case, i
).
For each element in the sequence, the Babylonian number is computed (by Seq.sumBy
, which maps each character to a number and totals the result) and then multiplied by i
. i
is then multiplied by 60, and this value is then passed to the next item in the sequence. The initial state for the accumulator is 1.
For example, the order of calls and results in Seq.mapFoldBack
for input <<<TT \ TTTT
would be:
(TTTT, 1) -> (4, 60)
(\, 60) -> (0, 3600)
(<<<TT, 3600) -> (115200, 216000)
The function will return a tuple of seq<int>, int
. The fst
function returns the first item in that tuple, and Seq.sum
does the actual summing.
###Why not use Seq.mapi
or similar?###
Seq.mapi
maps each element in the sequence, and provides the index to the mapping function. From there you could do 60 ** index
(where **
is the power operator in F#).
But **
requires floats
, not ints
, which means that you need to either initialise or cast all the values in the function as float
. The entire function will return a float
, which (in my opinion) is a little messy.
Using Seq.mapi
it can be done like this for 139 bytes:
let f(v:string)=v.Split ' '|>Seq.rev|>Seq.mapi(fun i r->Seq.sumBy(fun c->match c with|'<'->10.0|'T'->1.0|_->0.0)r*(60.0**float i))|>Seq.sum