Last active
August 29, 2015 14:16
-
-
Save pathawks/fc56fd43f48b737ae96b to your computer and use it in GitHub Desktop.
Challenge 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author: Pat Hawks | |
* Created on: Mar 06, 2015 | |
* Source File: Challenge2.c | |
* | |
* To compile: | |
* gcc Challenge2.c -Wall -o Challenge2 | |
*/ | |
#include <stdio.h> | |
#include <math.h> | |
#ifndef EXIT_SUCCESS | |
#define EXIT_SUCCESS 0 | |
#endif | |
#define CELSIUS 'C' | |
#define FAHRENHEIT 'F' | |
#define UNKNOWN '?' | |
typedef struct Temperature { | |
double degrees; | |
char system; | |
} Temperature; | |
/** | |
* Convert a temperature Fahrenheit <=> Celsius | |
* | |
* @param tempIn Input temperature | |
* @param tempOut Placeholder for Output temperature | |
*/ | |
void convertTemp( Temperature *tempIn, Temperature *tempOut ) { | |
switch( tempIn->system ) { | |
case FAHRENHEIT: | |
tempOut->degrees = (tempIn->degrees - 32) * 5/9; | |
tempOut->system = CELSIUS; | |
return; | |
case CELSIUS: | |
tempOut->degrees = tempIn->degrees * 9/5 + 32; | |
tempOut->system = FAHRENHEIT; | |
return; | |
default: | |
tempOut->degrees = NAN; | |
tempOut->system = UNKNOWN; | |
return; | |
} | |
} | |
int main( void ) { | |
const char *PROMPT_STRING = "Enter the temperature and scale (eg. 80.0F): "; | |
const char *SCAN_FORMAT = "%lf %1[CcFf] *[ \n\t]"; | |
const char *OUTPUT_FORMAT = "%.1lf°%1c == %.1lf°%1c\n"; | |
Temperature tempIn; | |
Temperature tempOut; | |
int scannedArgs; | |
do { | |
printf( "%s", PROMPT_STRING ); | |
scannedArgs = scanf( SCAN_FORMAT, &(tempIn.degrees), &(tempIn.system) ); | |
while ( getchar() != '\n' ) {} // Flush input buffer | |
tempIn.system &= 0xDF; // Char to Uppercase | |
} while ( scannedArgs != 2 ); | |
convertTemp( &tempIn, &tempOut ); | |
printf( | |
OUTPUT_FORMAT, | |
tempIn.degrees, tempIn.system, | |
tempOut.degrees, tempOut.system | |
); | |
return EXIT_SUCCESS; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author: Pat Hawks | |
* Created on: Mar 06, 2015 | |
* Source File: Challenge2.c | |
* | |
* To compile: | |
* g++ Challenge2.cpp -Wall -std=c++11 -o Challenge2 | |
*/ | |
#include <cmath> | |
#include <iomanip> | |
#include <iostream> | |
#include <string> | |
#if __cplusplus < 201103L | |
#warning You must compile this program with -std=c++11 | |
#endif | |
#ifndef EXIT_SUCCESS | |
#define EXIT_SUCCESS 0 | |
#endif | |
class Temperature { | |
public: | |
static const char CELSIUS = 'C'; | |
static const char FAHRENHEIT = 'F'; | |
static const char UNKNOWN = '?'; | |
Temperature convertTemp() const; | |
bool isValid() const; | |
friend std::ostream& operator<<( std::ostream&, const Temperature& ); | |
friend std::istream& operator>>( std::istream&, Temperature& ); | |
friend bool operator==( const Temperature&, const Temperature& ); | |
private: | |
double degrees; | |
char system; | |
}; | |
int main( void ) { | |
const char *PROMPT = "Enter the temperature and scale (eg. 80.0F): "; | |
const char *EQUALS = " == "; | |
Temperature tempIn; | |
Temperature tempOut; | |
do { | |
std::cout << PROMPT; | |
std::cin >> tempIn; | |
} while ( !tempIn.isValid() ); | |
tempOut = tempIn.convertTemp(); | |
std::cout << std::setprecision(1) << std::fixed | |
<< tempIn << EQUALS << tempOut << std::endl; | |
return EXIT_SUCCESS; | |
} | |
/** | |
* Converts a character to uppercase | |
* This happens at compile time, so there is no performance penalty! | |
* | |
* @param ch character to convert | |
* @return uppercase equivilant of ch | |
*/ | |
constexpr char ucase( char ch ){ | |
return ch & 0xDF; | |
} | |
/** | |
* Converts a character to lowercase | |
* | |
* @param ch character to convert | |
* @return lowercase equivilant of ch | |
*/ | |
constexpr char lcase( char ch ){ | |
return ch | 0x20; | |
} | |
/** | |
* Convert a temperature Fahrenheit <=> Celsius | |
* | |
* @return Converted temperature object | |
*/ | |
Temperature Temperature::convertTemp( void ) const { | |
Temperature tempOut; | |
switch( system ) { | |
case FAHRENHEIT: | |
tempOut.degrees = (degrees - 32) * 5/9; | |
tempOut.system = CELSIUS; | |
break; | |
case CELSIUS: | |
tempOut.degrees = degrees * 9/5 + 32; | |
tempOut.system = FAHRENHEIT; | |
break; | |
default: | |
tempOut.degrees = NAN; | |
tempOut.system = UNKNOWN; | |
} | |
return tempOut; | |
} | |
/** | |
* @return true if object contains a valid Temperature, otherwise false | |
*/ | |
bool Temperature::isValid( void ) const { | |
return system == FAHRENHEIT || system == CELSIUS; | |
} | |
std::ostream& operator<<( std::ostream &out, const Temperature &temp ) { | |
out << temp.degrees << "°" << temp.system; | |
return out; | |
} | |
std::istream& operator>>( std::istream &in, Temperature &temp ) { | |
const size_t NOT_FOUND = std::string::npos; | |
std::string input; | |
size_t *nextChar = nullptr; | |
std::getline( in, input ); | |
try { | |
temp.degrees = stod( input, nextChar ); | |
} catch(...) { | |
goto TemperatureInputFail; // I know, I know | |
} | |
if ( | |
input.find_first_of(ucase(Temperature::FAHRENHEIT))!=NOT_FOUND | |
|| input.find_first_of(lcase(Temperature::FAHRENHEIT))!=NOT_FOUND | |
) { | |
temp.system = Temperature::FAHRENHEIT; | |
} else if ( | |
input.find_first_of(ucase(Temperature::CELSIUS))!=NOT_FOUND | |
|| input.find_first_of(lcase(Temperature::CELSIUS))!=NOT_FOUND | |
) { | |
temp.system = Temperature::CELSIUS; | |
} else { | |
TemperatureInputFail: | |
temp.degrees = NAN; | |
temp.system = Temperature::UNKNOWN; | |
} | |
return in; | |
} | |
bool operator==( const Temperature &a, const Temperature &b ) { | |
if ( a.system == b.system ) | |
return a.degrees == b.degrees; | |
else | |
return a == b.convertTemp(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author: Pat Hawks | |
* Created on: Mar 06, 2015 | |
* Source File: Challenge2.js | |
* | |
* See this in action: | |
* http://student.pathawks.com/AICSC/Challenges/20150306/ | |
*/ | |
"use strict"; | |
window.onload=function(){ | |
var formatNum = function( degrees, system ) { | |
var FAHRENHEIT = "F"; | |
var CELSIUS = "C"; | |
var tempOut; | |
switch( system ) { | |
case FAHRENHEIT: | |
tempOut = ((degrees - 32) * 5/9).toFixed(1) + "°" + CELSIUS; | |
break; | |
case CELSIUS: | |
tempOut = (degrees * 9/5 + 32).toFixed(1) + "°" + FAHRENHEIT; | |
break; | |
default: | |
return false; | |
} | |
return tempOut; | |
}; | |
document.getElementsByTagName("form")[0].onsubmit=function(){ | |
var a=document.getElementById("tempin").value, | |
b=document.getElementById("system").value, | |
c=formatNum( a, b ), | |
d=(+a).toFixed(1) + "°" + b + " == " + c; // (+a) to cast as double | |
if ( !!a && !isNaN(+a) ) { // Not empty and can be cast as a double | |
document.getElementById("outnum").innerHTML=d, | |
document.body.className="displaying-output"; | |
} else { | |
document.getElementById("tempin").value=""; | |
document.body.className="waiting-for-input"; | |
} | |
return false; | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author: Pat Hawks | |
* Created on: Mar 06, 2015 | |
* Source File: Challenge2.s | |
* | |
* To compile: | |
* gcc Challenge2.s -o Challenge2 | |
*/ | |
.code32 | |
.equ _main, main | |
.equ printf, _printf | |
.equ scanf, _scanf | |
.equ STACK_SPACE, 28 | |
.equ tempA, 16 | |
.equ tempB, 4 | |
.equ tempASys, 24 | |
.equ tempBSys, 12 | |
.equ ptr2, 8 | |
.equ ptr1, 4 | |
.equ format, 0 | |
.equ UPPERCASE, 0xDF | |
.equ C, 'C' | |
.equ F, 'F' | |
.global _main | |
.data | |
PROMPT_STRING: | |
.asciz "Enter the temperature and scale (eg. 80.0F): " | |
FORMAT_STRING: | |
#ifdef WIN32 | |
.asciz "%.1lf\370%1c == %.1lf\370%1c\n" | |
#else | |
.asciz "%.1lf°%1c == %.1lf°%1c\n" | |
#endif | |
INPUT_STRING: | |
.asciz "%lf%1c" | |
NINE_FIFTHS: | |
.double +1.8 | |
FIVE: | |
.double +5 # These two could be combined into +0.5555556 | |
NINTHS: # but that would be less precise | |
.double +9 # ... I guess | |
THIRTY_TWO: | |
.double +32 | |
.text | |
main: | |
subl $STACK_SPACE, %esp | |
leal tempASys(%esp), %eax | |
movl %eax, 8(%esp) | |
leal tempA(%esp), %eax | |
movl %eax, ptr1(%esp) | |
PromptForTemp: | |
movl $PROMPT_STRING, format(%esp) | |
call printf | |
movl $INPUT_STRING, format(%esp) | |
call scanf | |
movl tempASys(%esp), %eax | |
andl $UPPERCASE, %eax # Force tempASys to uppercase | |
movl %eax, tempBSys(%esp) # Copy tempASys to tempBSys | |
cmpl $F, %eax # If (tempASys == 'F') | |
je FtoC # goto FtoC | |
cmpl $C, %eax # ElseIf (tempASys != 'C') | |
jne PromptForTemp # goto PromptForTemp | |
CtoF: | |
movl $F, tempASys(%esp) | |
movsd tempA(%esp), %xmm0 # Copy tempA to X | |
movsd %xmm0, tempB(%esp) # Copy X to tempB | |
mulsd NINE_FIFTHS, %xmm0 # X *= 9/5 | |
addsd THIRTY_TWO, %xmm0 # X += 32 | |
jmp Finish | |
FtoC: | |
movl $C, tempASys(%esp) | |
movsd tempA(%esp), %xmm0 # Copy tempA to X | |
movsd %xmm0, tempB(%esp) # Copy X to tempB | |
subsd THIRTY_TWO, %xmm0 # X -= 32 | |
mulsd FIVE, %xmm0 # X *= 5 | |
divsd NINTHS, %xmm0 # X /= 9 | |
Finish: | |
movsd %xmm0, tempA(%esp) # Copy X to tempA | |
movl $FORMAT_STRING, (%esp) | |
call printf | |
addl $STACK_SPACE, %esp | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment