is this algorithm right for checking a terminating decimal? - decimal

int is_ter(int x)
{
//it is not a TWOs nor a FIVEs and not 1.0
g:
if(x%2 !=0 && x%5 !=0 && x!=1 )
return 0;
// make sure it is 1.0
if(x%2 !=0 && x%5 !=0 && x==1 )
return 1;
//check if it is a two
if(x%2==0){
x/=2;
goto g;
}
if(x%5==0)
{
x/=5;
goto g;
}
}

From the looks of it, you want to check whether 1/x is terminating or not.
Your code looks somewhat confusing. You'll want to check whether all your primefactors are 2 or 5:
int is_ter(unsigned int x)
{
while (x>1)
{
if (x%2==0) x=x/2;
else if (x%5==0) x=x/5;
else return 0;
}
return 1;
}
should do the trick (ok, it says 1/0 is terminating, whatever that means. It's going to terminate the program, so it's not exactly wrong...)

No, not at all.
First of all, your decimal is an int. Second, you should probably be multiplying instead of dividing. Third, when working with decimals, rounding errors occur all the time, so you need to take that into account when comparing decimals to something.
And most importantly, all decimals stored on a computer are 'terminating', because in a computer, a decimal fraction is not much more than a rational number M/N, with N being a power of 2.
You should do some reading about floating point numbers.

Related

find the number of ways you can form a string on size N, given an unlimited number of 0s and 1s

The below question was asked in the atlassian company online test ,I don't have test cases , this is the below question I took from this link
find the number of ways you can form a string on size N, given an unlimited number of 0s and 1s. But
you cannot have D number of consecutive 0s and T number of consecutive 1s. N, D, T were given as inputs,
Please help me on this problem,any approach how to proceed with it
My approach for the above question is simply I applied recursion and tried for all possiblity and then I memoized it using hash map
But it seems to me there must be some combinatoric approach that can do this question in less time and space? for debugging purposes I am also printing the strings generated during recursion, if there is flaw in my approach please do tell me
#include <bits/stdc++.h>
using namespace std;
unordered_map<string,int>dp;
int recurse(int d,int t,int n,int oldd,int oldt,string s)
{
if(d<=0)
return 0;
if(t<=0)
return 0;
cout<<s<<"\n";
if(n==0&&d>0&&t>0)
return 1;
string h=to_string(d)+" "+to_string(t)+" "+to_string(n);
if(dp.find(h)!=dp.end())
return dp[h];
int ans=0;
ans+=recurse(d-1,oldt,n-1,oldd,oldt,s+'0')+recurse(oldd,t-1,n-1,oldd,oldt,s+'1');
return dp[h]=ans;
}
int main()
{
int n,d,t;
cin>>n>>d>>t;
dp.clear();
cout<<recurse(d,t,n,d,t,"")<<"\n";
return 0;
}
You are right, instead of generating strings, it is worth to consider combinatoric approach using dynamic programming (a kind of).
"Good" sequence of length K might end with 1..D-1 zeros or 1..T-1 of ones.
To make a good sequence of length K+1, you can add zero to all sequences except for D-1, and get 2..D-1 zeros for the first kind of precursors and 1 zero for the second kind
Similarly you can add one to all sequences of the first kind, and to all sequences of the second kind except for T-1, and get 1 one for the first kind of precursors and 2..T-1 ones for the second kind
Make two tables
Zeros[N][D] and Ones[N][T]
Fill the first row with zero counts, except for Zeros[1][1] = 1, Ones[1][1] = 1
Fill row by row using the rules above.
Zeros[K][1] = Sum(Ones[K-1][C=1..T-1])
for C in 2..D-1:
Zeros[K][C] = Zeros[K-1][C-1]
Ones[K][1] = Sum(Zeros[K-1][C=1..T-1])
for C in 2..T-1:
Ones[K][C] = Ones[K-1][C-1]
Result is sum of the last row in both tables.
Also note that you really need only two active rows of the table, so you can optimize size to Zeros[2][D] after debugging.
This can be solved using dynamic programming. I'll give a recursive solution to the same. It'll be similar to generating a binary string.
States will be:
i: The ith character that we need to insert to the string.
cnt: The number of consecutive characters before i
bit: The character which was repeated cnt times before i. Value of bit will be either 0 or 1.
Base case will: Return 1, when we reach n since we are starting from 0 and ending at n-1.
Define the size of dp array accordingly. The time complexity will be 2 x N x max(D,T)
#include<bits/stdc++.h>
using namespace std;
int dp[1000][1000][2];
int n, d, t;
int count(int i, int cnt, int bit) {
if (i == n) {
return 1;
}
int &ans = dp[i][cnt][bit];
if (ans != -1) return ans;
ans = 0;
if (bit == 0) {
ans += count(i+1, 1, 1);
if (cnt != d - 1) {
ans += count(i+1, cnt + 1, 0);
}
} else {
// bit == 1
ans += count(i+1, 1, 0);
if (cnt != t-1) {
ans += count(i+1, cnt + 1, 1);
}
}
return ans;
}
signed main() {
ios_base::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> d >> t;
memset(dp, -1, sizeof dp);
cout << count(0, 0, 0);
return 0;
}

