UVa 10035 Primary Arithmetic - c++

Can anybody tell me why my program keeps getting wrong answer? It must count the number of carry operations in a sum.
I tried every testcase came to my mind. I didn't get wrong output.
Problem Description:
Children are taught to add multi-digit numbers from right-to-left one digit at a time. Many find the "carry" operation - in which a 1 is carried from one digit position to be added to the next - to be a significant challenge. Your job is to count the number of carry operations for each of a set of addition problems so that educators may assess their difficulty.
Input
Each line of input contains two unsigned integers less than 10 digits. The last line of input contains 0 0.
Output
For each line of input except the last you should compute and print the number of carry operations that would result from adding the two numbers, in the format shown below.
Sample Input
123 456
555 555
123 594
0 0
Sample Output
No carry operation.
3 carry operations.
1 carry operation.
Here's my current code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
unsigned long a, b, carry;
vector <int> v1, v2;
int index_a, index_b;
void digit(unsigned long x, unsigned long y)
{
for(int i=x; i>0; i/=10)
v1.push_back(i%10);
for(int i=y; i>0; i/=10)
v2.push_back(i%10);
}
int main()
{
while(cin>>a>>b && a!=0 && b!=0)
{
v1.clear();
v2.clear();
int carry_counter=0;
digit(a, b);
for(int j=0; j<v1.size() && j<v2.size(); j++)
{
carry=(v1[j]+v2[j]+carry)/10;
if(carry)
carry_counter++;
index_a=index_b=j;
}
for(int i=index_a; i+1<v1.size(); i++)
{
carry=(v1[i]+carry)/10;
if(carry)
carry_counter++;
}
for(int i=index_b; i+1<v2.size(); i++)
{
carry=(v2[i]+carry)/10;
if(carry)
carry_counter++;
}
if(carry_counter==1)
cout<<"1 carry operation."<<endl;
else if(carry_counter>1)
cout<<carry_counter<<" carry operations."<<endl;
else
cout<<"No carry operation."<<endl;
}
return 0;
}

Your code at least has two bugs.
Bug #1
This is the test case you are failing
989 1
0 0
Your code answers that there are 2 carry operations, while there is only one. And the problem (actually, one of the problems) is in these lines:
for(int i=index_a; i+1<v1.size(); i++)
for(int i=index_b; i+1<v2.size(); i++)
These should start from index_a + 1 and index_b + 1 and end with i < v1.size() and i < v2.size().
Bug #2
And you are not reading all the input! Your main loop condition should be:
while (cin>>a>>b && (a!=0 || b!=0))
Test Case, Expected Output and Received Output
To be more clear, here's a test case:
989 1
1 989
11 0
0 11
2 3
2234 766
0 0
And here's the expected (correct) output:
1 carry operation.
1 carry operation.
No carry operation.
No carry operation.
No carry operation.
3 carry operations.
But your code gives this output (which is obviously wrong):
2 carry operations.
2 carry operations.

What about this test-case:
5 5
11 0
99 999
0 0
?

Related

Why does this C++ code give memory limit exceeded?

