/*
_______________________________________
| Thành Viên Nhóm | Mã Sinh Viên |
|_____________________________________|
| Nguy?n Ð?c Quang | :2411061767 |
| |
| Tr?n Minh Quang | :2411062029 |
| |
| Lu?ng Vi?t Nh?t | :2411061614 |
| |
| Hoàng Gia Th? | :2411061927 |
| |
| Nguy?n Ti?n Dung | :2411061649 |
|_____________________________________|
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef _WIN32
#define CLEAR "cls"
#else
#define CLEAR "clear"
#endif
#define MAX 100
typedef int Position;
// Cau truc mon hoc
typedef struct {
char tenMon[ 50 ] ;
} MonHoc;
// Cau truc sinh vien
struct Sinhvien {
char id[ 20 ] ;
char name[ 50 ] ;
char ns[ 20 ] ;
int tuoi;
float diem[ MAX] ;
int soMon;
float gpa; // Thêm
char hocLuc[ 20 ] ; // Thêm
} ;
// Kieu danh sach mang
typedef struct {
struct Sinhvien A[ MAX] ;
int Last;
} List;
typedef struct {
MonHoc A[ MAX] ;
int count;
} MonHocList;
// =============================== Cac thao tac co ban ===============================
Position FIRST( List L) {
return 1 ;
}
Position END( List L) {
return L.Last + 1 ;
}
Position NEXT( Position P, List L) {
if ( P < END( L) ) return P + 1 ;
return END( L) ;
}
Position PREVIOUS( Position P, List L) {
if ( P > FIRST( L) ) return P - 1 ;
return FIRST( L) ;
}
struct Sinhvien RETRIEVE( Position P, List L) {
return L.A [ P- 1 ] ;
}
Position LOCATE( char id[ ] , List L) {
for ( int i = 0 ; i < L.Last ; i++ ) {
if ( strcmp ( L.
A [ i
] .
id , id
) == 0 ) return i+ 1 ;
}
return END( L) ;
}
void MAKENULL_LIST( List * L) {
L-> Last = 0 ;
}
int EMPTY_LIST( List L) {
return L.Last == 0 ;
}
void INSERT_LIST( struct Sinhvien x, Position P, List * L) {
if ( L-> Last >= MAX) {
return ;
}
if ( P < FIRST( * L) || P > END( * L) ) {
printf ( "Vi tri khong hop le\n " ) ; return ;
}
for ( int i = L-> Last; i >= P; i-- ) {
L-> A[ i] = L-> A[ i- 1 ] ;
}
L-> A[ P- 1 ] = x;
L-> Last++;
}
void DELETE_LIST( Position P, List * L) {
if ( P < FIRST( * L) || P >= END( * L) ) {
printf ( "Vi tri khong hop le\n " ) ; return ;
}
for ( int i = P- 1 ; i < L-> Last- 1 ; i++ ) {
L-> A[ i] = L-> A[ i+ 1 ] ;
}
L-> Last--;
}
// Xoa sinh vien theo MSV
void DELETE_BY_ID( char id[ ] , List * L) {
printf ( "\n +==========================================================================+\n " ) ; printf ( "| XOA SINH VIEN THEO MSV |\n " ) ; printf ( "+==========================================================================+\n " ) ;
Position p = LOCATE( id, * L) ;
if ( p == END( * L) ) {
printf ( "| Khong tim thay sinh vien co MSV: %-36s|\n " , id
) ; printf ( "+==========================================================================+\n " ) ; return ;
}
struct Sinhvien sv = L-> A[ p - 1 ] ;
char confirm;
printf ( "| Tim thay sinh vien: |\n " ) ; printf ( "| MSSV : %-59s|\n " , sv.
id ) ; printf ( "| Ho ten : %-59s|\n " , sv.
name ) ; printf ( "| Ngay sinh : %-27sTuoi : %-11d |\n " , sv.
ns , sv.
tuoi ) ; printf ( "+--------------------------------------------------------------------------+\n " ) ; printf ( " Ban co chac chan muon xoa sinh vien nay khong? (y/n): " ) ; printf ( "+==========================================================================+\n " ) ;
if ( confirm != 'y' && confirm != 'Y' ) {
printf ( "| Da huy thao tac xoa sinh vien. |\n " ) ; printf ( "+==========================================================================+\n " ) ; return ;
}
for ( int i = p - 1 ; i < L-> Last - 1 ; i++ ) {
L-> A[ i] = L-> A[ i + 1 ] ;
}
L-> Last--;
printf ( "| Da xoa sinh vien thanh cong |\n " ) ; printf ( "+--------------------------------------------------------------------------+\n " ) ; printf ( "| Thong tin sinh vien da xoa: |\n " ) ; printf ( "| MSSV : %-59s|\n " , sv.
id ) ; printf ( "| Ho ten : %-59s|\n " , sv.
name ) ; printf ( "| Ngay sinh : %-27sTuoi : %-11d |\n " , sv.
ns , sv.
tuoi ) ; printf ( "+==========================================================================+\n " ) ; }
// ================== Cac chuc nang mo rong ==================
void ChuanHoan( char s[ ] , int size) {
for ( int i = 0 ; i < size; i++ ) {
if ( s[ i] == '/' ) {
if ( i == 1 ) {
for ( int j = size; j >= 0 ; j-- ) {
s[ j+ 1 ] = s[ j] ;
}
s[ 0 ] = '0' ;
size++;
}
if ( s[ i+ 2 ] == '/' && i+ 2 < size) {
for ( int k = size; k >= i+ 1 ; k-- ) {
s[ k+ 1 ] = s[ k] ;
}
s[ i+ 1 ] = '0' ;
size++;
}
}
}
}
int laNamNhuan( int y) {
return ( ( y % 400 == 0 ) || ( y % 4 == 0 && y % 100 != 0 ) ) ;
}
int soNgayTrongThang( int m, int y) {
if ( m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12 )
return 31 ;
if ( m == 4 || m == 6 || m == 9 || m == 11 )
return 30 ;
if ( m == 2 )
return laNamNhuan( y) ? 29 : 28 ;
return 0 ;
}
void ChuanHoaTen( char * name) {
char temp[ 100 ] ;
int i = 0 , j = 0 ;
while ( i < len && name[ i] == ' ' ) i++;
int space = 0 ;
while ( i < len) {
if ( name[ i] != ' ' ) {
if ( space && j > 0 ) {
temp[ j++ ] = ' ' ;
space = 0 ;
}
temp[ j++ ] = name[ i] ;
} else {
space = 1 ;
}
i++;
}
if ( j > 0 && temp[ j- 1 ] == ' ' ) j--;
temp[ j] = '\0 ' ;
for ( i = 0 ; i < j; i++ ) {
if ( temp[ i] >= 'A' && temp[ i] <= 'Z' )
temp[ i] = temp[ i] - 'A' + 'a' ;
}
int newWord = 1 ;
for ( i = 0 ; i < j; i++ ) {
if ( temp[ i] == ' ' ) {
newWord = 1 ;
} else if ( newWord && temp[ i] >= 'a' && temp[ i] <= 'z' ) {
temp[ i] = temp[ i] - 'a' + 'A' ;
newWord = 0 ;
} else {
newWord = 0 ;
}
}
}
struct Sinhvien nhapSinhVien( List L) {
struct Sinhvien sv;
printf ( "\n +-----------------------------------------+\n " ) ; printf ( "| NHAP THONG TIN SINH VIEN MOI |\n " ) ; printf ( "+-----------------------------------------+\n " ) ; while ( 1 ) {
if ( LOCATE( sv.id , L) != END( L) ) {
printf ( "MSSV da ton tai, nhap lai\n " ) ; } else {
break ;
}
}
int check;
do {
check = 1 ;
scanf ( " %19[^\n ]" , sv.
name ) ;
for ( int i
= 0 ; i
< strlen ( sv.
name ) ; i
++ ) { if ( ! ( ( sv.name [ i] >= 'a' && sv.name [ i] <= 'z' ) || ( sv.name [ i] >= 'A' && sv.name [ i] <= 'Z' ) || sv.name [ i] == ' ' ) ) {
check = 0 ;
break ;
}
}
if ( check == 0 ) {
printf ( "Ho va ten khong chua so hoac ky tu dac biet : \n " ) ; } else {
ChuanHoaTen( sv.name ) ;
}
} while ( check == 0 ) ;
do {
printf ( ">> Nhap ngay sinh (dd/mm/yyyy): " ) ;
ChuanHoan( sv.ns , size) ;
char day[ 3 ] , month[ 3 ] , year[ 5 ] ;
day[ 0 ] = sv.ns [ 0 ] ;
day[ 1 ] = sv.ns [ 1 ] ;
day[ 2 ] = '\0 ' ;
month[ 0 ] = sv.ns [ 3 ] ;
month[ 1 ] = sv.ns [ 4 ] ;
month[ 2 ] = '\0 ' ;
int index = 6 ;
for ( int i = 0 ; i < 1 ; i++ ) {
for ( int j = 0 ; j < 4 ; j++ ) {
year[ j] = sv.ns [ index + j] ;
}
}
year[ 4 ] = '\0 ' ;
int maxday = soNgayTrongThang( m, y) ;
if ( d <= 0 || d > maxday || m <= 0 || m > 12 || y <= 100 ) {
printf ( "Ngay sinh khong hop le vui long nhap lai!\n " ) ; } else {
int namNow = 2025 ;
do {
if ( sv.tuoi < namNow - y - 2 || sv.tuoi > namNow - y + 2 ) {
printf ( "Vui long nhap lai tuoi dung voi tuoi that cua ban\n " ) ; }
} while ( sv.tuoi < namNow - y - 2 || sv.tuoi > namNow - y + 2 ) ;
break ;
}
} while ( 1 ) ;
sv.soMon = 0 ;
sv.gpa = 0.0 ;
strcpy ( sv.
hocLuc , "Chua xep loai" ) ;
return sv;
}
void PRINT_LIST( List L) {
if ( L.Last == 0 ) {
return ;
}
printf ( "\n +-----+--------------+---------------------------+--------------+-------+\n " ) ; printf ( "| STT | MSSV | Ho Ten | Ngay Sinh | Tuoi |\n " ) ; printf ( "+-----+--------------+---------------------------+--------------+-------+\n " ) ;
for ( int i = 0 ; i < L.Last ; i++ ) {
printf ( "| %-3d | %-12s | %-25s | %-12s | %-5d |\n " , i+ 1 , L.A [ i] .id , L.A [ i] .name , L.A [ i] .ns , L.A [ i] .tuoi ) ;
}
printf ( "+-----+--------------+---------------------------+--------------+-------+\n " ) ; }
void SORT_BY_NAME( List * L) {
for ( int i = 0 ; i < L-> Last - 1 ; i++ ) {
for ( int j = i + 1 ; j < L-> Last; j++ ) {
if ( strcmp ( L
-> A
[ i
] .
name , L
-> A
[ j
] .
name ) > 0 ) { struct Sinhvien tmp = L-> A[ i] ;
L-> A[ i] = L-> A[ j] ;
L-> A[ j] = tmp;
}
}
}
printf ( "Da sap xep theo ten\n " ) ; }
void SORT_BY_TUOI( List * L) {
for ( int i = 0 ; i < L-> Last - 1 ; i++ ) {
for ( int j = i + 1 ; j < L-> Last; j++ ) {
if ( L-> A[ i] .tuoi > L-> A[ j] .tuoi ) {
struct Sinhvien tmp = L-> A[ i] ;
L-> A[ i] = L-> A[ j] ;
L-> A[ j] = tmp;
}
}
}
printf ( "Da sap xep theo tuoi\n " ) ; }
void themMonHoc( MonHocList * dsMon) {
if ( dsMon-> count >= MAX) {
printf ( "Danh sach mon hoc da day!\n " ) ; return ;
}
MonHoc mh;
printf ( ">> Nhap ten mon hoc: " ) ; scanf ( " %[^\n ]" , mh.
tenMon ) ; for ( int i = 0 ; i < dsMon-> count; i++ ) {
if ( strcmp ( dsMon
-> A
[ i
] .
tenMon , mh.
tenMon ) == 0 ) { printf ( "Mon hoc da ton tai!\n " ) ; return ;
}
}
dsMon-> A[ dsMon-> count++ ] = mh;
printf ( "Da them mon hoc thanh cong!\n " ) ; }
float diemHe10SangHe4( float diem10) {
if ( diem10 >= 9.0 ) return 4.0 ;
if ( diem10 >= 8.5 ) return 3.7 ;
if ( diem10 >= 8.0 ) return 3.5 ;
if ( diem10 >= 7.0 ) return 3.0 ;
if ( diem10 >= 6.5 ) return 2.5 ;
if ( diem10 >= 5.5 ) return 2.0 ;
if ( diem10 >= 5.0 ) return 1.5 ;
if ( diem10 >= 4.0 ) return 1.0 ;
return 0.0 ;
}
float tinhDiemTB10( struct Sinhvien sv) {
if ( sv.soMon == 0 ) return 0.0 ;
float tongDiem = 0 ;
for ( int i = 0 ; i < sv.soMon ; i++ ) {
tongDiem += sv.diem [ i] ;
}
return tongDiem / sv.soMon ;
}
float tinhGPA( struct Sinhvien sv) {
if ( sv.soMon == 0 ) return 0.0 ;
float tongDiemHe4 = 0 ;
for ( int i = 0 ; i < sv.soMon ; i++ ) {
tongDiemHe4 += diemHe10SangHe4( sv.diem [ i] ) ;
}
return tongDiemHe4 / sv.soMon ;
}
void xepLoaiHocLuc( float gpa, char * hocLuc) {
if ( gpa >= 3.6 ) {
} else if ( gpa >= 3.2 ) {
} else if ( gpa >= 2.5 ) {
} else if ( gpa >= 2.0 ) {
} else {
}
}
void nhapDiemChoSinhVien( List * L, MonHocList dsMon) {
if ( EMPTY_LIST( * L) ) {
printf ( "Danh sach sinh vien rong!\n " ) ; return ;
}
if ( dsMon.count == 0 ) {
printf ( "Chua co mon hoc nao trong he thong!\n " ) ; return ;
}
for ( int i = 0 ; i < L-> Last; i++ ) {
struct Sinhvien * sv = & L-> A[ i] ;
printf ( "\n Nhap diem cho sinh vien: %s - %s\n " , sv
-> id
, sv
-> name
) ; sv-> soMon = dsMon.count ;
for ( int j = 0 ; j < dsMon.count ; j++ ) {
float diem;
do {
printf ( ">> Diem mon %-25s: " , dsMon.
A [ j
] .
tenMon ) ; if ( diem < 0 || diem > 10 ) {
printf ( "Diem khong hop le! Nhap lai (0-10)\n " ) ; }
} while ( diem < 0 || diem > 10 ) ;
sv-> diem[ j] = diem;
}
sv-> gpa = tinhGPA( * sv) ;
xepLoaiHocLuc( sv-> gpa, sv-> hocLuc) ;
}
printf ( "\n Nhap diem thanh cong cho tat ca sinh vien!\n " ) ; }
void hienThiKetQuaHocTap( List L, MonHocList dsMon) {
if ( L.Last == 0 ) {
return ;
}
if ( dsMon.count == 0 ) {
printf ( "Chua co mon hoc nao de tinh diem!\n " ) ; PRINT_LIST( L) ;
return ;
}
printf ( "\n +-----+--------------+---------------------------+------------+------------+----------------+\n " ) ; printf ( "| STT | MSSV | Ho Ten | Diem TB 10 | Diem TB 4 | Xep Loai |\n " ) ; printf ( "+-----+--------------+---------------------------+------------+------------+----------------+\n " ) ;
for ( int i = 0 ; i < L.Last ; i++ ) {
struct Sinhvien sv = L.A [ i] ;
float diem10 = tinhDiemTB10( sv) ;
printf ( "| %-3d | %-12s | %-25s | %-10.2f | %-10.2f | %-14s |\n " , i + 1 , sv.id , sv.name , diem10, sv.gpa , sv.hocLuc ) ;
}
printf ( "+-----+--------------+---------------------------+------------+------------+----------------+\n " ) ; }
void SORT_BY_HOCLUC( List * L) {
if ( L-> Last == 0 || L-> A[ 0 ] .soMon == 0 ) {
printf ( "Chua co sinh vien hoac chua nhap diem de xep loai!\n " ) ; return ;
}
for ( int i = 0 ; i < L-> Last - 1 ; i++ ) {
for ( int j = i + 1 ; j < L-> Last; j++ ) {
if ( L-> A[ i] .gpa < L-> A[ j] .gpa ) {
struct Sinhvien tmp = L-> A[ i] ;
L-> A[ i] = L-> A[ j] ;
L-> A[ j] = tmp;
}
else if ( L-> A[ i] .gpa == L-> A[ j] .gpa ) {
if ( tinhDiemTB10( L-> A[ i] ) < tinhDiemTB10( L-> A[ j] ) ) {
struct Sinhvien tmp = L-> A[ i] ;
L-> A[ i] = L-> A[ j] ;
L-> A[ j] = tmp;
}
}
}
}
printf ( "Da sap xep danh sach sinh vien theo Hoc luc (GPA) giam dan.\n " ) ; }
// ================== MAIN ==================
int main( ) {
List L;
MAKENULL_LIST( & L) ;
MonHocList dsMon;
dsMon.count = 0 ;
int choice;
printf ( "\n +=================================================================+\n " ) ; printf ( "| HE THONG QUAN LY SINH VIEN |\n " ) ; printf ( "+=================================================================+\n " ) ; printf ( "| [1] Them sinh vien vao danh sach |\n " ) ; printf ( "| [2] Xoa sinh vien theo MSV |\n " ) ; printf ( "| [3] Nhap diem cho cac sinh vien |\n " ) ; printf ( "| [4] Tim kiem sinh vien theo MSV |\n " ) ; printf ( "| [5] Sap xep danh sach theo ten |\n " ) ; printf ( "| [6] In danh sach sinh vien |\n " ) ; printf ( "| [7] Them mon hoc moi vao danh sach |\n " ) ; printf ( "| [8] Xem ket qua hoc tap (Diem TB 10, GPA, Xep loai) |\n " ) ; printf ( "| [9] Sap xep danh sach theo hoc luc (GPA) |\n " ) ; printf ( "| [10] Clear man hinh (giu nguyen du lieu) |\n " ) ; printf ( "| [11] Chinh sua diem sinh vien theo MSV |\n " ) ; printf ( "| [0] Thoat chuong trinh |\n " ) ; printf ( "+=================================================================+\n " ) ; while ( 1 ) {
printf ( "\n >> Nhap lua chon cua ban: " ) ;
if ( choice == 0 ) {
break ;
}
switch ( choice) {
case 1 : {
struct Sinhvien sv = nhapSinhVien( L) ;
Position p;
printf ( "Nhap Vi Tri Sinh Vien Muon Them Chen Vao (Dau: 1, Cuoi: 2): " ) ; if ( p == 1 ) {
INSERT_LIST( sv, 1 , & L) ;
printf ( "Them sinh vien vao thanh cong. \n " ) ; }
else if ( p == 2 ) {
INSERT_LIST( sv, END( L) , & L) ;
printf ( "Them sinh vien vao thanh cong. \n " ) ; }
else {
printf ( "Lua chon khong hop le \n " ) ; }
break ;
}
case 2 : {
char id[ 20 ] ;
printf ( "\n +-----------------------------------------+\n " ) ; printf ( "| XOA SINH VIEN THEO MA SINH VIEN |\n " ) ; printf ( "+-----------------------------------------+\n " ) ; printf ( ">> Nhap MSV can xoa: " ) ; DELETE_BY_ID( id, & L) ;
break ;
}
case 3 : {
printf ( "\n +---------------------------------------------+\n " ) ; printf ( "| NHAP DIEM CHO CAC SINH VIEN |\n " ) ; printf ( "+---------------------------------------------+\n " ) ; nhapDiemChoSinhVien( & L, dsMon) ;
break ;
}
case 4 : {
char id[ 20 ] ;
printf ( "\n +-----------------------------------------+\n " ) ; printf ( "| TIM KIEM SINH VIEN THEO MSV |\n " ) ; printf ( "+-----------------------------------------+\n " ) ; Position p = LOCATE( id, L) ;
if ( p == END( L) ) {
printf ( " Khong tim thay sinh vien co MSV: %s\n " , id
) ;
} else {
struct Sinhvien sv = RETRIEVE( p, L) ;
printf ( " Da tim thay sinh vien trong danh sach \n " ) ; printf ( "+==========================================================================+\n " ) ; printf ( "| Thong tin sinh vien: |\n " ) ; printf ( "| MSSV : %-59s|\n " , sv.
id ) ; printf ( "| Ho ten : %-59s|\n " , sv.
name ) ; printf ( "| Ngay sinh : %-27sTuoi : %-11d |\n " , sv.
ns , sv.
tuoi ) ; printf ( "+==========================================================================+\n " ) ; }
break ;
}
case 5 :
SORT_BY_NAME( & L) ;
PRINT_LIST( L) ;
break ;
case 6 :
PRINT_LIST( L) ;
break ;
case 7 :
printf ( "\n +-----------------------------------------+\n " ) ; printf ( "| THEM MON HOC MOI |\n " ) ; printf ( "+-----------------------------------------+\n " ) ; themMonHoc( & dsMon) ;
break ;
case 8 : {
printf ( "\n +---------------------------------------------+\n " ) ; printf ( "| KET QUA HOC TAP CUA SINH VIEN |\n " ) ; printf ( "+---------------------------------------------+\n " ) ; hienThiKetQuaHocTap( L, dsMon) ;
break ;
}
case 9 : {
printf ( "\n +---------------------------------------------+\n " ) ; printf ( "| SAP XEP SINH VIEN THEO HOC LUC |\n " ) ; printf ( "+---------------------------------------------+\n " ) ; SORT_BY_HOCLUC( & L) ;
hienThiKetQuaHocTap( L, dsMon) ;
break ;
}
case 10 : {
printf ( "+==============================================================+\n " ) ; printf ( "| HE THONG QUAN LY SINH VIEN |\n " ) ; printf ( "+==============================================================+\n " ) ; printf ( "| [1] Them sinh vien vao danh sach |\n " ) ; printf ( "| [2] Xoa sinh vien theo MSV |\n " ) ; printf ( "| [3] Nhap diem cho cac sinh vien |\n " ) ; printf ( "| [4] Tim kiem sinh vien theo MSV |\n " ) ; printf ( "| [5] Sap xep danh sach theo ten |\n " ) ; printf ( "| [6] In danh sach sinh vien |\n " ) ; printf ( "| [7] Them mon hoc moi vao danh sach |\n " ) ; printf ( "| [8] Xem ket qua hoc tap (Diem TB 10, GPA, Xep loai) |\n " ) ; printf ( "| [9] Sap xep danh sach theo hoc luc (GPA) |\n " ) ; printf ( "| [10] Clear man hinh (giu nguyen du lieu) |\n " ) ; printf ( "| [11] Chinh sua diem sinh vien theo MSV |\n " ) ; printf ( "| [0] Thoat chuong trinh |\n " ) ; printf ( "+==============================================================+\n " ) ; printf ( "Man hinh da duoc lam moi.\n " ) ; break ;
}
default :
printf ( "Lua chon khong hop le\n " ) ; case 11 : {
char id[ 20 ] ;
int found = 0 ;
printf ( "\n +---------------------------------------------+\n " ) ; printf ( "| CHINH SUA DIEM SINH VIEN THEO MSV |\n " ) ; printf ( "+---------------------------------------------+\n " ) ; printf ( ">> Nhap MSV can chinh sua: " ) ;
for ( int i = 0 ; i < L.Last ; i++ ) {
if ( strcmp ( L.
A [ i
] .
id , id
) == 0 ) { found = 1 ;
struct Sinhvien * sv = & L.A [ i] ;
printf ( "\n Thong tin sinh vien:\n " ) ; printf ( "Ho ten: %s\n " , sv
-> name
) ; printf ( "So mon hoc hien co: %d\n " , sv
-> soMon
) ;
if ( sv-> soMon == 0 ) {
printf ( "Sinh vien chua co diem mon hoc nao de chinh sua!\n " ) ; break ;
}
printf ( "\n Cac diem hien tai:\n " ) ; for ( int j = 0 ; j < sv-> soMon; j++ ) {
printf ( " Mon %d: %.2f\n " , j
+ 1 , sv
-> diem
[ j
] ) ; }
int mon;
printf ( "\n >> Nhap thu tu mon muon chinh sua (1-%d): " , sv
-> soMon
) ;
if ( mon >= 1 && mon <= sv-> soMon) {
float diemMoi;
do {
printf ( ">> Nhap diem moi cho mon %d (0-10): " , mon
) ; if ( diemMoi < 0 || diemMoi > 10 )
printf ( "Diem khong hop le, vui long nhap lai!\n " ) ; } while ( diemMoi < 0 || diemMoi > 10 ) ;
sv-> diem[ mon - 1 ] = diemMoi;
} else {
printf ( "So thu tu mon khong hop le!\n " ) ; break ;
}
// C?p nh?t l?i GPA và h?c l?c
sv-> gpa = tinhGPA( * sv) ;
xepLoaiHocLuc( sv-> gpa, sv-> hocLuc) ;
printf ( "\n Da cap nhat diem cho sinh vien co MSV %s.\n " , id
) ; printf ( "GPA moi: %.2f | Hoc luc: %s\n " , sv
-> gpa
, sv
-> hocLuc
) ; break ;
}
}
if ( ! found)
printf ( "\n Khong tim thay sinh vien co MSV %s!\n " , id
) ;
break ;
}
}
}
return 0 ;
}
LyoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCnwgICBUaMOgbmggVmnDqm4gTmjDs20gIHwgICBNw6MgU2luaCBWacOqbiB8CnxfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19ffAp8CU5ndXk/biDDkD9jIFF1YW5nIHwJOjI0MTEwNjE3NjcJICB8CnwJCQkJCQkJCQkgIHwKfAlUcj9uIE1pbmggUXVhbmcJIHwJOjI0MTEwNjIwMjkgICB8CnwJCQkJCQkJCQkgIHwKfAlMdT9uZyBWaT90IE5oP3QJIHwJOjI0MTEwNjE2MTQgICB8CnwJCQkJCQkJCQkgIHwKfAlIb8OgbmcgR2lhIFRoPwkgfAk6MjQxMTA2MTkyNyAgIHwKfAkJCQkJCQkJCSAgfAp8CU5ndXk/biBUaT9uIER1bmcgfAk6MjQxMTA2MTY0OSAgIHwKfF9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX198CiovCgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaWZkZWYgX1dJTjMyICAgIAojZGVmaW5lIENMRUFSICJjbHMiCiNlbHNlCiNkZWZpbmUgQ0xFQVIgImNsZWFyIgojZW5kaWYKI2RlZmluZSBNQVggMTAwCiAKdHlwZWRlZiBpbnQgUG9zaXRpb247CiAKLy8gQ2F1IHRydWMgbW9uIGhvYwp0eXBlZGVmIHN0cnVjdCB7CiAgICBjaGFyIHRlbk1vbls1MF07CiAKfSBNb25Ib2M7CiAKLy8gQ2F1IHRydWMgc2luaCB2aWVuCnN0cnVjdCBTaW5odmllbiB7CiAgICBjaGFyIGlkWzIwXTsKICAgIGNoYXIgbmFtZVs1MF07CiAgICBjaGFyIG5zWzIwXTsKICAgIGludCB0dW9pOwogICAgZmxvYXQgZGllbVtNQVhdOyAgCiAgICBpbnQgc29Nb247ICAKICAgIGZsb2F0IGdwYTsgICAgICAgIC8vIFRow6ptCiAgICBjaGFyIGhvY0x1Y1syMF07ICAvLyBUaMOqbQp9OwogCi8vIEtpZXUgZGFuaCBzYWNoIG1hbmcKdHlwZWRlZiBzdHJ1Y3QgewogICAgc3RydWN0IFNpbmh2aWVuIEFbTUFYXTsKICAgIGludCBMYXN0OyAKfSBMaXN0OwogCnR5cGVkZWYgc3RydWN0IHsKICAgIE1vbkhvYyBBW01BWF07CiAgICBpbnQgY291bnQ7Cn0gTW9uSG9jTGlzdDsgCiAKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBDYWMgdGhhbyB0YWMgY28gYmFuID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIApQb3NpdGlvbiBGSVJTVChMaXN0IEwpIHsKICAgIHJldHVybiAxOwp9CiAKUG9zaXRpb24gRU5EKExpc3QgTCkgewogICAgcmV0dXJuIEwuTGFzdCArIDE7Cn0KIApQb3NpdGlvbiBORVhUKFBvc2l0aW9uIFAsIExpc3QgTCkgewogICAgaWYgKFAgPCBFTkQoTCkpIHJldHVybiBQICsgMTsKICAgIHJldHVybiBFTkQoTCk7Cn0KIApQb3NpdGlvbiBQUkVWSU9VUyhQb3NpdGlvbiBQLCBMaXN0IEwpIHsKICAgIGlmIChQID4gRklSU1QoTCkpIHJldHVybiBQIC0gMTsKICAgIHJldHVybiBGSVJTVChMKTsKfQogCnN0cnVjdCBTaW5odmllbiBSRVRSSUVWRShQb3NpdGlvbiBQLCBMaXN0IEwpIHsKICAgIHJldHVybiBMLkFbUC0xXTsKfQogClBvc2l0aW9uIExPQ0FURShjaGFyIGlkW10sIExpc3QgTCkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMLkxhc3Q7IGkrKykgewogICAgICAgIGlmIChzdHJjbXAoTC5BW2ldLmlkLCBpZCkgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIGkrMTsKICAgIH0KICAgIHJldHVybiBFTkQoTCk7Cn0KIAp2b2lkIE1BS0VOVUxMX0xJU1QoTGlzdCAqTCkgewogICAgTC0+TGFzdCA9IDA7Cn0KIAppbnQgRU1QVFlfTElTVChMaXN0IEwpewogICAgcmV0dXJuIEwuTGFzdCA9PSAwOwp9CiAKdm9pZCBJTlNFUlRfTElTVChzdHJ1Y3QgU2luaHZpZW4geCwgUG9zaXRpb24gUCwgTGlzdCAqTCkgewogICAgaWYgKEwtPkxhc3QgPj0gTUFYKSB7CiAgICAgICAgcHJpbnRmKCJEYW5oIHNhY2ggZGF5XG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoUCA8IEZJUlNUKCpMKSB8fCBQID4gRU5EKCpMKSkgewogICAgICAgIHByaW50ZigiVmkgdHJpIGtob25nIGhvcCBsZVxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZm9yIChpbnQgaSA9IEwtPkxhc3Q7IGkgPj0gUDsgaS0tKSB7CiAgICAgICAgTC0+QVtpXSA9IEwtPkFbaS0xXTsKICAgIH0KIAogICAgTC0+QVtQLTFdID0geDsKICAgIEwtPkxhc3QrKzsKfQogCnZvaWQgREVMRVRFX0xJU1QoUG9zaXRpb24gUCwgTGlzdCAqTCkgewogICAgaWYgKFAgPCBGSVJTVCgqTCkgfHwgUCA+PSBFTkQoKkwpKSB7CiAgICAgICAgcHJpbnRmKCJWaSB0cmkga2hvbmcgaG9wIGxlXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmb3IgKGludCBpID0gUC0xOyBpIDwgTC0+TGFzdC0xOyBpKyspIHsKICAgICAgICBMLT5BW2ldID0gTC0+QVtpKzFdOwogICAgfQogICAgTC0+TGFzdC0tOwp9CiAKIAogCi8vIFhvYSBzaW5oIHZpZW4gdGhlbyBNU1YKdm9pZCBERUxFVEVfQllfSUQoY2hhciBpZFtdLCBMaXN0ICpMKSB7CiAgICBwcmludGYoIlxuKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICBwcmludGYoInwgICAgICAgICAgICAgICAgICAgICAgWE9BIFNJTkggVklFTiBUSEVPIE1TViAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgcHJpbnRmKCIrPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKCiAgICBQb3NpdGlvbiBwID0gTE9DQVRFKGlkLCAqTCk7CgogICAgaWYgKHAgPT0gRU5EKCpMKSkgewogICAgICAgIHByaW50ZigifCAgICBLaG9uZyB0aW0gdGhheSBzaW5oIHZpZW4gY28gTVNWOiAlLTM2c3xcbiIsIGlkKTsKICAgICAgICBwcmludGYoIis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PStcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBzdHJ1Y3QgU2luaHZpZW4gc3YgPSBMLT5BW3AgLSAxXTsKCiAgICBjaGFyIGNvbmZpcm07CiAgICBwcmludGYoInwgICAgVGltIHRoYXkgc2luaCB2aWVuOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgcHJpbnRmKCJ8ICAgIE1TU1YgICAgICA6ICUtNTlzfFxuIiwgc3YuaWQpOwogICAgcHJpbnRmKCJ8ICAgIEhvIHRlbiAgICA6ICUtNTlzfFxuIiwgc3YubmFtZSk7CiAgICBwcmludGYoInwgICAgTmdheSBzaW5oIDogJS0yN3NUdW9pIDogJS0xMWQgICAgICAgICAgICAgIHxcbiIsIHN2Lm5zLCBzdi50dW9pKTsKICAgIHByaW50ZigiKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgICBwcmludGYoIiAgICAgQmFuIGNvIGNoYWMgY2hhbiBtdW9uIHhvYSBzaW5oIHZpZW4gbmF5IGtob25nPyAoeS9uKTogIik7CiAgICBzY2FuZigiICVjIiwgJmNvbmZpcm0pOwogICAgcHJpbnRmKCIrPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKCiAgICBpZiAoY29uZmlybSAhPSAneScgJiYgY29uZmlybSAhPSAnWScpIHsKICAgICAgICBwcmludGYoInwgICAgRGEgaHV5IHRoYW8gdGFjIHhvYSBzaW5oIHZpZW4uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigiKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciAoaW50IGkgPSBwIC0gMTsgaSA8IEwtPkxhc3QgLSAxOyBpKyspIHsKICAgICAgICBMLT5BW2ldID0gTC0+QVtpICsgMV07CiAgICB9CiAgICBMLT5MYXN0LS07CgogICAgcHJpbnRmKCJ8ICAgIERhIHhvYSBzaW5oIHZpZW4gdGhhbmggY29uZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgcHJpbnRmKCIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgIHByaW50ZigifCAgICBUaG9uZyB0aW4gc2luaCB2aWVuIGRhIHhvYTogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4iKTsKICAgIHByaW50ZigifCAgICBNU1NWICAgICAgOiAlLTU5c3xcbiIsIHN2LmlkKTsKICAgIHByaW50ZigifCAgICBIbyB0ZW4gICAgOiAlLTU5c3xcbiIsIHN2Lm5hbWUpOwogICAgcHJpbnRmKCJ8ICAgIE5nYXkgc2luaCA6ICUtMjdzVHVvaSA6ICUtMTFkICAgICAgICAgICB8XG4iLCBzdi5ucywgc3YudHVvaSk7CiAgICBwcmludGYoIis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PStcbiIpOwp9CgoKIAovLyA9PT09PT09PT09PT09PT09PT0gQ2FjIGNodWMgbmFuZyBtbyByb25nID09PT09PT09PT09PT09PT09PQogCnZvaWQgQ2h1YW5Ib2FuKGNoYXIgc1tdLCBpbnQgc2l6ZSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKICAgICAgICBpZiAoc1tpXSA9PSAnLycpIHsKICAgICAgICAgICAgaWYgKGkgPT0gMSkgeyAKICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBzaXplOyBqID49IDA7IGotLSkgewogICAgICAgICAgICAgICAgICAgIHNbaisxXSA9IHNbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzWzBdID0gJzAnOwogICAgICAgICAgICAgICAgc2l6ZSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzW2krMl0gPT0gJy8nICYmIGkrMiA8IHNpemUpIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSBzaXplOyBrID49IGkrMTsgay0tKSB7CiAgICAgICAgICAgICAgICAgICAgc1trKzFdID0gc1trXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNbaSsxXSA9ICcwJzsKICAgICAgICAgICAgICAgIHNpemUrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQogCmludCBsYU5hbU5odWFuKGludCB5KSB7CiAgICByZXR1cm4gKCAoeSAlIDQwMCA9PSAwKSB8fCAoeSAlIDQgPT0gMCAmJiB5ICUgMTAwICE9IDApICk7Cn0KIAppbnQgc29OZ2F5VHJvbmdUaGFuZyhpbnQgbSwgaW50IHkpIHsKICAgIGlmIChtID09IDEgfHwgbSA9PSAzIHx8IG0gPT0gNSB8fCBtID09IDcgfHwgbSA9PSA4IHx8IG0gPT0gMTAgfHwgbSA9PSAxMikKICAgICAgICByZXR1cm4gMzE7CiAgICBpZiAobSA9PSA0IHx8IG0gPT0gNiB8fCBtID09IDkgfHwgbSA9PSAxMSkKICAgICAgICByZXR1cm4gMzA7CiAgICBpZiAobSA9PSAyKQogICAgICAgIHJldHVybiBsYU5hbU5odWFuKHkpID8gMjkgOiAyODsKICAgIHJldHVybiAwOyAKfQogCnZvaWQgQ2h1YW5Ib2FUZW4oY2hhciAqbmFtZSkgewogICAgY2hhciB0ZW1wWzEwMF07CiAgICBpbnQgaSA9IDAsIGogPSAwOwogICAgaW50IGxlbiA9IHN0cmxlbihuYW1lKTsKIAogICAgd2hpbGUgKGkgPCBsZW4gJiYgbmFtZVtpXSA9PSAnICcpIGkrKzsKICAgIGludCBzcGFjZSA9IDA7IAogICAgd2hpbGUgKGkgPCBsZW4pIHsKICAgICAgICBpZiAobmFtZVtpXSAhPSAnICcpIHsKICAgICAgICAgICAgaWYgKHNwYWNlICYmIGogPiAwKSB7CiAgICAgICAgICAgICAgICB0ZW1wW2orK10gPSAnICc7IAogICAgICAgICAgICAgICAgc3BhY2UgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRlbXBbaisrXSA9IG5hbWVbaV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3BhY2UgPSAxOwogICAgICAgIH0KICAgICAgICBpKys7CiAgICB9CiAKICAgIGlmIChqID4gMCAmJiB0ZW1wW2otMV0gPT0gJyAnKSBqLS07CiAgICB0ZW1wW2pdID0gJ1wwJzsKIAogICAgZm9yIChpID0gMDsgaSA8IGo7IGkrKykgewogICAgICAgIGlmICh0ZW1wW2ldID49ICdBJyAmJiB0ZW1wW2ldIDw9ICdaJykKICAgICAgICAgICAgdGVtcFtpXSA9IHRlbXBbaV0gLSAnQScgKyAnYSc7CiAgICB9CiAKICAgIGludCBuZXdXb3JkID0gMTsKICAgIGZvciAoaSA9IDA7IGkgPCBqOyBpKyspIHsKICAgICAgICBpZiAodGVtcFtpXSA9PSAnICcpIHsKICAgICAgICAgICAgbmV3V29yZCA9IDE7CiAgICAgICAgfSBlbHNlIGlmIChuZXdXb3JkICYmIHRlbXBbaV0gPj0gJ2EnICYmIHRlbXBbaV0gPD0gJ3onKSB7CiAgICAgICAgICAgIHRlbXBbaV0gPSB0ZW1wW2ldIC0gJ2EnICsgJ0EnOwogICAgICAgICAgICBuZXdXb3JkID0gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuZXdXb3JkID0gMDsKICAgICAgICB9CiAgICB9CiAKICAgIHN0cmNweShuYW1lLCB0ZW1wKTsKfQogCnN0cnVjdCBTaW5odmllbiBuaGFwU2luaFZpZW4oTGlzdCBMKSB7CiAgICBzdHJ1Y3QgU2luaHZpZW4gc3Y7CiAgICBwcmludGYoIlxuKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgICBwcmludGYoInwgICAgICAgIE5IQVAgVEhPTkcgVElOIFNJTkggVklFTiBNT0kgICAgIHxcbiIpOwogICAgcHJpbnRmKCIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgcHJpbnRmKCI+PiBOaGFwIE1TVjogIik7CiAgICAgICAgc2NhbmYoIiVzIiwgc3YuaWQpOwogICAgICAgIGlmIChMT0NBVEUoc3YuaWQsIEwpICE9IEVORChMKSkgewogICAgICAgICAgICBwcmludGYoIk1TU1YgZGEgdG9uIHRhaSwgbmhhcCBsYWlcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KIAogCiAgICBpbnQgY2hlY2s7CiAKICAgIGRvIHsKICAgICAgICBjaGVjayA9IDE7IAogICAgICAgIHByaW50ZigiPj4gTmhhcCBobyB0ZW46ICIpOwogICAgICAgIHNjYW5mKCIgJTE5W15cbl0iLCBzdi5uYW1lKTsgCiAKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHN0cmxlbihzdi5uYW1lKTsgaSsrKSB7CiAgICAgICAgICAgIGlmICghKChzdi5uYW1lW2ldID49ICdhJyAmJiBzdi5uYW1lW2ldIDw9ICd6JykgfHwgKHN2Lm5hbWVbaV0gPj0gJ0EnICYmIHN2Lm5hbWVbaV0gPD0gJ1onKSB8fCBzdi5uYW1lW2ldID09ICcgJykpIHsKICAgICAgICAgICAgICAgIGNoZWNrID0gMDsgCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KIAogICAgICAgIGlmIChjaGVjayA9PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiSG8gdmEgdGVuIGtob25nIGNodWEgc28gaG9hYyBreSB0dSBkYWMgYmlldCA6IFxuIik7CiAgICAgICAgfSBlbHNlIHsKIAogICAgICAgICAgICAgQ2h1YW5Ib2FUZW4oc3YubmFtZSk7CiAKICAgICAgICB9CiAgICB9IHdoaWxlIChjaGVjayA9PSAwKTsgCiAKIGRvIHsKICAgIHByaW50ZigiPj4gTmhhcCBuZ2F5IHNpbmggKGRkL21tL3l5eXkpOiAiKTsKICAgIHNjYW5mKCIlcyIsIHN2Lm5zKTsKIAogICAgaW50IHNpemUgPSBzdHJsZW4oc3YubnMpOwogICAgQ2h1YW5Ib2FuKHN2Lm5zLCBzaXplKTsKIAogICAgY2hhciBkYXlbM10sIG1vbnRoWzNdLCB5ZWFyWzVdOwogICAgZGF5WzBdID0gc3YubnNbMF07CiAgICBkYXlbMV0gPSBzdi5uc1sxXTsKICAgIGRheVsyXSA9ICdcMCc7CiAgICBtb250aFswXSA9IHN2Lm5zWzNdOwogICAgbW9udGhbMV0gPSBzdi5uc1s0XTsKICAgIG1vbnRoWzJdID0gJ1wwJzsKICAgIAogICAgaW50IGluZGV4ID0gNjsgIAogICAgZm9yIChpbnQgaSA9IDA7IGkgPCAxOyBpKyspIHsgICAgIAogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgNDsgaisrKSB7ICAKICAgICAgICAgICAgeWVhcltqXSA9IHN2Lm5zW2luZGV4ICsgal07CiAgICAgICAgfQogICAgfQogICAgeWVhcls0XSA9ICdcMCc7IAogCiAgICAKICAgIGludCBkID0gYXRvaShkYXkpOwogICAgaW50IG0gPSBhdG9pKG1vbnRoKTsKICAgIGludCB5ID0gYXRvaSh5ZWFyKTsKICAgIAogCiAgICBpbnQgbWF4ZGF5ID0gc29OZ2F5VHJvbmdUaGFuZyhtLHkpOwogICAgaWYgKGQgPD0gMCB8fCBkID4gbWF4ZGF5IHx8IG0gPD0gMCB8fCBtID4gMTIgfHwgeSA8PSAxMDApIHsKICAgICAgICBwcmludGYoIk5nYXkgc2luaCBraG9uZyBob3AgbGUgdnVpIGxvbmcgbmhhcCBsYWkhXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaW50IG5hbU5vdyA9IDIwMjU7CiAgICAgICAgZG8gewogICAgICAgICAgICBwcmludGYoIj4+IE5oYXAgdHVvaTogIik7CiAgICAgICAgICAgIHNjYW5mKCIlZCIsICZzdi50dW9pKTsKICAgICAgICAgICAgaWYgKHN2LnR1b2kgPCBuYW1Ob3cgLSB5IC0gMiB8fCBzdi50dW9pID4gbmFtTm93IC0geSArIDIpIHsKICAgICAgICAgICAgICAgIHByaW50ZigiVnVpIGxvbmcgbmhhcCBsYWkgdHVvaSBkdW5nIHZvaSB0dW9pIHRoYXQgY3VhIGJhblxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IHdoaWxlIChzdi50dW9pIDwgbmFtTm93IC0geSAtIDIgfHwgc3YudHVvaSA+IG5hbU5vdyAtIHkgKyAyKTsKICAgICAgICBicmVhazsgCiAgICB9Cn0gd2hpbGUgKDEpOwogCiAgICBzdi5zb01vbiA9IDA7IAogICAgc3YuZ3BhID0gMC4wOwogICAgc3RyY3B5KHN2LmhvY0x1YywgIkNodWEgeGVwIGxvYWkiKTsKIAogICAgcmV0dXJuIHN2Owp9CiAKdm9pZCBQUklOVF9MSVNUKExpc3QgTCkgewogICAgaWYgKEwuTGFzdCA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJEYW5oIHNhY2ggcm9uZyFcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KIAogICAgcHJpbnRmKCJcbistLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLStcbiIpOwogICAgcHJpbnRmKCJ8IFNUVCB8IE1TU1YgICAgICAgICB8IEhvIFRlbiAgICAgICAgICAgICAgICAgICAgfCBOZ2F5IFNpbmggICAgfCBUdW9pICB8XG4iKTsKICAgIHByaW50ZigiKy0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLSstLS0tLS0tK1xuIik7CiAKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTC5MYXN0OyBpKyspIHsKICAgICAgICBwcmludGYoInwgJS0zZCB8ICUtMTJzIHwgJS0yNXMgfCAlLTEycyB8ICUtNWQgfFxuIiwKICAgICAgICAgICAgICAgaSsxLCBMLkFbaV0uaWQsIEwuQVtpXS5uYW1lLCBMLkFbaV0ubnMsIEwuQVtpXS50dW9pKTsKICAgIH0KIAogICAgcHJpbnRmKCIrLS0tLS0rLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0rXG4iKTsKfQogCnZvaWQgU09SVF9CWV9OQU1FKExpc3QgKkwpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTC0+TGFzdCAtIDE7IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IEwtPkxhc3Q7IGorKykgewogICAgICAgICAgICBpZiAoc3RyY21wKEwtPkFbaV0ubmFtZSwgTC0+QVtqXS5uYW1lKSA+IDApIHsKICAgICAgICAgICAgICAgIHN0cnVjdCBTaW5odmllbiB0bXAgPSBMLT5BW2ldOwogICAgICAgICAgICAgICAgTC0+QVtpXSA9IEwtPkFbal07CiAgICAgICAgICAgICAgICBMLT5BW2pdID0gdG1wOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcHJpbnRmKCJEYSBzYXAgeGVwIHRoZW8gdGVuXG4iKTsKfQogCnZvaWQgU09SVF9CWV9UVU9JKExpc3QgKkwpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTC0+TGFzdCAtIDE7IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IEwtPkxhc3Q7IGorKykgewogICAgICAgICAgICBpZiAoTC0+QVtpXS50dW9pID4gTC0+QVtqXS50dW9pKSB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gdG1wID0gTC0+QVtpXTsKICAgICAgICAgICAgICAgIEwtPkFbaV0gPSBMLT5BW2pdOwogICAgICAgICAgICAgICAgTC0+QVtqXSA9IHRtcDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHByaW50ZigiRGEgc2FwIHhlcCB0aGVvIHR1b2lcbiIpOwp9Cgp2b2lkIHRoZW1Nb25Ib2MoTW9uSG9jTGlzdCAqZHNNb24pIHsKICAgIGlmIChkc01vbi0+Y291bnQgPj0gTUFYKSB7CiAgICAgICAgcHJpbnRmKCJEYW5oIHNhY2ggbW9uIGhvYyBkYSBkYXkhXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgTW9uSG9jIG1oOwogICAgcHJpbnRmKCI+PiBOaGFwIHRlbiBtb24gaG9jOiAiKTsKICAgIHNjYW5mKCIgJVteXG5dIiwgbWgudGVuTW9uKTsgCiAgICBmb3IgKGludCBpID0gMDsgaSA8IGRzTW9uLT5jb3VudDsgaSsrKSB7CiAgICAgICAgaWYgKHN0cmNtcChkc01vbi0+QVtpXS50ZW5Nb24sIG1oLnRlbk1vbikgPT0gMCkgewogICAgICAgICAgICBwcmludGYoIk1vbiBob2MgZGEgdG9uIHRhaSFcbiIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIGRzTW9uLT5BW2RzTW9uLT5jb3VudCsrXSA9IG1oOwogICAgcHJpbnRmKCJEYSB0aGVtIG1vbiBob2MgdGhhbmggY29uZyFcbiIpOwp9CgpmbG9hdCBkaWVtSGUxMFNhbmdIZTQoZmxvYXQgZGllbTEwKSB7CiAgICBpZiAoZGllbTEwID49IDkuMCkgcmV0dXJuIDQuMDsKICAgIGlmIChkaWVtMTAgPj0gOC41KSByZXR1cm4gMy43OwogICAgaWYgKGRpZW0xMCA+PSA4LjApIHJldHVybiAzLjU7CiAgICBpZiAoZGllbTEwID49IDcuMCkgcmV0dXJuIDMuMDsKICAgIGlmIChkaWVtMTAgPj0gNi41KSByZXR1cm4gMi41OwogICAgaWYgKGRpZW0xMCA+PSA1LjUpIHJldHVybiAyLjA7CiAgICBpZiAoZGllbTEwID49IDUuMCkgcmV0dXJuIDEuNTsKICAgIGlmIChkaWVtMTAgPj0gNC4wKSByZXR1cm4gMS4wOwogICAgcmV0dXJuIDAuMDsKfQoKZmxvYXQgdGluaERpZW1UQjEwKHN0cnVjdCBTaW5odmllbiBzdikgewogICAgaWYgKHN2LnNvTW9uID09IDApIHJldHVybiAwLjA7CiAgICBmbG9hdCB0b25nRGllbSA9IDA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHN2LnNvTW9uOyBpKyspIHsKICAgICAgICB0b25nRGllbSArPSBzdi5kaWVtW2ldOwogICAgfQogICAgcmV0dXJuIHRvbmdEaWVtIC8gc3Yuc29Nb247Cn0KCmZsb2F0IHRpbmhHUEEoc3RydWN0IFNpbmh2aWVuIHN2KSB7CiAgICBpZiAoc3Yuc29Nb24gPT0gMCkgcmV0dXJuIDAuMDsKICAgIGZsb2F0IHRvbmdEaWVtSGU0ID0gMDsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc3Yuc29Nb247IGkrKykgewogICAgICAgIHRvbmdEaWVtSGU0ICs9IGRpZW1IZTEwU2FuZ0hlNChzdi5kaWVtW2ldKTsKICAgIH0KICAgIHJldHVybiB0b25nRGllbUhlNCAvIHN2LnNvTW9uOwp9Cgp2b2lkIHhlcExvYWlIb2NMdWMoZmxvYXQgZ3BhLCBjaGFyICpob2NMdWMpIHsKICAgIGlmIChncGEgPj0gMy42KSB7CiAgICAgICAgc3RyY3B5KGhvY0x1YywgIlh1YXQgc2FjIik7CiAgICB9IGVsc2UgaWYgKGdwYSA+PSAzLjIpIHsKICAgICAgICBzdHJjcHkoaG9jTHVjLCAiR2lvaSIpOwogICAgfSBlbHNlIGlmIChncGEgPj0gMi41KSB7CiAgICAgICAgc3RyY3B5KGhvY0x1YywgIktoYSIpOwogICAgfSBlbHNlIGlmIChncGEgPj0gMi4wKSB7CiAgICAgICAgc3RyY3B5KGhvY0x1YywgIlRydW5nIEJpbmgiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RyY3B5KGhvY0x1YywgIllldSIpOwogICAgfQp9Cgp2b2lkIG5oYXBEaWVtQ2hvU2luaFZpZW4oTGlzdCAqTCwgTW9uSG9jTGlzdCBkc01vbikgewogICAgaWYgKEVNUFRZX0xJU1QoKkwpKSB7CiAgICAgICAgcHJpbnRmKCJEYW5oIHNhY2ggc2luaCB2aWVuIHJvbmchXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGRzTW9uLmNvdW50ID09IDApIHsKICAgICAgICBwcmludGYoIkNodWEgY28gbW9uIGhvYyBuYW8gdHJvbmcgaGUgdGhvbmchXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMLT5MYXN0OyBpKyspIHsKICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gKnN2ID0gJkwtPkFbaV07CiAgICAgICAgcHJpbnRmKCJcbk5oYXAgZGllbSBjaG8gc2luaCB2aWVuOiAlcyAtICVzXG4iLCBzdi0+aWQsIHN2LT5uYW1lKTsKICAgICAgICBzdi0+c29Nb24gPSBkc01vbi5jb3VudDsKCiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBkc01vbi5jb3VudDsgaisrKSB7CiAgICAgICAgICAgIGZsb2F0IGRpZW07CiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIHByaW50ZigiPj4gRGllbSBtb24gJS0yNXM6ICIsIGRzTW9uLkFbal0udGVuTW9uKTsKICAgICAgICAgICAgICAgIHNjYW5mKCIlZiIsICZkaWVtKTsKICAgICAgICAgICAgICAgIGlmIChkaWVtIDwgMCB8fCBkaWVtID4gMTApIHsKICAgICAgICAgICAgICAgICAgICBwcmludGYoIkRpZW0ga2hvbmcgaG9wIGxlISBOaGFwIGxhaSAoMC0xMClcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IHdoaWxlIChkaWVtIDwgMCB8fCBkaWVtID4gMTApOwogICAgICAgICAgICBzdi0+ZGllbVtqXSA9IGRpZW07CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHN2LT5ncGEgPSB0aW5oR1BBKCpzdik7CiAgICAgICAgeGVwTG9haUhvY0x1Yyhzdi0+Z3BhLCBzdi0+aG9jTHVjKTsKICAgIH0KCiAgICBwcmludGYoIlxuTmhhcCBkaWVtIHRoYW5oIGNvbmcgY2hvIHRhdCBjYSBzaW5oIHZpZW4hXG4iKTsKfQoKCnZvaWQgaGllblRoaUtldFF1YUhvY1RhcChMaXN0IEwsIE1vbkhvY0xpc3QgZHNNb24pIHsKICAgIGlmIChMLkxhc3QgPT0gMCkgewogICAgICAgIHByaW50ZigiRGFuaCBzYWNoIHJvbmchXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAKICAgIGlmIChkc01vbi5jb3VudCA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJDaHVhIGNvIG1vbiBob2MgbmFvIGRlIHRpbmggZGllbSFcbiIpOwogICAgICAgIFBSSU5UX0xJU1QoTCk7IAogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBwcmludGYoIlxuKy0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgIHByaW50ZigifCBTVFQgfCBNU1NWICAgICAgICAgfCBIbyBUZW4gICAgICAgICAgICAgICAgICAgIHwgRGllbSBUQiAxMCB8IERpZW0gVEIgNCAgfCBYZXAgTG9haSAgICAgICB8XG4iKTsKICAgIHByaW50ZigiKy0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKCiAgICBmb3IgKGludCBpID0gMDsgaSA8IEwuTGFzdDsgaSsrKSB7CiAgICAgICAgc3RydWN0IFNpbmh2aWVuIHN2ID0gTC5BW2ldOwogICAgICAgIGZsb2F0IGRpZW0xMCA9IHRpbmhEaWVtVEIxMChzdik7CiAgICAgICAgCiAgICAgICAgcHJpbnRmKCJ8ICUtM2QgfCAlLTEycyB8ICUtMjVzIHwgJS0xMC4yZiB8ICUtMTAuMmYgfCAlLTE0cyB8XG4iLAogICAgICAgICAgICAgICBpICsgMSwgc3YuaWQsIHN2Lm5hbWUsIGRpZW0xMCwgc3YuZ3BhLCBzdi5ob2NMdWMpOwogICAgfQoKICAgIHByaW50ZigiKy0tLS0tKy0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKfQoKdm9pZCBTT1JUX0JZX0hPQ0xVQyhMaXN0ICpMKSB7CiAgICBpZiAoTC0+TGFzdCA9PSAwIHx8IEwtPkFbMF0uc29Nb24gPT0gMCkgewogICAgICAgIHByaW50ZigiQ2h1YSBjbyBzaW5oIHZpZW4gaG9hYyBjaHVhIG5oYXAgZGllbSBkZSB4ZXAgbG9haSFcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIAogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMLT5MYXN0IC0gMTsgaSsrKSB7CiAgICAgICAgZm9yIChpbnQgaiA9IGkgKyAxOyBqIDwgTC0+TGFzdDsgaisrKSB7CiAgICAgICAgICAgIGlmIChMLT5BW2ldLmdwYSA8IEwtPkFbal0uZ3BhKSB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gdG1wID0gTC0+QVtpXTsKICAgICAgICAgICAgICAgIEwtPkFbaV0gPSBMLT5BW2pdOwogICAgICAgICAgICAgICAgTC0+QVtqXSA9IHRtcDsKICAgICAgICAgICAgfSAKICAgICAgICAgICAgZWxzZSBpZiAoTC0+QVtpXS5ncGEgPT0gTC0+QVtqXS5ncGEpIHsKICAgICAgICAgICAgICAgIGlmICh0aW5oRGllbVRCMTAoTC0+QVtpXSkgPCB0aW5oRGllbVRCMTAoTC0+QVtqXSkpIHsKICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gdG1wID0gTC0+QVtpXTsKICAgICAgICAgICAgICAgICAgICBMLT5BW2ldID0gTC0+QVtqXTsKICAgICAgICAgICAgICAgICAgICBMLT5BW2pdID0gdG1wOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcHJpbnRmKCJEYSBzYXAgeGVwIGRhbmggc2FjaCBzaW5oIHZpZW4gdGhlbyBIb2MgbHVjIChHUEEpIGdpYW0gZGFuLlxuIik7Cn0KIAogCi8vID09PT09PT09PT09PT09PT09PSBNQUlOID09PT09PT09PT09PT09PT09PQppbnQgbWFpbigpIHsKIAogICAgTGlzdCBMOwogICAgTUFLRU5VTExfTElTVCgmTCk7CiAgICAKICAgIE1vbkhvY0xpc3QgZHNNb247CiAgICBkc01vbi5jb3VudCA9IDA7CiAKIAogCiAgICBpbnQgY2hvaWNlOwogICAgCiAgICAgIHByaW50ZigiXG4rPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKICAgICAgICBwcmludGYoInwgICAgICAgICAgICAgIEhFIFRIT05HIFFVQU4gTFkgU0lOSCBWSUVOICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigiKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICAgICAgcHJpbnRmKCJ8IFsxXSBUaGVtIHNpbmggdmllbiB2YW8gZGFuaCBzYWNoICAgICAgICAgICAgICAgIAkJICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzJdIFhvYSBzaW5oIHZpZW4gdGhlbyBNU1YgICAgICAgICAgICAgICAgICAgIAkJICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzNdIE5oYXAgZGllbSBjaG8gY2FjIHNpbmggdmllbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbNF0gVGltIGtpZW0gc2luaCB2aWVuIHRoZW8gTVNWICAgICAgICAgICAgICAJCQkgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbNV0gU2FwIHhlcCBkYW5oIHNhY2ggdGhlbyB0ZW4gICAgICAgICAgICAgICAgICAgICAgIAkJICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzZdIEluIGRhbmggc2FjaCBzaW5oIHZpZW4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbN10gVGhlbSBtb24gaG9jIG1vaSB2YW8gZGFuaCBzYWNoICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgICAgICAgcHJpbnRmKCJ8IFs4XSBYZW0ga2V0IHF1YSBob2MgdGFwIChEaWVtIFRCIDEwLCBHUEEsIFhlcCBsb2FpKSAgICAgICAgICAgICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzldIFNhcCB4ZXAgZGFuaCBzYWNoIHRoZW8gaG9jIGx1YyAoR1BBKSAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOyAKICAgICAgICBwcmludGYoInwgWzEwXSBDbGVhciBtYW4gaGluaCAoZ2l1IG5ndXllbiBkdSBsaWV1KQkgICAgICAgICAgICAgICAgICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzExXSBDaGluaCBzdWEgZGllbSBzaW5oIHZpZW4gdGhlbyBNU1YgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbMF0gVGhvYXQgY2h1b25nIHRyaW5oICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgICAgICAgcHJpbnRmKCIrPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKICAgIHdoaWxlICgxKSB7CiAgICAgIAogICAgICAgIHByaW50ZigiXG4+PiBOaGFwIGx1YSBjaG9uIGN1YSBiYW46ICIpOwogICAgICAgIHNjYW5mKCIlZCIsICZjaG9pY2UpOwogCiAgICAgICAgaWYgKGNob2ljZSA9PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiRGEgdGhvYXRcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChjaG9pY2UpIHsKICAgICAgICAgICAgY2FzZSAxOiB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gc3YgPSBuaGFwU2luaFZpZW4oTCk7CiAgICAgICAgICAgICAgICBQb3NpdGlvbiBwOwogICAgICAgICAgICAgICAgcHJpbnRmKCJOaGFwIFZpIFRyaSBTaW5oIFZpZW4gTXVvbiBUaGVtIENoZW4gVmFvIChEYXU6IDEsIEN1b2k6IDIpOiAiKTsKICAgICAgICAgICAgICAgIHNjYW5mKCIlZCIsICZwKTsKICAgICAgICAgICAgICAgIGlmKHAgPT0gMSApewogICAgICAgICAgICAgICAgICAgIElOU0VSVF9MSVNUKHN2LCAxLCAmTCk7IAogICAgICAgICAgICAgICAgICAgIHByaW50ZigiVGhlbSBzaW5oIHZpZW4gdmFvIHRoYW5oIGNvbmcuIFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmKHAgPT0gMil7CiAgICAgICAgICAgICAgICAgICAgSU5TRVJUX0xJU1Qoc3YsIEVORChMKSwgJkwpOwogICAgICAgICAgICAgICAgICAgIHByaW50ZigiVGhlbSBzaW5oIHZpZW4gdmFvIHRoYW5oIGNvbmcuIFxuIik7IAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICAgICBwcmludGYoIkx1YSBjaG9uIGtob25nIGhvcCBsZSBcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSAyOiB7CiAgICAgICAgICAgICAgICBjaGFyIGlkWzIwXTsKICAgICAgICAgICAgICAgIHByaW50ZigiXG4rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgICAgICAgICAgICAgIHByaW50ZigifCAgICAgIFhPQSBTSU5IIFZJRU4gVEhFTyBNQSBTSU5IIFZJRU4gICAgfFxuIik7CiAgICAgICAgICAgICAgICBwcmludGYoIistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgICAgICAgICAgICAgcHJpbnRmKCI+PiBOaGFwIE1TViBjYW4geG9hOiAiKTsKICAgICAgICAgICAgICAgIHNjYW5mKCIlcyIsIGlkKTsKICAgICAgICAgICAgICAgIERFTEVURV9CWV9JRChpZCwgJkwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSAzOiB7CiAgICAgICAgICAgICAgICBwcmludGYoIlxuKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgICAgICAgICAgICAgcHJpbnRmKCJ8ICAgICAgICAgIE5IQVAgRElFTSBDSE8gQ0FDIFNJTkggVklFTiAgICAgICAgfFxuIik7CiAgICAgICAgICAgICAgICBwcmludGYoIistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgICAgICAgICAgICAgIG5oYXBEaWVtQ2hvU2luaFZpZW4oJkwsIGRzTW9uKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgNDogewogCiAgICAgICAgICAgICAgICBjaGFyIGlkWzIwXTsKICAgICAgICAgICAgICAgIHByaW50ZigiXG4rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgICAgICAgICAgICAgIHByaW50ZigifCAgICAgICAgVElNIEtJRU0gU0lOSCBWSUVOIFRIRU8gTVNWICAgICAgfFxuIik7CiAgICAgICAgICAgICAgICBwcmludGYoIistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgICAgICAgICAgICAgcHJpbnRmKCI+PiBOaGFwIE1TVjogIik7CiAgICAgICAgICAgICAgICBzY2FuZigiJXMiLCBpZCk7CiAgICAgICAgICAgICAgICBQb3NpdGlvbiBwID0gTE9DQVRFKGlkLCBMKTsKICAgICAgICAgICAgICAgIGlmIChwID09IEVORChMKSkgewogICAgICAgICAgICAgICAgIHByaW50ZigiICAgS2hvbmcgdGltIHRoYXkgc2luaCB2aWVuIGNvIE1TVjogJXNcbiIsIGlkKTsKICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgc3RydWN0IFNpbmh2aWVuIHN2ID0gUkVUUklFVkUocCwgTCk7CiAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIiAgIERhIHRpbSB0aGF5IHNpbmggdmllbiB0cm9uZyBkYW5oIHNhY2ggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4iKTsKICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICAgICAgICAgICAgICAgICAgICBwcmludGYoInwgICBUaG9uZyB0aW4gc2luaCB2aWVuOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJ8ICAgTVNTViAgICAgIDogJS01OXN8XG4iLCBzdi5pZCk7CiAgICAgICAgICAgICAgICAgICAgICBwcmludGYoInwgICBIbyB0ZW4gICAgOiAlLTU5c3xcbiIsIHN2Lm5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJ8ICAgTmdheSBzaW5oIDogJS0yN3NUdW9pIDogJS0xMWQgICAgICAgICAgICAgIHxcbiIsIHN2Lm5zLCBzdi50dW9pKTsKICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIDU6IAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgU09SVF9CWV9OQU1FKCZMKTsKICAgICAgICAgICAgICAgICBQUklOVF9MSVNUKEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgICAgIFBSSU5UX0xJU1QoTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSA3OgogICAgICAgICAgICAgICAgcHJpbnRmKCJcbistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgICAgICAgICAgICAgcHJpbnRmKCJ8ICAgICAgICAgICBUSEVNIE1PTiBIT0MgTU9JICAgICAgICAgICAgICB8XG4iKTsKICAgICAgICAgICAgICAgIHByaW50ZigiKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgICAgICAgICAgICAgICB0aGVtTW9uSG9jKCZkc01vbik7IAogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgODogeyAKICAgICAgICAgICAgICAgIHByaW50ZigiXG4rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgICAgICAgICAgICAgICBwcmludGYoInwgICAgICBLRVQgUVVBIEhPQyBUQVAgQ1VBIFNJTkggVklFTiAgICAgICAgICB8XG4iKTsKICAgICAgICAgICAgICAgIHByaW50ZigiKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgICAgICAgICAgICAgaGllblRoaUtldFF1YUhvY1RhcChMLCBkc01vbik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIDk6IHsgCiAgICAgICAgICAgICAgICBwcmludGYoIlxuKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgICAgICAgICAgICAgcHJpbnRmKCJ8ICAgICAgU0FQIFhFUCBTSU5IIFZJRU4gVEhFTyBIT0MgTFVDICAgICAgICAgfFxuIik7CiAgICAgICAgICAgICAgICBwcmludGYoIistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgICAgICAgICAgICAgIFNPUlRfQllfSE9DTFVDKCZMKTsKICAgICAgICAgICAgICAgIGhpZW5UaGlLZXRRdWFIb2NUYXAoTCwgZHNNb24pOyAKICAgICAgICAgICAgICAgIGJyZWFrOyAgICAKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIDEwOiB7CiAgICAgICAgICAgICAgICAJc3lzdGVtKENMRUFSKTsKICAgCQkJCXByaW50ZigiKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgIAkJCQlwcmludGYoInwgICAgICAgICAgICBIRSBUSE9ORyBRVUFOIExZIFNJTkggVklFTiAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogIAkJCQlwcmludGYoIis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PStcbiIpOwogIAkJCQlwcmludGYoInwgWzFdIFRoZW0gc2luaCB2aWVuIHZhbyBkYW5oIHNhY2ggICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogCQkJCXByaW50ZigifCBbMl0gWG9hIHNpbmggdmllbiB0aGVvIE1TViAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgCQkJCXByaW50ZigifCBbM10gTmhhcCBkaWVtIGNobyBjYWMgc2luaCB2aWVuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgIAkJCQlwcmludGYoInwgWzRdIFRpbSBraWVtIHNpbmggdmllbiB0aGVvIE1TViAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAJCQkJcHJpbnRmKCJ8IFs1XSBTYXAgeGVwIGRhbmggc2FjaCB0aGVvIHRlbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4iKTsKICAJCQkJcHJpbnRmKCJ8IFs2XSBJbiBkYW5oIHNhY2ggc2luaCB2aWVuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4iKTsKICAJCQkgCXByaW50ZigifCBbN10gVGhlbSBtb24gaG9jIG1vaSB2YW8gZGFuaCBzYWNoICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgIAkJCQlwcmludGYoInwgWzhdIFhlbSBrZXQgcXVhIGhvYyB0YXAgKERpZW0gVEIgMTAsIEdQQSwgWGVwIGxvYWkpICAgICAgICAgIHxcbiIpOwogIAkJCSAgICBwcmludGYoInwgWzldIFNhcCB4ZXAgZGFuaCBzYWNoIHRoZW8gaG9jIGx1YyAoR1BBKSAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogIAkJCQlwcmludGYoInwgWzEwXSBDbGVhciBtYW4gaGluaCAoZ2l1IG5ndXllbiBkdSBsaWV1KSAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogIAkJCQlwcmludGYoInwgWzExXSBDaGluaCBzdWEgZGllbSBzaW5oIHZpZW4gdGhlbyBNU1YgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogIAkJCQlwcmludGYoInwgWzBdIFRob2F0IGNodW9uZyB0cmluaCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAJCQkJcHJpbnRmKCIrPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKICAgCQkJCXByaW50ZigiTWFuIGhpbmggZGEgZHVvYyBsYW0gbW9pLlxuIik7CgkJCQlicmVhazsKCQkJfQogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgcHJpbnRmKCJMdWEgY2hvbiBraG9uZyBob3AgbGVcbiIpOwogICAgICAgICAgICBjYXNlIDExOiB7CiAgICBjaGFyIGlkWzIwXTsKICAgIGludCBmb3VuZCA9IDA7CgogICAgcHJpbnRmKCJcbistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgIHByaW50ZigifCAgICAgICBDSElOSCBTVUEgRElFTSBTSU5IIFZJRU4gVEhFTyBNU1YgICAgIHxcbiIpOwogICAgcHJpbnRmKCIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgICBwcmludGYoIj4+IE5oYXAgTVNWIGNhbiBjaGluaCBzdWE6ICIpOwogICAgc2NhbmYoIiVzIiwgaWQpOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTC5MYXN0OyBpKyspIHsKICAgICAgICBpZiAoc3RyY21wKEwuQVtpXS5pZCwgaWQpID09IDApIHsKICAgICAgICAgICAgZm91bmQgPSAxOwogICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gKnN2ID0gJkwuQVtpXTsKICAgICAgICAgICAgcHJpbnRmKCJcblRob25nIHRpbiBzaW5oIHZpZW46XG4iKTsKICAgICAgICAgICAgcHJpbnRmKCJNU1NWOiAlc1xuIiwgc3YtPmlkKTsKICAgICAgICAgICAgcHJpbnRmKCJIbyB0ZW46ICVzXG4iLCBzdi0+bmFtZSk7CiAgICAgICAgICAgIHByaW50ZigiU28gbW9uIGhvYyBoaWVuIGNvOiAlZFxuIiwgc3YtPnNvTW9uKTsKCiAgICAgICAgICAgIGlmIChzdi0+c29Nb24gPT0gMCkgewogICAgICAgICAgICAgICAgcHJpbnRmKCJTaW5oIHZpZW4gY2h1YSBjbyBkaWVtIG1vbiBob2MgbmFvIGRlIGNoaW5oIHN1YSFcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHByaW50ZigiXG5DYWMgZGllbSBoaWVuIHRhaTpcbiIpOwogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IHN2LT5zb01vbjsgaisrKSB7CiAgICAgICAgICAgICAgICBwcmludGYoIiAgTW9uICVkOiAlLjJmXG4iLCBqICsgMSwgc3YtPmRpZW1bal0pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpbnQgbW9uOwogICAgICAgICAgICBwcmludGYoIlxuPj4gTmhhcCB0aHUgdHUgbW9uIG11b24gY2hpbmggc3VhICgxLSVkKTogIiwgc3YtPnNvTW9uKTsKICAgICAgICAgICAgc2NhbmYoIiVkIiwgJm1vbik7CgogICAgICAgICAgICBpZiAobW9uID49IDEgJiYgbW9uIDw9IHN2LT5zb01vbikgewogICAgICAgICAgICAgICAgZmxvYXQgZGllbU1vaTsKICAgICAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICAgICBwcmludGYoIj4+IE5oYXAgZGllbSBtb2kgY2hvIG1vbiAlZCAoMC0xMCk6ICIsIG1vbik7CiAgICAgICAgICAgICAgICAgICAgc2NhbmYoIiVmIiwgJmRpZW1Nb2kpOwogICAgICAgICAgICAgICAgICAgIGlmIChkaWVtTW9pIDwgMCB8fCBkaWVtTW9pID4gMTApCiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiRGllbSBraG9uZyBob3AgbGUsIHZ1aSBsb25nIG5oYXAgbGFpIVxuIik7CiAgICAgICAgICAgICAgICB9IHdoaWxlIChkaWVtTW9pIDwgMCB8fCBkaWVtTW9pID4gMTApOwogICAgICAgICAgICAgICAgc3YtPmRpZW1bbW9uIC0gMV0gPSBkaWVtTW9pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcHJpbnRmKCJTbyB0aHUgdHUgbW9uIGtob25nIGhvcCBsZSFcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEM/cCBuaD90IGw/aSBHUEEgdsOgIGg/YyBsP2MKICAgICAgICAgICAgc3YtPmdwYSA9IHRpbmhHUEEoKnN2KTsKICAgICAgICAgICAgeGVwTG9haUhvY0x1Yyhzdi0+Z3BhLCBzdi0+aG9jTHVjKTsKCiAgICAgICAgICAgIHByaW50ZigiXG5EYSBjYXAgbmhhdCBkaWVtIGNobyBzaW5oIHZpZW4gY28gTVNWICVzLlxuIiwgaWQpOwogICAgICAgICAgICBwcmludGYoIkdQQSBtb2k6ICUuMmYgfCBIb2MgbHVjOiAlc1xuIiwgc3YtPmdwYSwgc3YtPmhvY0x1Yyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIWZvdW5kKQogICAgICAgIHByaW50ZigiXG5LaG9uZyB0aW0gdGhheSBzaW5oIHZpZW4gY28gTVNWICVzIVxuIiwgaWQpOwoKICAgIGJyZWFrOwp9CgogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9Cgo=