Advent of Code 2016 Day3: Squares with Three Sides
This is a series of programming challenges for beginners and experienced Caché programmers.
For an introduction : goto to article https://community.intersystems.com/post/advent-code-2016-day1-no-time-ta... or look at the http://adventofcode.com/ website.
In today's challenge, you have to find out how many 'valid' triangles you find on the walls of the Easter Bunny HQ.
(you can find the input on the adventofcode website : http://adventofcode.com/2016/day/3/input)
A sample of the input looks like this :
810 679 10 783 255 616 545 626 626 84 910 149 607 425 901 556 616 883 938 900 621
A valid triangle is a set of three side lengths where the sum of any two sides is larger than the remaining side.
You can find the complete instructions here : http://adventofcode.com/2016/day/3
We can solve this challenge in only a few steps :
- stripping the input for unnecessary whitespace : $ZStrip(var,"<=>W") will strip leading, trailing, and repetitive whitespace
- check each input line for the three sides, and test on valid values : (S1 + S2 > S3, S1 + S3 > S2, S2 + S3 > S1)
- and display the number of valid triangles
... thats really all there is to do.
Here is my solution as a classmethod :
ClassMethod Part1(file As %String = "j:\winfo\aoc\day3.txt") { #Dim possibles as %Integer = 0 #Dim line as %String #Dim values as %Integer #Dim t, combi as %String #Dim possible as %Integer Open file:"R":1 Else Use 0 Write "Could not open file ",file Quit Try { For { Use file Read line If line="" Quit Set line=$ZStrip(line,"<=>W") For values=1:1:3 Set t(values)=$Piece(line," ",values) Set possible = 1 For combi=$lb(1,2,3),$lb(1,3,2),$lb(2,3,1) { If (t($List(combi,1))+t($List(combi,2)))'>t($List(combi,3)) set possible=0 quit } If possible set possibles = possibles + 1 } } Catch { If $ZE'["ENDOFFILE" Use 0 Write "Error : ",$ZE,! } Close file Use 0 Write "Possibles : ",possibles,! Quit }
The answer will unlock the second part of the puzzle, which does a twist in reading the input file : instead of each line being one triangle, for each three lines each column will be a triangle.
So after some fiddling with reading the input file, I think it's better to first read the input into an array (but that's for next time).
Here is the routine code that Bert wrote for the second part :
Start2() PUBLIC { s count=0 #Dim objFileStream As %Stream.FileCharacter s objFileStream = ##Class(%Stream.FileCharacter).%New() s sc=objFileStream.LinkToFile("C:\Users\15274\workspace\adventofcode\2016\input\day03\input.txt") while 'objFileStream.AtEnd { s line=objFileStream.ReadLine() s line2=objFileStream.ReadLine() s line3=objFileStream.ReadLine() s a=$ZSTRIP($EXTRACT(line,3,5),"*W") s b=$ZSTRIP($EXTRACT(line,8,10),"*W") s c=$ZSTRIP($EXTRACT(line,13,15),"*W") s a2=$ZSTRIP($EXTRACT(line2,3,5),"*W") s b2=$ZSTRIP($EXTRACT(line2,8,10),"*W") s c2=$ZSTRIP($EXTRACT(line2,13,15),"*W") s a3=$ZSTRIP($EXTRACT(line3,3,5),"*W") s b3=$ZSTRIP($EXTRACT(line3,8,10),"*W") s c3=$ZSTRIP($EXTRACT(line3,13,15),"*W") if $$IsValidTriangle(a,a2,a3) { s count = count + 1 } if $$IsValidTriangle(b,b2,b3) { s count = count + 1 } if $$IsValidTriangle(c,c2,c3) { s count = count + 1 } } w !,count } IsValidTriangle(A,B,C) { s sides(A)="" s sides(B)="" s sides(C)="" s smallest = $ORDER(sides("")) s middle = $ORDER(sides(smallest)) s last = $ORDER(sides(middle)) q (smallest+middle)>last }
I have a feeling that the next challenges will not all be so easy ...
As mentioned before, you can get all our solutions of the challenges as they pass on https://github.com/DannyWijnschenk/AdventOfCode2016 and https://bitbucket.org/bertsarens/advent2016
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