Advent of Code 2016 Day15: Timing is Everything

Primary tabs

This is a series of programming challenges for beginners and experienced Caché programmers.

For an introduction and an index of all articles: go to article https://community.intersystems.com/post/advent-code-2016-day1-no-time-ta...

The challenge for today consists of capsules that bounce through a maze of spinning discs.
The capsule can fall through a hole of each disc if they hit the disc at position 0,  each disc has a fixed amount of positions that rotate every second.
The distance between the release and the first disc is one second, as is the distance between each consecutive disc as well.
You have to calculate at what precise time you need to drop a capsule so that it will fall through all the discs.

For the complete explanation, and an example, go to http://adventofcode.com/2016/day/15, you will find the exact starting configuration of your discs at http://adventofcode.com/2016/day/15/input. (Each user that logs in at http://adventofcode.com gets a different input set, which will probably not match the input in our code example)

The challenge seems complicated than it really is : you just have to go through the different timings (from 0 onwards), and calculate if all the discs are aligned to postion 0 at the moment the capsule reach each disc. It turns out to be the easiest puzzle so far (day 11 was the toughest so far).  

 

Here is the routine Bert wrote to solve the challenge :

Start() PUBLIC {
  /*
  Disc #1 has 17 positions; at time=0, it is at position 5.
  Disc #2 has 19 positions; at time=0, it is at position 8.
  Disc #3 has 7 positions; at time=0, it is at position 1.
  Disc #4 has 13 positions; at time=0, it is at position 7.
  Disc #5 has 5 positions; at time=0, it is at position 1.
  Disc #6 has 3 positions; at time=0, it is at position 0.
  */

discs(1,"currentPosition")=5
discs(1,"positions")=17
discs(2,"currentPosition")=8
discs(2,"positions")=19
discs(3,"currentPosition")=1
discs(3,"positions")=7
discs(4,"currentPosition")=7
discs(4,"positions")=13
discs(5,"currentPosition")=1
discs(5,"positions")=5
discs(6,"currentPosition")=0
discs(6,"positions")=3

time=0
isBusy=1
  while isBusy {
isOk=1
discNr=$ORDER(discs(""))
    while isOk && (discNr'="") {
      if (discs(discNr,"currentPosition")+time+discNr)#discs(discNr,"positions") {
isOk=0
      }
discNr=$ORDER(discs(discNr))
    }
    if isOk {
!,"Time is:",time
isBusy = 0
else {
time=time+1
    }
  }
}

 


The unlocked part 2 of the challenge adds another disc, which does not change anything to the code (other than one disc in the input), so here is my implementation of the two parts in a class :

 

Class AOC2016.Day15
{

ClassMethod Part(part As %Integer = 1)
{
  #Dim disc, time as Array of %Integer
  #Dim found as %Boolean
  #Dim slot as %Integer

  Set disc(1)=13, time(1)=10
  Set disc(2)=17, time(2)=15
  Set disc(3)=19, time(3)=17
  Set disc(4)=7, time(4)=1
  Set disc(5)=5, time(5)=0
  Set disc(6)=3, time(6)=1
  If part=2 Set disc(7)=11, time(7)=0

  For time=0:1 {
    Set found=1
    Set disc="" For  {
      Set disc=$Order(disc(disc)) If disc="" Quit
      If (time(disc)+disc+time)#disc(disc) Set found=0 Quit
    }
    If found Write time,! Quit
  }
}

}


Look here for all our solutions so far : https://bitbucket.org/bertsarens/advent2016 and https://github.com/DannyWijnschenk/AdventOfCode2016
 

Here is the list of all Advent of Code 2016 articles  :

1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25