Partition function P: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (→{{header|J}}) |
m (→{{header|Wren}}: Minor tidy) |
||
(7 intermediate revisions by 3 users not shown) | |||
Line 3:
The [https://mathworld.wolfram.com/PartitionFunctionP.html Partition Function P]
Line 15:
The successive numbers in the above equation have the differences: 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8 ...
This task may be of popular interest because [https://www.youtube.com/channel/UC1_uAIS3r8Vu6JjXWvastJg Mathologer] made the video, [https://www.youtube.com/watch?v=iJ8pnCO0nTY The hardest "What comes next?" (Euler's pentagonal formula)], where he asks the programmers among his viewers to calculate P(666). The video
In Wolfram Language, this function has been implemented as PartitionsP.
Line 41:
{{trans|Python: Alternative}}
<
V p = [BigInt(1)] [+] [BigInt(0)] * n
L(i) 1 .. n
Line 67:
V start = time:perf_counter()
print(partitions(6666))
print(time:perf_counter() - start)</
{{out}}
Line 78:
=={{header|C}}==
{{libheader|GMP}}
<
#include <stdlib.h>
#include <stdio.h>
Line 114:
(double)(clock() - start) / (double)CLOCKS_PER_SEC);
return 0;
}</
{{out}}
Line 124:
=={{header|C#|CSharp}}==
This can also be done using BigIntegers, but will take around five times longer. Since only adding and subtracting are required, some simple routines can be created to handle the tabulations. Also note that detecting odd and even numbers on each loop iteration is avoided by coding four increments per loop.
<
class Program {
Line 182:
Console.Write("{0} {1} ms", fmt(res), sw.Elapsed.TotalMilliseconds);
}
}</
{{out}}
<pre>193655306161707661080005073394486091998480950338405932486880600467114423441282418165863 12.9365 ms</pre>
Line 190:
===GMP version===
{{libheader|GMP}}
<
#include <iostream>
#include <vector>
Line 228:
std::cout << result << '\n';
std::cout << "elapsed time: " << ms.count() << " milliseconds\n";
}</
{{out}}
Line 238:
===Non GMP version===
{{trans|C#}}
<
#include <iostream>
Line 299:
duration<double, milli> ms(end - start);
cout << fmt(result) << " " << ms.count() << " ms";
}</
{{out}}
Timing from Tio.run, but execution time can't be directly compared to the GMP version, as GMP isn't accessible at Tio.run.
Line 309:
{{libheader| System.Diagnostics}}
{{Trans|Go}}
<syntaxhighlight lang="delphi">
program Partition_function_P;
Line 378:
writeln('Took ', stopwatch.ElapsedMilliseconds, 'ms');
Readln;
end.</
{{out}}
<pre>p[6666] = 193655306161707661080005073394486091998480950338405932486880600467114423441282418165863
Line 385:
=={{header|Elixir}}==
Loosely based on the Erlang version.
<syntaxhighlight lang="elixir">
use Bitwise, skip_operators: true
Line 424:
Partition.init
IO.puts Partition.p 6666
</syntaxhighlight>
</lang>▼
{{Out}}
<pre>
Line 436:
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-mode(compile).
Line 473:
true -> gpentagonals(M + 1, Max, [GP|Ps])
end.
</syntaxhighlight>
{{Out}}
<pre>
Line 486:
=={{header|F_Sharp|F#}}==
An implementation of the formula in the task description. P(123456) is included for comparison with the largest value in the related task.
<
// PartionP: Nigel Galloway. April 12th., 2021
let pP g=let rec fN i g e l=seq{yield(l,e+i);yield(-l,e+i+g);yield! fN(i+1)(g+2)(e+i+g)(-l)}
Line 492:
seq{2..g}|>Seq.iter(fun p->N.[p]<-G|>List.takeWhile(fun(_,n)->n<=p)|>Seq.fold(fun Σ (n,g)->Σ+n*N.[p-g]) 0I); N.[g]
printfn "666->%A\n\n6666->%A\n\n123456->%A" (pP 666) (pP 6666) (pP 123456)
</syntaxhighlight>
{{out}}
<pre>
Line 505:
=={{header|Factor}}==
{{works with|Factor|0.99 2020-08-14}}
<
! Compute the nth pentagonal number.
Line 527:
: partitions ( m -- n )
[ seq swap [ <= ] curry lwhile list>array ]
[ V{ 1 } clone swap [ step ] times last nip ] bi ;</
{{out}}
<pre>
Line 541:
===Unsiged 64bit version===
{{trans|Python}}
<
' if n > 416, the result becomes to large for a unsigned 64bit integer
Dim As ULongInt p(n)
Line 577:
Print !"\n\ndone"
Sleep</
{{out}}
<pre>PartitionsP: 1 1 2 3 5 7 11 15 22 30 42 56 77</pre>
Line 584:
{{libheader|GMP}}
[https://rosettacode.org/wiki/9_billion_names_of_God_the_integer#FreeBASIC From the 9_billion_names_of_God_the_integer entry]
<
' compile with: fbc -s console
Line 646:
Print : Print "hit any key to end program"
Sleep
End</
{{out}}
<pre>PartitionsP(6666) = 193655306161707661080005073394486091998480950338405932486880600467114423441282418165863
Line 653:
=={{header|Frink}}==
Frink has a built-in function for counting partitions that uses Euler's pentagonal method. It works for arbitrarily-large integers and caches results.
<syntaxhighlight lang
{{out}}
<pre>
Line 662:
{{trans|Julia}}
I also tried using Euler's generating function but it was about 20 times slower than this version.
<
import (
Line 720:
fmt.Printf("p[%d)] = %d\n", N, p[N])
fmt.Printf("Took %s\n", time.Since(start))
}</
{{out}}
Line 729:
=={{header|Java}}==
<
public class PartitionFunction {
Line 764:
return p[n];
}
}</
{{out}}
Line 774:
=={{header|JavaScript}}==
<
function p(n){
var a = new Array(n+1)
Line 793:
console.log("p(6666) = " + p(6666))
console.log("Computation time in ms: ", Date.now() - t)
</syntaxhighlight>
{{out}}
Line 803:
=={{header|Haskell}}==
<
------------------------------------------------------------
Line 847:
main :: IO ()
main = print $ partitionP 6666</
<pre>*Main> partitionP <$> [1..10]
Line 864:
Solution stolen [https://code.jsoftware.com/wiki/Essays/Partitions#The_Number_of_Partitions verbatim from the J Wiki]. Note the use of memoization (M.) for efficiency:
<
rec=: - (-: (*"1) _1 1 +/ 3 * ]) @ (>:@i.@>.@%:@((2%3)&*))</
{{out}}
Line 881:
Translation of: Python:Alternative
<
def div2: (. - (.%2)) / 2;
reduce range(1; $n + 1) as $i ( {p: ([1] + [range(0;$n)|0])};
Line 902:
| .p[$n] ;
[partitions(range(1;15))]</
{{out}}
<pre>[1,2,3,5,7,11,15,22,30,42,56,77,101,135]</pre>
Using gojq 0.12.11, `partitions(6666)` yields (in about 12 minutes (u+s) on a 3GHz machine):
jq's built-in integer precision is insufficient for computing ``partitions(6666)``, but more as a test▼
of the BigInt.jq library for jq than anything else, here are the results of using it in conjunction▼
193655306161707661080005073394486091998480950338405932486880600467114423441282418165863
▲
▲of the BigInt.jq library for jq
with a trivially-modified version of the ''partitions'' implementation above. That is, after
modifying the lines that refer to "p" (or ".p"), we see that ''partitions(6666)'' yields:
Line 913 ⟶ 917:
"193655306161707661080005073394486091998480950338405932486880600467114423441282418165863"
=== Recursive ===
{{trans|Julia}} with memoization
<
if ($n % 2) == 1 then ($n+1) / 2 else $n+1 end;
Line 966 ⟶ 970:
# Stretch goal:
6666 | partitionsP
</syntaxhighlight>
Using gojq, the above program takes 41.35 seconds (u+s) on a 3GHz Mac Mini to produce:<pre>
193655306161707661080005073394486091998480950338405932486880600467114423441282418165863</pre>
Line 972 ⟶ 976:
=={{header|Julia}}==
===Recursive===
<
function partDiffDiff(n::Int)::Int
Line 1,004 ⟶ 1,008:
n=6666
@time println("p($n) = ", partitionsP(n))</
{{out}}
<pre>p(6666) = 193655306161707661080005073394486091998480950338405932486880600467114423441282418165863
Line 1,011 ⟶ 1,015:
=={{header|Lingo}}==
Lingo natively only supports 32 bit integers, so P(6666) would be way too big.
<
on partitions(n, res_table)
if n < 2 then return 1
Line 1,038 ⟶ 1,042:
res_table[n] = res
return res
end</
{{out}}
<pre>
Line 1,049 ⟶ 1,053:
=={{header|Maple}}==
<
option remember;
local k,s:=0,m;
Line 1,078 ⟶ 1,082:
combinat[numbpart](1000);
# 24061467864032622473692149727991</
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
PartitionsP[666]
PartitionsP[6666]</
{{out}}
<pre>{1,2,3,5,7,11,15,22,30,42,56,77,101,135,176}
Line 1,092 ⟶ 1,096:
{{trans|C++}}
{{libheader|bignum}}
<
import bignum
Line 1,118 ⟶ 1,122:
let t0 = cpuTime()
echo partitions(6666)
echo &"Elapsed time: {(cpuTime() - t0) * 1000:.2f} ms"</
{{out}}
Line 1,125 ⟶ 1,129:
=={{header|Perl}}==
<
use warnings;
no warnings qw(recursion);
Line 1,153 ⟶ 1,157:
print partitionsP($_) . ' ' for 0..25; print "\n";
print partitionsP(6666) . "\n";</
{{out}}
<pre>1 1 2 3 5 7 11 15 22 30 42 56 77 101 135 176 231 297 385 490 627 792 1002 1255 1575 1958
Line 1,162 ⟶ 1,166:
{{libheader|Phix/mpfr}}
Not exactly super-fast, but this sort of stuff is not really what Phix does best.
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">partDiffDiff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
Line 1,203 ⟶ 1,207:
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">6666</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"p(%d) = %s (%s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">partitionsP</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)),</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)})</span>
<!--</
{{out}}
<pre>
Line 1,210 ⟶ 1,214:
=={{header|Picat}}==
<
/* Picat 3.0#5 */
/* Author: Hakan Kjellerstrand */
Line 1,237 ⟶ 1,241:
CPU time 0.206 seconds.
</syntaxhighlight>
=={{header|PicoLisp}}==
Based on the Erlang implementation.
<syntaxhighlight lang="picolisp">
(de gpentagonals (Max)
(make
Line 1,260 ⟶ 1,264:
(setq Sgn (& 3 (inc Sgn))))
Sum))))
</syntaxhighlight>
{{Out}}
<pre>
Line 1,269 ⟶ 1,273:
=={{header|Prolog}}==
<
/* SWI-Prolog 8.3.21 */
/* Author: Jan Burse */
Line 1,285 ⟶ 1,289:
X = 1936553061617076610800050733944860919984809503384
05932486880600467114423441282418165863.
</syntaxhighlight>
=={{header|Python}}==
Line 1,291 ⟶ 1,295:
This follows the algorithm from the Mathloger video closely
<
def posd():
Line 1,341 ⟶ 1,345:
print(" pos_gen:", list(islice(pos_gen(), 10)))
print(" plus_minus:", list(islice(plus_minus(), 15)))
print("\nPartitions:", [part(x) for x in range(15)])</
{{out}}
Line 1,362 ⟶ 1,366:
====Python: Mathloger video prime generator====
Add the following code after that above
<
"Prime number generator from the partition machine"
p = [1]
Line 1,379 ⟶ 1,383:
yield p
print("\nPrimes:", list(islice(par_primes(), 15)))</
{{Out}}
Line 1,386 ⟶ 1,390:
===Python: Alternative===
{{trans|C++}}
<
Line 1,415 ⟶ 1,419:
if __name__ == '__main__':
print("\nPartitions:", [partitions(x) for x in range(15)])</
{{out}}
Line 1,427 ⟶ 1,431:
In [4]: %timeit partitions(6666)
215 ms ± 1.84 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
=={{header|Quackery}}==
<code>0 partitions</code> returns <code>1</code> as per [https://oeis.org/A000041 oeis.org/A000041 (Partitions of n)].
This is a naive recursive solution, so computing the partitions of 6666 would take a hideously long time.
<syntaxhighlight lang="Quackery"> [ 1 swap
dup 0 = iff drop done
[ 2dup = iff [ 2drop 1 ] done
2dup > iff [ 2drop 0 ] done
2dup dip 1+ recurse
unrot over - recurse + ] ] is partitions ( n --> n )
say "Partitions of 0 to 29" cr
30 times [ i^ partitions echo sp ]
</syntaxhighlight>
{{out}}
<pre>Partitions of 0 to 29
1 1 2 3 5 7 11 15 22 30 42 56 77 101 135 176 231 297 385 490 627 792 1002 1255 1575 1958 2436 3010 3718 4565
</pre>
Line 1,433 ⟶ 1,460:
Backwards range was used to get responsive feedback for progress.
<
(require math/number-theory)
Line 1,460 ⟶ 1,487:
(p 666)
(p 1000)
(p 10000)</
{{out}}
Line 1,482 ⟶ 1,509:
{{works with|Rakudo|2020.09}}
Not the fastest, but it gets the job done.
<syntaxhighlight lang="raku"
my @i = lazy [\+] flat 1, (
sub p ($n) { sum @P[$n X- @i
put @P[^26];
put @P[6666];</
{{out}}
<pre>1 1 2 3 5 7 11 15 22 30 42 56 77 101 135 176 231 297 385 490 627 792 1002 1255 1575 1958
Line 1,495 ⟶ 1,522:
These three REXX versions are recursive.
=== version 1 ===
<
numeric digits 1000 /*able to handle some ginormous numbers*/
parse arg lo hi . /*obtain optional arguments from the CL*/
Line 1,525 ⟶ 1,552:
else #= # - (x + y) /*Even? " subtract " " " */
end /*k*/
@.n= #; return # /*define and return partitionsP of N. */</
{{out|output|text= when using the input of: <tt> 6666 </tt>}}
<pre>
Line 1,539 ⟶ 1,566:
The biggest part of the improvement was using the expression '''k+k+k''' instead of '''k*3'''.
<
numeric digits 1000 /*able to handle some ginormous numbers*/
parse arg lo hi . /*obtain optional arguments from the CL*/
Line 1,570 ⟶ 1,597:
else #= # - (x + y) /*Even? " subtract " " " */
end /*k*/
@.n= #; return # /*define and return partitionsP of N. */</
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}}
Line 1,577 ⟶ 1,604:
The biggest part of the improvement was using memoization of the expressions ('''k+k+k - 1) * k % 2''' for all values of (positive) '''k''' up to '''hi'''.
<
numeric digits 1000 /*able to handle some ginormous numbers*/
parse arg lo hi . /*obtain optional arguments from the CL*/
Line 1,610 ⟶ 1,637:
else #= # - (x + y) /*Even? " subtract " " " */
end /*k*/
@.n= #; return # /*define and return partitionsP of N. */</
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}} <br><br>
=={{header|Rust}}==
<
// rug = "1.11"
Line 1,659 ⟶ 1,686:
println!("P({}) = {}", n, result);
println!("elapsed time: {} microseconds", time.as_micros());
}</
{{out}}
Line 1,670 ⟶ 1,697:
Built-in:
<
User-defined:
<
func (n) is cached {
Line 1,695 ⟶ 1,722:
say partitionsP(6666)
say ("Took %.4f seconds" % Time.micro-t)</
{{out}}
Line 1,711 ⟶ 1,738:
Using AttaSwift's BigInt library.
<
func partitions(n: Int) -> BigInt {
Line 1,754 ⟶ 1,781:
}
print("partitions(6666) = \(partitions(n: 6666))")</
{{out}}
Line 1,764 ⟶ 1,791:
{{libheader|Wren-big}}
Although it may not look like it, this is actually a decent time for Wren which is interpreted and the above module is written entirely in Wren itself.
<
var p = []
Line 1,799 ⟶ 1,826:
for (n in 2..N) partitionsP.call(n)
System.print("p[%(N)] = %(p[N])")
System.print("Took %(System.clock - start) seconds")</
{{out}}
|