/*
_______________________________________
| 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>
#define MAX 100
typedef int Position;
// Cau truc sinh vien
struct Sinhvien {
char id[ 20 ] ;
char name[ 50 ] ;
char ns[ 20 ] ;
int tuoi;
} ;
// Kieu danh sach mang
typedef struct {
struct Sinhvien A[ MAX] ;
int Last;
} List;
// ================== Cac thao tac co ban ==================
// Vi tri dau tien
Position FIRST( List L) {
return 1 ;
}
// Vi tri ket thuc (sau phan tu cuoi)
Position END( List L) {
return L.Last + 1 ;
}
// Vi tri ke tiep
Position NEXT( Position P, List L) {
if ( P < END( L) ) return P + 1 ;
return END( L) ;
}
// Vi tri truoc do
Position PREVIOUS( Position P, List L) {
if ( P > FIRST( L) ) return P - 1 ;
return FIRST( L) ;
}
// Lay phan tu o vi tri P
struct Sinhvien RETRIEVE( Position P, List L) {
return L.A [ P- 1 ] ;
}
// Tim sinh vien theo MSSV
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) ;
}
// Tao danh sach rong
void MAKENULL_LIST( List * L) {
L-> Last = 0 ;
}
// Kiem tra rong
int EMPTY_LIST( List L) {
return L.Last == 0 ;
}
// Chen phan tu vao vi tri P
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++;
}
// Xoa phan tu tai vi tri P
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--;
}
// ================== Cac chuc nang mo rong ==================
// Chuan hoa ngay sinh
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 ;
}
// Nhap thong tin sinh vien moi
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 ;
}
}
scanf ( " %[^\n ]" , sv.
name ) ;
do {
printf ( "Nhap ngay sinh (dd/mm/yyyy): " ) ;
ChuanHoan( sv.ns , size) ;
// printf("%s",sv.ns);
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 ' ;
for ( int i = 6 , j = 0 ; i <= size; i++, j++ ) {
year[ j] = sv.ns [ i] ;
year[ j+ 1 ] = '\0 ' ;
}
// printf("thang: %d \n",m);
// printf("nam: %d \n",y);
int maxday = soNgayTrongThang( m, y) ;
// printf("Ngay max: %d \n",maxday);
if ( d <= 0 || d > maxday || m <= 0 || m > 12 || y <= 100 ) {
printf ( "Ngay sinh khong hop le vui long nhap lai!\n " ) ; } else {
break ;
}
} while ( 1 ) ;
return sv;
}
// In danh sach sinh vien
void PRINT_LIST( List L) {
if ( L.Last == 0 ) {
return ;
}
printf ( "\n +================================================================================+\n " ) ; printf ( "| DANH SACH SINH VIEN |\n " ) ; printf ( "+================================================================================+\n " ) ; printf ( "| %-10s | %-20s | %-12s | %-5s |\n " , "MSV" , "Ho Ten" , "Ngay Sinh" , "Tuoi" ) ; printf ( "+--------------------------------------------------------------------------------+\n " ) ; for ( int i = 0 ; i < L.Last ; i++ ) {
printf ( "%d) MSSV: %s | Ho ten: %s | Ngay sinh: %s | Tuoi: %d\n " , i+ 1 , L.A [ i] .id , L.A [ i] .name , L.A [ i] .ns , L.A [ i] .tuoi ) ;
}
}
// Sap xep theo ten
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 " ) ; }
// Sap xep theo tuoi
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 " ) ; }
// Tim kiem theo ten
void SEARCH_BY_NAME( List L) {
char ten[ 50 ] ;
int found = 0 ;
for ( int i = 0 ; i < L.Last ; i++ ) {
if ( strcmp ( L.
A [ i
] .
name , ten
) == 0 ) { printf ( "MSSV: %s | Ho ten: %s | Ngay sinh: %s | Tuoi: %d\n " , L.A [ i] .id , L.A [ i] .name , L.A [ i] .ns , L.A [ i] .tuoi ) ;
found = 1 ;
}
}
if ( ! found
) printf ( "Khong tim thay sinh vien\n " ) ; }
// ================== MAIN ==================
int main( ) {
char * names[ ] = {
"NGUYEN DUC QUANG" ,
"TRAN MINH QUANG" ,
"LUONG VIET NHAT" ,
"HOANG GIA THE" ,
"NGUYEN TIEN DUNG"
} ;
char * ids[ ] = {
"2411061767" ,
"2411062029" ,
"2411061614" ,
"2411061927" ,
"2411061649"
} ;
int n = 5 ; // so thanh vien
printf ( "+==================================================================================+\n " ) ; printf ( "| BAI TAP LON BAI 7 - QUAN LI SINH VIEN | \n " ) ; printf ( "+==================================================================================+\n " ) ; printf ( "| %-30s | %-20s | |\n " , "THANH VIEN NHOM" , "MA SINH VIEN" ) ; printf ( "+----------------------------------------------------------------------------------+\n " ) ;
for ( int i = 0 ; i < n; i++ ) {
printf ( "| %-30s | :%-19s | | \n " , names
[ i
] , ids
[ i
] ) ; printf ( "+----------------------------------------------------------------------------------+\n " ) ; }
List L;
MAKENULL_LIST( & L) ;
int choice;
while ( 1 ) {
printf ( "\n +=================================================================+\n " ) ; printf ( "| HE THONG QUAN LY SINH VIEN |\n " ) ; printf ( "+=================================================================+\n " ) ; printf ( "| [1] Them sinh vien vao vi tri bat ky (INSERT_LIST) |\n " ) ; printf ( "| [2] Xoa sinh vien tai vi tri (DELETE_LIST) |\n " ) ; printf ( "| [3] Tim kiem sinh vien theo MSSV (LOCATE) |\n " ) ; printf ( "| [4] Xem thong tin theo vi tri (RETRIEVE) |\n " ) ; printf ( "| [5] In danh sach sinh vien (PRINT_LIST) |\n " ) ; printf ( "| [6] Sap xep danh sach theo ten |\n " ) ; printf ( "| [7] Sap xep danh sach theo tuoi |\n " ) ; printf ( "| [8] Tim kiem sinh vien theo ten |\n " ) ; printf ( "| [0] Thoat chuong trinh |\n " ) ; printf ( "+=================================================================+\n " ) ; printf ( ">> Nhap lua chon cua ban: " ) ;
if ( choice == 0 ) {
break ;
}
switch ( choice) {
case 1 : {
struct Sinhvien sv = nhapSinhVien( L) ;
Position p;
printf ( "Nhap vi tri chen (1..%d): " , END
( L
) ) ; INSERT_LIST( sv, p, & L) ;
break ;
}
case 2 : {
Position p;
printf ( "Nhap vi tri muon xoa (1..%d): " , L.
Last ) ; DELETE_LIST( p, & L) ;
break ;
}
case 3 : {
char id[ 20 ] ;
printf ( "\n +-----------------------------------------+\n " ) ; printf ( "| TIM KIEM SINH VIEN THEO MSV |\n " ) ; printf ( "+-----------------------------------------+\n " ) ; printf ( ">> Nhap MSV can tim: " ) ; Position pos = LOCATE( id, L) ;
if ( pos == END( L) ) {
} else {
struct Sinhvien sv = RETRIEVE( pos, L) ;
printf ( "Tim thay MSSV: %s | Ho ten: %s | Ngay sinh: %s | Tuoi: %d\n " , sv.id , sv.name , sv.ns , sv.tuoi ) ;
}
break ;
}
case 4 : {
Position p;
printf ( "\n +-----------------------------------------+\n " ) ; printf ( "| XEM THONG TIN THEO VI TRI |\n " ) ; printf ( "+-----------------------------------------+\n " ) ; if ( p < FIRST( L) || p >= END( L) ) {
printf ( "Vi tri khong hop le\n " ) ; } else {
struct Sinhvien sv = RETRIEVE( p, L) ;
printf ( "Thong tin SV tai vi tri %d: MSSV: %s | Ho ten: %s | Ngay sinh: %s | Tuoi: %d\n " , p, sv.id , sv.name , sv.ns , sv.tuoi ) ;
}
break ;
}
case 5 :
PRINT_LIST( L) ;
break ;
case 6 :
SORT_BY_NAME( & L) ;
break ;
case 7 :
SORT_BY_TUOI( & L) ;
break ;
case 8 :
SEARCH_BY_NAME( L) ;
break ;
default :
printf ( "Lua chon khong hop le\n " ) ; }
}
return 0 ;
}
LyoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCnwgICBUaMOgbmggVmnDqm4gTmjDs20gIHwgICBNw6MgU2luaCBWacOqbiB8CnxfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19ffAp8CU5ndXk/biDDkD9jIFF1YW5nIHwJOjI0MTEwNjE3NjcJICB8CnwJCQkJCQkJCQkgIHwKfAlUcj9uIE1pbmggUXVhbmcJIHwJOjI0MTEwNjIwMjkgICB8CnwJCQkJCQkJCQkgIHwKfAlMdT9uZyBWaT90IE5oP3QJIHwJOjI0MTEwNjE2MTQgICB8CnwJCQkJCQkJCQkgIHwKfAlIb8OgbmcgR2lhIFRoPwkgfAk6MjQxMTA2MTkyNyAgIHwKfAkJCQkJCQkJCSAgfAp8CU5ndXk/biBUaT9uIER1bmcgfAk6MjQxMTA2MTY0OSAgIHwKfF9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX198CiovCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2RlZmluZSBNQVggMTAwCnR5cGVkZWYgaW50IFBvc2l0aW9uOwoKLy8gQ2F1IHRydWMgc2luaCB2aWVuCnN0cnVjdCBTaW5odmllbiB7CiAgICBjaGFyIGlkWzIwXTsKICAgIGNoYXIgbmFtZVs1MF07CiAgICBjaGFyIG5zWzIwXTsKICAgIGludCB0dW9pOwp9OwoKLy8gS2lldSBkYW5oIHNhY2ggbWFuZwp0eXBlZGVmIHN0cnVjdCB7CiAgICBzdHJ1Y3QgU2luaHZpZW4gQVtNQVhdOwogICAgaW50IExhc3Q7IAp9IExpc3Q7CgovLyA9PT09PT09PT09PT09PT09PT0gQ2FjIHRoYW8gdGFjIGNvIGJhbiA9PT09PT09PT09PT09PT09PT0KCi8vIFZpIHRyaSBkYXUgdGllbgpQb3NpdGlvbiBGSVJTVChMaXN0IEwpIHsKICAgIHJldHVybiAxOwp9CgovLyBWaSB0cmkga2V0IHRodWMgKHNhdSBwaGFuIHR1IGN1b2kpClBvc2l0aW9uIEVORChMaXN0IEwpIHsKICAgIHJldHVybiBMLkxhc3QgKyAxOwp9CgovLyBWaSB0cmkga2UgdGllcApQb3NpdGlvbiBORVhUKFBvc2l0aW9uIFAsIExpc3QgTCkgewogICAgaWYgKFAgPCBFTkQoTCkpIHJldHVybiBQICsgMTsKICAgIHJldHVybiBFTkQoTCk7Cn0KCi8vIFZpIHRyaSB0cnVvYyBkbwpQb3NpdGlvbiBQUkVWSU9VUyhQb3NpdGlvbiBQLCBMaXN0IEwpIHsKICAgIGlmIChQID4gRklSU1QoTCkpIHJldHVybiBQIC0gMTsKICAgIHJldHVybiBGSVJTVChMKTsKfQoKLy8gTGF5IHBoYW4gdHUgbyB2aSB0cmkgUApzdHJ1Y3QgU2luaHZpZW4gUkVUUklFVkUoUG9zaXRpb24gUCwgTGlzdCBMKSB7CiAgICByZXR1cm4gTC5BW1AtMV07Cn0KCi8vIFRpbSBzaW5oIHZpZW4gdGhlbyBNU1NWClBvc2l0aW9uIExPQ0FURShjaGFyIGlkW10sIExpc3QgTCkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMLkxhc3Q7IGkrKykgewogICAgICAgIGlmIChzdHJjbXAoTC5BW2ldLmlkLCBpZCkgPT0gMCkKICAgICAgICAgICAgcmV0dXJuIGkrMTsKICAgIH0KICAgIHJldHVybiBFTkQoTCk7Cn0KCi8vIFRhbyBkYW5oIHNhY2ggcm9uZwp2b2lkIE1BS0VOVUxMX0xJU1QoTGlzdCAqTCkgewogICAgTC0+TGFzdCA9IDA7Cn0KCi8vIEtpZW0gdHJhIHJvbmcKaW50IEVNUFRZX0xJU1QoTGlzdCBMKXsKICAgIHJldHVybiBMLkxhc3QgPT0gMDsKfQoKLy8gQ2hlbiBwaGFuIHR1IHZhbyB2aSB0cmkgUAp2b2lkIElOU0VSVF9MSVNUKHN0cnVjdCBTaW5odmllbiB4LCBQb3NpdGlvbiBQLCBMaXN0ICpMKSB7CiAgICBpZiAoTC0+TGFzdCA+PSBNQVgpIHsKICAgICAgICBwcmludGYoIkRhbmggc2FjaCBkYXlcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChQIDwgRklSU1QoKkwpIHx8IFAgPiBFTkQoKkwpKSB7CiAgICAgICAgcHJpbnRmKCJWaSB0cmkga2hvbmcgaG9wIGxlXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmb3IgKGludCBpID0gTC0+TGFzdDsgaSA+PSBQOyBpLS0pIHsKICAgICAgICBMLT5BW2ldID0gTC0+QVtpLTFdOwogICAgfQogICAgTC0+QVtQLTFdID0geDsKICAgIEwtPkxhc3QrKzsKfQoKLy8gWG9hIHBoYW4gdHUgdGFpIHZpIHRyaSBQCnZvaWQgREVMRVRFX0xJU1QoUG9zaXRpb24gUCwgTGlzdCAqTCkgewogICAgaWYgKFAgPCBGSVJTVCgqTCkgfHwgUCA+PSBFTkQoKkwpKSB7CiAgICAgICAgcHJpbnRmKCJWaSB0cmkga2hvbmcgaG9wIGxlXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmb3IgKGludCBpID0gUC0xOyBpIDwgTC0+TGFzdC0xOyBpKyspIHsKICAgICAgICBMLT5BW2ldID0gTC0+QVtpKzFdOwogICAgfQogICAgTC0+TGFzdC0tOwp9CgovLyA9PT09PT09PT09PT09PT09PT0gQ2FjIGNodWMgbmFuZyBtbyByb25nID09PT09PT09PT09PT09PT09PQoKCi8vIENodWFuIGhvYSBuZ2F5IHNpbmgKCnZvaWQgQ2h1YW5Ib2FuKGNoYXIgc1tdLCBpbnQgc2l6ZSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKICAgICAgICBpZiAoc1tpXSA9PSAnLycpIHsKICAgICAgICAgICAgaWYgKGkgPT0gMSkgeyAKICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSBzaXplOyBqID49IDA7IGotLSkgewogICAgICAgICAgICAgICAgICAgIHNbaisxXSA9IHNbal07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzWzBdID0gJzAnOwogICAgICAgICAgICAgICAgc2l6ZSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChzW2krMl0gPT0gJy8nICYmIGkrMiA8IHNpemUpIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSBzaXplOyBrID49IGkrMTsgay0tKSB7CiAgICAgICAgICAgICAgICAgICAgc1trKzFdID0gc1trXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNbaSsxXSA9ICcwJzsKICAgICAgICAgICAgICAgIHNpemUrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKCgppbnQgbGFOYW1OaHVhbihpbnQgeSkgewogICAgcmV0dXJuICggKHkgJSA0MDAgPT0gMCkgfHwgKHkgJSA0ID09IDAgJiYgeSAlIDEwMCAhPSAwKSApOwp9CgppbnQgc29OZ2F5VHJvbmdUaGFuZyhpbnQgbSwgaW50IHkpIHsKICAgIGlmIChtID09IDEgfHwgbSA9PSAzIHx8IG0gPT0gNSB8fCBtID09IDcgfHwgbSA9PSA4IHx8IG0gPT0gMTAgfHwgbSA9PSAxMikKICAgICAgICByZXR1cm4gMzE7CiAgICBpZiAobSA9PSA0IHx8IG0gPT0gNiB8fCBtID09IDkgfHwgbSA9PSAxMSkKICAgICAgICByZXR1cm4gMzA7CiAgICBpZiAobSA9PSAyKQogICAgICAgIHJldHVybiBsYU5hbU5odWFuKHkpID8gMjkgOiAyODsKICAgIHJldHVybiAwOyAKfQoKCgoKCgovLyBOaGFwIHRob25nIHRpbiBzaW5oIHZpZW4gbW9pCnN0cnVjdCBTaW5odmllbiBuaGFwU2luaFZpZW4oTGlzdCBMKSB7CiAgICBzdHJ1Y3QgU2luaHZpZW4gc3Y7CiAgICAgcHJpbnRmKCJcbistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgcHJpbnRmKCJ8ICAgICAgIE5IQVAgVEhPTkcgVElOIFNJTkggVklFTiBNT0kgICAgICB8XG4iKTsKICAgIHByaW50ZigiKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7Cgl3aGlsZSAoMSkgewogICAgICAgIHByaW50ZigiTmhhcCBNU1NWOiAiKTsKICAgICAgICBzY2FuZigiJXMiLCBzdi5pZCk7CiAgICAgICAgaWYgKExPQ0FURShzdi5pZCwgTCkgIT0gRU5EKEwpKSB7CiAgICAgICAgICAgIHByaW50ZigiTVNTViBkYSB0b24gdGFpLCBuaGFwIGxhaVxuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcHJpbnRmKCJOaGFwIGhvIHRlbjogIik7CiAgICBzY2FuZigiICVbXlxuXSIsIHN2Lm5hbWUpOwogICAgCiAgZG8gewogICAgcHJpbnRmKCJOaGFwIG5nYXkgc2luaCAoZGQvbW0veXl5eSk6ICIpOwogICAgc2NhbmYoIiVzIiwgc3YubnMpOwogICAgCiAgICBpbnQgc2l6ZSA9IHN0cmxlbihzdi5ucyk7CiAgICBDaHVhbkhvYW4oc3YubnMsIHNpemUpOwogICAgCi8vICAgIHByaW50ZigiJXMiLHN2Lm5zKTsKCiAgICBjaGFyIGRheVszXSwgbW9udGhbM10sIHllYXJbNV07CgogCiAgICBkYXlbMF0gPSBzdi5uc1swXTsKICAgIGRheVsxXSA9IHN2Lm5zWzFdOwogICAgZGF5WzJdID0gJ1wwJzsKCiAgCiAgICBtb250aFswXSA9IHN2Lm5zWzNdOwogICAgbW9udGhbMV0gPSBzdi5uc1s0XTsKICAgIG1vbnRoWzJdID0gJ1wwJzsKCiAgICBmb3IgKGludCBpID0gNiwgaiA9IDA7IGkgPD0gc2l6ZTsgaSsrLCBqKyspIHsKICAgICAgICB5ZWFyW2pdID0gc3YubnNbaV07CiAgICAgICAgeWVhcltqKzFdID0gJ1wwJzsKICAgIH0KCiAgICBpbnQgZCA9IGF0b2koZGF5KTsKICAgIGludCBtID0gYXRvaShtb250aCk7CiAgICBpbnQgeSA9IGF0b2koeWVhcik7Ci8vICAgIHByaW50ZigidGhhbmc6ICVkIFxuIixtKTsKLy8gICAgcHJpbnRmKCJuYW06ICVkIFxuIix5KTsKICAgIGludCBtYXhkYXkgPSBzb05nYXlUcm9uZ1RoYW5nKG0seSk7Ci8vCXByaW50ZigiTmdheSBtYXg6ICVkIFxuIixtYXhkYXkpOwogICAgaWYgKGQgPD0gMCB8fCBkID4gbWF4ZGF5IHx8IG0gPD0gMCB8fCBtID4gMTIgfHwgeSA8PSAxMDApIHsKICAgICAgICBwcmludGYoIk5nYXkgc2luaCBraG9uZyBob3AgbGUgdnVpIGxvbmcgbmhhcCBsYWkhXG4iKTsKICAgIH0gZWxzZSB7CiAgICAJCiAgICAgICAgYnJlYWs7IAogICAgfQoKfSB3aGlsZSAoMSk7CgogICAgCiAgICAKICAgIHByaW50ZigiTmhhcCB0dW9pOiAiKTsKICAgIHNjYW5mKCIlZCIsICZzdi50dW9pKTsKICAgIHJldHVybiBzdjsKfQoKLy8gSW4gZGFuaCBzYWNoIHNpbmggdmllbgp2b2lkIFBSSU5UX0xJU1QoTGlzdCBMKSB7CiAgICBpZiAoTC5MYXN0ID09IDApIHsKICAgICAgICBwcmludGYoIkRhbmggc2FjaCByb25nXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwcmludGYoIlxuKz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICBwcmludGYoInwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEQU5IIFNBQ0ggU0lOSCBWSUVOICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgcHJpbnRmKCIrPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKICAgIHByaW50ZigifCAlLTEwcyB8ICUtMjBzIHwgJS0xMnMgfCAlLTVzIHxcbiIsICJNU1YiLCAiSG8gVGVuIiwgIk5nYXkgU2luaCIsICJUdW9pIik7CiAgICBwcmludGYoIistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBMLkxhc3Q7IGkrKykgewogICAgICAgIHByaW50ZigiJWQpIE1TU1Y6ICVzIHwgSG8gdGVuOiAlcyB8IE5nYXkgc2luaDogJXMgfCBUdW9pOiAlZFxuIiwKICAgICAgICAgICAgICAgaSsxLCBMLkFbaV0uaWQsIEwuQVtpXS5uYW1lLCBMLkFbaV0ubnMsIEwuQVtpXS50dW9pKTsKICAgIH0KfQoKLy8gU2FwIHhlcCB0aGVvIHRlbgp2b2lkIFNPUlRfQllfTkFNRShMaXN0ICpMKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IEwtPkxhc3QgLSAxOyBpKyspIHsKICAgICAgICBmb3IgKGludCBqID0gaSArIDE7IGogPCBMLT5MYXN0OyBqKyspIHsKICAgICAgICAgICAgaWYgKHN0cmNtcChMLT5BW2ldLm5hbWUsIEwtPkFbal0ubmFtZSkgPiAwKSB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gdG1wID0gTC0+QVtpXTsKICAgICAgICAgICAgICAgIEwtPkFbaV0gPSBMLT5BW2pdOwogICAgICAgICAgICAgICAgTC0+QVtqXSA9IHRtcDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHByaW50ZigiRGEgc2FwIHhlcCB0aGVvIHRlblxuIik7Cn0KCi8vIFNhcCB4ZXAgdGhlbyB0dW9pCnZvaWQgU09SVF9CWV9UVU9JKExpc3QgKkwpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTC0+TGFzdCAtIDE7IGkrKykgewogICAgICAgIGZvciAoaW50IGogPSBpICsgMTsgaiA8IEwtPkxhc3Q7IGorKykgewogICAgICAgICAgICBpZiAoTC0+QVtpXS50dW9pID4gTC0+QVtqXS50dW9pKSB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gdG1wID0gTC0+QVtpXTsKICAgICAgICAgICAgICAgIEwtPkFbaV0gPSBMLT5BW2pdOwogICAgICAgICAgICAgICAgTC0+QVtqXSA9IHRtcDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHByaW50ZigiRGEgc2FwIHhlcCB0aGVvIHR1b2lcbiIpOwp9CgovLyBUaW0ga2llbSB0aGVvIHRlbgp2b2lkIFNFQVJDSF9CWV9OQU1FKExpc3QgTCkgewogICAgY2hhciB0ZW5bNTBdOwogICAgaW50IGZvdW5kID0gMDsKICAgIHByaW50ZigiTmhhcCB0ZW4gY2FuIHRpbTogIik7CiAgICBzY2FuZigiICVbXlxuXSIsIHRlbik7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IEwuTGFzdDsgaSsrKSB7CiAgICAgICAgaWYgKHN0cmNtcChMLkFbaV0ubmFtZSwgdGVuKSA9PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiTVNTVjogJXMgfCBIbyB0ZW46ICVzIHwgTmdheSBzaW5oOiAlcyB8IFR1b2k6ICVkXG4iLAogICAgICAgICAgICAgICAgICAgTC5BW2ldLmlkLCBMLkFbaV0ubmFtZSwgTC5BW2ldLm5zLCBMLkFbaV0udHVvaSk7CiAgICAgICAgICAgIGZvdW5kID0gMTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoIWZvdW5kKSBwcmludGYoIktob25nIHRpbSB0aGF5IHNpbmggdmllblxuIik7Cn0KCi8vID09PT09PT09PT09PT09PT09PSBNQUlOID09PT09PT09PT09PT09PT09PQppbnQgbWFpbigpIHsKCQogIGNoYXIgKm5hbWVzW10gPSB7CiAgICAgICAgIk5HVVlFTiBEVUMgUVVBTkciLAogICAgICAgICJUUkFOIE1JTkggUVVBTkciLAogICAgICAgICJMVU9ORyBWSUVUIE5IQVQiLAogICAgICAgICJIT0FORyBHSUEgVEhFIiwKICAgICAgICAiTkdVWUVOIFRJRU4gRFVORyIKICAgIH07CgogICAgY2hhciAqaWRzW10gPSB7CiAgICAgICAgIjI0MTEwNjE3NjciLAogICAgICAgICIyNDExMDYyMDI5IiwKICAgICAgICAiMjQxMTA2MTYxNCIsCiAgICAgICAgIjI0MTEwNjE5MjciLAogICAgICAgICIyNDExMDYxNjQ5IgogICAgfTsKCiAgICBpbnQgbiA9IDU7IC8vIHNvIHRoYW5oIHZpZW4KCiAgICBwcmludGYoIis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICBwcmludGYoInwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCQUkgVEFQIExPTiBCQUkgNyAtIFFVQU4gTEkgU0lOSCBWSUVOICAgICAgICAgICAgICAgfCAgICBcbiIpOwogICAgcHJpbnRmKCJ8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgXG4iKTsKICAgIHByaW50ZigifCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT1A6IERIMTRDNCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIFxuIik7CiAgICBwcmludGYoIis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09K1xuIik7CiAgICBwcmludGYoInwgICAgICAgICAgICAgICAlLTMwcyB8ICUtMjBzIHwgICAgICAgICAgICB8XG4iLCAiVEhBTkggVklFTiBOSE9NIiwgIk1BIFNJTkggVklFTiIpOwogICAgcHJpbnRmKCIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICBwcmludGYoInwgICAgICAgICAgICAgICAlLTMwcyB8IDolLTE5cyB8ICAgICAgICAgICAgfCBcbiIsIG5hbWVzW2ldLCBpZHNbaV0pOwogICAgcHJpbnRmKCIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiIpOwogICAgfQoJCgkKCQoJCgkKCQoJCgkKCQoJCgkKCQogICAgTGlzdCBMOwogICAgTUFLRU5VTExfTElTVCgmTCk7CiAgICAgICAgaW50IGNob2ljZTsKICAgIHdoaWxlICgxKSB7CiAgICAgICAgcHJpbnRmKCJcbis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PStcbiIpOwogICAgICAgIHByaW50ZigifCAgICAgICAgICAgICAgICAgICAgIEhFIFRIT05HIFFVQU4gTFkgU0lOSCBWSUVOICAgICAgICAgICAgICAgICAgfFxuIik7CiAgICAgICAgcHJpbnRmKCIrPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0rXG4iKTsKICAgICAgICBwcmludGYoInwgWzFdIFRoZW0gc2luaCB2aWVuIHZhbyB2aSB0cmkgYmF0IGt5IChJTlNFUlRfTElTVCkgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbMl0gWG9hIHNpbmggdmllbiB0YWkgdmkgdHJpIChERUxFVEVfTElTVCkgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgICAgICAgcHJpbnRmKCJ8IFszXSBUaW0ga2llbSBzaW5oIHZpZW4gdGhlbyBNU1NWIChMT0NBVEUpICAgICAgICAgICAgICAgICAgICAgICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzRdIFhlbSB0aG9uZyB0aW4gdGhlbyB2aSB0cmkgKFJFVFJJRVZFKSAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbNV0gSW4gZGFuaCBzYWNoIHNpbmggdmllbiAoUFJJTlRfTElTVCkgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgICAgICAgcHJpbnRmKCJ8IFs2XSBTYXAgeGVwIGRhbmggc2FjaCB0aGVvIHRlbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4iKTsKICAgICAgICBwcmludGYoInwgWzddIFNhcCB4ZXAgZGFuaCBzYWNoIHRoZW8gdHVvaSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiIpOwogICAgICAgIHByaW50ZigifCBbOF0gVGltIGtpZW0gc2luaCB2aWVuIHRoZW8gdGVuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuIik7CiAgICAgICAgcHJpbnRmKCJ8IFswXSBUaG9hdCBjaHVvbmcgdHJpbmggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4iKTsKICAgICAgICBwcmludGYoIis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PStcbiIpOwogICAgICAgIHByaW50ZigiPj4gTmhhcCBsdWEgY2hvbiBjdWEgYmFuOiAiKTsKICAgICAgICBzY2FuZigiJWQiLCAmY2hvaWNlKTsKCiAgICAgICAgaWYgKGNob2ljZSA9PSAwKSB7CiAgICAgICAgICAgIHByaW50ZigiRGEgdGhvYXRcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgc3dpdGNoIChjaG9pY2UpIHsKICAgICAgICAgICAgY2FzZSAxOiB7CiAgICAgICAgICAgICAgICBzdHJ1Y3QgU2luaHZpZW4gc3YgPSBuaGFwU2luaFZpZW4oTCk7CiAgICAgICAgICAgICAgICBQb3NpdGlvbiBwOwogICAgICAgICAgICAgICAgcHJpbnRmKCJOaGFwIHZpIHRyaSBjaGVuICgxLi4lZCk6ICIsIEVORChMKSk7CiAgICAgICAgICAgICAgICBzY2FuZigiJWQiLCAmcCk7CiAgICAgICAgICAgICAgICBJTlNFUlRfTElTVChzdiwgcCwgJkwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSAyOiB7CiAgICAgICAgICAgICAgICBQb3NpdGlvbiBwOwogICAgICAgICAgICAgICAgcHJpbnRmKCJOaGFwIHZpIHRyaSBtdW9uIHhvYSAoMS4uJWQpOiAiLCBMLkxhc3QpOwogICAgICAgICAgICAgICAgc2NhbmYoIiVkIiwgJnApOwogICAgICAgICAgICAgICAgREVMRVRFX0xJU1QocCwgJkwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSAzOiB7CiAgICAgICAgICAgICAgICBjaGFyIGlkWzIwXTsKICAgICAgICAgICAgICAgIHByaW50ZigiXG4rLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgCQkJIAlwcmludGYoInwgICAgICAgICBUSU0gS0lFTSBTSU5IIFZJRU4gVEhFTyBNU1YgICAgICB8XG4iKTsKICAgCQkJCXByaW50ZigiKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgIAkJCQlwcmludGYoIj4+IE5oYXAgTVNWIGNhbiB0aW06ICIpOwogICAgICAgICAgICAgICAgc2NhbmYoIiVzIiwgaWQpOwogICAgICAgICAgICAgICAgUG9zaXRpb24gcG9zID0gTE9DQVRFKGlkLCBMKTsKICAgICAgICAgICAgICAgIGlmIChwb3MgPT0gRU5EKEwpKSB7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJLaG9uZyB0aW0gdGhheVxuIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN0cnVjdCBTaW5odmllbiBzdiA9IFJFVFJJRVZFKHBvcywgTCk7CiAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCJUaW0gdGhheSBNU1NWOiAlcyB8IEhvIHRlbjogJXMgfCBOZ2F5IHNpbmg6ICVzIHwgVHVvaTogJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN2LmlkLCBzdi5uYW1lLCBzdi5ucywgc3YudHVvaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIDQ6IHsKICAgICAgICAgICAgICAgIFBvc2l0aW9uIHA7CiAgICAgICAgICAgICAgICBwcmludGYoIlxuKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuIik7CiAgICAgICAgICAgICAgICBwcmludGYoInwgICAgICAgIFhFTSBUSE9ORyBUSU4gVEhFTyBWSSBUUkkgICAgICAgIHxcbiIpOwogICAgICAgICAgICAgICAgcHJpbnRmKCIrLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4iKTsKICAgICAgICAgICAgICAgIHByaW50ZigiTmhhcCB2aSB0cmk6ICIpOwogICAgICAgICAgICAgICAgc2NhbmYoIiVkIiwgJnApOwogICAgICAgICAgICAgICAgaWYgKHAgPCBGSVJTVChMKSB8fCBwID49IEVORChMKSkgewogICAgICAgICAgICAgICAgICAgIHByaW50ZigiVmkgdHJpIGtob25nIGhvcCBsZVxuIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHN0cnVjdCBTaW5odmllbiBzdiA9IFJFVFJJRVZFKHAsIEwpOwogICAgICAgICAgICAgICAgICAgIHByaW50ZigiVGhvbmcgdGluIFNWIHRhaSB2aSB0cmkgJWQ6IE1TU1Y6ICVzIHwgSG8gdGVuOiAlcyB8IE5nYXkgc2luaDogJXMgfCBUdW9pOiAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcCwgc3YuaWQsIHN2Lm5hbWUsIHN2Lm5zLCBzdi50dW9pKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgNToKICAgICAgICAgICAgICAgIFBSSU5UX0xJU1QoTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICAgICAgU09SVF9CWV9OQU1FKCZMKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDc6CiAgICAgICAgICAgICAgICBTT1JUX0JZX1RVT0koJkwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgICAgIFNFQVJDSF9CWV9OQU1FKEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBwcmludGYoIkx1YSBjaG9uIGtob25nIGhvcCBsZVxuIik7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAwOwp9