/* Author: Sunil Kata
** Filename: ExpressionEvaluator.php
** Date: 10 May 2014
** Input: Expects a file name which has spreadsheets information with the test cases
** Output: Evaluates expression of each test case for those spreadsheets
** Description: This program creates a hash map of all cells per spreadsheet, considers mapping via expressions as edges of a tree.
This will result in disconnected collection of trees, which could be called as Forest.
The program does DFS on each of disconnected tree and evalutes the expression while traversing.
** PreConditions: The format of the input file has to be in certain order. Order shown below
No of test cases as T
S1 :No of cells
c1: Expression
c2:
.
.
S2: No of cells
c1: Expression
.
.
S Tth: No of cells
c1: expression
.
.
*/
if( sizeof($argv) < 2 )
{
echo "Usage: ExpressionEvaluator.php input_file_name\n";
exit(1);
}
$testCasesArray = createHashedArrayOfCells( $argv[1] );
foreach($testCasesArray as $testCaseNumber => $spreadsheet)
{
** Date: 10 May 2014
** Input: Expects a file name which has spreadsheets information with the test cases
** Output: Evaluates expression of each test case for those spreadsheets
** Description: This program creates a hash map of all cells per spreadsheet, considers mapping via expressions as edges of a tree.
This will result in disconnected collection of trees, which could be called as Forest.
The program does DFS on each of disconnected tree and evalutes the expression while traversing.
** PreConditions: The format of the input file has to be in certain order. Order shown below
No of test cases as T
S1 :No of cells
c1: Expression
c2:
.
.
S2: No of cells
c1: Expression
.
.
S Tth: No of cells
c1: expression
.
.
*/
if( sizeof($argv) < 2 )
{
echo "Usage: ExpressionEvaluator.php input_file_name\n";
exit(1);
}
$testCasesArray = createHashedArrayOfCells( $argv[1] );
foreach($testCasesArray as $testCaseNumber => $spreadsheet)
{
depthFirstForests($spreadsheet);
$singleSheetEvaluated = array();
foreach($spreadsheet as $key => $cell )
{
$singleSheetEvaluated[$key]=$cell['value'];
}
ksort($singleSheetEvaluated);
$outputArray[]=$singleSheetEvaluated;
}
writeOutput($outputArray);
/************** End of Processing **********************/
/* Input: Takes the file name that contains spreadsheets info
** Description: Read the cell info from the file line-by-line and stores the info in a hashed array of spreadsheets info
** Output: One element is one test case info. Gives out hashed array of all test cases info.
** Precondition: Valid input file name.
** Modifies: None
*/
function createHashedArrayOfCells( $inputFileName )
{
$testCasesArray = array();
$expressionArray = array();
$expectingTotalTestCasesNumber=true;
$totalNumberOfCases=0;
$expressionRead=0;
$testCasesRead=0;
$handle = fopen($inputFileName,'r');
if( $handle )
{
while( ( $buffer = fgets($handle) ) != false )
{
$buffer = trim($buffer);
$length = strlen($buffer);
if( $length == 0 ) continue;
if( $expectingTotalTestCasesNumber )
{
$expectingTotalTestCasesNumber = false;
$expectingTestCaseLength = true;
$totalNumberOfCases = intval($buffer) != 0 ? intval($buffer) : 0;
if( ! $totalNumberOfCases )
{
echo "Not a valid test cases number."; exit(1);
}
continue;
}
if( $expectingTestCaseLength )
{
$expectingTestCaseLength = false;
$testCasesRead++;
$expectingExpression = true;
$totalNumberOfExpressions = intval($buffer) != 0 ? intval($buffer) : 0;
if( ! $totalNumberOfExpressions )
{
echo "Not a valid number of expressions.";
}
continue;
}
if( $expectingExpression )
{
$expressionRead++;
if( $length >= 3 )
{
$expressionEquation = explode("=",$buffer);
$expressionEquation[0] = trim($expressionEquation[0]);
$expressionEquation[1] = trim($expressionEquation[1]);
if( sizeof($expressionEquation) > 2 )
echo "invalid expression";
else
{
$isExpression = ( intval($expressionEquation[1]) == 0 );
$expressionArray[$expressionEquation[0]] = array('expression'=>$expressionEquation[1],'value'=>intval($expressionEquation[1]),'visited'=>false);
}
}
else
{
echo "expression cannot have 2 characters";
}
if( $expressionRead == $totalNumberOfExpressions )
{
$testCasesArray[] = $expressionArray;
$expressionArray = array();
$expressionRead=0;
$expectingExpression = false;
if( $testCasesRead == $totalNumberOfCases )
$expectingTestCaseLength=false;
else
$expectingTestCaseLength=true;
}
}
}
fclose($handle);
return $testCasesArray;
}
else
{
echo "Cannot open file name. Path to file could be incorrect";
exit(1);
}
}
/* Input: An array of cells for one spreadsheet
** Output: An array of cells with expression evaluted for all trees in one spreadsheet.
** Description: Calls DepthFirstSearch i.e., expressionEvaluator here, for all unvisited
trees in the spreadsheet forest.
*/
function depthFirstForests(&$spreadsheet)
{
foreach($spreadsheet as $cell => $value )
{
if(!$spreadsheet[$cell]['visited'])
expressionEvaluator($spreadsheet, $cell);
}
}
/* Input: An array of cells for one spreadsheet.
** Output: Array of cells with expression evaluted to value field.
** Modifies: The input array is modified
** Description: Evaluates expression using Depth First search on cells.
Extract each cell from expression, recursively calls the
same function until all cells are evaluated to integers.
*/
function expressionEvaluator(&$spreadsheet, $currentCell)
{
if( ! $spreadsheet[$currentCell]['visited'] )
{
$spreadsheet[$currentCell]['visited']=true;
$expression = $spreadsheet[$currentCell]['expression'];
$newExpression = str_replace(array('+','-','/','*'),"+",$expression);
$valuesArray = explode("+", $newExpression);
foreach( $valuesArray as $cell )
{
$cell = trim($cell);
if( intval($cell) == 0 && array_key_exists($cell, $spreadsheet) )
{
// found a cell. visit it before evaluating
if( ! $spreadsheet[$cell]['visited'] )
{
expressionEvaluator($spreadsheet, $cell);
}
$spreadsheet[$currentCell]['expression'] = str_replace($cell, $spreadsheet[$cell]['value'], $spreadsheet[$currentCell]['expression']);
}
}
// evaluate this expression
eval("\$expression=intval(".$spreadsheet[$currentCell]['expression'].");");
$spreadsheet[$currentCell]['value']=$expression;
}
return;
}
/*Input: Expects the output of the program
**output: Write to a file called output.txt
** Description: If it could not write to output.txt, it just prints the result.
*/
function writeOutput(&$outputArray)
{
$handle = fopen('output.txt','w');
if($handle)
{
foreach($outputArray as $spreadsheet )
{
foreach($spreadsheet as $cell => $value )
{
$line=$cell." = ".$value."\n";
fputs($handle,$line);
}
fputs($handle, "\n");
}
fclose($handle);
}
else
{
echo "Cannot open file, so printing output here ";
print_r($outputArray);
}
}
No comments:
Post a Comment