This is the question Im trying to solve: Link
Im running this code in an online editor and it gives a memory limit exceeded, even though I have used str+=c instead of str=str+c. And I cant seem to figure out why. Could anyone help me wth this?
#include <bits/stdc++.h>
using namespace std;
void solve(){
int a,b,x;
cin>>a>>b>>x;
string res="";
res+='0';
a--;
while(x--){
cout<<res;
res+=res.back()=='0'?'1':'0';
if(res.back()=='0')
a--;
else
b--;
}
string ans="";
for(char ch: res){
ans+=ch;
if(ch=='0'){
while (a--){
ans+='0';
}
}
else{
while(b--){
ans+='1';
}
}
}
cout<<ans;
}
int main() {
int t;
t=1;
while(t--){
solve();
}
return 0;
}
The input I give is 3 3 3
and output I expect is 101100
Basically your solution idea is nearly correct.
The most important requirement here is the number of tansitions. So, when we go from a 1 to a 0 or from a 0 to a 1. These transitions must exist. And the number of transisitions also determines the minimum numbers of 0es or 1s needed.
If more 0es or 1s should be present, then you can simply repeat any 0 or 1 with the same value. This will have no impact on the transistion.
Let's have a closer look. Below is an example for the minimum number of 0es or 1s for a given number of transitions
Transitions Sequence Min 0es Min 1s
1 01 1 1
2 010 2 1
3 0101 2 2
4 01010 3 2
5 010101 3 3
6 0101010 4 3
You immediately see that there is a simple mathematical relation between the number of transitions and the minimum number of needed 1s or 0es. It is:
(Number of Transitions + 1)/2 rounded up
(Number of Transitions + 1)/2 rounded down
For odd number of transisitions, the minimum numbers of 1s or 0es are always the same. For even numbers of transitions however, it depends on the starting value.
The reverse conclusion is that it does not matter for odd transitions, if you start with a 0 or a 1. For an even number of transitions it is important.
Example:
Input 1 2 2, meaning one 0, two 1s and 2 transitions.
With the above formula, we calculate that we need two digits of the one and 2 digits for the other, so theoretically 010 or 101, But since we shall use only one 0, it can only be 101
Resulting in: If we have an even number of transitions, then the start value may depend from other input parameters. And more precicely: If the minimum number needed for a digit is equal to the given number for that digit, then we must start with the other digit.
Example:
1 2 2 must be 101
2 2 2 can be 0110 or 1001
Knowing that we can now draft an algorithm. We will work only one one of the many solutions.
Check, if the number of transitions is odd or even
If even, then determine the start digit with above condition
create a sequence of 010101... or 10101... depending on the start digit and the given number of sequences
Add the not yet consumed 0es or 1s to the sequence by simply duplicating or repeating existing 0es or ones.
This can then be implemented in a similar way like your approach:
#include <iostream>
#include <string>
int main() {
// Here we will store the input parameters
int numberOfZeroes{}, numberOfOnes{}, numberOfTransitions{};
// The input will always be correct, so need to check it
std::cin >> numberOfZeroes >> numberOfOnes >> numberOfTransitions;
// Start digit
char digit{ '0' };
// Check, if the number of transitions is even, then we need a special additional check
if (numberOfTransitions % 2 == 0) {
// Calculate the minimum number of needed 0es or 1s
const int minimum = (numberOfTransitions + 1) / 2;
// Check, if we need to start with digit 1
if (minimum == numberOfZeroes)
digit = '1';
}
// Now we want to create a string starting made of alternating 0es and 1s, so transitions
std::string sequenceWithTransitions{};
do {
// Build string
sequenceWithTransitions += digit;
// Update counters and digits
if (digit == '1') {
digit = '0'; // Make transition
--numberOfOnes; // Update counter
}
else {
digit = '1'; // Make transition
--numberOfZeroes; // Update counter
}
} while (numberOfTransitions--);
// Fill in the remaining 0es and 1s
std::string result{};
for (char c : sequenceWithTransitions) {
result += c; // Copy value
if (c == '1') // Potential replications of 1
while (numberOfOnes-- > 0)
result += '1';
if (c == '0') // Potential replications of 0
while (numberOfZeroes-- > 0)
result += '0';
}
std::cout << result << '\n';
}
Of course this code can be optimzied in many ways

count consecutive 1's in binary

I am writing code in Hackerrank. And recently the problem said, convert decimal to base 2 and then count the max consecutive 1's in the binary number. And first I come with following solution. It works fine. But I do not understand the counting part of it, even though I wrote it.
The code is
int main(){
int n,ind=0, count=0, mmax=0;
char bin[100];
cin >> n;
while(n){
if(n%2==0) {
bin[ind]='0';
n = n / 2;
ind = ind + 1;
}
else if(n%2==1) {
bin[ind]='1';
n = n / 2;
ind = ind + 1;
}
}
for(int i=0; i<=(ind-1); i++){
if(bin[i] == '1' && bin[i+1] == '1'){
count++;
if(mmax < count)
mmax = count;
}
else
count=0;
}
cout << mmax + 1 << endl;
return 0;
}
In the above code, I guess that variable mmax will give me the max consecutive number of 1's but it gives me value that has (max consecutive - 1), So I just wrote like that and submitted the code. But I am curious about. why it is working that way. I am little bit of confused the way that code works like this.
Thanks
Lets say you have this binary sequence:
11110
Your code will compare starting from the first and second:
|11|110 1 && 1 -> max = 1
1|11|10 1 && 1 -> max = 2
11|11|0 1 && 1 -> max = 3
111|10| 1 && 0 -> max = 3
you can see, that although there are 4 1's you only do 3 comparisons, so your max will always be -1 of the actual max. You can fix this by adding mmax += 1 after your for loop.
Just a little bit of trace using small example will show why.
First, lets say there is only 1 '1' in your array.
Since you require both the current position and your next position to be '1', you will always get 0 for this case.
Let's say I have "11111". At the first '1', since next position is also '1', you increment count once. This repeats until 4th '1' and you increment your count 4 times in total so far. When you reach 5th '1', your next position is not '1', thus your count stops at 4.
In general, your method is like counting gaps between fingers, given 5 fingers, you get 4 gaps.
Side note: your code will fail for the case when there is no '1' in your array.

C++ Converting a text file list with numbers and words into an integer 2D array

