How do I convert recursion into memoization or bottom up? - recursion

int count(n){
if(n==1) return 1;
if(n%2==0)
return 1+count(n/2);
else
return Math.min(1+count(n+1),1+count(n-1));
}
can you please explain how do I convert this code into dynamic programming? and if this can not be converted into can you please explain why. Else, is there any way to reduce the complexity of the program.
Thank you.

I can offer the solution of your problem, using memoization and C++.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maximumSize=10;
void showContentVector1D(vector<int>& input)
{
for(int i=0; i<input.size(); ++i)
{
cout<<input[i]<<", ";
}
return;
}
int count(int n, vector<int>& input)
{
if(n==1)
{
input[n]=n;
return input[n];
}
if(n%2==0)
{
input[n]=1+count(n/2, input);
return input[n];
}
else
{
input[n]=min(1+count(n+1, input), 1+count(n-1, input));
return input[n];
}
return input[n];
}
void solve()
{
vector<int> memoization(maximumSize, -1);
cout<<"Before, memoization <- ";
showContentVector1D(memoization);
count(7, memoization);
cout<<endl<<"After, memoization <- ";
showContentVector1D(memoization);
cout<<endl;
return;
}
int main()
{
solve();
return 0;
}
If we will perform the command-function count(7, memoization); with the number 7 and with the parameter memoization, therefore, the next output will appear:
Output:
Before, memoization <- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
After, memoization <- -1, 1, 2, 3, 3, -1, 4, 5, 4, -1,

Related

Copy an array into another array

char arrA[ 6 ] = { 1, 2, 3, 4, 5, 0 };
char arrB[ 6 ] = {};
void setup(){
strcpy( arrB, arrA );
}
Hi all, I obtained the code above from here. My case is I need to use int arrA[6] instead of char arrA[6] when initializing variables so that it remains as values and not string. May I ask how do I actually accomplish it with arduino code. The link above only uses string as array and not numbers. Thank you for reading and have a nice day !!!
You can write a for loop to copy the contents of arrA to arrB.
int arrA[ 6 ] = { 1, 2, 3, 4, 5, 0 };
int arrB[ 6 ];
void setup(){
for(int i = 0; i < (sizeof(arrA)/sizeof(arrA[0])); i++)
{
arrB[i] = arrA[i];
}
}

OpenCL distance between strings

I have this C++ code from the web that computes for distance between two strings. Can someone help me convert this to OpenCL for parallelism? I'm having hard time learning OpenCL.
#include <stdio.h>
#include <math.h>
#include <string.h>
#define MIN(x,y) ((x) < (y) ? (x) : (y))
int main()
{
int d[100][100];
int i,j,m,n,temp,tracker;
char s[] = "Sanfoundry";
char t[] = "Education";
m = strlen(s);
n = strlen(t);
for(i=0;i<=m;i++)
d[0][i] = i;
for(j=0;j<=n;j++)
d[j][0] = j;
for (j=1;j<=m;j++)
{
for(i=1;i<=n;i++)
{
if(s[i-1] == t[j-1])
{
tracker = 0;
} else {
tracker = 1;
}
temp = MIN((d[i-1][j]+1),(d[i][j-1]+1));
d[i][j] = MIN(temp,(d[i-1][j-1]+tracker));
}
}
printf("the Levinstein distance is %d\n",d[n][m]);
return 0;
}
Specifically, what part of the code must be put in a kernel? Also, what memory objects needed to be created?
Thanks

Correct method of implementing a recursive function in C?

I am trying to implement a recursive function into a piece of code. I have tried multiple methods but I can't quite get it right. I was wondering if there was anything I might have overlooked or if I didn't do it correctly at all.
For reference, the question I am trying to answer is the Waterloo CCC 2013 J3
#include <stdio.h>
int year, counter = 0, tempNum;
int isDistinct (int num) {
tempNum = num;
int number[10] = { 0 };
while (tempNum > 0) {
if (number[tempNum % 10] == 1) {num++; isDistinct(num);}
else { number[tempNum % 10] = 1; tempNum /= 10; }
}
return num;
}
int main() {
scanf("%d", &year);
printf("%d", isDistinct(year+1));
}

Generate random numbers from 1 to 7 using a given random generator function

