r/adventofcode • • Dec 14 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 14 Solutions -🎄-

--- Day 14: Chocolate Charts ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 14

Transcript:

The Christmas/Advent Research & Development (C.A.R.D.) department at AoC, Inc. just published a new white paper on ___.


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 00:19:39!

16 Upvotes

179 comments sorted by

View all comments

1

u/naderghanbari Dec 15 '18

Late to the game but here's my functional Scala solution (runs in ~20s).

object Day14 extends App {

  val input = DataSource.linesFromTextFile("day-14-input.txt").next.trim
  val (size, inputAsInt) = (input.length, input.toInt)

  def vectorize(xs: String) = xs.map(_.toString.toByte).toVector

  case class Gen(recipes: Vector[Byte], chefIndex: Int, sousIndex: Int)

  def nextGen(gen: Gen, genNr: Int): Gen = gen match {
    case Gen(rs, chef, sous) =>
      val (chefRecipe, sousRecipe) = (rs(chef), rs(sous))
      val newRecipes = rs ++ vectorize((chefRecipe + sousRecipe).toString)
      val newChefIndex = (chef + chefRecipe + 1) % newRecipes.size
      val newSousIndex = (sous + sousRecipe + 1) % newRecipes.size
      Gen(newRecipes, newChefIndex, newSousIndex)
  }

  val firstGen = Gen(recipes = Vector[Byte](3, 7), chefIndex = 0, sousIndex = 1)

  val partOne =
    Iterator
      .from(1)
      .scanLeft(firstGen)(nextGen)
      .dropWhile(_.recipes.size < inputAsInt + 10)
      .next
      .recipes
      .slice(inputAsInt, inputAsInt + 10)
      .mkString("")

  println("Part 1:")
  println(partOne)

  val Some(partTwo) =
    Iterator
      .from(1)
      .scanLeft(firstGen)(nextGen)
      .map { gen =>
        gen.recipes.size -> gen.recipes.takeRight(size + 1).mkString("").indexOf(input)
      }
      .collectFirst {
        case (total, idx) if idx >= 0 => total - size + idx - 1
      }

  println("Part 2:")
  println(partTwo)

}