I have a basic text file which has one entry per line, most entries are are numerical, however there are a few lines with the word and (evenly spaced) in them. Here is an example of one such spacing between and :
<event>
4
0
0.1005960E+03
0.2722592E+03
0.7546771E-02
0.1099994E+00
21
-1
0
0
501
502
0.00000000000E+00
0.00000000000E+00
0.17700026409E+03
0.17700026409E+03
0.00000000000E+00
0.
-1.
21
-1
0
0
502
503
0.00000000000E+00
0.00000000000E+00
-0.45779372796E+03
0.45779372796E+03
0.00000000000E+00
0.
1.
6
1
1
2
501
0
-0.13244216743E+03
-0.16326397666E+03
-0.47746002227E+02
0.27641406353E+03
0.17300000000E+03
0.
-1.
-6
1
1
2
0
503
0.13244216743E+03
0.16326397666E+03
-0.23304746164E+03
0.35837992852E+03
0.17300000000E+03
0.
1.
</event>
What I need to do is create a numerical matrix (using only the numerical values) where each column holds all the data values between each separate instance of and .
This is what I have so far:
using namespace std;
int main()
{
vector <string> data;
string str;
ifstream fin("final_small.txt");
while (fin >> str)
{
data.push_back(str);
}
fin.close(); // Close the file.
int N = data.size();
int matrix[13][19];
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 19; j++) {
matrix[i][j] = data[i];
}
}
}
Obviously this is a huge work in progress. First of all, I read the text file in to a vector, which can not be of type int because of the words. This then causes problems later on when I try to input it into the matrix.
Does anyone have any suggestions?
Thanks in advance!
In C++11, use std::stoi to convert a string to an int. Note that std::stoi will throw an exception of type std::invalid_argument if the conversion cannot be performed.
Could you give some example inputs? What you could do is iterate through each line and only convert characters that are numbers. You can check this with the stdlib function isdigit() which you can see here. You can then use atoi() for numerical conversion. Hope this helps!

How to improve upon this?

There are n groups of friends staying in the queue in front of bus station. The i-th group consists of ai men. Also, there is a single bus that works on the route. The size of the bus is x, that is it can transport x men simultaneously.
When the bus comes (it always comes empty) to the bus station, several groups from the head of the queue goes into the bus. Of course, groups of friends don't want to split, so they go to the bus only if the bus can hold the whole group. In the other hand, none wants to lose his position, that is the order of groups never changes.
The question is: how to choose the size x of the bus in such a way that the bus can transport all the groups and everytime when the bus moves off the bus station there is no empty space in the bus (the total number of men inside equals to x)?
Input Format:
The first line contains the only integer n (1≤n≤10^5). The second line contains n space-separated integers a1,a2,…,an (1≤ai≤10^4).
Output Format:
Print all the possible sizes of the bus in the increasing order.
Sample:
8
1 2 1 1 1 2 1 3
Output:
3 4 6 12
I made this code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(void)
{
int max=0,sum=0,i,n;
cin>>n;
int values[100000];
for ( i = 0; i < n; i++ )
{
cin>>values[i];
sum = sum + values[i];
if ( values[i] > max )
max = values[i];
}
int p = 0,j;
int count = 0;
vector<int> final;
for ( i = 0; i < n; i++ )
{
p = p + values[i];
j = 0;
if ( p >= max && sum%p == 0)
{
flag = 0;
while ( j < n )
{
garb = p;
while (garb!= 0)
{
garb = garb - values[j++];
if ( garb < 0 )
flag = 1;
}
}
if ( flag == 0 )
{
final.push_back(p);
count++;
}
}
}
sort(final.begin(),final.end());
for ( j = 0; j < count; j++ )
{
cout<<final[j]<<"\t";
}
return 0;
}
Edit: I did this in which basically, I am checking if the found divisor satisfies the condition, and if at any point of time, I get a negative integer on taking difference with the values, I mark it by using a flag. However, it seems to give me a seg fault now. Why?
I firstly, calculated the maximum value out of the all possible values, and then, I checked if its a divisor of the sum of the values. However, this approach doesn't work for the input as:
10
2 2 1 1 1 1 1 2 1 2
My output is
2 7 14
whereas the output should be
7 14
only.
Any other approach that I can go with?
Thanks!
I can think of the following simple solution (since your present concern is correctness and not time complexity):
Calculate the sum of all ai's (as you are already doing).
Calculate the maximum of all ai's (as you are already doing).
Find all the factors of sum that are > max(ai).
For each factor, iterate through the ai's and check whether the bus condition is satisfied.

Long Hand Multiplication In C++