How do I return the smallest value using a for loop?

I am given a limit, and I have to return the smallest value for n to make it true: 1+2+3+4+...+n >= limit. I feel like there's one thing missing, but I can't tell.
public int whenToReachLimit(int limit) {
int sum = 0;
for (int i = 1; sum < limit; i++) {
sum = sum + i;
}
return sum;
}
The output would be:
1 : 1
4 : 3
10 : 4
You get avoid the loop to compute the sum of the n first integers, using:
Thus the inequality becomes:
Notice that the left-hand side is positive (if n is negative, the sum is empty) and strictly increasing. Notice also that you are looking for the first integer satisfying the inequality. The idea here is first to replace the inequality by an equality which will allow us to solve the equation for n. In a second step, the possibly non-integer solution will be rounder to the closest integer.
Solving this equation for n should give you two solutions. The negative one can be discarded (remember n is positive). That is:
Finally, let's round this solution to the closest integer that will also satisfy the inequality:
NB: it can be overkilled for small inputs
I'm not sure if I know exactly what you want to do. But I would recommend to make a "practice run".
If Limit = 0 the function returns 0
If Limit = 1 the function returns 1
If Limit = 2 the function return 3
If Limit = 3 the function return 3
If Limit = 4 the function return 6
If Limit = 5 the function return 6
Now you decide by your own if the functions does what you're expecting.
I've found the answer. Turns out it doesn't work with a for loop which I find odd. But this is the answer to my own question.
public int whenToReachLimit(int limit) {
int n = 0;
int sum = 0;
while (sum < limit) {
sum += n;
n++;
}
return n-1;
}
You don't want to return sum, you want to return n (smallest possible value satisfying the given requirement).
return i-1 instead of sum.

Counter for two binary strings C++

I am trying to count two binary numbers from string. The maximum number of counting digits have to be 253. Short numbers works, but when I add there some longer numbers, the output is wrong. The example of bad result is "10100101010000111111" with "000011010110000101100010010011101010001101011100000000111000000000001000100101101111101000111001000101011010010111000110".
#include <iostream>
#include <stdlib.h>
using namespace std;
bool isBinary(string b1,string b2);
int main()
{
string b1,b2;
long binary1,binary2;
int i = 0, remainder = 0, sum[254];
cout<<"Get two binary numbers:"<<endl;
cin>>b1>>b2;
binary1=atol(b1.c_str());
binary2=atol(b2.c_str());
if(isBinary(b1,b2)==true){
while (binary1 != 0 || binary2 != 0){
sum[i++] =(binary1 % 10 + binary2 % 10 + remainder) % 2;
remainder =(binary1 % 10 + binary2 % 10 + remainder) / 2;
binary1 = binary1 / 10;
binary2 = binary2 / 10;
}
if (remainder != 0){
sum[i++] = remainder;
}
--i;
cout<<"Result: ";
while (i >= 0){
cout<<sum[i--];
}
cout<<endl;
}else cout<<"Wrong input"<<endl;
return 0;
}
bool isBinary(string b1,string b2){
bool rozhodnuti1,rozhodnuti2;
for (int i = 0; i < b1.length();i++) {
if (b1[i]!='0' && b1[i]!='1') {
rozhodnuti1=false;
break;
}else rozhodnuti1=true;
}
for (int k = 0; k < b2.length();k++) {
if (b2[k]!='0' && b2[k]!='1') {
rozhodnuti2=false;
break;
}else rozhodnuti2=true;
}
if(rozhodnuti1==false || rozhodnuti2==false){ return false;}
else{ return true;}
}
One of the problems might be here: sum[i++]
This expression, as it is, first returns the value of i and then increases it by one.
Did you do it on purporse?
Change it to ++i.
It'd help if you could also post the "bad" output, so that we can try to move backward through the code starting from it.
EDIT 2015-11-7_17:10
Just to be sure everything was correct, I've added a cout to check what binary1 and binary2 contain after you assing them the result of the atol function: they contain the integer numbers 547284487 and 18333230, which obviously dont represent the correct binary-to-integer transposition of the two 01 strings you presented in your post.
Probably they somehow exceed the capacity of atol.
Also, the result of your "math" operations bring to an even stranger result, which is 6011111101, which obviously doesnt make any sense.
What do you mean, exactly, when you say you want to count these two numbers? Maybe you want to make a sum? I guess that's it.
But then, again, what you got there is two signed integer numbers and not two binaries, which means those %10 and %2 operations are (probably) misused.
EDIT 2015-11-07_17:20
I've tried to use your program with small binary strings and it actually works; with small binary strings.
It's a fact(?), at this point, that atol cant handle numerical strings that long.
My suggestion: use char arrays instead of strings and replace 0 and 1 characters with numerical values (if (bin1[i]){bin1[i]=1;}else{bin1[i]=0}) with which you'll be able to perform all the math operations you want (you've already written a working sum function, after all).
Once done with the math, you can just convert the char array back to actual characters for 0 and 1 and cout it on the screen.
EDIT 2015-11-07_17:30
Tested atol on my own: it correctly converts only strings that are up to 10 characters long.
Anything beyond the 10th character makes the function go crazy.

