Why this code works in 2 Keys Keyboard question in C++? - c++

I was solving this question which is pretty interesting in leetcode and I found a solution for this.Though this iterative approach works,I want to know the logical thinking behind this solution.
Question:
There is only one character 'A' on the screen of a notepad. You can perform two operations on this notepad for each step:
Copy All: You can copy all the characters present on the screen (a partial copy is not allowed).
Paste: You can paste the characters which are copied last time.
Given an integer n, return the minimum number of operations to get the character 'A' exactly n times on the screen.
Example testcases:
Input: n = 3
Output: 3
Explanation: Intitally, we have one character 'A'.
In step 1, we use Copy All operation.
In step 2, we use Paste operation to get 'AA'.
In step 3, we use Paste operation to get 'AAA'.
My code:
class Solution {
public:
int minSteps(int n) {
int res=0;
for(int i=2;i<=n;i++)
{
while(n%i==0)
{
res+=i;
n=n/i;
}
}
return res;
}
};
The code is pretty simple,Just need to understand the intuition behind it.
Thanks

Related

Recursion with C++

I am learning recursion in my current class and the idea is a little tricky for me. From my understanding, when we build a function it will run as many times until our "base case" is satisfied. What I am wondering is how this looks and is returned on the stack. For an example I wrote the following function for a simple program to count how many times a digit shows up in an integer.
What does this look and work in a stack frame view? I don't completely understand how the returning works. I appreciate the help!
int count_digits(int n, int digit) {
// Base case: When n is a single digit.
if (n / 10 == 0) {
// Check if n is the same as the digit.
// When recursion hits the base case it will end the recursion.
if (n == digit) {
return 1;
} else {
return 0;
}
} else {
if (n % 10 == digit) {
return (1 + count_digits(n / 10, digit));
} else {
return (count_digits(n / 10, digit));
}
}
}
What does this look and work in a stack frame view? I don't completely understand how the returning works. I appreciate the help!
Let's try to build the solution bottom-up.
If you called the function - int count_digits(int n, int digit) as count_digits(4, 4) what would happen ?
This is the base case of your solution so it is very easy to see what is the return value. Your function would return 1.
Now, let's add one more digit and call the function like- count_digits(42, 4). What would happen ?
Your function will check the last digit which is 2 and compare with 4 since they are not equal so it will call the function count_digits(4, 4) and whatever is the returned value, will be returned as the result of count_digits(42, 4).
Now, let's add one more digit and call the function like - count_digits(424, 4). What would happen ?
Your function will check the last digit which is 4 and compare with 4 since they are equal so it will call the function count_digits(42, 4) and whatever is the returned value, will be returned by adding 1 to it. Since, number of 4s in 424 is 1 + number of 4s in 42. The result of count_digits(42,4) will be calculated exactly like it was done previously.
The recursive function builds up the solution in a top-down manner. If there are n digits initially, then your answer is (0 or 1 depending on the last digit) + answer with n-1 digits. And this process repeats recursively. So, your recursive code, reduces the problems by one digit at a time and it depends on the result of the immediate sub-problem.
You can use the C++ tutor at pythontutor.com website for step by step visualization of the stack frame. http://pythontutor.com/cpp.html#mode=edit
You can also try with smaller inputs and add some debug output to help you track and see how recursion works.
Check this stackoverflow answer for understanding what a stack frame is - Explain the concept of a stack frame in a nutshell
Check this stackoverflow answer for understanding recursion -
Understanding recursion
If you would like more help, please let me know in comments.

How to convert one string to another by successive substitutions of characters?

I'm currently trying to design an algorithm that doing such thing:
I got two strings A and B which consist of lowercase characters 'a'-'z'
and I can modify string A using the following operations:
1. Select two characters 'c1' and 'c2' from the character set ['a'-'z'].
2. Replace all characters 'c1' in string A with character 'c2'.
I need to find the minimum number of operations needed to convert string A to string B when possible.
I have 2 ideas that didn't work
1. Simple range-based for cycle that changes string B and compares it with A.
2. Idea with map<char, int> that does the same.
Right now I'm stuck on unit-testing with such situation : 'ab' is transferable to 'ba' in 3 iterations and 'abc' to 'bca' in 4 iterations.
My algorithm is wrong and I need some fresh ideas or working solution.
Can anyone help with this?
Here is some code that shows minimal RepEx:
int Transform(string& A, string& B)
{
int count = 0;
if(A.size() != B.size()){
return -1;
}
for(int i = A.size() - 1; i >= 0; i--){
if(A[i]!=B[i]){
char rep_elem = A[i];
++count;
replace(A.begin(),A.end(),rep_elem,B[i]);
}
}
if(A != B){
return -1;
}
return count;
}
How can I improve this or I should find another ideas?
First of all, don't worry about string operations. Your problem is algorithmic, not textual. You should somehow analyze your data, and only afterwards print your solution.
Start with building a data structure which tells, for each letter, which letter it should be replaced with. Use an array (or std::map<char, char> — it should conceptually be similar, but have different syntax).
If you discover that you should convert a letter to two different letters — error, conversion impossible. Otherwise, count the number of non-trivial cycles in the conversion graph.
The length of your solution will be the number of letters which shouldn't be replaced by themselves plus the number of cycles.
I think the code to implement this would be too long to be helpful.

