Я немного опоздал с игрой, но я могу предложить вклад, который может считаться более элегантным в нескольких смыслах:
def partitions(n, m = None):
"""Partition n with a maximum part size of m. Yield non-increasing
lists in decreasing lexicographic order. The default for m is
effectively n, so the second argument is not needed to create the
generator unless you do want to limit part sizes.
"""
if m is None or m >= n: yield [n]
for f in range(n-1 if (m is None or m >= n) else m, 0, -1):
for p in partitions(n-f, f): yield [f] + p
Только 3 строки кода. Выдает их в лексикографическом порядке. Опционально позволяет наложение максимального размера детали.
У меня также есть вариация описанного выше для разделов с заданным количеством частей:
def sized_partitions(n, k, m = None):
"""Partition n into k parts with a max part of m.
Yield non-increasing lists. m not needed to create generator.
"""
if k == 1:
yield [n]
return
for f in range(n-k+1 if (m is None or m > n-k+1) else m, (n-1)//k, -1):
for p in sized_partitions(n-f, k-1, f): yield [f] + p
После составления вышеупомянутого я наткнулся на решение, которое я создал почти 5 лет назад, но которое я забыл о. Помимо максимального размера детали, этот предлагает дополнительную функцию, которая позволяет наложить максимальную длину (в отличие от определенной длины). FWIW:
def partitions(sum, max_val=100000, max_len=100000):
""" generator of partitions of sum with limits on values and length """
# Yields lists in decreasing lexicographical order.
# To get any length, omit 3rd arg.
# To get all partitions, omit 2nd and 3rd args.
if sum <= max_val: # Can start with a singleton.
yield [sum]
# Must have first*max_len >= sum; i.e. first >= sum/max_len.
for first in range(min(sum-1, max_val), max(0, (sum-1)//max_len), -1):
for p in partitions(sum-first, first, max_len-1):
yield [first]+p
лямбда
в Ruby являются объектами класса Proc. Объекты Proc
не принадлежат никакому объекту. Они вызываются без привязки их к объекту.
Методы - это объекты либо класса Method
, либо UnboundMethod
, в зависимости от того, связаны они или нет. См. Объяснение здесь . Несвязанные методы нельзя вызывать, пока они не будут привязаны к объекту.
lambda{|x| x}.class # => Proc
lambda{|x| x}.call(123) # => 123
class Foo
def bar(baz)
baz
end
end
puts Foo.new.method(:bar).class # => Method
puts Foo.new.method(:bar).call(123) # => 123
puts Foo.instance_method(:bar).class # => UnboundMethod
puts Foo.instance_method(:bar).call(123) # => throws an exception
Вы можете привязать
UnboundMethod
к объекту, а затем вызвать его. Но вы вообще не можете привязать
Proc
к объекту. Однако объекты Proc
могут захватывать локальные переменные в окружающей области видимости, становясь замыканиями.
Procs и lambdas являются объектами сами по себе, с методом call
, который фактически вызывает блок, связанный с процедурой (или lambda). Однако Ruby предоставляет некоторый синтаксический сахар для их вызова без явного вызова call
.
Я думаю, что разница между методами и функцией первого порядка т.е. функции, которые можно передавать как значения.