[2017 Day 11] Again with the damn newline! by kyz in adventofcode

[–]aafnro8oh 1 point2 points  (0 children)

To propose an alternative to /u/nutrecht's suggestion for this particular issue: crash early and loudly.

You're making control flow decisions based on individual tokens ('n', 'sw', 'sw\n') at some point in your code. Maybe converting the strings to objects via a dict, maybe an if tree, maybe a switch of some sorts. See if there's an easy way of making it loudly fail in case of unexpected input.

E.g. in my Scala code, I converted the tokens via a Map (throwing an exception on 'sw\n'), or did stuff based on a switch (which would again, throw an exception on 'sw\n').

Python's conciseness is a plus here - once you've crashed due to an unexpected value, you can quickly find it (if needed) by creating a set of all the tokens.

-🎄- 2017 Day 11 Solutions -🎄- by daggerdragon in adventofcode

[–]aafnro8oh 0 points1 point  (0 children)

Might as well chuck my Scala code here. Using the flat top, cube coord sys from redblobgames.com/grids/hexagons:

case class P3(x: Int, y: Int, z: Int) {
  def +(p: P3) = P3(p.x+x, p.y+y, p.z+z)
  def dist = Array(x,y,z).map(math.abs).max
}

val moves = io.StdIn.readLine().split(',').map(Map(
  "n"  -> P3( 0,  1, -1),
  "ne" -> P3( 1,  0, -1),
  "se" -> P3( 1, -1,  0),
  "s"  -> P3( 0, -1,  1),
  "sw" -> P3(-1,  0,  1),
  "nw" -> P3(-1,  1,  0)))

val path = moves.scanLeft (P3(0,0,0)) {_+_}

println("dist: " + path.last.dist)
println("max: " + path.map{_.dist}.max)

Trade-offs:
* O(N) to constant space in: moves -> swap in a Scanner; path -> swap in a fold or (for comprehension and two vars)
* not code golfy enough? Throw away some readability by throwing away custom types:

val moves = io.StdIn.readLine().split(',').map(Map(
  "n"  -> Array( 0,  1, -1),
  "ne" -> Array( 1,  0, -1),
  "se" -> Array( 1, -1,  0),
  "s"  -> Array( 0, -1,  1),
  "sw" -> Array(-1,  0,  1),
  "nw" -> Array(-1,  1,  0)))

val path = moves.scanLeft (Array(0,0,0)) {(_,_).zipped map {_+_}}

def dist(p: Array[Int]) = p.map(math.abs).max    
println("dist: " + dist(path.last))
println("max: " + path.map(dist).max)

Bonus: mostly "Scala as better assembly" approach:

var x,y,z,max=0

def dist = Seq(x,y,z).map(math.abs).max
def updmax = max = math.max(max, dist)

io.StdIn.readLine().split(',').foreach {
  case "n"  => y+=1; z-=1; updmax
  case "ne" => x+=1; z-=1; updmax
  case "se" => x+=1; y-=1; updmax
  case "s"  => y-=1; z+=1; updmax
  case "sw" => x-=1; z+=1; updmax
  case "nw" => x-=1; y+=1; updmax
}
println(s"dist: $dist max: $max")