Negative values returned from file in NXC

I am saving values to a .csv file in NXC(Not eXactly C) and then calling on them ata later point in time. The problem I am having is when calling any negative values back from a cell it is displayed as 0123 instead of -123 which is throwing all my additional calculations off.
The current code is:
OpenFileRead("map.csv", fSize, count);
until (eof == true) {
ReadLnString(count, val);
int lstFwd = StrToNum(val);
NumOut(0,LCD_LINE1,lstFwd);
}
while(true);
Can anyone explain how to rectify this issue as it is causing me a great deal of stress now.
StrToNum should convert negativ numbers. Its a bit strange that an integer number starts with 0. You should also use Enhanced NBC/NXC firmware.
First: You should always clear the screen before writing some output!
Use:
NumOut(0,LCD_LINE1,lstFwd, DRAW_OPT_CLEAR_LINE);
If the problem still exists try:
string val;
OpenFileRead("map.csv", fSize, count);
until (eof == true) {
ReadLnString(count, val);
int lstFwd = StrToNum(val);
if(SubStr(val, 0, 1) == "-") lstFwd *= -1; // Check if first char is "-"
NumOut(0,LCD_LINE1,lstFwd, DRAW_OPT_CLEAR_LINE);
}
while(true);

Trouble with functions returning bool!

I don't understand exactly how to use a function that returns a boolean. I know what it is, but I can't figure out how to make it work in my program. I'm trying to say that if my variable "selection" is any letter beween 'A' and 'I' then it is valid and can continue on to the next function which is called calcExchangeAmt(amtExchanged, selection). If it is false I want it to ask the user if they want to repeat the program and if they agree to repeat. I want it to clear the screen and restart to the main function. How do I make my program work as intended?
This is my bool function:
bool isSelectionValid(char selection, char yesNo, double amtExchanged)
{
bool validData;
validData = true;
if ((selection >= 'a' && selection <= 'i') ||
(selection >= 'A' && selection <= 'I'))
{
validData = calcExchangeAmt (amtExchanged, selection);
}
else(validData == false);
{
cout << "Do you wish to continue? (Y for Yes / N for No)";
cin >> yesNo;
}
do
{
main();
}
while ((yesNo =='y')||(yesNo == 'Y'));
{
system("cls");
}
return 0;
}
I get this warning:
warning C4800: 'double' : forcing value to bool 'true' or 'false' (performance warning)
A bool function should return true or false. I'm guessing your warning is caused by the fact that you're declaring validData as bool, but then assign it a different value (returned by calcExchangeAmt function). That value is getting converted from its value type (double) to boolean (true or false).
So, your IsSelectionValid method should just return true if selection is valid, or false if it's not. Then whatever code needs to know that information can proceed accordingly.
I don't know much C++, so forgive me for syntax problems my code is bound to have, but your code should look something like this:
bool isSelectionValid(char selection)
{
return (selection >= 'a' && selection <= 'i') || (selection >= 'A' && selection <= 'I');
}
void myCallingFunction(double amtExchanged, char selection)
{
bool isSelectionValid = isSelectionValid(selection);
if(isSelectionValid)
{
double exchangeAmt = calcExchangeAmt (amtExchanged, selection);
}
else
{
cout<<"Do you wish to continue? (Y for Yes / N for No)";
cin>>yesNo;
if((yesNo =='y')||(yesNo == 'Y'))
{
main(); // or whatever code starts another attempt
}
}
This code is seriously confusing and very non-C++ like. We normally expect main() to be the function that drives things and calls other functions, not to have it called from some other place. We generally avoid do unless there is a compelling reason (and I don't see one here). I think it's highly unlikely that a function called calcExchangeAmt returns true or false; I suspect it actually returns a number that you should be doing something else with (showing to the user?).
With all this going on, trying to explain your actual compiler error messages is of limited value. Your code is all inside out and backwards. Anna Lear's answer seems like a better starting point if it makes sense to you.
The type of 0 is not bool; true or false is bool. It is telling you that 0 is a double, but it is forcing it to a boolean type.

Resources