Hello true but no summand may appear twice, and only numbers 1 to 9 may be used. For example, (10, 3) yields
Array[Int16[2,3,5],Int16[1,4,5],Int16[1,3,6],Int16[1,2,7]] Regards, -Patrick On Monday, October 19, 2015 at 12:51:49 PM UTC+2, Jason Merrill wrote: > > If I'm reading correctly, it looks like decompose is intended to give all > partitions of val into num summands. > > Julia actually has this function as part of Base: > > julia> collect(Vector{Int}, partitions(10, 3)) > 8-element Array{Array{Int64,1},1}: > [8,1,1] > [7,2,1] > [6,3,1] > [5,4,1] > [6,2,2] > [5,3,2] > [4,4,2] > [4,3,3] > > partitions actually returns an iterator, so if you can process the > partitions 1-by-1, you don't actually have to store them all at once. > > You can see how it's implemented here: > > > https://github.com/JuliaLang/julia/blob/8396c9f5c9a3483e35f5e1f9ef63d4c6b3f45b04/base/combinatorics.jl#L307-L369 > > On Sunday, October 18, 2015 at 9:49:45 PM UTC-4, Patrick Useldinger wrote: >> >> Hi everybody, >> >> I am currently benchmarking languages to write a kakuro solver in. I am >> not really familiar with Julia but ported the small algorithm I had written >> in Lisp and PyPy to Julia nevertheless. Unfortunately Julia's performance >> is really bad and I'm reaching out to the community to find out whether >> it's due to my coding or not. >> >> Here's the code in Julia: >> >> function decompose(val, num) >> function sub(num, tot, res, pos, allres) >> if val==tot && num==0 >> union(allres, res) >> elseif tot<val && num>0 && !isempty(pos) >> sub(num-1, tot+pos[1], union(copy(res),pos[1]), pos[2:end], >> sub(num, tot, res, pos[2:end], allres)) >> else >> allres >> end >> end >> sub(num, 0, Int16[], 1:(max(num, 10))-1, Array[]) >> end >> >> for i in 1:45 >> for j in 2:20 >> res = decompose(i, j) >> end >> end >> >> It takes roughly 13.4 seconds on my computer. >> >> The equivalent Python code >> >> def decompose(val, num): >> def sub(num, tot, res, pos, allres): >> if tot == val and num == 0: >> return allres+res >> elif tot < val and num != 0 and pos: >> return sub(num-1, tot+pos[0], res+[pos[0]], pos[1:], sub(num, >> tot, res, pos[1:], allres)) >> else: >> return allres >> return sub(num, 0, [], range(1, max(num, 10)), []) >> >> >> if __name__ == "__main__": >> for i in range(1, 46): >> for j in range(2,21): >> res = decompose(i,j) >> >> is 1.4 seconds and the Lisp >> >> defun decompose (val num) >> (labels ((sub (num tot res pos allres) >> (cond >> ((and (= tot val) (zerop num)) (cons (reverse res) allres)) >> ((and (< tot val) (not (zerop num)) (not (null pos))) >> (sub (1- num) (+ tot (car pos)) (cons (car pos) res) (cdr >> pos) >> (sub num tot res (cdr pos) allres))) >> (t allres)))) >> (reverse (sub num 0 nil (loop for i from 1 below (max num 10) collect >> i) nil)))) >> >> (time >> (loop for val from 1 below 46 do >> (loop for num from 2 below 21 do >> (let ((res (decompose val num))))))) >> >> is 0.5 seconds. >> >> Any hints to make the Julia code perform better? >> >> Regards, >> -Patrick >> >