use IO; // It's easiest to just yield all numbers as a list, then reshape that list // into a square given `rowSize` information. iter allNumbers(ref rowSize: int) { for line in stdin.lines() { const trimmedLine = line.strip(); rowSize = trimmedLine.size; for num in trimmedLine { yield num : int; } } } // Time to do that reshaping! var rowSize = 0; var allNums = allNumbers(rowSize); var shapedNums = reshape(allNums, { 1..allNums.size / rowSize, 1..rowSize }); // In this problem, we're considering the view from each direction at each // tree. Define a helper iterator to return an array slice representing trees // in that direction, as well as the "by" step indicating which direction // the path should be walked in. iter eachDirection((x,y)) { yield (shapedNums[..= this then break; } return count; } // Finally, we iterate (in parallel) over each tree, and tally up if it's // visible, as well as compute and note its score. var visible = 0; var bestScore = 0; forall coord in shapedNums.domain with (+ reduce visible, max reduce bestScore) { const tree = shapedNums[coord]; visible += || reduce tree.visibleAlong(eachDirection(coord)); bestScore reduce= * reduce tree.scoreAlong(eachDirection(coord)); } writeln(visible); writeln(bestScore);