Prime Factorization Using Recursion - c++

My program currently outputs the prime factorization of a positive integer in ascending order. I'm trying to figure out how to set up the function so that it outputs the numbers in descending order.
For example, showFactors(100) currently outputs "2 2 5 5".
Instead I want it to output "5 5 2 2".
10 // Void function "showFactors" that takes in an int "number" and another int "factor", which is initialized to 2
11 void showFactors(int number, int factor = 2)
12 {
13
14 if (number<2) //returns nothing if number<2
15 {
16 return;
17 }
18 if (number%factor==0) //modulus function is used to get prime factorization
19 {
20 cout<<factor<<" ";
21 showFactors(number/factor, factor); //recursive call
22 }
23 else //if (number%factor != 0) //this modulus function is used in order to output factor !=2
24 {
25 showFactors(number, factor+1);
26 }
27 }
I feel like there should be an easy fix by simply rearranging where the cout call goes, but I haven't had any luck so far.
Edit: Yeah it was as simple as switching lines 20 and 21.

#include <iostream>
using namespace std;
void sf (int number,int factor=2)
{
if (number<2)
return;
if (number%factor == 0)
{
sf (number/factor,factor);
cout<<factor<<"\t";
}
else
sf (number,factor+1);
}
int main ()
{
sf (1729);
cout<<"\n";
return 0;
}

Here is my Ruby solution to get a list of prime factors of a given number. Maybe it will help someone
def prime_factorization(num)
(2...num).each do |fact|
if (num % fact == 0)
otherFact = num / fact
return [ *prime_factorization(fact), *prime_factorization(otherFact) ]
end
end
return [num]
end

Related

Knapsack problem with multiple availabe packages using dynamic programming

Hello and thanks for helping!
So we've got a list of fireworks containing 1) Number in stock 2) Number of fireworks in this package 3) Diameter which equals the noise and
4) The price.
This is the list:
25 17 10 21
10 15 10 18
5 16 10 19
10 15 12 20
15 9 11 12
10 7 28 23
8 7 16 11
10 6 16 10
25 10 18 25
25 12 18 27
10 5 40 35
60 40 5 27
5 25 30 90
50 1 60 8
Our task is to create a shopping list and buy fireworks so we get the highest possible noise. We've got a knapsack capacity of 1000€. We're also supposed to solve this without using tables (so with dynamic programming instead).
I only use one class called Package which contains the four constraints as shown above.
At first I thought it would make sense to try to write an algorithm for a normal knapsack, so just with the price and the diameter (=weight). I tested it with a different list and it worked perfectly fine. I just iterated through all packages and then again used a nested for loop to find the best constellation (exhaustive search). My next idea was to merge the number of fireworks per package with the diameter, because fireworks can only be bought in a full package.
The only thing left which I still haven't found out is what to do with the amount of packages in stock. Like, with my current algorithm it just buys all packages of a firework until the knapsack is full. But obviously that won't be correct.
void knapsack(vector<Package*> stock){
vector<int> indices, tmp_indices;
int noise,tmp_noise= 0;
int price;
for (unsigned int i = 0; i < stock.size(); i++) {
price = stock[i]->price;
noise = stock[i]->diameter*stock[i]->number_fireworks;
indices.push_back(i);
for (unsigned int j = 0; j < stock.size(); j++) {
if (i != j) {
if (price+stock[j]->price<= BUDGET) {
price+=stock[j]->price;
noise+=stock[j]->diameter*stock[j]->number_fireworks;
indices.push_back(j);
}
}
}
// After second loop we have a new possible constellation
// Check if the previous constellation had a lower value and if so, set it to the current one
if (noise > tmp_noise) {
tmp_noise = noise;
tmp_indices.clear();
// tmp save
for (auto &index : indices) {
tmp_indices.push_back(index);
}
}
price= 0;
noise = 0;
indices.clear();
}
// Best constellation found, Print the shopping list
cout << "\Stock.\tNum\Diameter.\Price\n" << endl;
for(unsigned int i = 0; i < tmp_indices.size(); i++) {
cout << stock[tmp_indices[i]]->stock<< "\t";
cout << stock[tmp_indices[i]]->number_fireworks<< "\t";
cout << stock[tmp_indices[i]]->diameter<< "\t";
cout << stock[tmp_indices[i]]->price<< "\t\n";
}
}
We've been told that we should be able to spend exactly 1000€ to get the correct constellation of fireworks. My idea was to add another for loop to iterate through the amount of available packages, but that didn't really work...
This was our first lesson and I'm a bit desperate, because we have only learned how to solve a knapsack problem with 2 constraints and by using a table R.
Edit: Since one user insisted to get a specific question, here it is: Is the idea of using another loop to include the third constraint correct or is there a better/easier way of doing it? Or is it possible that I need a completely different approach for a knapsack with 3 instead of 2 constraints?
Thanks for help in advance

