2014-09-28 02:37:53 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is the model class for table "{{eulerproblem}}".
|
|
|
|
*
|
|
|
|
* The followings are the available columns in table '{{eulerproblem}}':
|
|
|
|
* @property integer $Problemnumber
|
|
|
|
* @property string $Problemtitle
|
|
|
|
* @property string $Problemdescription
|
|
|
|
* @property string $Code
|
|
|
|
* @property string $Explanation
|
|
|
|
* @property integer $AbbreviatedCode
|
|
|
|
* @property string $SolutionSteps
|
|
|
|
* @property string $SolutionTime
|
|
|
|
* @property string $SolutionWidth
|
|
|
|
* @property string $SolutionHeight
|
|
|
|
* @property string $SolutionValue
|
|
|
|
*/
|
|
|
|
class EulerProblem extends CActiveRecord
|
|
|
|
{
|
|
|
|
const TIMELEVEL_PERFECT = 0;
|
|
|
|
const TIMELEVEL_GOOD = 1;
|
|
|
|
const TIMELEVEL_OK = 2;
|
|
|
|
const TIMELEVEL_BAD = 3;
|
|
|
|
const TIMELEVEL_FAIL = 4;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string the associated database table name
|
|
|
|
*/
|
|
|
|
public function tableName()
|
|
|
|
{
|
|
|
|
return '{{eulerproblem}}';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array validation rules for model attributes.
|
|
|
|
*/
|
|
|
|
public function rules()
|
|
|
|
{
|
|
|
|
// NOTE: you should only define rules for those attributes that
|
|
|
|
// will receive user inputs.
|
|
|
|
return array(
|
|
|
|
array('Problemnumber, Problemtitle, Problemdescription, Code, Explanation, AbbreviatedCode, SolutionSteps, SolutionTime, SolutionWidth, SolutionHeight, SolutionValue', 'required'),
|
|
|
|
array('AbbreviatedCode', 'numerical', 'integerOnly'=>true),
|
|
|
|
array('SolutionSteps, SolutionTime, SolutionValue', 'length', 'max'=>20),
|
|
|
|
array('Problemtitle', 'length', 'max'=>50),
|
|
|
|
|
|
|
|
array('Problemnumber, Problemtitle, Problemdescription, Code, Explanation, AbbreviatedCode, SolutionSteps, SolutionTime, SolutionValue', 'safe', 'on'=>'search'),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array relational rules.
|
|
|
|
*/
|
|
|
|
public function relations()
|
|
|
|
{
|
|
|
|
// NOTE: you may need to adjust the relation name and the related
|
|
|
|
// class name for the relations automatically generated below.
|
|
|
|
return array(
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array customized attribute labels (name=>label)
|
|
|
|
*/
|
|
|
|
public function attributeLabels()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'Problemnumber' => 'Problemnumber',
|
|
|
|
'Problemtitle' => 'Problemtitle',
|
|
|
|
'Problemdescription' => 'Problemdescription',
|
|
|
|
'Code' => 'Code',
|
|
|
|
'Explanation' => 'Explanation',
|
|
|
|
'AbbreviatedCode' => 'Abbreviated Code',
|
|
|
|
'SolutionSteps' => 'Solution Steps',
|
|
|
|
'SolutionTime' => 'Solution Time',
|
|
|
|
'SolutionWidth' => 'Solution Width',
|
|
|
|
'SolutionHeight' => 'Solution Height',
|
|
|
|
'SolutionValue' => 'Solution Value',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves a list of models based on the current search/filter conditions.
|
|
|
|
*
|
|
|
|
* Typical usecase:
|
|
|
|
* - Initialize the model fields with values from filter form.
|
|
|
|
* - Execute this method to get CActiveDataProvider instance which will filter
|
|
|
|
* models according to data in model fields.
|
|
|
|
* - Pass data provider to CGridView, CListView or any similar widget.
|
|
|
|
*
|
|
|
|
* @return CActiveDataProvider the data provider that can return the models
|
|
|
|
* based on the search/filter conditions.
|
|
|
|
*/
|
|
|
|
public function search()
|
|
|
|
{
|
|
|
|
$criteria=new CDbCriteria;
|
|
|
|
|
|
|
|
$criteria->compare('Problemnumber',$this->Problemnumber);
|
|
|
|
$criteria->compare('Problemtitle',$this->Problemdescription,true);
|
|
|
|
$criteria->compare('Problemdescription',$this->Problemdescription,true);
|
|
|
|
$criteria->compare('Code',$this->Code,true);
|
|
|
|
$criteria->compare('Explanation',$this->Explanation,true);
|
|
|
|
$criteria->compare('AbbreviatedCode',$this->AbbreviatedCode);
|
|
|
|
$criteria->compare('SolutionSteps',$this->SolutionSteps,true);
|
|
|
|
$criteria->compare('SolutionTime',$this->SolutionTime,true);
|
|
|
|
$criteria->compare('SolutionWidth',$this->SolutionWidth);
|
|
|
|
$criteria->compare('SolutionHeight',$this->SolutionHeight);
|
|
|
|
$criteria->compare('SolutionValue',$this->SolutionValue,true);
|
|
|
|
|
|
|
|
return new CActiveDataProvider($this, array(
|
|
|
|
'criteria'=>$criteria,
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the static model of the specified AR class.
|
|
|
|
* Please note that you should have this exact method in all your CActiveRecord descendants!
|
|
|
|
* @param string $className active record class name.
|
|
|
|
* @return EulerProblem the static model class
|
|
|
|
*/
|
|
|
|
public static function model($className=__CLASS__)
|
|
|
|
{
|
|
|
|
return parent::model($className);
|
|
|
|
}
|
|
|
|
|
2014-10-14 14:13:25 +02:00
|
|
|
public function getBlogLink()
|
|
|
|
{
|
|
|
|
return '/blog/1/Project_Euler_with_Befunge/problem-' . str_pad($this->Problemnumber, 3, '0', STR_PAD_LEFT);
|
|
|
|
}
|
|
|
|
|
2014-09-28 02:37:53 +02:00
|
|
|
public function getSourcecodefile($absolute = true)
|
|
|
|
{
|
|
|
|
return ($absolute ? '/' : '') . 'data/blog/Befunge/Euler_Problem-' . str_pad($this->Problemnumber, 3, '0', STR_PAD_LEFT) . '.b93';
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getTimeScore()
|
|
|
|
{
|
|
|
|
if ($this->SolutionTime < 100) // < 100ms
|
|
|
|
return EulerProblem::TIMELEVEL_PERFECT;
|
|
|
|
|
|
|
|
else if ($this->SolutionTime < 15 * 1000) // < 5s
|
|
|
|
return EulerProblem::TIMELEVEL_GOOD;
|
|
|
|
|
|
|
|
else if ($this->SolutionTime < 60 * 1000) // < 1min
|
|
|
|
return EulerProblem::TIMELEVEL_OK;
|
|
|
|
|
|
|
|
else if ($this->SolutionTime < 5 * 60 * 1000) // < 5min
|
|
|
|
return EulerProblem::TIMELEVEL_BAD;
|
|
|
|
|
|
|
|
else
|
|
|
|
return EulerProblem::TIMELEVEL_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function isBefunge93()
|
|
|
|
{
|
|
|
|
return $this->SolutionWidth <= 80 AND $this->SolutionHeight <= 25;
|
|
|
|
}
|
|
|
|
|
2014-10-14 14:13:25 +02:00
|
|
|
public function getRawGithubLink()
|
|
|
|
{
|
|
|
|
return 'https://raw.githubusercontent.com/Mikescher/Project-Euler_Befunge/master/processed/Euler_Problem-' . str_pad($this->Problemnumber, 3, '0', STR_PAD_LEFT) . '.b93';
|
|
|
|
}
|
|
|
|
|
2014-09-28 02:37:53 +02:00
|
|
|
public function generateMarkdown()
|
|
|
|
{
|
|
|
|
$num_padded = str_pad($this->Problemnumber, 3, '0', STR_PAD_LEFT);
|
|
|
|
|
|
|
|
return
|
|
|
|
'Problem [' . $num_padded. '](http://projecteuler.net/problem=' . $num_padded . '): ' . $this->Problemtitle . PHP_EOL .
|
|
|
|
'--------' . PHP_EOL .
|
|
|
|
'' . PHP_EOL .
|
|
|
|
MsHelper::encloseLines($this->Problemdescription, '> ', '') . PHP_EOL .
|
|
|
|
'' . PHP_EOL .
|
|
|
|
'```befunge' . PHP_EOL .
|
|
|
|
$this->Code . PHP_EOL .
|
|
|
|
'```' . PHP_EOL .
|
2014-10-14 14:13:25 +02:00
|
|
|
|
|
|
|
($this->AbbreviatedCode ?
|
|
|
|
(
|
|
|
|
'> **NOTE** ' . PHP_EOL .
|
|
|
|
'> This program is too big to display here, click **[download]** to see the full program. ' . PHP_EOL . PHP_EOL
|
|
|
|
) : '').
|
|
|
|
|
|
|
|
'<a class="btn btn-primary" href="' . $this->getRawGithubLink() . '">Download</a>' . PHP_EOL .
|
2014-09-28 02:37:53 +02:00
|
|
|
'' . PHP_EOL .
|
|
|
|
$this->Explanation . PHP_EOL .
|
|
|
|
'' . PHP_EOL .
|
|
|
|
'**Interpreter steps:** `' . number_format($this->SolutionSteps, 0, null, ',') . '` ' . PHP_EOL .
|
|
|
|
'**Execution time** ([BefunExec](/programs/view/BefunGen)): `' . number_format($this->SolutionTime, 0, null, ',') . '` ms' . (($this->SolutionTime < 1000) ? (' ') : (' *(= ' . MsHelper::formatMilliseconds($this->SolutionTime) . ')* ')) . PHP_EOL .
|
2014-10-14 14:13:25 +02:00
|
|
|
'**Program size:** `' . $this->SolutionWidth . 'x' . $this->SolutionHeight . '` ' . ($this->isBefunge93() ? '*(fully valid Befunge-93)*' : '') . ' ' . PHP_EOL .
|
2014-09-28 02:37:53 +02:00
|
|
|
'**Solution:** `' . number_format($this->SolutionValue, 0, null, ',') . '` ';
|
|
|
|
}
|
|
|
|
}
|