Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
117
Task/Almost-prime/Phix/almost-prime-1.phix
Normal file
117
Task/Almost-prime/Phix/almost-prime-1.phix
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
-- Naieve stuff, mostly, but coded with enthuiasm!
|
||||
-- Following the idea behind (but not the code from!) the J submission:
|
||||
-- Generate 10 primes (kept in p10) -- (print K=1)
|
||||
-- Multiply each of them by the first ten primes
|
||||
-- Sort and find unique values, take the first ten of those -- (print K=2)
|
||||
-- Multiply each of them by the first ten primes
|
||||
-- Sort and find unique values, take the first ten of those -- (print K=3)
|
||||
-- ...
|
||||
-- However I just keep a "top 10", using a bubble insertion, and stop
|
||||
-- multiplying as soon as everything else for p10[i] will be too big.
|
||||
|
||||
-- (as calculated earlier from this routine,
|
||||
-- or that "return 1" in pi() works just fine.)
|
||||
--constant f17={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59}
|
||||
constant f17={2,3,5,7,11,13,17}
|
||||
|
||||
function pi(integer n)
|
||||
-- approximates the number of primes less than or equal to n
|
||||
-- if n<=10 then return 4 end if
|
||||
-- -- best estimate
|
||||
-- return floor(n/(log(n)-1))
|
||||
-- if n<=20 then return 1 end if -- (or use a table:)
|
||||
if n<17 then
|
||||
for i=1 to length(f17) do
|
||||
if n<=f17[i] then return i end if
|
||||
end for
|
||||
end if
|
||||
-- -- upper bound for n>=17 (Rosser and Schoenfeld 1962):
|
||||
-- return floor(1.25506*n/log(n))
|
||||
-- lower bound for n>=17 (Rosser and Schoenfeld 1962):
|
||||
return floor(n/log(n))
|
||||
end function
|
||||
|
||||
function primes(integer n)
|
||||
-- return the first n prime numbers (tested 0 to 20,000, which took ~86s)
|
||||
sequence prime
|
||||
integer count = 0
|
||||
integer lowN, highN, midN
|
||||
|
||||
-- First, iteratively estimate the sieve size required
|
||||
lowN = 2*n
|
||||
highN = n*n+1
|
||||
while lowN<highN do
|
||||
midN = floor((lowN+highN)/2)
|
||||
if pi(midN)>n then
|
||||
highN = midN
|
||||
else
|
||||
lowN = midN+1
|
||||
end if
|
||||
end while
|
||||
-- Then apply standard sieve and store primes as we find
|
||||
-- them towards the (no longer used) start of the sieve.
|
||||
prime = repeat(1,highN)
|
||||
for i=2 to highN do
|
||||
if prime[i] then
|
||||
count += 1
|
||||
prime[count] = i
|
||||
if count>=n then exit end if
|
||||
for k=i+i to highN by i do
|
||||
prime[k] = 0
|
||||
end for
|
||||
end if
|
||||
end for
|
||||
return prime[1..n]
|
||||
end function
|
||||
|
||||
procedure display(integer k, sequence kprimes)
|
||||
printf(1,"%d: ",k)
|
||||
for i=1 to length(kprimes) do
|
||||
printf(1,"%5d",kprimes[i])
|
||||
end for
|
||||
puts(1,"\n")
|
||||
end procedure
|
||||
|
||||
function bubble(sequence next, integer v)
|
||||
-- insert v into next (discarding next[$]), keeping next in ascending order
|
||||
-- (relies on next[1] /always/ being smaller that anything that we insert.)
|
||||
for i=length(next)-1 to 1 by -1 do
|
||||
if v>next[i] then
|
||||
next[i+1] = v
|
||||
exit
|
||||
end if
|
||||
next[i+1] = next[i]
|
||||
end for
|
||||
return next
|
||||
end function
|
||||
|
||||
procedure almost_prime()
|
||||
sequence p10 = primes(10)
|
||||
sequence apk = p10 -- (almostprime[k])
|
||||
sequence next = repeat(0,length(p10))
|
||||
integer high, test
|
||||
for k=1 to 5 do
|
||||
display(k,apk)
|
||||
if k=5 then exit end if
|
||||
next = apk
|
||||
for i=1 to length(p10) do
|
||||
-- next[i] = apk[i]*p10[1]
|
||||
next[i] = apk[i]*2
|
||||
end for
|
||||
high = next[$]
|
||||
for i=2 to length(p10) do
|
||||
for j=1 to length(next) do
|
||||
test = apk[j]*p10[i]
|
||||
if not find(test,next) then
|
||||
if test>high then exit end if
|
||||
next = bubble(next,test)
|
||||
high = next[$]
|
||||
end if
|
||||
end for
|
||||
end for
|
||||
apk = next
|
||||
end for
|
||||
if getc(0) then end if
|
||||
end procedure
|
||||
|
||||
almost_prime()
|
||||
44
Task/Almost-prime/Phix/almost-prime-2.phix
Normal file
44
Task/Almost-prime/Phix/almost-prime-2.phix
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
function kprime(integer n, integer k)
|
||||
--
|
||||
-- returns true if n has exactly k factors
|
||||
--
|
||||
-- p is a "pseudo prime" in that 2,3,4,5,6,7,8,9,10,11 will behave
|
||||
-- exactly like 2,3,5,7,11, ie the remainder(n,4)=0 (etc) will never
|
||||
-- succeed because remainder(n,2) would have succeeded twice first.
|
||||
-- Hence for larger n consider replacing p+=1 with p=next_prime(),
|
||||
-- then again, on "" this performs an obscene number of divisions..
|
||||
--
|
||||
integer p = 2,
|
||||
factors = 0
|
||||
|
||||
while factors<k and p*p<=n do
|
||||
while remainder(n,p)=0 do
|
||||
n = n/p
|
||||
factors += 1
|
||||
end while
|
||||
p += 1
|
||||
end while
|
||||
factors += (n>1)
|
||||
return factors==k
|
||||
end function
|
||||
|
||||
procedure almost_primeC()
|
||||
integer nextkprime, count
|
||||
|
||||
for k=1 to 5 do
|
||||
printf(1,"k = %d: ", k);
|
||||
nextkprime = 2
|
||||
count = 0
|
||||
while count<10 do
|
||||
if kprime(nextkprime, k) then
|
||||
printf(1," %4d", nextkprime)
|
||||
count += 1
|
||||
end if
|
||||
nextkprime += 1
|
||||
end while
|
||||
puts(1,"\n")
|
||||
end for
|
||||
if getc(0) then end if
|
||||
end procedure
|
||||
|
||||
almost_primeC()
|
||||
Loading…
Add table
Add a link
Reference in a new issue