How can I write this algorithm using iteration? - recursion

How can I write this algorithm using iteration?
function generate(num1:byval)
if num1 > 10 then
return 10
else
return num1 + (generate(num1 + 1) DIV 2)
endif
endfunction

So it's not straight forward so I start by doing some grunt work:
n result
11.. 10
10 10
9 9 + 10/2
8 8 + (9 + 10/2)/2
7 7 + (8 + (9 + 10/2)/2)/2
This looks like a pattern.. While the recursive version started on the input and went upwards it's easy to see that by starting at 10 and going downwards one can simply update the accumulator by halving the value and adding the current value.
This can easily be implemented using a helper:
procedure generate(num : integer) : integer
begin
generate := generateHelper(10, num, 0)
end
procedure generateHelper(cur : integer, num: integer, acc : integer) : integer
begin
if cur = num then
generateHelper := cur + acc/2;
else
generateHelper := generateHelper(cur - 1, num, acc/2 + cur);
end
Or by using a loop:
procedure generate(num : integer) : integer
var cur, acc : integer;
begin
for cur := 10 downto cur do
acc := acc / 2 + cur;
generate := acc;
end

If you work out some values for the function…
f(10) = 10
f(9) = 9+f(10)/2 = 9+10/2 = 14
f(8) = 8+f(9)/2 = 8+14/2 = 15
…
You will get a sense that you could repeatedly apply the same formula to a value in a loop. You see if you start from 10, you divide by 2 and add 9, then divide by 2 and add 8, and keep going until you reach the number given to the function. That would look something like this, e.g. in JavaScript:
function generate(n) {
let x = 10;
for(let i = 10; i > n; i--) {
x = i - 1 + x / 2;
}
return x;
}

Related

How to create Pascal?

I am very difficult to display all the output results.
this code.
DEF VAR INPUTAN AS INTEGER.
DEF VAR i AS INTEGER.
DEF VAR j AS INTEGER.
DEF VAR a AS INTEGER.
DEF VAR rows AS INT.
DEF VAR pascal AS CHAR FORMAT "x(25)".
SET INPUTAN.
a = 1.
REPEAT i = 0 TO INPUTAN:
rows = i.
DISPLAY rows.
REPEAT j = 0 TO i :
IF j = 0 OR j = i THEN DO:
a = 1.
END.
ELSE
a = a * (i + 1 - j) / j.
pascal = STRING(a).
display a.
END.
END.
DEF VAR INPUTAN AS INTEGER.
DEF VAR i AS INTEGER.
DEF VAR j AS INTEGER.
DEF VAR a AS INTEGER.
DEF VAR rows AS INT.
DEF VAR pascal AS CHAR.
SET INPUTAN.
a = 1.
REPEAT i = 0 TO INPUTAN:
rows = i.
/*DISPLAY rows. */
REPEAT j = 0 TO i :
IF j = 0 OR j = i THEN DO:
a = 1.
END.
ELSE
a = a * (i + 1 - j) / j.
IF j = 0 THEN
pascal = pascal + FILL(" ", INPUTAN - i).
pascal = pascal + STRING(a) + " ".
IF j = i THEN
pascal = pascal + CHR(13).
/* display a.*/
END.
END.
MESSAGE pascal
VIEW-AS ALERT-BOX INFO BUTTONS OK.

Generating list of integers with given number of bit set and sum of bit indices