Project Euler # 5; this solution works - but why?

The project Euler problem 5 is stated as : "2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?"
Here's the c++ code for the function I'm using.
long long unsigned int rangeLCM(int n)
{
long long unsigned int ans=1;
for(int i=1;i<=n;i++)
{
if(ans%i!=0)
{
if(i%(ans%i)==0)ans*=(i/(ans%i));
else ans*=i;
}
}
return ans;
}
The code works well for the example stated in the problem and the problem itself{rangeLCM(10)=2520 and rangeLCM(20)=232792560}, but I think it's not perfect and is missing out on some edge cases.
Instead of actually calculating the LCM(ans,i), I have checked that the bigger of the two(always ans) is divisible by i. If not, then ans is multiplied by a number equal to i/(ans%i) or i depending on whether i is divisible by (ans%i) or not.
This is based on the following facts:
LCM(8,12)=24=12*(8/(12%8));
LCM(9,30)=90=30*(9/(30%9)
LCM(7,13)=91=13*7
However, it fails for the following types of cases:LCM(8,14)=56 != 8*14
Yet, the code for rangeLCM gives the right output for all inputs I have tried yet. Why?
Your logic does not work
if(i%(ans%i)==0)ans*=(i/(ans%i));
else ans*=i;
For example, if ans = 10 and i = 14, so, the lcm should be 70, but in your code, it is 140.
The reason is, between ans and i , there are common divisors, but your code cannot detect that.
For experiment, I have written a small piece of code to check using Java.
class Solution {
public static void main(String[] args) {
long ans = 1;
for (long i = 1; i <= 40; i++) {
if (ans % i != 0) {
long before = (ans*i/gcd(ans,i));
if (i % (ans % i) == 0){
ans *= (i / (ans % i));
}else{
ans *= i;
}
System.out.println(ans + " " + before + " " + i);
}
}
}
public static long gcd(long a, long b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
}
Output
2 2 2
6 6 3
12 12 4
60 60 5
420 420 7
840 840 8
2520 2520 9
27720 27720 11
360360 360360 13
720720 720720 16
12252240 12252240 17
232792560 232792560 19
5354228880 5354228880 23
26771144400 26771144400 25
722820898800 80313433200 27
20961806065200 20961806065200 29
649815988021200 649815988021200 31
1299631976042400 1299631976042400 32
48086383113568800 48086383113568800 37
When i = 27, there is different between the correct answer and ans
The formula for lcm(a,b) is
lcm(a,b) = a*b/gcd(a,b)
With gcd is Greatest common divisor between two number a and b
I think you are missing a lot of cases you have to implement the Euclidean algorithm at
if(i%(ans%i)==0)ans*=(i/(ans%i));

A program that takes in a matrix and outputs the fastest path to the "exit" and the number it takes to get there

So I'm having a lot of trouble understanding c++ again I've taken my programming class twice and failed. I need help. I'm not interested in programming anymore because it's obviously not for me. I just need to pass. Here's the problem:
The goal of this assignment is to practice recursive algorithms by writing a program that takes in a matrix representing the number of guards in each room of the castle and outputs the fastest path to the princess and the number of guards you will have to fight.
You're moving through a map(array) that looks like:
5 5
6 2 3 44 15
1 7 2 9 10
11 1 5 14 12
5 17 2 1 20
21 7 33 4 25
Where the first to numbers are the size of your array and you can only move right and down.
So an output would be:
50 > > v v v > v >
We're given a skeleton which we have to fill in but I don't know what some of it does and it might be too long to copy and paste here, I'm new to the community.
How would you tackle this assignment
Using recursion you try to simplify the problem. So take a step right, compute the score for this step and add it to the rest of the solution by calling the same function on a smaller matrix (leaving out the left column). Then take a step down and do the same with the smaller matrix leaving out the top row. Then choose the solution with the lowest score.
This is just a dynamic programming problem.
I don't know how to pass a 2-d array as a function parameter.
Someone correct me please(How to pass 'matrix' array and 'result' array as function parameters). Rest all part is fine
Algorithm is simple. Just start from the last position and come backwards.
where result[i][j] = min(result[i+1][j],result[i][j+1])
void function(int a,int b,int** matrix,int** result){
if(result[a+1][b] == -1 && result[a][b+1] == -1){
result[a][b] = min(function(a+1,b,matrix,result),function(a,b+1,matrix,result));
}
else if(result[a+1][b] == -1 && result[a][b+1] != -1){
result[a][b] = min(function(a+1,b,matrix,result),result[a][b+1]);
}
else if(result[a+1][b] != -1 && result[a][b+1] == -1){
result[a][b] = min(result[a+1][b],function(a,b+1,matrix,result));
}
return;
}
int main(){
int p,q;
cin>>p>>q;
int matrix[p][q];
for(int i=0;i<p;i++){
for(int j=0;j<q;j++){
cin>>matrix[i][j];
}
}
int result[p][q];
for(int i=0;i<p;i++){
for(int j=0;j<q;j++){
result[i][j] = -1;
}
}
result[p-1][q-1] = matrix[p-1][q-1];
for(int i=q-2;i>=0;i++){
result[p-1][i] = matrix[p-1][i] + result[p-1][i+1];
}
for(int i=p-2;i>=0;i++){
result[i][q-1] = matrix[i][q-1] + result[i+1][q-1];
}
function(0,0,matrix,result);
cout<<results[0][0]<<endl;
}

find all palindromes inside a string

I am stuck and cant seem to figure out where I should go from here.
I would appreciate any hints or tips on how I should approach this problem. Been trying to figure this out for over 9 hrs no luck.
The question is as follows:
A string s is said to be palindromic if it reads the same backwards and forwards. A decomposition of s is a set of non-overlapping sub-strings of s whose concatenation is s.
Write a C++ program that takes as input a string and computes all its palin-
dromic decompositions. For example.if s is the string 0204451881 then the
decomposition 020, 44 5 1881 is a palindromic decomposition. So is
0 2 0 4 4 5 1 8 8 1
0 2 0 4 4 5 1 88 1
0 2 0 4 4 5 1881
0 2 0 44 5 1 8 8 1
0 2 0 44 5 1 88 1
020 4 4 5 1 8 8 1
020 4 4 5 1 88 1
020 4 4 5 1881
020 44 5 1 8 8 1
020 44 5 1 88 1
020 44 5 1881
this is a class project.
so far I have:
#include <iostream>
#include <string>
using namespace std;
void palDecom(string str1);
bool isPal(const string &str);
void subPal(string str1);
int main()
{
string s = "0204451881";
palDecom(s);
subPal(s);
return 0;
}
//shows the decomposition as the single char of the string
//takes a string as input
void palDecom(string str1)
{
int stringLastIndex = (str1.length());
for (int i = 0; i < stringLastIndex; i++)
{
cout<< str1[i] <<" ";
}
cout<<endl;
}
void subPal(string str1)
{
int stringLastIndex = (str1.length());
for (int curIndx = 0; curIndx < stringLastIndex; curIndx++)
{
for(int comparIndx = 1; comparIndx < stringLastIndex; comparIndx++)
{
//cout<< "i was in this loop"<<endl;
if (isPalindrome((str1,curIndx,comparIndx)))
//cout<<str1.substr(0,curIndx-1)<<" "<< str1.substr(curIndx,comparIndx) <<" "<< str1.substr(comparIndx,stringLastIndex)<<endl;
}
}
}
bool isPal(const string &str)
{
int start=0, end=str.length()-1;
while (start < end) {
if (str[start++] != str[end--])
return false;
}
return true;
}
Actually, I just managed to realize this:
Palindromes decompose to combination splits.
What this means is that each palindrome will "split" into additional sub-palindromes based on how many "layers" of palindrome it possesses.
For example: The sequence
12213443
-> 1221 + 3443
-> 1 + 22 + 1 + 3 + 44 + 3
-> 1 + 2 + 2 + 1 + 3 + 44 + 3
As you parse down the string, the possibilities will just increase by the amount of palindromes a larger one can decompose to until you have palindromes of 1 character width.
Granted, I realize that palindromes can overlap:
1221221
-> 1221 + 22 + 1
OR -> 1 + 22 + 1221
This is an additional quandary, but is definitely solvable.
Additionally, you can choose to think about smaller palindromes coming together to create larger ones.
Personally, I think this line of thought will lead to a better algorithm and method of solving from the above, as composing new palindromes while iterating in one direction is probably easier than decomposing them in just one direction.
I think the best course is to start playing with palindromes and map out the possible decompositions. By analysing this, you should be able to find a repetitive pattern that can then be mapped to a recursive solution.
Regardless, this answer definitely can use recursion. There is a clear pattern here; you just need to explore it more and find it.
I wish I had a more definitive answer but I myself am struggling with the problem. I hope someone else can edit this and pick up the threads?
Use recursion to solve this problem by scanning the string from left to right.
Keep a stack of the previous palindrome partitions that have already been found "to the left" of the "current position" in the overall string. This stack could be an array or std::vector of pointers to the ends (i.e. - one past the last character) of each previously found palindrome. In this case, the "current position" is indicated by the top element of the stack, or the beginning of the string if the stack is empty.
The base/exit case of the recursion is when the current position refers to the end of the entire string. In that case you've already exhausted the string. Print out the palindromes as indicated by the palindrome stack (starting from the bottom) and then return. (Hint: Don't alter the original string to insert nul terminators to print each palindrome as a string. Instead, just print each palindrome character-by-character according to the partitions on the stack, print spaces between the palindromes and a newline at the end of the stack.)
Otherwise, have a loop that goes from 1 up through the number of characters remaining in the string starting from the current position. At each iteration, test if the current position is a palindrome of length equal to your loop index. If it is such a palindrome, then push a partition for that palindrome onto the stack and recurse down to one level deeper.
That should do it.
I wouldn't use a std::stack to implement the stack. Instead use a std::vector or an array. If you use std::vector, then don't do structural operations (e.g. - push_back, pop_back, etc.) on it in the recursion. Instead, just resize() it to hold up to strlen(str) partition elements before you begin recursing because the deepest stack will be when each character of the string is a palindrome. Then in your recursion, you simply pass the logical, current size of the stack. This tells you the index where the next palindrome partition should be placed (i.e. - at index size) and allows you to access any previously existing top element of the stack (i.e. - at index size - 1). This approach will work for an array or a std::vector.
If you do want to use std::vector::push_back() (or std::stack), then you just need to remember to std::vector::pop_back() after you return from each recursion. This approach would allow you to not need to pass the "logical" size of the stack explicitly around as the vector itself would know its correct size.
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <iomanip>
using std:: cin;
using std:: cout;
using std:: endl;
using std:: setw;
const int MAX_LEN = 100;
int palDecom(const char str[]);
bool isPal(const char str[], int start, int end);
int main()
{
char str[MAX_LEN];
cin >> setw(MAX_LEN) >> str;
cout << palDecom(str) ;
return EXIT_SUCCESS;
}
int palDecom(const char str[])
{
int counter=0;
for (int i = 1; i < strlen(str) ; i++)
for(int lastindex = strlen(str)-1; lastindex < strlen(str) ; lastindex--)
{
if(isPal(str, i , lastindex-1))
counter ++;
}
return counter;
}
bool isPal(const char str[], int start, int end)
{
if(start == strlen(str))
return 1;
if (str[start] == str[end]){
isPal(str, str[start], str[end-1]);
return true;
}
return false;
}

Number guessing game with illogical bug

#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace std;
srand(time(NULL));
int main(){
int botguess;
int playerinput;
int mi=1, ma=100;
int turns = 0;
cout<<" what do you want guessed:";
cin>> playerinput;
cout<< "time for me to start guessing\n";
for(int i = 0;i < 50;i++) {
botguess = rand() % ma + mi;
if(playerinput > botguess){ //<--the problem
mi = botguess;
}
if(playerinput < botguess) {
ma = botguess;
}
cout<<"Max:"<<ma<<"\n"<<botguess<<"\n";
Sleep(1000);
if(botguess == playerinput)
{
cout<<"you win";
}
}
cin.get();
return 0;
}
So I've been tearing my hair out about why logically this doesn't work. This is a program that is supposed to guess the players number quickly but not instantly. The program doesn't perform like it looks.
The line that I noted causes a bug where the max number possible is being ignored. im getting number that are 100+ but under 200 and i don't know why. When I remove the lines concerning the mi variable nested in the statement in the for loop. The program doesn't go over 100 but I don't get the other end of the program solving the player number.
Also if you figure it out can you please explain it to me I don't just want a answer.
botguess = rand() % (ma - mi + 1) + mi
You don't want ma different numbers, you want much less of them. Look at an example: (5..10) contains 6 different numbers: [5, 6, 7, 8, 9, 10]; but if you do rand() % 10 + 5, you're getting numbers from 5 (5 + 0) to 14 (5 + 9). What you need is rand() % 6 + 5, where 6 is 10 - 5 + 1.
The problem you are having is caused by the fact that mi is set to botguess, which can easily be greater than zero, then on the next cycle if ma is still 100 (or anywhere near it), you're going to sometimes get numbers greater than 100 set into botguess.
Edit added: the % operator in C++ is mod division (ie. gives the remainder of integer division) So for example, 98 % 100 + 15 will be 98 + 15, i.e. 113
This link may help you:
http://www.cplusplus.com/reference/cstdlib/rand/