Николай обнови решението на 06.11.2013 02:44 (преди почти 12 години)
+class Criteria
+  class << self
+    def status(checkFor)
+      Criteria.new(-> (tested) { tested.status == checkFor })
+    end
+
+    def priority(priorityToCheck)
+      Criteria.new(-> (tested) { tested.priority == priorityToCheck })
+    end
+
+    def tags(tagsNeeded)
+      Criteria.new(-> (tested) { (tagsNeeded - tested.tags).empty? })
+    end
+  end
+
+  def &(against)
+    Criteria.new(->(x) { @lambdaTest.call(x) & against.lambdaTest.call(x) })
+  end
+
+  def |(against)
+    Criteria.new(->(x) { @lambdaTest.call(x) | against.lambdaTest.call(x) })
+  end
+
+  def !
+    Criteria.new(->(x) { not @lambdaTest.call(x) } )
+  end
+
+  def initialize(lambdaTest)
+    @lambdaTest = lambdaTest
+  end
+
+  attr_accessor :lambdaTest
+end
+
+class Task
+  attr_accessor :status
+  attr_accessor :description
+  attr_accessor :priority
+  attr_accessor :tags
+
+  def initialize(args)
+    statusString, @description, priorityString, tagsString = refine(args,'|')
+    @status = statusString.downcase.to_sym
+    @priority = priorityString.downcase.to_sym
+    @tags = tagsString ? refine(tagsString,',') : []
+  end
+
+  private def refine(args,separator)
+    args.split(separator).map { |item| item.strip }
+  end
+end
+
+class TodoList < Array
+  def tasks_todo
+    count { |task| task.status == :todo }
+  end
+
+  def tasks_in_progress
+    count { |task| task.status == :current }
+  end
+
+  def tasks_completed
+    count { |task| task.status == :done }
+  end
+
+  def completed?
+    all? { |task| task.status == :done }
+  end
+
+  def filter(criterion)
+     filtered =TodoList.new
+     each { |item| filtered << item }
+     filtered.select! { |item| criterion.lambdaTest.call(item) }
+  end
+
+  def TodoList.parse(text)
+    emptyList = Array::TodoList.new
+    text.lines.reduce(emptyList) { |tasks,line| tasks << Task.new(line) }
+  end
+
+  alias adjoin +
+end
+