I would like to generate in an efficient way a list of integers (preferably ordered)
with the following defining properties:
All integers have the same number of bit set N.
All integers have the same sum of bit indices K.
To be definite, for an integer I
its binary representation is:
$I=\sum_{j=0}^M c_j 2^j$ where $c_j=0$ or $1$
The number of bit sets is:
$N(I)=\sum_{j=0}^M c_j$
The sum of bit indices is:
$K(I)=\sum_{j=0}^M j c_j$
I have an inefficient way to generate the list as follows:
make a do/for loop over integers incrementing by use
of a "snoob" function - smallest next integer with same number of bit set
and at each increment checking if it has the correct value of K
this is grossly inefficient because in general starting from an integer
with the correct N and K value the snoob integer from I does not have the correct K and one has to make many snoob calculations to get the next integer
with both N and K equal to the chosen values.
Using snoob gives an ordered list which is handy for dichotomic search but
not absolutely compulsory.
Counting the number of elements in this list is easily done by recursion
when viewed as a partition numner counting. here is a recursive function in fortran 90 doing that job:
=======================================================================
recursive function BoundedPartitionNumberQ(N, M, D) result (res)
implicit none
! number of partitions of N into M distinct integers, bounded by D
! appropriate for Fermi counting rules
integer(8) :: N, M, D, Nmin
integer(8) :: res
Nmin = M*(M+1)/2 ! the Fermi sea
if(N < Nmin) then
res = 0
else if((N == Nmin) .and. (D >= M)) then
res = 1
else if(D < M) then
res = 0
else if(D == M) then
if(N == Nmin) then
res = 1
else
res = 0
endif
else if(M == 0) then
res = 0
else
res = BoundedPartitionNumberQ(N-M,M-1,D-1)+BoundedPartitionNumberQ(N-M,M,D-1)
endif
end function BoundedPartitionNumberQ
========================================================================================
My present solution is inefficient when I want to generate lists with several $10^7$
elements. Ultimately I want to stay within the realm of C/C++/Fortran and reach lists of lengths
up to a few $10^9$
my present f90 code is the following:
program test
implicit none
integer(8) :: Nparticles
integer(8) :: Nmax, TmpL, CheckL, Nphi
integer(8) :: i, k, counter
integer(8) :: NextOne
Nphi = 31 ! word size is Nphi+1
Nparticles = 16 ! number of bit set
print*,Nparticles,Nphi
Nmax = ishft(1_8, Nphi + 1) - ishft(1_8, Nphi + 1 - Nparticles)
i = ishft(1, Nparticles) - 1
counter = 0
! integer CheckL is the sum of bit indices
CheckL = Nparticles*Nphi/2 ! the value of the sum giving the largest list
do while(i .le. Nmax) ! we increment the integer
TmpL = 0
do k=0,Nphi
if (btest(i,k)) TmpL = TmpL + k
end do
if (TmpL == CheckL) then ! we check whether the sum of bit indices is OK
counter = counter + 1
end if
i = NextOne(i) ! a version of "snoob" described below
end do
print*,counter
end program
!==========================================================================
function NextOne (state)
implicit none
integer(8) :: bit
integer(8) :: counter
integer(8) :: NextOne,state,pstate
bit = 1
counter = -1
! find first one bit
do while (iand(bit,state) == 0)
bit = ishft(bit,1)
end do
! find next zero bit
do while (iand(bit,state) /= 0)
counter = counter + 1
bit = ishft(bit,1)
end do
if (bit == 0) then
print*,'overflow in NextOne'
NextOne = not(0)
else
state = iand(state,not(bit-1)) ! clear lower bits i &= (~(bit-1));
pstate = ishft(1_8,counter)-1 ! needed by IBM/Zahir compiler
! state = ior(state,ior(bit,ishft(1,counter)-1)) ! short version OK with gcc
state = ior(state,ior(bit,pstate))
NextOne = state
end if
end function NextOne
Since you mentioned C/C++/Fortran, I've tried to keep this relatively language agnostic/easily transferable but have also included faster builtins alternatives where applicable.
All integers have the same number of bit set N
Then we can also say, all valid integers will be permutations of N set bits.
First, we must generate the initial/min permutation:
uint32_t firstPermutation(uint32_t n){
// Fill the first n bits (on the right)
return (1 << n) -1;
}
Next, we must set the final/max permutation - indicating the 'stop point':
uint32_t lastPermutation(uint32_t n){
// Fill the last n bits (on the left)
return (0xFFFFFFFF >> n) ^ 0xFFFFFFFF;
}
Finally, we need a way to get the next permutation.
uint32_t nextPermutation(uint32_t n){
uint32_t t = (n | (n - 1)) + 1;
return t | ((((t & -t) / (n & -n)) >> 1) - 1);
}
// or with builtins:
uint32_t nextPermutation(uint32_t &p){
uint32_t t = (p | (p - 1));
return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(p) + 1));
}
All integers have the same sum of bit indices K
Assuming these are integers (32bit), you can use this DeBruijn sequence to quickly identify the index of the first set bit - fsb.
Similar sequences exist for other types/bitcounts, for example this one could be adapted for use.
By stripping the current fsb, we can apply the aforementioned technique to identify index of the next fsb, and so on.
int sumIndices(uint32_t n){
const int MultiplyDeBruijnBitPosition[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
int sum = 0;
// Get fsb idx
do sum += MultiplyDeBruijnBitPosition[((uint32_t)((n & -n) * 0x077CB531U)) >> 27];
// strip fsb
while (n &= n-1);
return sum;
}
// or with builtin
int sumIndices(uint32_t n){
int sum = 0;
do sum += __builtin_ctz(n);
while (n &= n-1);
return sum;
}
Finally, we can iterate over each permutation, checking if the sum of all indices matches the specified K value.
p = firstPermutation(n);
lp = lastPermutation(n);
do {
p = nextPermutation(p);
if (sumIndices(p) == k){
std::cout << "p:" << p << std::endl;
}
} while(p != lp);
You could easily change the 'handler' code to do something similar starting at a given integer - using it's N & K values.
A basic recursive implementation could be:
void listIntegersWithWeight(int currentBitCount, int currentWeight, uint32_t pattern, int index, int n, int k, std::vector<uint32_t> &res)
{
if (currentBitCount > n ||
currentWeight > k)
return;
if (index < 0)
{
if (currentBitCount == n && currentWeight == k)
res.push_back(pattern);
}
else
{
listIntegersWithWeight(currentBitCount, currentWeight, pattern, index - 1, n, k, res);
listIntegersWithWeight(currentBitCount + 1, currentWeight + index, pattern | (1u << index), index - 1, n, k, res);
}
}
That is not my suggestion, just the starting point. On my PC, for n = 16, k = 248, both this version and the iterative version take almost (but not quite) 9 seconds. Almost exactly the same amount of time, but that's just a coincidence. More pruning can be done:
currentBitCount + index + 1 < n if the number of set bits cannot reach n with the number of unfilled positions that are left, continuing is pointless.
currentWeight + (index * (index + 1) / 2) < k if the sum of positions cannot reach k, continuing is pointless.
Together:
void listIntegersWithWeight(int currentBitCount, int currentWeight, uint32_t pattern, int index, int n, int k, std::vector<uint32_t> &res)
{
if (currentBitCount > n ||
currentWeight > k ||
currentBitCount + index + 1 < n ||
currentWeight + (index * (index + 1) / 2) < k)
return;
if (index < 0)
{
if (currentBitCount == n && currentWeight == k)
res.push_back(pattern);
}
else
{
listIntegersWithWeight(currentBitCount, currentWeight, pattern, index - 1, n, k, res);
listIntegersWithWeight(currentBitCount + 1, currentWeight + index, pattern | (1u << index), index - 1, n, k, res);
}
}
On my PC with the same parameters, this only takes half a second. It can probably be improved further.

Writing a factorial() function without distinction between 0 and other numbers

This question has been bugging me for quite a while: is it possible to write a factorial function (in any programming language) without any if statement (or similar) which returns 1 when called with 0 as argument too?
Many factorial functions are something like this (Python):
def factorial(n):
for x in range(1, n):
n *= x
return n if n > 0 else 1
But I don't know if it can be done without distinction between varied values of n... What do you think? It is not a matter of speed and optimizing, just my curiosity.
0! is defined as 1.
Here are the results from my code.
0 factorial = 1
1 factorial = 1
2 factorial = 2
3 factorial = 6
10 factorial = 3628800
And here's Java code with no if statement,
package com.ggl.testing;
public class Factorial {
public static void main(String[] args) {
int n = 0;
System.out.println(n + " factorial = " + factorial(n));
n = 1;
System.out.println(n + " factorial = " + factorial(n));
n = 2;
System.out.println(n + " factorial = " + factorial(n));
n = 3;
System.out.println(n + " factorial = " + factorial(n));
n = 10;
System.out.println(n + " factorial = " + factorial(n));
}
public static long factorial(int n) {
long product = 1L;
for (int i = 2; i <= n; i++) {
product *= (long) i;
}
return product;
}
}
Here's a Haskell version:
factorial n = product [1 .. n]
Not sure if that's considered cheating, though.
There are many ways to calculate the factorial of a number with code.
The original question shows how to do it by recursion, one answer shows how to use a for loop. The same could be achieved by a while loop.
Another answer shows the product function of an array in Haskell (similar to prod(1:n) in Matlab).
Another way to calculate factorial of n (including n=0) in Javascript whithout using a loop is:
function factorial(n){
return (new Array(n)).join().split(",").map((x,i) => i+1).reduce((x,y) => x*y)
}
def factor(n):
fact=1
for i in range (1,n+1):
fact= fact*1
return fact
try:
x=int(input('Input a number to find the factiorial: '))
print(factor(x))
except:
print('Number should be an integer')
x=int(input('Input a number to find the factiorial: '))
print(factor(x))
Hope this helps you!

SML: How can I simulate a counter in SML without having an additional argument

I have a recursive function in SML that does a certain computation that doesn't really matter for my question. What I want to do is I want to track the number of times the recursion has taken place, as in I want to count the iterations of my algorithm. I know if for example I declared:
val counter = 0;
val counter = counter + 1;
The other counter is a different variable. It is not the same one incremented by one. So this type of incrementing will lose its scope in one recursive call.
Is there any way I can keep track?
You can use an int ref as a mutable cell:
val counter : int ref = ref 0
-- Some dummy recursive function for testing
fun factorial n =
if n < 1
then 1
else (counter := !counter + 1; n * factorial (n - 1))
You can use it like this:
- !counter;
val it = 0 : int
- factorial 10;
val it = 3628800 : int
- !counter;
val it = 10 : int
- factorial 5;
val it = 120 : int
- !counter;
val it = 15 : int

Recursive permutation

So I'm trying to permute all possible n digit long numbers out of x long array/set of elements. I've come up with a code that does that, however the digits are the same, how do I prevent that from happening. Here's my come(Pascal):
program Noname10;
var stop : boolean;
A : array[1..100] of integer;
function check( n : integer ) : boolean;
begin
if n = 343 // sets the limit when to stop.
then check := true
else check := false;
end;
procedure permute(p,result : integer);
var i : integer;
begin
if not stop
then if p = 0 then
begin
WriteLn(result);
if check(result)
then stop := true
end
else for i := 1 to 9 do
begin
permute(p - 1, 10*result+i);
end;
end;
begin
stop := false;
permute(3,0);
readln;
end.
Here is the code in Prolog
permutate(As,[B|Cs]) :- select(B, As, Bs), permutate(Bs, Cs).
select(A, [A|As], As).
select(A, [B|Bs], [B|Cs]) :- select(A, Bs, Cs).
?- permutate([a,b,c], P).
Pascal is much harder.
Here is an usefull algorithm, you might want to use. But it is not tested, so you have to debug it yourself. So you have to know how the algorithm works.
The Bell Permutation algorithm: http://programminggeeks.com/bell-algorithm-for-permutation/
procedure permutate(var numbers: array [1..100] of integer; size: integer;
var pos, dir: integer)
begin
if pos >= size then
begin
dir = -1 * dir;
swap(numbers, 1, 2);
end
else if pos < 1 then
begin
dir = -1 * dir;
swap(numbers, size-1, size);
end
else
begin
swap(numbers, pos, pos+1);
end;
pos = pos + dir;
end;
begin
var a, b: integer;
a = 1; b = 1;
while true do
begin
permutate(A, 5, a, b);
printArray(A, 5);
end;
end.

Resources