This is a fairly simple Ruby solution to the August 2016 community challenge.Ok, the title is way too dramatic. But tributary is a nice word, and the alliteration was too good to pass up.Besides, konijn started it!I didn't bother to output a 2D map of the basins, I just print their sizes as the challenge requires. (Printing a map wouldn't be a difficult thing graft onto this, but I just wanted to keep things clean.)Anyway, the script:# Simple class that models a point on the terrainclass Cell  attr_reader :altitude  # Init with the cell's altitude  def initialize(altitude)    @altitude = altitude    @neighbors = []  end  # Add another cell instance as a neighbor of the receiver  def add_neighbor(cell)    @neighbors << cell  end  # Returns the drain of the receiver (lowest of lower neighbors),  # or nil if no such neighbor exists  def drain    @drain ||= @neighbors      .select { |neighbor| neighbor.altitude < altitude }      .min_by(&:altitude)  end  # Returns the sink of the receiver, i.e. the drain's drain (ad fundum),  # or self if the cell is itself a sink  def sink    @sink ||= drain.nil? ? self : drain.sink  endend# Helper method. Given an array of cells, register adjacent# cells as neighbors of each otherdef link_cells(cells)  cells.each_cons(2) do |a, b|    a.add_neighbor(b)    b.add_neighbor(a)  endend# Get the terrain size (first line of input)size = gets.chomp.to_i# Init the altitude cells (as a 2D array) from inputterrain = size.times.map do  gets.strip.split.map { |altitude| Cell.new(altitude.to_i) }end# Register neighbors (first row-wise, then column-wise)terrain.each { |row| link_cells(row) }terrain.transpose.each { |col| link_cells(col) }# Divide into basins (cells sharing same sink) and print basin sizesbasins = terrain.flatten.group_by(&:sink).valuesputs basins.map(&:size).sort.reverse.join( )It passes the test cases given in the challenge. It also works with non-square terrains for that matter.To my eyes, the code suffers a bit from the 2-step process needed to create a useful Cell. It's initialized with an altitude, but that isn't really useful until a 2nd pass links all cells to their neighbors. Just seems crude.I considered having each cell know its coordinates and adding a Terrain class to handle the neighbor-lookups, but that seemed like overkill. And it'd introduce a pet peeve of mine: The circular referencing between a cell and the collection it's part of. I've run into this tons of times (e.g. board game-type code), and never found a solution that didn't irk me a little.Anyway, there are probably more efficient solutions out there; I just went for simple and (hopefully) readable.Looking at it again, I see a couple of issues related to the memoizing, but I'll wait and see what reviewers find.
Trials, tribulations, and tributaries (Rainfall challenge)
ruby;community challenge