Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Functions for parsing and sorting roman numerals



I started fiddling and came up with this, it doesn't do much validation.

# pass a second arg to set result to that var, otherwise echo result
parseroman () {
  local max=0 sum i j
  local -A conv
  conv=(I 1 V 5 X 10 L 50 C 100 D 500 M 1000)
  for j in ${(Oas::)1}; do
    i=conv[(e)$j]
    if (( i >= max )); then
      (( sum+=i ))
      (( max=i ))
    else
      (( sum-=i ))
    fi
  done
  if (( ${+2} )); then
    : ${(P)2::=$sum}
  else
    echo $sum
  fi
}

#delimits numerals by space, _, or start/end of filename, to protect
random letters in words
#here's hoping gmail won't munge this line
romansort() {
  REPLY=${REPLY:gs/(#b)( |_|(#s))([IVXLCDM]#)(
|_|(#e))/'$match[1]$(parseroman ${match[2]})$match[3]'}
}

% parseroman MMXI
2011
% parseroman MCMLXXXIV
1984
% parseroman MMMC result
% echo $result
3100

% touch I II III IV V VI VII VIII IX X XI MMXI MCMLXXXIV MMMC
# default lexical sort
% print *
I II III IV IX MCMLXXXIV MMMC MMXI V VI VII VIII X XI
# lexical sort of values, not that useful ;)
% print *(o+romansort)
I X XI MCMLXXXIV II MMXI III MMMC IV V VI VII VIII IX
# numeric sort of values
% print *(no+romansort)
I II III IV V VI VII VIII IX X XI MCMLXXXIV MMXI MMMC
# and the actual reason I wrote it
% print -l *(no+romansort)
Album I with music
Album II with music
Album III with music
Album IV with music
Album V with music
Album VI with music
Album VII with music

-- 
Mikael Magnusson



Messages sorted by: Reverse Date, Date, Thread, Author