I am trying to implement Long Hand Multiplication method for 8 bit binary numbers stored in two arrays BeforeDecimal1 and BeforeDecimal2. The problem is I always get the wrong result. I tried to figure out the issue but couldn't do it. Here is the code:
This is a much more refined code then previous one. It is giving me result but the result is not correct.
int i=0,carry=0;
while(true)
{
if(BeforeDecimal2[i]!=0)
for(int j=7;j>=0;j--)
{
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside first, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside second, j= "<<j<<endl;
carry=1;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==1)
{
cout<<"Inside third, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==0 && carry==0)
{
cout<<"Inside fourth, j= "<<j<<endl;
carry=0;
s[j]=0;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==0)
{
cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=1;
}
else
if(s[j]==1 && BeforeDecimal1[j]==0 && carry==0)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=0;
s[j]=1;
}
else
if(s[j]==0 && BeforeDecimal1[j]==1 && carry==1)
{
//cout<<"Inside fifth, j= "<<j<<endl;
carry=1;
s[j]=0;
}
}
for(int h=7;h>=0;h--)
{
if(h==0)
{
BeforeDecimal1[0]=0; // that is inserting zeros from the right
}
else
{
BeforeDecimal1[h]=BeforeDecimal1[h-1];
BeforeDecimal1[h-1]=0;
}
}
if(i==3)
break;
i++;
}
Regards
Maybe it would be easiest to back up and start with 8-bit binary numbers stored as 8-bit binary numbers. Much like when we do decimal multiplication, we start with a number of digits. We take the values of multiplying by those individual digits, and add them together to get the final result. The difference (or one obvious difference) is this since we're working in binary, all our digits represent powers of two, so we can get each intermediate result by simply bit shifting the input.
Since it's binary, we have only two possibilities for each digit: if it's a 0, then we need to add 0 times the other number shifted left the appropriate number of places. Obviously, 0 time whatever is still 0, so we simply do nothing in this case. The other possibility is that we have a 1, in which case we add 1 times the other number shifted left the appropriate number of places.
For example, let's consider something like 17 x 5, or (in binary) 10001 x 101.
10001
101
------
10001
+ 1000100
--------
= 1010101
Converting that to something more recognizable, we get 0x55, or 85d.
In code, that process comes out fairly short and simple. Start with a result of 0. Check whether the least significant bit in one operand is set. If so, add the other operand to the result. Shift the one operand right a bit and the other left a bit, and repeat until the operand you're shifting to the right equals 0:
unsigned short mul(unsigned char input1, unsigned char input2) {
unsigned short result = 0;
while (input2 != 0) {
if (input2 & 1)
result += input1;
input1 <<= 1;
input2 >>= 1;
}
return result;
}
If you want to deal with signed numbers, it's generally easiest to figure up the sign of the result separately, and do the multiplication on the absolute values.
You have problem in following lines of code
if(reverse==0)
{
totalReverse=totalReverse-1;
reverse=totalReverse;
}
after some iterations of the inner for loop (index j based) the values of reverse goes should goes to negative and when reverse less than 3 then there should be exception thrown.
Are you running this code without exception handling?
to me this smells like shift and add. is there a requirement that you may use operations simulating logical gates only?
for your full adder you have 3 inputs s(s[j]), b(BeforeDecimal1[j]), c(carry), and two outputs ns(new s[j]), nc (new carry)
the table looks like this
s b c ns nc
0 0 0 0 0 handled in v5 clause 4
0 0 1 1 0 handled in v5 clause 3
0 1 0 1 0 handled in v6 clause 5
0 1 1 0 1
1 0 0 1 0
1 0 1 0 1 handled in v5 clause 2
1 1 0 0 1 handled in v5 clause 1
1 1 1 1 1
your code covers only 4 (now 5) of these 8 clauses
to avoid the ugly if-else-if rake i recommend to use temporary result variables (carry and s still valid in the next if clause)
when you analyze the table you could also do (pseudo bool notation)
nc = s && b || s && c || b && c;
ns = s XOR b XOR c; // there is no XOR in C++: axb = a&&!b || !a&&b
arithmetic notation
nc = (s + b + c) / 2;
ns = (s + b + c) % 2;
// [...]
for(int j=7;j>=0;j--)
{
// start changed code
const int sum = s[j] + BeforeDecimal1[j] + carry;
s[j]=sum % 2;
carry=sum / 2;
// end changed code
}
// [...]
here is a nice simulation of your problem Sequential Multiplication
Unless your requirement precisely states otherwise, which isn't clear from your question or any of your comments so far, it is not necessary to process arrays of bits. Arrays of bytes are much more efficient in both space and time.
You don't need this exhaustive explosion of cases either. The only special case is where either operand is zero, i.e. a[i]|b[i] == 0, when
result[i] = carry;
carry = 0;
All other cases can be handled by:
result[i] = a[i]*b[i]+carry;
carry = (result[i] >>> 8) & 1;
result[i] &= 0xff;
I don't see much point in the names BeforeDecimal1 and BeforeDecimal2 either.