Last active
September 5, 2015 13:42
-
-
Save aramalipoor/1441e975471de25f191d to your computer and use it in GitHub Desktop.
IAUN Score Match
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
<?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" /> کمترین روز ممکن | |
<input type="radio" value="most_days" <?php echo('most_days'===$_SESSION['relevance'] ? 'checked="checked"':''); ?> name="relevance" /> بیشترین روز ممکن | |
<input type="radio" value="least_weight" <?php echo('least_weight'===$_SESSION['relevance'] ? 'checked="checked"':''); ?> name="relevance" /> کمترین واحد ممکن | |
<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