How to use a string or a char vector (containing any chemical composition respectively formula) and calculate its molar mass?

I try to write a simple console application in C++ which can read any chemical formula and afterwards compute its molar mass, for example:
Na2CO3, or something like:
La0.6Sr0.4CoO3, or with brackets:
Fe(NO3)3
The problem is that I don't know in detail how I can deal with the input stream. I think that reading the input and storing it into a char vector may be in this case a better idea than utilizing a common string.
My very first idea was to check all elements (stored in a char vector), step by step: When there's no lowercase after a capital letter, then I have found e.g. an element like Carbon 'C' instead of "Co" (Cobalt) or "Cu" (Copper). Basically, I've tried with the methods isupper(...), islower(...) or isalpha(...).
// first idea, but it seems to be definitely the wrong way
// read input characters from char vector
// check if element contains only one or two letters
// ... and convert them to a string, store them into a new vector
// ... finally, compute the molar mass elsewhere
// but how to deal with the numbers... ?
for (unsigned int i = 0; i < char_vec.size()-1; i++)
{
if (islower(char_vec[i]))
{
char arr[] = { char_vec[i - 1], char_vec[i] };
string temp_arr(arr, sizeof(arr));
element.push_back(temp_arr);
}
else if (isupper(char_vec[i]) && !islower(char_vec[i+1]))
{
char arrSec[] = { char_vec[i] };
string temp_arrSec(arrSec, sizeof(arrSec));
element.push_back(temp_arrSec);
}
else if (!isalpha(char_vec[i]) || char_vec[i] == '.')
{
char arrNum[] = { char_vec[i] };
string temp_arrNum(arrNum, sizeof(arrNum));
stoechiometr_num.push_back(temp_arrNum);
}
}
I need a simple algorithm which can handle with letters and numbers. There also may be the possibility working with pointer, but currently I am not so familiar with this technique. Anyway I am open to that understanding in case someone would like to explain to me how I could use them here.
I would highly appreciate any support and of course some code snippets concerning this problem, since I am thinking for many days about it without progress… Please keep in mind that I am rather a beginner than an intermediate.
This problem is surely not for a beginner but I will try to give you some idea about how you can do that.
Assumption: I am not considering Isotopes case in which atomic mass can be different with same atomic number.
Model it to real world.
How will you solve that in real life?
Say, if I give you Chemical formula: Fe(NO3)3, What you will do is:
Convert this to something like this:
Total Mass => [1 of Fe] + [3 of NO3] => [1 of Fe] + [ 3 of [1 of N + 3 of O ] ]
=> 1 * Fe + 3 * (1 * N + 3 * O)
Then, you will search for individual masses of elements and then substitute them.
Total Mass => 1 * 56 + 3 * (1 * 14 + 3 * 16)
=> 242
Now, come to programming.
Trust me, you have to do the same in programming also.
Convert your chemical formula to the form discussed above i.e. Convert Fe(NO3)3 to Fe*1+(N*1+O*3)*3. I think this is the hardest part in this problem. But it can be done also by breaking down into steps.
Check if all the elements have number after it. If not, then add "1" after it. For example, in this case, O has a number after it which is 3. But Fe and N doesn't have it.
After this step, your formula should change to Fe1(N1O3)3.
Now, Convert each number, say num of above formula to:
*num+ If there is some element after current number.
*num If you encountered ')' or end of formula after it.
After this, your formula should change to Fe*1+(N*1+O*3)*3.
Now, your problem is to solve the above formula. There is a very easy algorithm for this. Please refer to: https://www.geeksforgeeks.org/expression-evaluation/. In your case, your operands can be either a number (say 2) or an element (say Fe). Your operators can be * and +. Parentheses can also be present.
For finding individual masses, you may maintain a std::map<std::string, int> containing element name as key and its mass as value.
Hope this helps a bit.