Create a function that generates numbers 1 to 7 with equal probability using a function that generates numbers 1 to 5 randomly with equal probability.
I modified one of the previous answers. Is it correct?
#include <bits/stdc++.h>
#define ran rand()%5
using namespace std;
int main(){
int a[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 0, 0, 0}};
int ct[8] = {0};
for(int i = 0; i<50000000; i++){
int j = ran;
while(j>1){
j = ran;
}
int k = ran;
if(a[j][k]>0)
ct[a[j][k]]++;
}
for(int i = 1; i<=7; i++){
cout<<ct[i]<<endl;
}
return 0;
}
I had the following output:
4997165
4998128
4997312
5002487
5000661
4998637
4999720
Please tell if there is anything wrong with it.
Here is a modern C++ solution:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <ostream>
#include <random>
template <unsigned int Min, unsigned int Max>
class imbued_urng
{
public:
using result_type = unsigned int;
static constexpr result_type min() { return Min; }
static constexpr result_type max() { return Max; }
imbued_urng(const std::function<result_type()>& source) : random{ source } {}
imbued_urng(const imbued_urng& rhs) = delete;
imbued_urng& operator=(const imbued_urng& rhs) = delete;
result_type operator()() { return random(); }
private:
const std::function<result_type()>& random;
};
int main()
{
// Create a random number engine
std::mt19937::result_type seed = std::random_device{}();
std::cout << "seed = " << seed << std::endl;
auto engine = std::mt19937{ seed };
// Create the rand5 distribution
auto const dist5{ std::uniform_int_distribution<> {1, 5} };
auto const rand5{ std::function<unsigned int()>{ [&engine, &dist5] { return dist5(engine); } } };
auto const n = 32;
std::generate_n(std::ostream_iterator<unsigned int>(std::cout, " "), n, rand5);
std::cout << std::endl;
// Create a uniform random number generator based on rand5
imbued_urng<1, 5> urng { rand5 };
// Create the rand7 distribution
auto const dist7{ std::uniform_int_distribution<> {1, 7} };
auto const rand7{ std::function<unsigned int()>{ [&urng, &dist7] { return dist7(urng); } } };
std::generate_n(std::ostream_iterator<unsigned int>(std::cout, " "), n, rand7);
std::cout << std::endl;
return 0;
}

C - IPC semaphores with fork

I'm having a problem with following program:
What it was supposed to do:
First child process should get a number from STDIN and set it to shared variable.
Second child process should read number from shared variable and print it binary on STDOUT.
What it does:
It never asks for a number, after running it, it just prints inifnite number of zero's. It looks like it jumps straight away into a second child and never leaves it.
Code:
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* jest zdefiniowane w sys/sem.h */
#else
union semun
{
int val;
struct semid_ds* buf;
unsigned short int* array;
struct seminfo* __buf;
};
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <fcntl.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/mman.h>
//shared
static int *glob_var;
struct sembuf operacja;
void operacjaSem(int, int, int);
int main(void)
{
/*---------------------------------------*/
//shared memory
glob_var = mmap(NULL, sizeof(*glob_var), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
/*---------------------------------------*/
//semafory
key_t klucz;
int semafor;
union semun ustaw;
//tworze jednoznaczny klucz dla semaforow
if((klucz = ftok(".", 'B')) == -1)
{
fprintf(stderr, "blad tworzenia klucza\\n");
exit(1);
}
//stworzenie semaforow
if((semafor = semget(klucz, 2, IPC_CREAT | IPC_EXCL | 0600)) == -1)
{
fprintf(stderr, "blad tworzenia semaforow\\n");
exit(1);
}
//inicjacja semaforow
ustaw.val = 1;
if(semctl(semafor, 0, SETVAL, ustaw) == -1)
{
fprintf(stderr, "blad ustawienia semafora0\\n");
exit(1);
}
ustaw.val = 0;
if(semctl(semafor, 1, SETVAL, ustaw) == -1)
{
fprintf(stderr, "blad ustawienia semafora1\\n");
exit(1);
}
if(fork() == 0)
{
//first child process
while(1)
{
if(semctl(semafor, 0, GETVAL) == 1)
{
//ustawiam zmienna wspoldzielona
char buf2[128];
fgets(buf2, 128, 0);
*glob_var = atoi(buf2);
//printf("buf: %d", *glob_var);
//przestawiam semafory
operacjaSem(semafor, 0, -1);
operacjaSem(semafor, 1, 1);
}
}
}
if(fork() == 0)
{
//second child process
while(1)
{
if(semctl(semafor, 1, GETVAL) == 1)
{
operacjaSem(semafor, 1, -1);
//odczytuje i wypisuje
int x = *glob_var;
int p[32];
for(int z = 0; z < 32; z++)
{
if(x % 2 == 1 || x % 2 == -1) p[z] = 1;
else p[z] = 0;
x = x >> 1;
}
for(int z = 31; z >= 0; z--)
printf("%d", p[z]);
printf("\n");
//przestawiam semafory
operacjaSem(semafor, 1, -1);
operacjaSem(semafor, 0, 1);
}
}
}
return 0;
}
void operacjaSem(int semafor, int nr, int op)
{
operacja.sem_num = nr;
operacja.sem_op = op;
operacja.sem_flg = 0;
if(semop(semafor, &operacja, 1) == -1)
{
fprintf(stderr, "blad operacji na semaforze\\n");
exit(1);
}
}
Change the first line that reads:
if(fork() == 0)
To something like
pid_t processID = fork();
if(processID == 0)
Change the second line that reads
if(fork() == 0)
To an else. More explicitly, for that second line, change:
}
if(fork() == 0)
{
//second child process
To:
}
else
{
if (processID < 0) {
printf ("Fork error\n"); exit(-1);
}
//second child process
And probably if the rest of your code is OK, it will start working. At least this will get your forks in good shape so you can keep working with the rest of the code.

Resources