0

I just started to study informatics. Now i got my first task and i,am full of questions. Does someone have some advice for me? The task is to create an math formula which allows to decide between 3 different formula without any kind of "switch, if-else or other operators" Sooo goal is it to just cin a number; decide with cin 1, 2 or 3 between Celsius to Fahrenheit, meters in foot or € in $ and gettin a result. Im pretty new and just asking me for like 2 hours what such a formula would look like D: any idea?

My Actual Code looks like this. (we arent allowed to use any kind of code we hadnt in our lectures yet. Allowed are just: value assignment, variables, simply data types , basic calculus, cins and couts..

Im just curious on that formula which does not get into my head and how to code it...

#include <iostream>
using namespace std;

int main()
{
    double eingabe;
    int auswahl = 0;
    double ergebnis;


    //zahleneingabe
    cout << "Ihre Eingabe: ? " << endl;
    cin >> eingabe;
    cout << "Ihre Eingabe: " << eingabe << endl;

    system("PAUSE");


    //abfragenausgabe der umrechnungsart
    cout << "Ihre Auswahl der Umwandlung: " << endl;
    cout << "1 - Celsius in Fahrenheit" << endl;
    cout << "2 - Meter in Fuss" << endl;
    cout << "3 - Euro in US Dollar " << endl;

    cin >> auswahl;

    cout << "Ihr Ergebnis ist: " << ergebnis << endl;

    system("PAUSE");

}
DerStarkeBaer
  • 669
  • 8
  • 28
  • 1
    Welcome to Stack Overflow. Please read [the help pages](http://stackoverflow.com/help), take [the SO tour](http://stackoverflow.com/tour), read about [how to ask good questions](http://stackoverflow.com/help/how-to-ask), as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Lastly please show your [mcve] ***as text***. An image is impossible to copy and try for ourselves, and impossible for screen-readers to parse, or search engines to index – Some programmer dude Oct 25 '19 at 06:33
  • Please don't post your code as an image, but as text. – Steven Oct 25 '19 at 06:34
  • Are arrays allowed? Also take a look at [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). Doesn't matter for such small projects, but could be useful for the future. – Lukas-T Oct 25 '19 at 07:37
  • Sadly arrays are not allowed. Trying to get trough it with modulo only or an F function. Sadly im to bad at it =3= – Noc-Noc Noctis Oct 25 '19 at 08:07

5 Answers5

2

If Yasir's solution still uses features that aren't to your teacher's liking (operator == might be forbidden as well), the remaining solution is polynomial regression...

#include <iostream>

int main()
{
    //zahleneingabe
    std::cout << "Ihre Eingabe: ?\n";

    double eingabe;
    std::cin >> eingabe;
    std::cout << "Ihre Eingabe: " << eingabe << '\n';

    //abfragenausgabe der umrechnungsart
    std::cout << "Ihre Auswahl der Umwandlung:\n";
    std::cout << "1 - Celsius in Fahrenheit\n";
    std::cout << "2 - Meter in Fuss\n";
    std::cout << "3 - Euro in US Dollar\n";

    int auswahl;
    std::cin >> auswahl;

    // Found using http://www.xuru.org/rt/PR.asp (ain't nobody got time for that)
    double const coefficient = (-1.82584 * auswahl + 6.95836) * auswahl - 3.33252;
    double const offset = (16.0 * auswahl - 80.0) * auswahl + 96.0;

    double const ergebnis = eingabe * coefficient + offset;

    std::cout << "Ihr Ergebnis ist: " << ergebnis << '\n';
}

Note that I have also cleaned up the code by removing using namespace std;, rescoping variables to their actual use, and added const where relevant. I leave it to you to translate the new variables to german ;)

See it live on Wandbox

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • That's a pretty slick solution, could you please share some explanation on how this is working? I am slightly familiar with regression between 2 variables but what are the variables in this case? – Yasir Khan Oct 25 '19 at 09:50
  • @YasirKhan the three points of interest are (1, 1.8), (2, 3.28084), (3, 1.11), which map `auswahl` to `coefficient`. Same thing for `offset` with values 32, 0, 0. – Quentin Oct 25 '19 at 11:31
  • Thank you very much for the explanation, it makes sense now. A very elegant solution. – Yasir Khan Oct 25 '19 at 14:44
1

You could also use modulo to your advantage.

Assume the formulae:

const float fahrenheitConst = 9.f/5.f;
const float feetConst = 3.2f;
const float exchangeRate = 1.11f;


// eingabe = x, auswahl = y
double a = x * fahrenheitConst + 32;
double b = x * feetConst;
double c = x * exchangeRate;

double result = ( y % 3 ) * ( y % 2 ) * a + ( ( y + 2 ) % 3 ) * ( y + 1 ) % 2 * b + ( y + 1 ) % 3 * ( ( y - 1 ) / 2 ) * c 

Explanation

Basically we want a formula, that is a sum of three terms, where each term is the result of a subformula and two coefficients. For every input, the coefficients for one of the three terms must result in 1 each, while the coefficients for the other two terms must include at least one 0 coefficient per term. To put differently, we want only one of the three subformulae a, b or c to be part of result and its magnitude needs to be exactly 1.

  1. y % 3 results in 0 for 3 and in 1 for 1
  2. y % 2 results in 0 for 2 and in 1 for 1
  3. ( y + 2 ) % 3 results in 0 for 1 and in 1 for 2
  4. ( y + 1 ) % 2 results in 0 for 3 and in 1 for 2
  5. ( y + 1 ) % 3 results in 0 for 2 and in 1 for 3
  6. ( ( y - 1 ) / 2 ) results in 0 for 1 and in 1 for 3 (cannot use % 1)

Demonstration

  1. Let input be 1:
result = ( 1 % 3 ) * ( 1 % 2 ) * a + ( ( 1 + 2 ) % 3 ) * ( 1 + 1 ) % 2 * b + ( 1 + 1 ) % 3 * ( ( 1 - 1 ) / 2 ) * c
= 1 * 1 * a + 0 * 0 * b + 1 * ( 0 / 2 ) * c
= 1 * a + 0 * b + 0 * c
= a
  1. Let input be 2:
result = ( 2 % 3 ) * ( 2 % 2 ) * a + ( ( 2 + 2 ) % 3 ) * ( 2 + 1 ) % 2 * b + ( 2 + 1 ) % 3 * ( ( 2 - 1 ) / 2 ) * c
= 1 * 0 * a + 1 * 1 * b + 0 * [1/2 --> 0 in INT] * c
= 0 * a + 1 * b + 0 * c
= b
  1. Let input be 3:
result = ( 3 % 3 ) * ( 3 % 2 ) * a + ( ( 3 + 2 ) % 3 ) * ( 3 + 1 ) % 2 * b + ( 3 + 1 ) % 3 * ( ( 3 - 1 ) / 2 ) * c
= 0 * 1 * a + 2 * 0 * b + 1 * 1 * c
= 0 * a + 0 * b + 1 * c 
= c

Notes

There is an ambiguity in the division, that depends on the types used, this is where I wrote [1/2 --> 0 in INT]. That is because for float or double this results in 1/2, but for int this results in 0. Please note how this makes absolutely no difference here. The result could be 5000, but as long as the previous factor results in 0, the whole term resolves to 0.

Additionally you could use integer division to your advantage, i.e. dividing a smaller numer by a larger number will result in 0 for int . I chose not to go that way, because OP mentioned a mathematical solution, while taking advantage of integer division is rather a programmatical approach.

Conclusion

Use:

result = c1 * c2 * formula1 + c3 * c4 * formula2 + c5 * c6 * formula3

So that only the coefficients c_i for one of the three formulae resolve to exactly 1 each, while for the other coefficients at least one per formula must resolve in 0.

Community
  • 1
  • 1
Koenigsberg
  • 1,726
  • 1
  • 10
  • 22
0

I think this should solve your problem. I can't think of anything else that solves it.

#include <iostream>
using namespace std;

int main()
{
    double eingabe;
    int auswahl = 0;
    double ergebnis;

    //zahleneingabe
    cout << "Ihre Eingabe: ? " << endl;
    cin >> eingabe;
    cout << "Ihre Eingabe: " << eingabe << endl;


    //abfragenausgabe der umrechnungsart
    cout << "Ihre Auswahl der Umwandlung: " << endl;
    cout << "1 - Celsius in Fahrenheit" << endl;
    cout << "2 - Meter in Fuss" << endl;
    cout << "3 - Euro in US Dollar " << endl;

    cin >> auswahl;

    double feet_conv = 3.28084;
    double dollar_conv = 1.11;

    ergebnis = (auswahl == 1) * ((eingabe * 9.0 / 5) + 32) + 
               (auswahl == 2) *  eingabe * feet_conv +
               (auswahl == 3) * eingabe * dollar_conv;

     cout << "Ihr Ergebnis ist: " << ergebnis << endl;

    return 0;

}
Yasir Khan
  • 645
  • 4
  • 9
  • 2
    OP said no *if-else*, *switch* or other operators. You used the *ternary* operator to model *switch* - from what I read in the opening question this is not allowed. – Koenigsberg Oct 25 '19 at 08:52
  • 1
    Your function pointer answer was good (+1). It didn't need the ternary operator update - just confuses the answer. – acraig5075 Oct 25 '19 at 08:57
  • 2
    It also uses an array which again, according to OP, is not allowed – Koenigsberg Oct 25 '19 at 08:58
  • Thanks for your comments, I have edited my solution to not use function pointers, arrays, and conditional operator. I can't think of any other solution. – Yasir Khan Oct 25 '19 at 09:14
0

Can do without if/switch or ternary operator, or comparison, just boolean operations, implicit bool-to-integer conversion, and multiplication:

#include <iostream>
using namespace std;

double c_zu_f(double in)     { return in * (9.0/5.0) + 32.0; }
double m_zu_ft(double in)    { return 3.0 * in; }  // approx.
double eur_zu_usd(double in) { return 1.2 * in; }  // approx.

int main()
{
    double eingabe;
    int auswahl = 0;
    double ergebnis;

    //zahleneingabe
    cout << "Ihre Eingabe: ? " << endl;
    cin >> eingabe;
    cout << "Ihre Eingabe: " << eingabe << endl;

    system("PAUSE");


    //abfragenausgabe der umrechnungsart
    cout << "Ihre Auswahl der Umwandlung: " << endl;
    cout << "1 - Celsius in Fahrenheit" << endl;
    cout << "2 - Meter in Fuss" << endl;
    cout << "3 - Euro in US Dollar " << endl;

    cin >> auswahl;



    bool auswahl_gueltig  = auswahl && (auswahl & 0x03);  // oder nur (auswahl & 0x03), da 0 --> false
    bool auswahl_ist_eins = auswahl_gueltig &&  ( (auswahl & 1) && !(auswahl & 2));
    bool auswahl_ist_zwei = auswahl_gueltig &&  (!(auswahl & 1) &&  (auswahl & 2));
    bool auswahl_ist_drei = auswahl_gueltig && !( auswahl_ist_eins || auswahl_ist_zwei );

    ergebnis = auswahl_ist_eins * c_zu_f(eingabe) + auswahl_ist_zwei * m_zu_ft(eingabe) + auswahl_ist_drei * eur_zu_usd(eingabe);

    cout << "Ihr Ergebnis ist: " << ergebnis << endl;

    system("PAUSE");

}

If given invalid (not 1, 2, or 3) auswahl, the result shown will be zero, but that's as good as you can get without if or ternary operator (though you could assert(auswahl_gueltig) of course, which isn't exactly the same but at least won't fail silently).

Can make the implicit bool to int conversion explicit with a cast, too, if you like -- but that's unnecessary and ugly.

Damon
  • 67,688
  • 20
  • 135
  • 185
0

Give an integer named choice representing the user's choice, the following expression evaluates to 0 when the the user chooses 1 or 2 and it evaluates to 1 when the user chooses 3:

(choice - 1) * (choice - 2) * 0.5 

Therefore, this expression is a pretty good replacement for choice == 3, which you are not allowed to use in this homework problem because it contains ==.

With the hint above, you can probably guess what to do. But here is a complete solution:

#include <iostream>

int main()
{
  double input;
  std::cout << "Enter your input: " << std::endl;
  std::cin >> input;

  int choice;
  std::cout << "Choose your conversion: " << std::endl;
  std::cout << "1: Celsius to Fahrenheit" << std::endl;
  std::cout << "2: Meters to feet" << std::endl;
  std::cout << "3: Euros to US Dollars" << std::endl;
  std::cin >> choice;

  double result =
    (choice - 2) * (choice - 3) * 0.5 * (1.8 * input + 32) +  // C to F
    (choice - 1) * (choice - 3) * -1  * (3.28084 * input) +   // m to ft
    (choice - 1) * (choice - 2) * 0.5 * (0.97 * input)        // Euro to USD
  ;
  std::cout << "Result: " << result << std::endl;
}
David Grayson
  • 84,103
  • 24
  • 152
  • 189