github.com/cycloss/advent-of-code@v0.0.0-20221210145555-15039b95faa6/2022/lib/day8.dart (about)

     1  import 'dart:io';
     2  
     3  import 'package:2022/wrapped_primitives.dart';
     4  
     5  class Tree {
     6    final int height;
     7    bool visible;
     8    Tree(this.height, this.visible);
     9    List<int> scenicScores = [];
    10    int get totalScenicScore {
    11      var scoreTotal = 1;
    12      for (var score in scenicScores) {
    13        scoreTotal *= score;
    14      }
    15      return scoreTotal;
    16    }
    17  }
    18  
    19  void day8() {
    20    var lines = File('inputs/day8').readAsLinesSync();
    21    var grid = generateGrid(lines);
    22    // tree heights 0 to 9 (0 is a tree)
    23    // tree visible if all trees from it to edge are shorter than it
    24    // plan is to start at level 9 and go down to 0
    25    // do each row forward and back, and each column up and down
    26    // start all tuples as visible null
    27    // possibly unnecessary: if index of iteration is 0 (an edge), set visible to true
    28    // if a visible tree is found before tree of current level, stop and move to next (lower) level as that tree is taller and so nothing after will be visible for the current level
    29    // if a tree of the current height is found, set it to visible, and all trees after to invisible, until you get to a tree that is visible (will be higher than it, set on a previous iteration)
    30  
    31    findVisibleTrees(grid);
    32    // printGrid(grid);
    33    print("Part 1:");
    34    countVisibleTrees(grid);
    35  
    36    findScenicScores(grid);
    37  
    38    print("Part 2:");
    39    findMaxScenicScore(grid);
    40  }
    41  
    42  void countVisibleTrees(List<List<Tree>> grid) {
    43    var total = 0;
    44    for (var row in grid) {
    45      for (var tree in row) {
    46        if (tree.visible) {
    47          total++;
    48        }
    49      }
    50    }
    51    print(total);
    52  }
    53  
    54  void findMaxScenicScore(List<List<Tree>> grid) {
    55    var max = 0;
    56    for (var row in grid) {
    57      for (var tree in row) {
    58        if (tree.totalScenicScore > max) {
    59          max = tree.totalScenicScore;
    60        }
    61      }
    62    }
    63    print(max);
    64  }
    65  
    66  void printGrid(List<List<Tree>> grid) {
    67    for (var row in grid) {
    68      for (var tree in row) {
    69        stdout.write('${tree.visible} ');
    70      }
    71      print("");
    72    }
    73  }
    74  
    75  void findVisibleTrees(List<List<Tree>> grid) {
    76    for (var currentLevel = 9; currentLevel >= 0; currentLevel--) {
    77      for (var row in grid) {
    78        // iterate row forward for current level
    79        processVisibilityOfLine(row, currentLevel);
    80        // iterate row backward for current level
    81        processVisibilityOfLine(row.reversed, currentLevel);
    82      }
    83      for (var column in getGridColumns(grid)) {
    84        // iterate row forward for current level
    85        processVisibilityOfLine(column, currentLevel);
    86        // iterate row backward for current level
    87        processVisibilityOfLine(column.reversed, currentLevel);
    88      }
    89    }
    90  }
    91  
    92  List<List<Tree>> getGridColumns(List<List<Tree>> grid) {
    93    var columns = <List<Tree>>[];
    94    for (var i = 0; i < grid[0].length; i++) {
    95      var column = <Tree>[];
    96      for (var j = 0; j < grid.length; j++) {
    97        column.add(grid[j][i]);
    98      }
    99      columns.add(column);
   100    }
   101    return columns;
   102  }
   103  
   104  void processVisibilityOfLine(Iterable<Tree> line, int currentLevel) {
   105    var found = Bool(false);
   106    for (var tree in line) {
   107      if (tree.visible) {
   108        // break as found a tree taller of the same size before found tree of current height
   109        break;
   110      }
   111      processTreeVisibility(tree, found, currentLevel);
   112    }
   113  }
   114  
   115  void processTreeVisibility(Tree tree, Bool found, int currentLevel) {
   116    if (found.b) {
   117      // tree must be smaller and therefore not visible as not encountered large visible tree yet, and tree of current level found
   118      tree.visible = false;
   119      return;
   120    }
   121    if (tree.height == currentLevel) {
   122      tree.visible = true;
   123      found.b = true;
   124    }
   125  }
   126  
   127  void findScenicScores(List<List<Tree>> grid) {
   128    for (var currentLevel = 9; currentLevel >= 0; currentLevel--) {
   129      for (var row in grid) {
   130        // iterate row forward for current level
   131        processScenicScoreOfLine(row, currentLevel);
   132        // iterate row backward for current level
   133        processScenicScoreOfLine(row.reversed, currentLevel);
   134      }
   135      for (var column in getGridColumns(grid)) {
   136        // iterate row forward for current level
   137        processScenicScoreOfLine(column, currentLevel);
   138        // iterate row backward for current level
   139        processScenicScoreOfLine(column.reversed, currentLevel);
   140      }
   141    }
   142  }
   143  
   144  void processScenicScoreOfLine(Iterable<Tree> line, int currentLevel) {
   145    // set score to 0 as no trees on edge
   146    var score = 0;
   147    for (var tree in line) {
   148      if (tree.height >= currentLevel) {
   149        if (tree.height == currentLevel) {
   150          tree.scenicScores.add(score);
   151        }
   152        // set score to one as current tree counts
   153        score = 1;
   154      } else {
   155        score++;
   156      }
   157    }
   158  }
   159  
   160  List<List<Tree>> generateGrid(List<String> lines) {
   161    var grid = <List<Tree>>[];
   162    for (var line in lines) {
   163      var gridLine = <Tree>[];
   164      for (var char in line.split("")) {
   165        gridLine.add(Tree(int.parse(char), false));
   166      }
   167      grid.add(gridLine);
   168    }
   169    return grid;
   170  }