Skip to content

Instantly share code, notes, and snippets.

@pathawks
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pathawks/fc56fd43f48b737ae96b to your computer and use it in GitHub Desktop.
Save pathawks/fc56fd43f48b737ae96b to your computer and use it in GitHub Desktop.
Challenge 2
/**
* @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;
}
/**
* @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();
}
/**
* @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;
}
};
/**
* @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