<commit_before>object Roman {
  val ones = Vector("I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX")
  val tens = Vector("X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC")
  val hundreds = Vector("C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM")
  val thousands = Vector("M", "MM", "MMM")
  val toRoman = Vector(ones, tens, hundreds, thousands)

  def apply(number: Int): String = {
    assert(number <= 3000)
    assert(number > 0)

    def convert(acc: List[String], normal: List[Char]): List[String] = {
      if (normal.isEmpty) {
        acc
      } else {
        if (normal.head == '0') {
          convert("" :: acc, normal.tail)
        } else {
          val pos = normal.size - 1
          val index = augmentString(normal.head.toString).toInt - 1
          convert(toRoman(pos)(index) :: acc, normal.tail)
        }
      }
    }
    convert(List(), number.toString.toList).reverse mkString ""
  }

  def toNormal(roman:String):Int = {
    val uber = toRoman.reverse.map(iv => iv.reverse).flatten
    def convert(acc: List[Int], romans:String): List[Int] = {
      if (romans.isEmpty){
        acc
      } else {
        val found = uber.filter(numeral => romans.startsWith(numeral)).head
        val int = if (thousands.contains(found)) {
          1000 * (thousands.indexOf(found) +1)
        } else if (hundreds.contains(found)) {
          100 * (hundreds.indexOf(found) +1)
        } else if (tens.contains(found)) {
          10 * (tens.indexOf(found) +1)
        } else {
          ones.indexOf(found) + 1
        }
        convert(int :: acc, romans.replaceFirst(found, ""))
      }
    }
    convert(List(), roman).sum
  }
}<commit_msg>More functional approach to rolling up the numbers<commit_after>object Roman {
  val ones = Vector("I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX")
  val tens = Vector("X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC")
  val hundreds = Vector("C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM")
  val thousands = Vector("M", "MM", "MMM")
  val toRoman = Vector(ones, tens, hundreds, thousands)

  def apply(number: Int): String = {
    assert(number <= 3000)
    assert(number > 0)

    def convert(acc: List[String], normal: List[Char]): List[String] = {
      if (normal.isEmpty) {
        acc
      } else {
        if (normal.head == '0') {
          convert("" :: acc, normal.tail)
        } else {
          val pos = normal.size - 1
          val index = augmentString(normal.head.toString).toInt - 1
          convert(toRoman(pos)(index) :: acc, normal.tail)
        }
      }
    }
    convert(List(), number.toString.toList).reverse mkString ""
  }

  def toNormal(roman:String):Int = {
    val allRomans = toRoman.reverse.map(iv => iv.reverse).flatten
    def convert(acc: List[Int], romans:String): List[Int] = {
      if (romans.isEmpty){
        acc
      } else {
        val found = allRomans.filter(numeral => romans.startsWith(numeral)).head
        //Fold up the maths for converting scales
        val int = toRoman.foldLeft(0)((acc, col) => {
          if (col.contains(found)){
            acc + math.pow(10, toRoman.indexOf(col)).toInt * (col.indexOf(found) + 1)
          } else {
            acc
          }
        })
        convert(int :: acc, romans.replaceFirst(found, ""))
      }
    }
    convert(List(), roman).sum
  }
}
{'fraction_non_alphanumeric': 0.18037690696978761, 'fraction_numerical': 0.009871373018247084, 'mean_word_length': 2.4192229038854807, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3096520', 'n_tokens_mistral': 1169, 'n_tokens_neox': 1116, 'n_words': 267}