Skip to content

Instantly share code, notes, and snippets.

@aramalipoor
Last active September 5, 2015 13:42
Show Gist options
  • Save aramalipoor/1441e975471de25f191d to your computer and use it in GitHub Desktop.
Save aramalipoor/1441e975471de25f191d to your computer and use it in GitHub Desktop.
IAUN Score Match
<?php
session_cache_expire(0);
session_set_cookie_params(1000000000);
session_start();
$start_time = time();
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<?php
if(@$_GET['action'] === 'clearall') {
$_SESSION['data'] = array();
$_POST['data'] = array();
header('Location: /vahed');
}
function get_week_number($name) {
$no = '';
switch(trim($name)) {
case 'صفرشنبه':
case 'شنبه':
$no = '0';
break;
case 'يك شنبه':
case 'یکشنبه':
case 'یک شنبه':
$no = '1';
break;
case 'دوشنبه':
case 'دو شنبه':
$no = '2';
break;
case 'سه شنبه':
case 'سهشنبه':
$no = '3';
break;
case 'چهارشنبه':
case 'چهار شنبه':
$no = '4';
break;
case 'پنجشنبه':
case 'پنج شنبه':
$no = '5';
break;
}
return $no;
}
function isin(&$array, $key, $value) {
foreach($array as $item) {
if($item[$key] == $value) return true;
}
return false;
}
if(isset($_POST['data'])) {
$_SESSION['data'] = array();
foreach($_POST['data'] as $row) {
$_SESSION['data'][] = $row;
}
header('Location: /vahed');
}
if(!isset($_SESSION['data'])) {
$_SESSION['data'] = array();
}
if(isset($_POST['groups'])) {
$_SESSION['groups'] = $_POST['groups'];
}
if(!isset($_SESSION['groups'])) {
$groups = array();
/*foreach($_SESSION['data'] as $item) {
if(!isset($groups[$item['group']])) {
$groups[$item['group']] = true;
}
}*/
$_SESSION['groups'] = array_keys($groups);
}
if(@$_GET['action'] === 'import' && isset($_POST['raw'])) {
$_POST['raw'] = str_replace(
array('يك شنبه','یک شنبه','دو شنبه','سه شنبه','چهار شنبه','پنج شنبه'),
array('یکشنبه','یکشنبه','دوشنبه','سهشنبه','چهارشنبه','پنجشنبه'),
$_POST['raw']
);
$_POST['raw'] = preg_replace('/(\s)شنبه(\s)/i', '$1صفرشنبه$2', $_POST['raw']);
$matches = array();
$list_single = array();
preg_match_all("/([0-9]{5})\\s([^\\t]*)\\s.*(صفرشنبه|یکشنبه|دوشنبه|سهشنبه|چهارشنبه|پنجشنبه)\\s([0-9][0-9]:[0-9][0-9])\\s-\\s([0-9][0-9]:[0-9][0-9]).*([0-9][\\.][0-9][0-9]).*([0-9][\\.][0-9][0-9])/i", $_POST['raw'], $matches);
for($i = 0, $s = count($matches[0]); $i < $s; $i++) {
if(isset($matches[6][$i])) {
if(!isin($list_single, 'code', $matches[1][$i])) {
$list_single[] = array(
'group' => trim($matches[2][$i]),
'code' => $matches[1][$i],
'weight' => intval($matches[6][$i]),
'times' => get_week_number($matches[3][$i]).'='.str_replace(':', '', $matches[5][$i]).'-'.str_replace(':', '', $matches[4][$i])
);
}
}
}
$matches = array();
$list_double = array();
preg_match_all("/([0-9]{5})\\s*(.*)\\s*(صفرشنبه|یکشنبه|دوشنبه|سهشنبه|چهارشنبه|پنجشنبه)\\s([0-9][0-9]:[0-9][0-9])\\s-\\s([0-9][0-9]:[0-9][0-9]).*\\n(صفرشنبه|یکشنبه|دوشنبه|سهشنبه|چهارشنبه|پنجشنبه)\\s([0-9][0-9]:[0-9][0-9])\\s-\\s([0-9][0-9]:[0-9][0-9]).*([0-9][\\.][0-9][0-9]).*([0-9][\\.][0-9][0-9])/i", $_POST['raw'], $matches);
for($i = 0, $s = count($matches[0]); $i < $s; $i++) {
if(isset($matches[10][$i])) {
if(!isin($list_double, 'code', $matches[1][$i])) {
$list_double[] = array(
'group' => trim($matches[2][$i]),
'code' => $matches[1][$i],
'weight' => intval($matches[9][$i]),
'times' =>
get_week_number($matches[3][$i])
.'='.str_replace(':', '', $matches[5][$i]).'-'.str_replace(':', '', $matches[4][$i])
."\n".
get_week_number($matches[6][$i])
.'='.str_replace(':', '', $matches[8][$i]).'-'.str_replace(':', '', $matches[7][$i])
);
}
}
}
$_SESSION['data'] = array_merge($_SESSION['data'], $list_single, $list_double);
header('Location: /vahed');
}
if(isset($_POST['max_days'])) $_SESSION['max_days'] = $_POST['max_days'];
if(isset($_POST['min_weight'])) $_SESSION['min_weight'] = $_POST['min_weight'];
if(isset($_POST['max_weight'])) $_SESSION['max_weight'] = $_POST['max_weight'];
if(isset($_POST['relevance'])) $_SESSION['relevance'] = $_POST['relevance'];
if(!isset($_SESSION['max_days'])) $_SESSION['max_days'] = 7;
if(!isset($_SESSION['min_weight'])) $_SESSION['min_weight'] = 9;
if(!isset($_SESSION['max_weight'])) $_SESSION['max_weight'] = 24;
if(!isset($_SESSION['relevance'])) $_SESSION['relevance'] = 'least_days';
$iterator = 0;
$data_raw = $_SESSION['data'];
$data_flat = array();
for($size = count($data_raw); $iterator < $size; $iterator++) {
$times = str_replace(array("\r", "\n\n", "\n"), array("\n", "\n", "\\n"), $data_raw[$iterator]['times']);
$times = str_replace("\n", "xx", $times);
$data_flat[] = '["'.$data_raw[$iterator]['group'].'",'.
'"'.$data_raw[$iterator]['code'].'",'.
'"'.$data_raw[$iterator]['weight'].'",'.
'"'.$times.'"]'."\n";
}
?>
<script type="text/javascript">
(function($) {
var main_table,
iterator = 0;
function append_row(group, code, weight, times) {
iterator++;
if(!group) group = '';
if(!code) code = '';
if(!weight) weight = '';
if(!times) times = '';
main_table.append(
$('<tr>' +
'<td><input type="text" name="data['+iterator+'][group]" placeholder="Riazi" value="'+group+'" /></td>'+
'<td><input type="text" name="data['+iterator+'][code]" placeholder="11320" value="'+code+'" maxlength="5" size="8" /></td>'+
'<td><input type="text" name="data['+iterator+'][weight]" placeholder="3" value="'+weight+'" maxlength="1" size="3" /></td>'+
'<td><textarea name="data['+iterator+'][times]" cols="15" placeholder="1=1130-1300 2=1200-1400" class="times">'+times+'</textarea></td>'+
'</tr>')
.append(
$('<td>X</td>').click(function() {
$(this).parent().remove();
})
)
);
}
$(document).ready(function() {
main_table = $('#main-table');
$('.row-appender').click(function(){append_row();});
var i = 0, default_rows = [<?php echo(implode(',', $data_flat)); ?>], s = default_rows.length;
for(; i < s; i++) {
append_row(default_rows[i][0], default_rows[i][1], default_rows[i][2], default_rows[i][3]);
}
});
})(jQuery);
</script>
<style>
body {
direction: rtl;
text-align: right;
/*
direction: ltr;
text-align: left;
*/
background-color: #f6f6f6;
font-family: tahoma;
font-size: 12px;
}
input, textarea {
font-family: tahoma;
font-size: 12px;
}
input[type=text], textarea {
border: 1px solid #bbb;
border-radius: 3px;
padding: 6px;
}
input[type=submit], input[type=button] {
padding: 5px 10px;
}
h1 {
font-size: 27px;
font-family: BYekan, B Yekan, Yekan, Arial;
}
.wrapper {
width: 800px;
margin: 0 auto;
}
form {
background-color: #efefef;
padding: 20px;
}
#main-table {
border-bottom: 1px solid #D5D5D5;
background-color: #E9E9E9;
border-left: 1px solid #D5D5D5;
margin: 10px 0px;
}
#main-table th {
background-color: rgba(0, 0, 0, 0.03);
border: 1px solid #D5D5D5;
border-left: none;
}
.copyright {
margin: 12px 3px;
}
.times {
direction: ltr;
}
#result-table {
border: 3px solid rgba(0, 128, 0, 0.38);
margin: 10px 0;
}
#result-table th {
background-color: rgba(6, 99, 6, 0.56);
color: #FFF;
}
</style>
</head>
<body>
<div class="wrapper">
<h1>انتخاب واحد کوفتی !</h1>
<?php
if(count($data_raw) > 0) {
if(isset($_SESSION['search_cache'])) {
$result = $_SESSION['search_cache'];
}
if(isset($_GET['reset']) || !isset($_SESSION['search_hash']) || $_SESSION['search_hash'] != md5(serialize(array($data_raw)))) {
$result = start_search($data_raw, array(
'max_days' => intval($_SESSION['max_days']),
'min_weight' => intval($_SESSION['min_weight']),
'max_weight' => intval($_SESSION['max_weight']),
'relevance' => $_SESSION['relevance'],
'groups' => $_SESSION['groups']
));
$_SESSION['search_hash'] = md5(serialize($data_raw));
$_SESSION['search_cache'] = $result;
}
?>
<h3>انتخاب واحد پیشنهادی :</h3>
<table id="result-table" cellpadding="9" cellspacing="0" border="0" width="100%">
<?php
if(!$result) {
echo('<tr><td>هیچ ترکیب مناسبی پیدا نشد</td></tr>');
} else {
echo('
<tr>
<th>دسته بندی (عنوان درس)</th>
<th>کد درس</th>
<th>تعداد واحد</th>
<th>روز و ساعت ها</th>
</tr>
');
foreach($result['selection'] as $row) {
$times = '';
foreach($row['times'] as $session) {
$times .= get_week_name($session['day']) . ' ساعت ' . $session['start'] . ' تا ' . $session['end'] . '<br />';
}
echo('
<tr>
<td>'.$row['group'].'</td>
<td>'.$row['code'].'</td>
<td>'.$row['weight'].'</td>
<td>'.$times.'</td>
</tr>
');
}
}
?>
<tr>
<td colspan="4">بهترین نتیجه <b><?php echo($result['total_weight']); ?></b> واحد در <b><?php echo($result['total_days']); ?></b> روز شد.</td>
</tr>
</table>
<?php
}
?>
<form action="?action=setdata" method="post">
<h2>جدول دروس</h2>
<table id="main-table" cellpadding="9" cellspacing="0" border="0" width="100%">
<tr>
<th>دسته بندی (عنوان درس)</th>
<th>کد درس</th>
<th>تعداد واحد</th>
<th>روز و ساعت ها</th>
<th>حذف؟</th>
</tr>
</table>
<table>
<tr>
<td>حداکثر روز هفته</td>
<td><input type="text" placeholder="5" maxlength="1" size="3" name="max_days" value="<?php echo($_SESSION['max_days']); ?>" /></td>
<td>حداقل واحد</td>
<td><input type="text" placeholder="9" maxlength="2" size="3" name="min_weight" value="<?php echo($_SESSION['min_weight']); ?>" /></td>
<td>حداکثر واحد</td>
<td><input type="text" placeholder="24" maxlength="2" size="3" name="max_weight" value="<?php echo($_SESSION['max_weight']); ?>" /></td>
</tr>
<tr>
<td colspan="6">
<input type="radio" value="least_days" <?php echo('least_days'===$_SESSION['relevance'] ? 'checked="checked"':''); ?> name="relevance" /> کمترین روز ممکن&nbsp;&nbsp;&nbsp;
<input type="radio" value="most_days" <?php echo('most_days'===$_SESSION['relevance'] ? 'checked="checked"':''); ?> name="relevance" /> بیشترین روز ممکن&nbsp;&nbsp;&nbsp;
<input type="radio" value="least_weight" <?php echo('least_weight'===$_SESSION['relevance'] ? 'checked="checked"':''); ?> name="relevance" /> کمترین واحد ممکن&nbsp;&nbsp;&nbsp;
<input type="radio" value="most_weight" <?php echo('most_weight'===$_SESSION['relevance'] ? 'checked="checked"':''); ?> name="relevance" /> بیشترین واحد ممکن
</td>
</tr>
<tr>
<td colspan="6">
<?php
$all_groups = array();
foreach($_SESSION['data'] as $item) {
if(!isset($all_groups[$item['group']])) {
$all_groups[$item['group']] = true;
}
}
$all_groups = array_keys($all_groups);
foreach($all_groups as $group) {
echo('<input type="checkbox" name="groups[]" value="'.$group.'" '.(in_array($group, $_SESSION['groups']) ? 'checked':'').' /> '.$group.'<br />');
}
?>
</td>
</tr>
</table>
<input class="row-appender" type="button" value="+ سطر جدید" /><input type="submit" value="پیشنهاد بده !" />
<a href="?action=clearall">- حذف همه</a>
</form>
<form action="?action=import" method="post">
<h2>درود خام دروس</h2>
<textarea name="raw" cols="145"></textarea><br />
<input type="submit" value="ذخیره کن !" />
</form>
<div class="copyright">هرگونه کپی برداری آزاده آزاد است. هرچی نباشه ما دانشگاه آزاد درس میخونیم دیگه. طراحی و کدنویسی توسط <a href="http://profiler.ir/alipoor">آرام عالیپور</a></div> (محاسبه صفحه: <?php echo((time() - $start_time).' ثانیه'); ?>)
</div>
</body>
<?php
function start_search($data, $ops) {
$temp = array();
foreach($data as $row) {
if(in_array($row['group'], $ops['groups'])) {
$times = array();
$row['times'] = str_replace(array("\r", "\n\n"), "\n", $row['times']);
$sessions = explode("\n", $row['times']);
foreach($sessions as $session) {
$session = str_replace(' ', '', trim($session));
$tmp = explode('-', substr($session, 2));
$times[] = array(
'day' => $session[0],
'start' => $tmp[0],
'end' => $tmp[1]
);
}
$row['times'] = $times;
if(!isset($temp[$row['group']])) {
$temp[$row['group']] = array();
}
$temp[$row['group']][] = $row;
}
}
return find_best_supplementary(array(), $temp, $ops);
}
function find_best_supplementary($selection, $groups, $ops) {
if(has_collision($selection)) {
return false;
}
$new_total_weight = 0;
$new_total_days = 0;
$collection = array(
'criteria' => check_ceriteria($selection, $ops, $new_total_weight, $new_total_days),
'selection' => $selection,
'total_weight' => $new_total_weight,
'total_days' => $new_total_days
);
// TODO Experimental
// if(!$collection['criteria']) return false;
if(count($groups) === 0) return $collection;
$best_supplementary = false;
$next_groups = array_slice($groups, 1, count($groups), true);
foreach($groups as $group_name => $group_lessons) {
foreach($group_lessons as $lesson) {
$result = find_best_supplementary(array_merge($collection['selection'], array($lesson)), $next_groups, $ops);
if($result && $result['criteria']) {
if(!$best_supplementary || better_relevant($best_supplementary, $ops, $result['total_weight'], $result['total_days'])) {
$best_supplementary = $result;
}
}
}
}
return $best_supplementary;
}
function has_collision($selection) {
$i = $j = $m = $n = $m_len = $n_len = 0;
$size = count($selection);
for($i = 0; $i < $size; $i++) {
for($j = 0; $j < $size; $j++) {
if($i !== $j && $selection[$i]['group'] == $selection[$j]['group']) {
return true;
}
}
}
for($i = 0; $i < $size; $i++) {
$m_len = count($selection[$i]['times']);
for($m = 0; $m < $m_len; $m++) {
for($j = 0; $j < $size; $j++) {
if($i !== $j) {
$n_len = count($selection[$j]['times']);
for($n = 0; $n < $n_len; $n++) {
if($selection[$i]['times'][$m]['day'] === $selection[$j]['times'][$n]['day']) {
$m_start = intval($selection[$i]['times'][$m]['start']);
$m_end = intval($selection[$i]['times'][$m]['end']);
$n_start = intval($selection[$j]['times'][$n]['start']);
$n_end = intval($selection[$j]['times'][$n]['end']);
if(
($m_start < $n_end && $n_end < $m_end) ||
($n_start < $m_end && $m_end < $n_end) ||
($n_start === $m_start) ||
($n_end === $m_end)
) {
return true;
}
}
}
}
}
}
}
return false;
}
function check_ceriteria($selection, $ops, &$total_weight, &$total_days) {
$weight = 0;
$days = array();
foreach($selection as $lesson) {
$weight += $lesson['weight'];
foreach($lesson['times'] as $time) {
$days[$time['day']] = true;
}
}
$total_weight = $weight;
$total_days = count($days);
return $weight <= $ops['max_weight'] &&
$weight >= $ops['min_weight'] &&
count($days) <= $ops['max_days'];
}
function better_relevant($old_collection, $ops, $new_weight, $new_days) {
switch($ops['relevance']) {
case 'least_days':
return !isset($old_collection['total_days']) || $old_collection['total_days'] > $new_days;
break;
case 'most_days':
return !isset($old_collection['total_days']) || $old_collection['total_days'] < $new_days;
break;
case 'least_weight':
return !isset($old_collection['total_weight']) || $old_collection['total_weight'] > $new_weight;
break;
case 'most_weight':
return !isset($old_collection['total_weight']) || $old_collection['total_weight'] < $new_weight;
break;
}
}
function get_week_name($number) {
$list = array('شنبه', 'یک شنبه', 'دو شنبه', 'سه شنبه', 'چهار شنبه', 'پنج شنبه');
return @$list[$number];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment