Comments (5)
Beginning of my attempt at a functional version:
(declare stack-partitions-M)
(defn multiset-partitions-M
[multiset r s]
(let [m (count multiset)
init (reduce (fn [acc i]
(let [v (multiset i)]
(assoc acc i [v v])))
(sorted-map)
(range m))
stack [init]]
(stack-partitions-M stack r s)))
(defn stack-partitions-M [stack r s]
(letfn [(next-block [block]
(second
(reduce (fn [[v-changed? acc] [ci [ui vi]]]
(let [uj (- ui vi)]
(if (zero? uj)
[true acc]
(let [changed? (or v-changed? (< uj vi))
vj (if changed?
uj
(min uj vi))
elem [ci [uj vj]]]
[changed? (conj acc elem)]))))
[false []]
block)))
(m5 [stack]
(let [block (peek stack)
head (pop stack)
;; Also assumes no fully zero entries.
j (loop [j (into [] (keys block))]
(if (zero? (block j))
(recur (pop j))
j))]
(cond
(and (= j a)
(or (= (v j) 1)
(and r
(let [new-val (dec (v j))
uj (block j)]
(> (+ (inc l)
(dec (quot uj new-val)))
r)))))
(if (= 1 (count block))
[]
(recur head))
:else
(let [v (update v j dec)
prefix (subvec v 0 (inc j))
v (into prefix (subvec u (inc j)))
amount-to-dec (if s
(let [diff-uv (apply + (for [i (range a (inc j))]
(- (u i) (v i))))
min-partitions-left (- s (inc l))]
(max 0 (- min-partitions-left diff-uv)))
0)
v (if (zero? amount-to-dec)
v
(loop [k-1 (dec b)
v v
amount amount-to-dec]
(let [vk (v k-1)]
(if (> amount vk)
(recur (dec k-1)
(assoc v k-1 0)
(- amount vk))
(assoc v k-1 (- vk amount))))))]
(if (zero? (v a))
(recur (pop stack))
(conj head ,,,))))))]
(let [n-blocks (count stack)
candidate (next-block (peek stack))]
(cond (seq candidate)
(if (and r (= n-blocks r))
(recur (m5 stack) r s)
(recur (conj stack candidate) r s))
;; Did we NOT march forward, but we don't have enough blocks yet?
(and s (< n-blocks s))
(recur (m5 stack) r s)
:else
(lazy-seq
(let [part (for [block stack]
;; TODO recover the zero filter?
(zipmap (map first block)
(map (comp second second) stack)))]
(cons part (stack-partitions-M (m5 stack) r s))))))))
(defn items->multiset
"returns [ditems, multiset]"
[items]
(let [freqs (frequencies items)
ditems (into [] (distinct) items)]
[ditems (into {} (map-indexed
(fn [i item]
[i (freqs item)]))
ditems)]))
(defn multiset->items
"Returns the items."
[ditems mset]
(into [] (mapcat
(fn [[i n]]
(repeat n (ditems i))))
mset))
(defn- partitions-M
[items & {from :min to :max}]
(let [N (count items)]
(if (= N 0)
(if (<= (or from 0) 0 (or to 0))
'(())
())
;; `from` and `to` only make sense inside the bounds.
(let [from (if (and from (<= from 1)) nil from)
to (if (and to (>= to N)) nil to)]
(cond
;; Check if the order is reversed?
(not (<= 1 (or from 1) (or to N) N)) ()
(= N 1) (list (list [(first items)]))
:else
(let [[ditems start-multiset] (items->multiset items)]
(for [part (multiset-partitions-M start-multiset to from)]
(for [multiset part]
(multiset->items ditems multiset)))))))))
from emmy.
This comes from my attempts to find a minimal bugfix for https://clojure.atlassian.net/browse/MCOMB-11...
from emmy.
sympy has a well documented version of this algorithm.
- notes on the modification of m5: https://github.com/sympy/sympy/blob/e56ec3aa582b05d306b973ba7290e3e6260df471/sympy/utilities/enumerative.py#L531-L564 This is an implementation of the upper bound, described in the exercise. Did they do a better job?
I think they do. Here are two more tests we can implement: https://github.com/sympy/sympy/blob/e56ec3aa582b05d306b973ba7290e3e6260df471/sympy/utilities/enumerative.py#L576-L594
from emmy.
Here is some code to count the number of partitions, vs just generating and counting: https://github.com/sympy/sympy/blob/e56ec3aa582b05d306b973ba7290e3e6260df471/sympy/utilities/enumerative.py#L1021-L1090
from emmy.
Another take on the lower bound code: https://github.com/sympy/sympy/blob/e56ec3aa582b05d306b973ba7290e3e6260df471/sympy/utilities/enumerative.py#L597-L662
from emmy.
Related Issues (20)
- Next Journal link leads to blank notebook HOT 1
- unary negation handling is broken in ->JavaScript HOT 3
- Port axch's adaptive-plot library
- Links to documentation are broken HOT 2
- Feature request for 'collect' function
- Feature request for 'Expand' function
- Simplifier doesn't detect trigonometric identity HOT 1
- state-advancer throws "Cannot mix BigInt and other types" HOT 4
- CSE leaving a lot on the table due to variadic *, + etc HOT 1
- Overhaul SCI interface to use modern copy-ns etc HOT 1
- FDG Link in Readme broken HOT 1
- Add pretty-print extensions for custom types
- Protocol ICoordinateSystem is overwriting function uuid
- symbolic-taylor-series can't take perturbations as arguments
- Write a TeXmacs plugin
- Can `compare` handle literal square root? HOT 10
- Implement "An Algebra of Properties"
- Update all nextjournal notebooks with new require form for code HOT 1
- Speed up compiled state derivatives HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from emmy.