As I’ve mentioned in a previous post, I had been partitcipating in the WRO 2016 competition. Unfortunately, our team lost the national game in September due to a flaw in the part of the program regarding the surprise rule. In fact, we were the only team that got >= 300 points in both runs. (By the way, we were also the fastest, finishing at 70 seconds if the special rule isn’t counted.) However, since the ranking prioritizes the best score, we ended up in 7th place.

Anyway, while we were working on the program, we ran into a decision: at the hexagon part, should we always go clockwise, or should we change the direction if there isn’t a tank on the first position? (See the rules for more information.)

Thus, I wrote a simple Scala script to brute force all the combinations of the tanks to see how much time we would save if we used the latter:

val possibleConditions =
  // Fill with combinations of the four possibilities with repetition
  Seq.fill(6)(Seq("000", "100", "010", "001")).
  flatten.
  combinations(6).
  flatMap(_.permutations).
  map(_.mkString("")).
  // Strictly 4 tanks are needed
  filter(_.count(_ == '1') == 4).
  // No tanks can be put together
  filter(!_.contains("11")).
  filter(x => !(x(0) == '1' && x(17) == '1')).
  toList

def getWalkLenData(s: List[String]): (Double, Seq[Int]) = {
  // The number of corners that need to be passed (0-indexed)
  val toLen = s.map(_.lastIndexOf('1') / 3)
  val avg = toLen.sum.toDouble / toLen.size + 1
  // count(i) = number of possibilities that result in passing (i + 1) corners
  val count = toLen.foldLeft(Seq.fill(6)(0))(
    (acc, i) => acc.updated(i, acc(i) + 1))
  (avg, count)
}

// Go in one direction no matter what
println("One-way: " + getWalkLenData(possibleConditions))
// If the first space is empty, go the other way
println("Two-way: " + getWalkLenData(possibleConditions.map(x =>
  if (x(0) == '0') x.reverse else x)))

Output:

One-way: (5.605555555555555,List(0, 0, 0, 55, 245, 600))
Two-way: (5.482222222222222,List(0, 0, 0, 76, 314, 510))

The second strategy saves about the time of 0.12 corners. However, detecting whether there is a tank and turning in reverse if not definitely takes more time than that. Thus we stuck to the first strategy, which was also easier to implement.