how is program executed when there are 2 or more recursion function written togeather?

how does line return((count-2)+(count-1)) works in below cpp program?
ans of the given code is -18 .how to know the ans without running the code
and out of two function count(n-2) and count(n-1) which one is called first and how is it decided?
#include <iostream>
using namespace std;
int count(int n);
int main() {
int n, m;
n = 4;
m = count(n);
cout << m;
}
int count(int n)
{
if (n<0)
{
return n;
}
else
{
return (count(n - 2) + count(n - 1));
}
}
There's no sequencing between the left-hand and right-hand side of the + operator. So which one is evaluated first is unknown (and left up to the compiler).
The only way to figure it out is to step thought he code line by line, statement by statement, expression by expression in a debugger.
However, since each recursive call is not depending on any side-effects they can be executed independently of each other, and therefore the order doesn't matter as the result will always be the same.
We can simply draw a binary tree to know the answer without compiling it. Just start breaking branch into two for count(n-1) and count(n-2) then add all leaves of trees.
Like if we took n as 4 it would be split as 3 and 2, Which would be two branch of 4. Similarly and recursively break nodes in to branch. 3 would be split into 1 and 2 so on. till leaves node is less then 0. In the end add value of all leaves to get the answers.

C++ - solve a sudoku game

I'm new to C++ and have to do a home assignment (sudoku). I'm stuck on a problem.
Problem is that to implement a search function which to solve a sudoku.
Instruction:
In order to find a solution recursive search is used as follows. Suppose that there is a
not yet assigned field with digits (d1....dn) (n > 1). Then we first try to
assign the field to d1, perform propagation, and then continue with search
recursively.
What can happen is that propagation results in failure (a field becomes
empty). In that case search fails and needs to try different digits for one of
the fields. As search is recursive, a next digit for the field considered last
is tried. If none of the digits lead to a solution, search fails again. This in
turn will lead to trying a different digit from the previous field, and so on.
Before a digit d is tried by assigning a field to
it, you have to create a new board being a copy of the current board (use
the copy constructor and allocate the board from the heap with new). Only
then perform the assignment on the copy. If the recursive call to search
returns unsuccessfully, a new board can be created for the next digit to be
tried.
I've tried:
// Search for a solution, returns NULL if no solution found
Board* Board::search(void) {
// create a copy of the cur. board
Board *copyBoard = new Board(*this);
Board b = *copyBoard;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
// if the field has not been assigned, assign it with a digit
if(!b.fs[i][j].assigned()){
digit d = 1;
// try another digit if failed to assign (1 to 9)
while (d <=9 && b.assign(i, j, d) == false){
d++;
// if no digit matches, here is the problem, how to
// get back to the previous field and try another digit?
// and return null if there's no pervious field
if(d == 10){
...
return NULL;
}
}
}
}
return copyBoard;
}
Another problem is where to use the recursive call? Any tips? thx!
Complete instruction can been found here: http://www.kth.se/polopoly_fs/1.136980!/Menu/general/column-content/attachment/2-2.pdf
Code: http://www.kth.se/polopoly_fs/1.136981!/Menu/general/column-content/attachment/2-2.zip
There is no recursion in your code. You can't just visit each field once and try to assign a value to it. The problem is that you may be able to assign, say, 5 to field (3,4) and it may only be when you get to field (6,4) that it turns out there can't be a 5 at (3, 4). Eventually you need to back out of recursion until you come back to (3,4) and try another value there.
With recursion you might not use nested for loops to visit fields, but visit the next field with a recursive call. Either you manage to reach the last field, or you try all possibilities and then leave the function to get back to the previous field you visited.
Sidenote: definitely don't allocate dynamic memory for this task:
//Board *copyBoard = new Board(*this);
Board copyBoard(*this); //if you need a copy in the first place
Basically what you can try is something like this (pseudocode'ish)
bool searchSolution(Board board)
{
Square sq = getEmptySquare(board)
if(sq == null)
return true; // no more empty squares means we solved the puzzle
// otherwise brute force by trying all valid numbers
foreach (valid nr for sq)
{
board.doMove(nr)
// recurse
if(searchSolution(board))
return true
board.undoMove(nr) // backtrack if no solution found
}
// if we reach this point, no valid solution was found and the puzzle is unsolvable
return false;
}
The getEmptySquare(...) function could return a random empty square or the square with the least number of options left.
Using the latter will make the algorithm converge much faster.