From 23255e9121ee5cfb8ea8ad5e4e7c8eb484fe5848 Mon Sep 17 00:00:00 2001 From: krosh Date: Sun, 13 Apr 2025 21:48:15 +0300 Subject: [PATCH] init commit --- .clang-format | 34 + .gitignore | 3 + 3sem/cnts/contest1/02.c | 53 + 3sem/cnts/contest1/03.c | 80 ++ 3sem/cnts/contest1/05.c | 78 ++ 3sem/cnts/contest1/test.c | 51 + 3sem/cnts/contest10/t1/ans1 | 3 + 3sem/cnts/contest10/t1/cJSON.c | 1129 +++++++++++++++++ 3sem/cnts/contest10/t1/cJSON.h | 133 ++ 3sem/cnts/contest10/t1/gdb command | 12 + 3sem/cnts/contest10/t1/gdb command copy | 12 + 3sem/cnts/contest10/t1/gdb-1-task.tar | Bin 0 -> 31232 bytes .../t1/gdb-1-task.tarZone.Identifier | 4 + 3sem/cnts/contest10/t1/task1 | Bin 0 -> 39456 bytes 3sem/cnts/contest10/t1/task1.c | 27 + 3sem/cnts/contest10/t2/cJSON.c | 1126 ++++++++++++++++ 3sem/cnts/contest10/t2/cJSON.h | 133 ++ 3sem/cnts/contest10/t2/gdb-2-task.tar | Bin 0 -> 32256 bytes .../t2/gdb-2-task.tarZone.Identifier | 4 + 3sem/cnts/contest10/t2/task2 | Bin 0 -> 39704 bytes 3sem/cnts/contest10/t2/task2.c | 30 + 3sem/cnts/contest10/t2/task2.out | 1 + 3sem/cnts/contest11/01.c | 22 + 3sem/cnts/contest11/01_ans.c | 1 + 3sem/cnts/contest11/02.c | 35 + 3sem/cnts/contest11/03.c | 39 + 3sem/cnts/contest11/04 | 1 + 3sem/cnts/contest11/04.c | 38 + 3sem/cnts/contest11/05 | 1 + 3sem/cnts/contest11/05.c | 43 + 3sem/cnts/contest12/01.c | 47 + 3sem/cnts/contest12/02-ai.c | 47 + 3sem/cnts/contest12/02.c | 36 + 3sem/cnts/contest12/03.c | 59 + 3sem/cnts/contest12/04.c | 89 ++ 3sem/cnts/contest13/01.c | 74 ++ 3sem/cnts/contest13/03.c | 92 ++ 3sem/cnts/contest13/04.c | 71 ++ 3sem/cnts/contest13/05.c | 73 ++ 3sem/cnts/contest14/01.c | 35 + 3sem/cnts/contest14/02.c | 51 + 3sem/cnts/contest14/04.c | 68 + 3sem/cnts/contest14/04a.c | 75 ++ 3sem/cnts/contest14/05.c | 72 ++ 3sem/cnts/contest14/t1.c | 34 + 3sem/cnts/contest2/01.c | 27 + 3sem/cnts/contest2/02.c | 41 + 3sem/cnts/contest2/03.c | 39 + 3sem/cnts/contest2/04.c | 22 + 3sem/cnts/contest3/04.c | 19 + 3sem/cnts/contest3/05.c | 45 + 3sem/cnts/contest4/01.c | 59 + 3sem/cnts/contest4/02.c | 91 ++ 3sem/cnts/contest4/03-test.c | 93 ++ 3sem/cnts/contest4/03.c | 118 ++ 3sem/cnts/contest4/04-copy.c | 98 ++ 3sem/cnts/contest4/04-test.c | 102 ++ 3sem/cnts/contest4/04.c | 104 ++ 3sem/cnts/contest4/04cc.c | 78 ++ 3sem/cnts/contest4/05.c | 68 + 3sem/cnts/contest4/test.c | 72 ++ 3sem/cnts/contest4/test.py | 32 + 3sem/cnts/contest5/01.c | 31 + 3sem/cnts/contest5/02.c | 32 + 3sem/cnts/contest5/03.c | 36 + 3sem/cnts/contest5/04.c | 92 ++ 3sem/cnts/contest5/05-old.c | 99 ++ 3sem/cnts/contest5/05.c | 99 ++ 3sem/cnts/contest6/01.c | 55 + 3sem/cnts/contest6/02-t.c | 68 + 3sem/cnts/contest6/02-ttt.c | 110 ++ 3sem/cnts/contest6/02.c | 114 ++ 3sem/cnts/contest6/03.c | 36 + 3sem/cnts/contest6/04.c | 119 ++ 3sem/cnts/contest7/01-old.c | 56 + 3sem/cnts/contest7/01-test.c | 98 ++ 3sem/cnts/contest7/01.c | 90 ++ 3sem/cnts/contest7/02.c | 54 + 3sem/cnts/contest7/03.c | 67 + 3sem/cnts/contest7/04.c | 0 3sem/cnts/contest7/05.c | 104 ++ 3sem/cnts/contest7/input | 20 + 3sem/exam/2019/1 | 32 + 3sem/exam/2019/2 | 9 + 3sem/exam/2021/1.c | 21 + 3sem/exam/2021/2-wrong.c | 55 + 3sem/exam/2021/2.c | 43 + 3sem/exam/2021/3 | 35 + 3sem/exam/2021/4 | 42 + 3sem/exam/a.execute | 1 + 3sem/exam/a.out | Bin 0 -> 16440 bytes 3sem/exam/bitmas.c | 54 + 3sem/exam/prog-tmp.c | 24 + 3sem/exam/prog.c | 42 + 3sem/exam/raid.c | 43 + 3sem/exam/raid4.c | 33 + 3sem/exam/sem2.c | 24 + 3sem/exam/sem3.c | 38 + 3sem/kr/001.c | 54 + 3sem/kr/002.c | 41 + 3sem/kr/01.c | 39 + 3sem/kr/02.c | 34 + 3sem/kr/03.c | 33 + 3sem/kr/signal.c | 13 + 3sem/kr16/01-ai.c | 20 + 3sem/kr16/01.c | 22 + 3sem/kr16/02.c | 38 + 3sem/kr16/04.c | 65 + 3sem/seminars/l10/01.c | 30 + 3sem/seminars/l10/02.c | 39 + 3sem/seminars/l10/03.c | 63 + 3sem/seminars/l11/01-2.c | 56 + 3sem/seminars/l11/01.c | 64 + 3sem/seminars/l11/02.c | 25 + 3sem/seminars/l3/01.c | 40 + 3sem/seminars/l3/02.c | 52 + 3sem/seminars/l3/03.с | 27 + 3sem/seminars/l3/04.c | 35 + 3sem/seminars/l3/in | Bin 0 -> 16 bytes 3sem/seminars/l3/out | 1 + 3sem/seminars/l4/01.c | 51 + 3sem/seminars/l4/02.c | 76 ++ 3sem/seminars/l4/03.c | 39 + 3sem/seminars/l5/01.c | 37 + 3sem/seminars/l5/02.c | 42 + 3sem/seminars/l5/03.c | 66 + 3sem/seminars/l6/01.c | 50 + 3sem/seminars/l6/02.c | 33 + 3sem/seminars/l6/03.c | 45 + 3sem/seminars/l6/04.c | 47 + 3sem/seminars/l7/01.c | 27 + 3sem/seminars/l7/02.c | 29 + 3sem/seminars/l8/01-1.c | 62 + 3sem/seminars/l8/01.c | 58 + 3sem/seminars/l8/02.c | 52 + 3sem/seminars/l8/03.c | 61 + 3sem/seminars/l9/01.c | 52 + 3sem/seminars/l9/02.c | 41 + 3sem/seminars/l9/03.c | 37 + 3sem/seminars/l9/04.c | 16 + 3sem/seminars/l9/in_01 | 3 + 3sem/templates.c | 171 +++ compile.sh | 25 + contests/1contest/1.cpp | 14 + contests/1contest/2.cpp | 27 + contests/1contest/3.cpp | 36 + contests/1contest/4 copy.cpp | 33 + contests/1contest/4.cpp | 19 + contests/2contest/1.cpp | 12 + contests/2contest/2.cpp | 42 + contests/2contest/4.cpp | 28 + contests/2contest/5.cpp | 56 + contests/3contest/1.cpp | 81 ++ contests/3contest/4.cpp | 33 + contests/4contest/1.cpp | 15 + contests/4contest/2.cpp | 35 + contests/4contest/3.cpp | 22 + contests/5contest/1.cpp | 36 + contests/5contest/2.cpp | 28 + contests/5contest/3.cpp | 0 contests/5contest/4.cpp | 26 + contests/5contest/5.cpp | 26 + contests/6contest/1.cpp | 21 + contests/6contest/2.cpp | 16 + contests/6contest/3.cpp | 0 contests/6contest/5.cpp | 19 + contests/7contest/1.cpp | 5 + contests/7contest/2.cpp | 58 + contests/7contest/5.cpp | 36 + contests/8contest/1.cpp | 30 + contests/8contest/2.cpp | 60 + contests/8contest/3.cpp | 91 ++ lectures/BlackHole.cpp | 165 +++ lectures/Count copy.cpp | 105 ++ lectures/Count.cpp | 117 ++ lectures/DataBuffer-Data.cpp | 110 ++ lectures/Reverse.cpp | 45 + lectures/Sort copy.cpp | 81 ++ lectures/Sort.cpp | 90 ++ lectures/Tree.cpp | 137 ++ lectures/Vector.cpp | 69 + lectures/t.cpp | 72 ++ seminars/1.md | 221 ++++ seminars/2.md | 204 +++ seminars/3.md | 259 ++++ seminars/4.md | 180 +++ seminars/4.pdf | Bin 0 -> 88196 bytes seminars/5.md | 61 + seminars/6.md | 187 +++ seminars/codes/1.cpp | 66 + seminars/codes/4.cpp | 96 ++ seminars/markdown-cheat-sheet.md | 119 ++ 192 files changed, 12200 insertions(+) create mode 100755 .clang-format create mode 100644 .gitignore create mode 100755 3sem/cnts/contest1/02.c create mode 100755 3sem/cnts/contest1/03.c create mode 100755 3sem/cnts/contest1/05.c create mode 100755 3sem/cnts/contest1/test.c create mode 100755 3sem/cnts/contest10/t1/ans1 create mode 100755 3sem/cnts/contest10/t1/cJSON.c create mode 100755 3sem/cnts/contest10/t1/cJSON.h create mode 100755 3sem/cnts/contest10/t1/gdb command create mode 100755 3sem/cnts/contest10/t1/gdb command copy create mode 100755 3sem/cnts/contest10/t1/gdb-1-task.tar create mode 100755 3sem/cnts/contest10/t1/gdb-1-task.tarZone.Identifier create mode 100755 3sem/cnts/contest10/t1/task1 create mode 100755 3sem/cnts/contest10/t1/task1.c create mode 100755 3sem/cnts/contest10/t2/cJSON.c create mode 100755 3sem/cnts/contest10/t2/cJSON.h create mode 100755 3sem/cnts/contest10/t2/gdb-2-task.tar create mode 100755 3sem/cnts/contest10/t2/gdb-2-task.tarZone.Identifier create mode 100755 3sem/cnts/contest10/t2/task2 create mode 100755 3sem/cnts/contest10/t2/task2.c create mode 100755 3sem/cnts/contest10/t2/task2.out create mode 100755 3sem/cnts/contest11/01.c create mode 100755 3sem/cnts/contest11/01_ans.c create mode 100755 3sem/cnts/contest11/02.c create mode 100755 3sem/cnts/contest11/03.c create mode 100755 3sem/cnts/contest11/04 create mode 100755 3sem/cnts/contest11/04.c create mode 100755 3sem/cnts/contest11/05 create mode 100755 3sem/cnts/contest11/05.c create mode 100755 3sem/cnts/contest12/01.c create mode 100755 3sem/cnts/contest12/02-ai.c create mode 100755 3sem/cnts/contest12/02.c create mode 100755 3sem/cnts/contest12/03.c create mode 100755 3sem/cnts/contest12/04.c create mode 100755 3sem/cnts/contest13/01.c create mode 100755 3sem/cnts/contest13/03.c create mode 100755 3sem/cnts/contest13/04.c create mode 100755 3sem/cnts/contest13/05.c create mode 100755 3sem/cnts/contest14/01.c create mode 100755 3sem/cnts/contest14/02.c create mode 100755 3sem/cnts/contest14/04.c create mode 100755 3sem/cnts/contest14/04a.c create mode 100755 3sem/cnts/contest14/05.c create mode 100755 3sem/cnts/contest14/t1.c create mode 100755 3sem/cnts/contest2/01.c create mode 100755 3sem/cnts/contest2/02.c create mode 100755 3sem/cnts/contest2/03.c create mode 100755 3sem/cnts/contest2/04.c create mode 100755 3sem/cnts/contest3/04.c create mode 100755 3sem/cnts/contest3/05.c create mode 100755 3sem/cnts/contest4/01.c create mode 100755 3sem/cnts/contest4/02.c create mode 100755 3sem/cnts/contest4/03-test.c create mode 100755 3sem/cnts/contest4/03.c create mode 100755 3sem/cnts/contest4/04-copy.c create mode 100755 3sem/cnts/contest4/04-test.c create mode 100755 3sem/cnts/contest4/04.c create mode 100755 3sem/cnts/contest4/04cc.c create mode 100755 3sem/cnts/contest4/05.c create mode 100755 3sem/cnts/contest4/test.c create mode 100755 3sem/cnts/contest4/test.py create mode 100755 3sem/cnts/contest5/01.c create mode 100755 3sem/cnts/contest5/02.c create mode 100755 3sem/cnts/contest5/03.c create mode 100755 3sem/cnts/contest5/04.c create mode 100755 3sem/cnts/contest5/05-old.c create mode 100755 3sem/cnts/contest5/05.c create mode 100755 3sem/cnts/contest6/01.c create mode 100755 3sem/cnts/contest6/02-t.c create mode 100755 3sem/cnts/contest6/02-ttt.c create mode 100755 3sem/cnts/contest6/02.c create mode 100755 3sem/cnts/contest6/03.c create mode 100755 3sem/cnts/contest6/04.c create mode 100755 3sem/cnts/contest7/01-old.c create mode 100755 3sem/cnts/contest7/01-test.c create mode 100755 3sem/cnts/contest7/01.c create mode 100755 3sem/cnts/contest7/02.c create mode 100755 3sem/cnts/contest7/03.c create mode 100755 3sem/cnts/contest7/04.c create mode 100755 3sem/cnts/contest7/05.c create mode 100755 3sem/cnts/contest7/input create mode 100755 3sem/exam/2019/1 create mode 100755 3sem/exam/2019/2 create mode 100755 3sem/exam/2021/1.c create mode 100755 3sem/exam/2021/2-wrong.c create mode 100755 3sem/exam/2021/2.c create mode 100755 3sem/exam/2021/3 create mode 100755 3sem/exam/2021/4 create mode 100755 3sem/exam/a.execute create mode 100755 3sem/exam/a.out create mode 100755 3sem/exam/bitmas.c create mode 100755 3sem/exam/prog-tmp.c create mode 100755 3sem/exam/prog.c create mode 100755 3sem/exam/raid.c create mode 100755 3sem/exam/raid4.c create mode 100755 3sem/exam/sem2.c create mode 100755 3sem/exam/sem3.c create mode 100755 3sem/kr/001.c create mode 100755 3sem/kr/002.c create mode 100755 3sem/kr/01.c create mode 100755 3sem/kr/02.c create mode 100755 3sem/kr/03.c create mode 100755 3sem/kr/signal.c create mode 100755 3sem/kr16/01-ai.c create mode 100755 3sem/kr16/01.c create mode 100755 3sem/kr16/02.c create mode 100755 3sem/kr16/04.c create mode 100755 3sem/seminars/l10/01.c create mode 100755 3sem/seminars/l10/02.c create mode 100755 3sem/seminars/l10/03.c create mode 100755 3sem/seminars/l11/01-2.c create mode 100755 3sem/seminars/l11/01.c create mode 100755 3sem/seminars/l11/02.c create mode 100755 3sem/seminars/l3/01.c create mode 100755 3sem/seminars/l3/02.c create mode 100755 3sem/seminars/l3/03.с create mode 100755 3sem/seminars/l3/04.c create mode 100755 3sem/seminars/l3/in create mode 100755 3sem/seminars/l3/out create mode 100755 3sem/seminars/l4/01.c create mode 100755 3sem/seminars/l4/02.c create mode 100755 3sem/seminars/l4/03.c create mode 100755 3sem/seminars/l5/01.c create mode 100755 3sem/seminars/l5/02.c create mode 100755 3sem/seminars/l5/03.c create mode 100755 3sem/seminars/l6/01.c create mode 100755 3sem/seminars/l6/02.c create mode 100755 3sem/seminars/l6/03.c create mode 100755 3sem/seminars/l6/04.c create mode 100755 3sem/seminars/l7/01.c create mode 100755 3sem/seminars/l7/02.c create mode 100755 3sem/seminars/l8/01-1.c create mode 100755 3sem/seminars/l8/01.c create mode 100755 3sem/seminars/l8/02.c create mode 100755 3sem/seminars/l8/03.c create mode 100755 3sem/seminars/l9/01.c create mode 100755 3sem/seminars/l9/02.c create mode 100755 3sem/seminars/l9/03.c create mode 100755 3sem/seminars/l9/04.c create mode 100755 3sem/seminars/l9/in_01 create mode 100755 3sem/templates.c create mode 100755 compile.sh create mode 100644 contests/1contest/1.cpp create mode 100755 contests/1contest/2.cpp create mode 100755 contests/1contest/3.cpp create mode 100755 contests/1contest/4 copy.cpp create mode 100755 contests/1contest/4.cpp create mode 100644 contests/2contest/1.cpp create mode 100644 contests/2contest/2.cpp create mode 100644 contests/2contest/4.cpp create mode 100644 contests/2contest/5.cpp create mode 100644 contests/3contest/1.cpp create mode 100644 contests/3contest/4.cpp create mode 100644 contests/4contest/1.cpp create mode 100644 contests/4contest/2.cpp create mode 100644 contests/4contest/3.cpp create mode 100644 contests/5contest/1.cpp create mode 100644 contests/5contest/2.cpp create mode 100644 contests/5contest/3.cpp create mode 100644 contests/5contest/4.cpp create mode 100644 contests/5contest/5.cpp create mode 100644 contests/6contest/1.cpp create mode 100644 contests/6contest/2.cpp create mode 100644 contests/6contest/3.cpp create mode 100644 contests/6contest/5.cpp create mode 100644 contests/7contest/1.cpp create mode 100644 contests/7contest/2.cpp create mode 100644 contests/7contest/5.cpp create mode 100644 contests/8contest/1.cpp create mode 100644 contests/8contest/2.cpp create mode 100644 contests/8contest/3.cpp create mode 100644 lectures/BlackHole.cpp create mode 100644 lectures/Count copy.cpp create mode 100644 lectures/Count.cpp create mode 100644 lectures/DataBuffer-Data.cpp create mode 100644 lectures/Reverse.cpp create mode 100644 lectures/Sort copy.cpp create mode 100644 lectures/Sort.cpp create mode 100644 lectures/Tree.cpp create mode 100644 lectures/Vector.cpp create mode 100644 lectures/t.cpp create mode 100644 seminars/1.md create mode 100644 seminars/2.md create mode 100644 seminars/3.md create mode 100644 seminars/4.md create mode 100644 seminars/4.pdf create mode 100644 seminars/5.md create mode 100644 seminars/6.md create mode 100644 seminars/codes/1.cpp create mode 100644 seminars/codes/4.cpp create mode 100644 seminars/markdown-cheat-sheet.md diff --git a/.clang-format b/.clang-format new file mode 100755 index 0000000..ae6c7ef --- /dev/null +++ b/.clang-format @@ -0,0 +1,34 @@ +LineEnding: LF +BasedOnStyle: LLVM +IndentWidth: 4 +ColumnLimit: 120 +# ColumnLimit: 80 +UseTab: Never +SortIncludes: Never +SpaceAfterCStyleCast: true +IndentCaseLabels: false +InsertBraces: true +InsertNewlineAtEOF: true +IndentGotoLabels: false +AlwaysBreakAfterReturnType: AllDefinitions +AllowShortEnumsOnASingleLine: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Never + AfterEnum: true + AfterExternBlock: false + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cfe5e57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode +run +test \ No newline at end of file diff --git a/3sem/cnts/contest1/02.c b/3sem/cnts/contest1/02.c new file mode 100755 index 0000000..a66df3b --- /dev/null +++ b/3sem/cnts/contest1/02.c @@ -0,0 +1,53 @@ +#include +#include + +enum +{ + NUM_OF_DIGITS = '9' - '0' + 1, + NUM_OF_LETTERS = 'z' - 'a' + 1, + BIT_MASK_1 = 0b111011, + BIT_MASK_2 = 0b001000, + MAX_NUM = 64, +}; + +int +main(void) +{ + int c; + + while ((c = getchar()) != EOF) { + int code = 0; + + if (c <= '9' && c >= '0') { + code = c - '0' + 1; + } else if (c <= 'z' && c >= 'a') { + code = c - 'a' + NUM_OF_DIGITS + 1; + } else if (c <= 'Z' && c >= 'A') { + code = c - 'A' + NUM_OF_DIGITS + NUM_OF_LETTERS + 1; + } + + if (code == 0) { + continue; + } + + code = code & BIT_MASK_1; + code ^= BIT_MASK_2; + + int res = 0; + if (code <= NUM_OF_DIGITS && code >= 1) { + res = code - 1 + '0'; + } else if (code <= NUM_OF_DIGITS + NUM_OF_LETTERS && code >= NUM_OF_DIGITS + 1) { + res = code + 'a' - NUM_OF_DIGITS - 1; + } else if (code <= NUM_OF_DIGITS + NUM_OF_LETTERS * 2 && code >= NUM_OF_DIGITS + NUM_OF_LETTERS + 1) { + res = code + 'A' - NUM_OF_DIGITS - NUM_OF_LETTERS - 1; + } else if (code == 0) { + res = '@'; + } else if (code == MAX_NUM - 1) { + res = '#'; + } + + putchar(res); + } + + return 0; +} diff --git a/3sem/cnts/contest1/03.c b/3sem/cnts/contest1/03.c new file mode 100755 index 0000000..6cf0265 --- /dev/null +++ b/3sem/cnts/contest1/03.c @@ -0,0 +1,80 @@ +#include +#include + +enum +{ + MAX_N = 2000 +}; + +int +is_prime(int num) +{ + if (num <= 1) { + return 0; + } + if (num <= 3) { + return 1; + } + if (num % 2 == 0 || num % 3 == 0) { + return 0; + } + for (int i = 5; i * i <= num; i += 6) { + if (num % i == 0 || num % (i + 2) == 0) { + return 0; + } + } + return 1; +} + +int +main(void) +{ + int n; + if (scanf("%d", &n) != 1) { + fprintf(stderr, "Error reading input\n"); + return 1; + } + + if (n >= MAX_N || !is_prime(n)) { + return 1; + } + + // двумерный под хранение результата. Не может быть одномерным, т.к. заполняются столбцы по порядку + int **mas = (int **) malloc(n * sizeof(mas)); + if (mas == NULL) { + return 1; + } + + for (int i = 0; i < n; i++) { + mas[i] = (int *) malloc(n * sizeof(*mas)); + + if (mas[i] == NULL) { + for (int j = 0; j < i; j++) { + free(mas[j]); + } + + free(mas); + return 1; + } + } + + for (int i = 1; i < n; i++) { + for (int a = 0; a < n; a++) { + mas[i][(a * i) % n] = a; + } + } + + for (int j = 0; j < n; j++) { + for (int i = 1; i < n; i++) { + printf("%d ", mas[i][j]); + } + printf("\n"); + } + + for (int i = 0; i < n; i++) { + free(mas[i]); + } + free(mas); + + return 0; +} diff --git a/3sem/cnts/contest1/05.c b/3sem/cnts/contest1/05.c new file mode 100755 index 0000000..bd7641b --- /dev/null +++ b/3sem/cnts/contest1/05.c @@ -0,0 +1,78 @@ +#include +#include + +void +swap(int *a, int *b) +{ + int temp = *a; + *a = *b; + *b = temp; + + return; +} + +int +next_permutation(int *arr, int n) +{ + int i = n - 2; + + while (i >= 0 && arr[i] >= arr[i + 1]) { + i--; + } + + if (i < 0) { + return 0; + } + + int j = n - 1; + + while (arr[j] <= arr[i]) { + j--; + } + + swap(&arr[i], &arr[j]); + + int pt1 = i + 1, pt2 = n - 1; + + while (pt1 < pt2) { + swap(&arr[pt1++], &arr[pt2--]); + } + + return 1; +} + +int +main() +{ + int n; + + if (scanf("%d", &n) != 1) { + fprintf(stderr, "Error reading input\n"); + return 1; + } + + if (n <= 0 || n >= 10) { + return 1; + } + + int *arr = (int *) malloc(n * sizeof(*arr)); + if (arr == NULL) { + return 1; + } + + for (int i = 0; i < n; i++) { + arr[i] = i + 1; + } + + do { + for (int i = 0; i < n; i++) { + printf("%d", arr[i]); + } + + printf("\n"); + } while (next_permutation(arr, n)); + + free(arr); + + return 0; +} diff --git a/3sem/cnts/contest1/test.c b/3sem/cnts/contest1/test.c new file mode 100755 index 0000000..b8a62a5 --- /dev/null +++ b/3sem/cnts/contest1/test.c @@ -0,0 +1,51 @@ +#include +#include +#include + +int +cmp(const void *a, const void *b) +{ + if (*(int *) a % 2 == 0) { + if (*(int *) b % 2 == 1) { + return -1; + } + if (*(int *) a > *(int *) b) { + return 1; + } + if (*(int *) a < *(int *) b) { + return -1; + } + return 0; + } + if (*(int *) b % 2 == 0) { + return 1; + } + if (*(int *) a > *(int *) b) { + return -1; + } + if (*(int *) a < *(int *) b) { + return 1; + } + return 0; +} + +void +sort_even_odd(size_t count, int *data) +{ + qsort(data, count, sizeof(int), cmp); +} + +int +main() +{ + int a[] = {4, 2, 5, 3, 1, 0, -4, -2, -68, 23, 3}; + sort_even_odd(sizeof(a) / sizeof(a[0]), a); + + for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { + printf("%d ", a[i]); + } + + printf("\n"); + + return 0; +} diff --git a/3sem/cnts/contest10/t1/ans1 b/3sem/cnts/contest10/t1/ans1 new file mode 100755 index 0000000..1977e66 --- /dev/null +++ b/3sem/cnts/contest10/t1/ans1 @@ -0,0 +1,3 @@ +1) 'a' +2) 1 +3) 7 \ No newline at end of file diff --git a/3sem/cnts/contest10/t1/cJSON.c b/3sem/cnts/contest10/t1/cJSON.c new file mode 100755 index 0000000..d503e22 --- /dev/null +++ b/3sem/cnts/contest10/t1/cJSON.c @@ -0,0 +1,1129 @@ +/* +Copyright (c) 2009 Dave Gamble + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" + +static const char *ep; + +const char * +cJSON_GetErrorPtr() +{ + return ep; +} + +static int +cJSON_strcasecmp(const char *s1, const char *s2) +{ + if (!s1) { + return (s1 == s2) ? 0 : 1; + } + if (!s2) { + return 1; + } + for (; tolower(*s1) == tolower(*s2); ++s1, ++s2) { + if (*s1 == 0) { + return 0; + } + } + return tolower(*(const unsigned char *) s1) - tolower(*(const unsigned char *) s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char * +cJSON_strdup(const char *str) +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + if (!(copy = (char *) cJSON_malloc(len))) { + return 0; + } + memcpy(copy, str, len); + return copy; +} + +void +cJSON_InitHooks(cJSON_Hooks *hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc; + cJSON_free = (hooks->free_fn) ? hooks->free_fn : free; +} + +/* Internal constructor. */ +static cJSON * +cJSON_New_Item() +{ + cJSON *node = (cJSON *) cJSON_malloc(sizeof(cJSON)); + if (node) { + memset(node, 0, sizeof(cJSON)); + } + return node; +} + +/* Delete a cJSON structure. */ +void +cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) { + next = c->next; + if (!(c->type & cJSON_IsReference) && c->child) { + cJSON_Delete(c->child); + } + if (!(c->type & cJSON_IsReference) && c->valuestring) { + cJSON_free(c->valuestring); + } + cJSON_free(c); + c = next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char * +parse_number(cJSON *item, const char *num) +{ + double n = 0, sign = 1, scale = 0; + int subscale = 0, signsubscale = 1; + + /* Could use sscanf for this? */ + if (*num == '-') { + sign = -1, num++; /* Has sign? */ + } + if (*num == '0') { + num++; /* is zero */ + } + if (*num >= '1' && *num <= '9') { + do { + n = (n * 10.0) + (*num++ - '0'); + } while (*num >= '0' && *num <= '9'); /* Number? */ + } + if (*num == '.' && num[1] >= '0' && num[1] <= '9') { + num++; + do { + n = (n * 10.0) + (*num++ - '0'), scale--; + } while (*num >= '0' && *num <= '9'); + } /* Fractional part? */ + if (*num == 'e' || *num == 'E') /* Exponent? */ + { + num++; + if (*num == '+') { + num++; + } else if (*num == '-') { + signsubscale = -1, num++; /* With sign? */ + } + while (*num >= '0' && *num <= '9') { + subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ + } + } + + n = sign * n * pow(10.0, (scale + subscale * signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble = n; + item->valueint = (int) n; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char * +print_number(cJSON *item) +{ + char *str; + double d = item->valuedouble; + if (fabs(((double) item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) { + str = (char *) cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) { + sprintf(str, "%d", item->valueint); + } + } else { + str = (char *) cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) { + if (fabs(floor(d) - d) <= DBL_EPSILON) { + sprintf(str, "%.0f", d); + } else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9) { + sprintf(str, "%e", d); + } else { + sprintf(str, "%f", d); + } + } + } + return str; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; +static const char * +parse_string(cJSON *item, const char *str) +{ + const char *ptr = str + 1; + char *ptr2; + char *out; + int len = 0; + unsigned uc, uc2; + if (*str != '\"') { + ep = str; + return 0; + } /* not a string! */ + + while (*ptr != '\"' && *ptr && ++len) { + if (*ptr++ == '\\') { + ptr++; /* Skip escaped quotes. */ + } + } + + out = (char *) cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */ + if (!out) { + return 0; + } + + ptr = str + 1; + ptr2 = out; + while (*ptr != '\"' && *ptr) { + if (*ptr != '\\') { + *ptr2++ = *ptr++; + } else { + ptr++; + switch (*ptr) { + case 'b': + *ptr2++ = '\b'; + break; + case 'f': + *ptr2++ = '\f'; + break; + case 'n': + *ptr2++ = '\n'; + break; + case 'r': + *ptr2++ = '\r'; + break; + case 't': + *ptr2++ = '\t'; + break; + case 'u': /* transcode utf16 to utf8. */ + sscanf(ptr + 1, "%4x", &uc); + ptr += 4; /* get the unicode char. */ + + if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) { + break; // check for invalid. + } + + if (uc >= 0xD800 && uc <= 0xDBFF) // UTF16 surrogate pairs. + { + if (ptr[1] != '\\' || ptr[2] != 'u') { + break; // missing second-half of surrogate. + } + sscanf(ptr + 3, "%4x", &uc2); + ptr += 6; + if (uc2 < 0xDC00 || uc2 > 0xDFFF) { + break; // invalid second-half of surrogate. + } + uc = 0x10000 | ((uc & 0x3FF) << 10) | (uc2 & 0x3FF); + } + + len = 4; + if (uc < 0x80) { + len = 1; + } else if (uc < 0x800) { + len = 2; + } else if (uc < 0x10000) { + len = 3; + } + ptr2 += len; + + switch (len) { + case 4: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 3: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 2: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 1: + *--ptr2 = (uc | firstByteMark[len]); + } + ptr2 += len; + break; + default: + *ptr2++ = *ptr; + break; + } + ptr++; + } + } + *ptr2 = 0; + if (*ptr == '\"') { + ptr++; + } + item->valuestring = out; + item->type = cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char * +print_string_ptr(const char *str) +{ + const char *ptr; + char *ptr2, *out; + int len = 0; + unsigned char token; + + if (!str) { + return cJSON_strdup(""); + } + ptr = str; + while ((token = *ptr) && ++len) { + if (strchr("\"\\\b\f\n\r\t", token)) { + len++; + } else if (token < 32) { + len += 5; + } + ptr++; + } + + out = (char *) cJSON_malloc(len + 3); + if (!out) { + return 0; + } + + ptr2 = out; + ptr = str; + *ptr2++ = '\"'; + while (*ptr) { + if ((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\') { + *ptr2++ = *ptr++; + } else { + *ptr2++ = '\\'; + switch (token = *ptr++) { + case '\\': + *ptr2++ = '\\'; + break; + case '\"': + *ptr2++ = '\"'; + break; + case '\b': + *ptr2++ = 'b'; + break; + case '\f': + *ptr2++ = 'f'; + break; + case '\n': + *ptr2++ = 'n'; + break; + case '\r': + *ptr2++ = 'r'; + break; + case '\t': + *ptr2++ = 't'; + break; + default: + sprintf(ptr2, "u%04x", token); + ptr2 += 5; + break; /* escape and print */ + } + } + } + *ptr2++ = '\"'; + *ptr2++ = 0; + return out; +} + +/* Invote print_string_ptr (which is useful) on an item. */ +static char * +print_string(cJSON *item) +{ + return print_string_ptr(item->valuestring); +} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item, const char *value); +static char *print_value(cJSON *item, int depth, int fmt); +static const char *parse_array(cJSON *item, const char *value); +static char *print_array(cJSON *item, int depth, int fmt); +static const char *parse_object(cJSON *item, const char *value); +static char *print_object(cJSON *item, int depth, int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char * +skip(const char *in) +{ + while (in && *in && (unsigned char) *in <= 32) { + in++; + } + return in; +} + +/* Parse an object - create a new root, and populate. */ +cJSON * +cJSON_Parse(const char *value) +{ + cJSON *c = cJSON_New_Item(); + ep = 0; + if (!c) { + return 0; /* memory fail */ + } + + if (!parse_value(c, skip(value))) { + cJSON_Delete(c); + return 0; + } + return c; +} + +/* Render a cJSON item/entity/structure to text. */ +char * +cJSON_Print(cJSON *item) +{ + return print_value(item, 0, 1); +} + +char * +cJSON_PrintUnformatted(cJSON *item) +{ + return print_value(item, 0, 0); +} + +/* Parser core - when encountering text, process appropriately. */ +static const char * +parse_value(cJSON *item, const char *value) +{ + if (!value) { + return 0; /* Fail on null. */ + } + if (!strncmp(value, "null", 4)) { + item->type = cJSON_NULL; + return value + 4; + } + if (!strncmp(value, "false", 5)) { + item->type = cJSON_False; + return value + 5; + } + if (!strncmp(value, "true", 4)) { + item->type = cJSON_True; + item->valueint = 1; + return value + 4; + } + if (*value == '\"') { + return parse_string(item, value); + } + if (*value == '-' || (*value >= '0' && *value <= '9')) { + return parse_number(item, value); + } + if (*value == '[') { + return parse_array(item, value); + } + if (*value == '{') { + return parse_object(item, value); + } + + ep = value; + return 0; /* failure. */ +} + +/* Render a value to text. */ +static char * +print_value(cJSON *item, int depth, int fmt) +{ + char *out = 0; + if (!item) { + return 0; + } + switch ((item->type) & 255) { + case cJSON_NULL: + out = cJSON_strdup("null"); + break; + case cJSON_False: + out = cJSON_strdup("false"); + break; + case cJSON_True: + out = cJSON_strdup("true"); + break; + case cJSON_Number: + out = print_number(item); + break; + case cJSON_String: + out = print_string(item); + break; + case cJSON_Array: + out = print_array(item, depth, fmt); + break; + case cJSON_Object: + out = print_object(item, depth, fmt); + break; + } + return out; +} + +/* Build an array from input text. */ +static const char * +parse_array(cJSON *item, const char *value) +{ + cJSON *child; + if (*value != '[') { + ep = value; + return 0; + } /* not an array! */ + + item->type = cJSON_Array; + value = skip(value + 1); + if (*value == ']') { + return value + 1; /* empty array. */ + } + + item->child = child = cJSON_New_Item(); + if (!item->child) { + return 0; /* memory fail */ + } + value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */ + if (!value) { + return 0; + } + + while (*value == ',') { + cJSON *new_item; + if (!(new_item = cJSON_New_Item())) { + return 0; /* memory fail */ + } + child->next = new_item; + child = new_item; + value = skip(parse_value(child, skip(value + 1))); + if (!value) { + return 0; /* memory fail */ + } + } + + if (*value == ']') { + return value + 1; /* end of array */ + } + ep = value; + return 0; /* malformed. */ +} + +/* Render an array to text */ +static char * +print_array(cJSON *item, int depth, int fmt) +{ + char **entries; + char *out = 0, *ptr, *ret; + int len = 5; + cJSON *child = item->child; + int numentries = 0, i = 0, fail = 0; + + /* How many entries in the array? */ + while (child) { + numentries++, child = child->next; + } + /* Allocate an array to hold the values for each */ + entries = (char **) cJSON_malloc(numentries * sizeof(char *)); + if (!entries) { + return 0; + } + memset(entries, 0, numentries * sizeof(char *)); + /* Retrieve all the results: */ + child = item->child; + while (child && !fail) { + ret = print_value(child, depth + 1, fmt); + entries[i++] = ret; + if (ret) { + len += strlen(ret) + 2 + (fmt ? 1 : 0); + } else { + fail = 1; + } + child = child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) { + out = (char *) cJSON_malloc(len); + } + /* If that fails, we fail. */ + if (!out) { + fail = 1; + } + + /* Handle failure. */ + if (fail) { + for (i = 0; i < numentries; i++) { + if (entries[i]) { + cJSON_free(entries[i]); + } + } + cJSON_free(entries); + return 0; + } + + /* Compose the output array. */ + *out = '['; + ptr = out + 1; + *ptr = 0; + for (i = 0; i < numentries; i++) { + strcpy(ptr, entries[i]); + ptr += strlen(entries[i]); + if (i != numentries - 1) { + *ptr++ = ','; + if (fmt) { + *ptr++ = ' '; + } + *ptr = 0; + } + cJSON_free(entries[i]); + } + cJSON_free(entries); + *ptr++ = ']'; + *ptr++ = 0; + return out; +} + +/* Build an object from the text. */ +static const char * +parse_object(cJSON *item, const char *value) +{ + cJSON *child; + if (*value != '{') { + ep = value; + return 0; + } /* not an object! */ + + item->type = cJSON_Object; + value = skip(value + 1); + if (*value == '}') { + return value + 1; /* empty array. */ + } + + item->child = child = cJSON_New_Item(); + if (!item->child) { + return 0; + } + value = skip(parse_string(child, skip(value))); + if (!value) { + return 0; + } + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') { + ep = value; + return 0; + } /* fail! */ + value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) { + return 0; + } + + while (*value == ',') { + cJSON *new_item; + if (!(new_item = cJSON_New_Item())) { + return 0; /* memory fail */ + } + child->next = new_item; + new_item->prev = child; + child = new_item; + value = skip(parse_string(child, skip(value + 1))); + if (!value) { + return 0; + } + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') { + ep = value; + return 0; + } /* fail! */ + value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) { + return 0; + } + } + + if (*value == '}') { + return value + 1; /* end of array */ + } + ep = value; + return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char * +print_object(cJSON *item, int depth, int fmt) +{ + char **entries = 0, **names = 0; + char *out = 0, *ptr, *ret, *str; + int len = 7, i = 0, j; + cJSON *child = item->child; + int numentries = 0, fail = 0; + /* Count the number of entries. */ + while (child) { + numentries++, child = child->next; + } + /* Allocate space for the names and the objects */ + entries = (char **) cJSON_malloc(numentries * sizeof(char *)); + if (!entries) { + return 0; + } + names = (char **) cJSON_malloc(numentries * sizeof(char *)); + if (!names) { + cJSON_free(entries); + return 0; + } + memset(entries, 0, sizeof(char *) * numentries); + memset(names, 0, sizeof(char *) * numentries); + + /* Collect all the results into our arrays: */ + child = item->child; + depth++; + if (fmt) { + len += depth; + } + while (child) { + names[i] = str = print_string_ptr(child->string); + entries[i++] = ret = print_value(child, depth, fmt); + if (str && ret) { + len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); + } else { + fail = 1; + } + child = child->next; + } + + /* Try to allocate the output string */ + if (!fail) { + out = (char *) cJSON_malloc(len); + } + if (!out) { + fail = 1; + } + + /* Handle failure */ + if (fail) { + for (i = 0; i < numentries; i++) { + if (names[i]) { + cJSON_free(names[i]); + } + if (entries[i]) { + cJSON_free(entries[i]); + } + } + cJSON_free(names); + cJSON_free(entries); + return 0; + } + + /* Compose the output: */ + *out = '{'; + ptr = out + 1; + if (fmt) { + *ptr++ = '\n'; + } + *ptr = 0; + for (i = 0; i < numentries; i++) { + if (fmt) { + for (j = 0; j < depth; j++) { + *ptr++ = '\t'; + } + } + strcpy(ptr, names[i]); + ptr += strlen(names[i]); + *ptr++ = ':'; + if (fmt) { + *ptr++ = '\t'; + } + strcpy(ptr, entries[i]); + ptr += strlen(entries[i]); + if (i != numentries - 1) { + *ptr++ = ','; + } + if (fmt) { + *ptr++ = '\n'; + } + *ptr = 0; + cJSON_free(names[i]); + cJSON_free(entries[i]); + } + + cJSON_free(names); + cJSON_free(entries); + if (fmt) { + for (i = 0; i < depth - 1; i++) { + *ptr++ = '\t'; + } + } + *ptr++ = '}'; + *ptr++ = 0; + return out; +} + +/* Get Array size/item / object item. */ +int +cJSON_GetArraySize(cJSON *array) +{ + cJSON *c = array->child; + int i = 0; + while (c) { + i++, c = c->next; + } + return i; +} + +cJSON * +cJSON_GetArrayItem(cJSON *array, int item) +{ + cJSON *c = array->child; + while (c && item > 0) { + item--, c = c->next; + } + return c; +} + +cJSON * +cJSON_GetObjectItem(cJSON *object, const char *string) +{ + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) { + c = c->next; + } + return c; +} + +/* Utility for array list handling. */ +static void +suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON * +create_reference(cJSON *item) +{ + cJSON *ref = cJSON_New_Item(); + if (!ref) { + return 0; + } + memcpy(ref, item, sizeof(cJSON)); + ref->string = 0; + ref->type |= cJSON_IsReference; + ref->next = ref->prev = 0; + return ref; +} + +/* Add item to array/object. */ +void +cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + cJSON *c = array->child; + if (!item) { + return; + } + if (!c) { + array->child = item; + } else { + while (c && c->next) { + c = c->next; + } + suffix_object(c, item); + } +} + +void +cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + if (!item) { + return; + } + if (item->string) { + cJSON_free(item->string); + } + item->string = cJSON_strdup(string); + cJSON_AddItemToArray(object, item); +} + +void +cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + cJSON_AddItemToArray(array, create_reference(item)); +} + +void +cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + cJSON_AddItemToObject(object, string, create_reference(item)); +} + +cJSON * +cJSON_DetachItemFromArray(cJSON *array, int which) +{ + cJSON *c = array->child; + while (c && which > 0) { + c = c->next, which--; + } + if (!c) { + return 0; + } + if (c->prev) { + c->prev->next = c->next; + } + if (c->next) { + c->next->prev = c->prev; + } + if (c == array->child) { + array->child = c->next; + } + c->prev = c->next = 0; + return c; +} + +void +cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +cJSON * +cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) { + i++, c = c->next; + } + if (c) { + return cJSON_DetachItemFromArray(object, i); + } + return 0; +} + +void +cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +/* Replace array/object items with new ones. */ +void +cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *c = array->child; + while (c && which > 0) { + c = c->next, which--; + } + if (!c) { + return; + } + newitem->next = c->next; + newitem->prev = c->prev; + if (newitem->next) { + newitem->next->prev = newitem; + } + if (c == array->child) { + array->child = newitem; + } else { + newitem->prev->next = newitem; + } + c->next = c->prev = 0; + cJSON_Delete(c); +} + +void +cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) { + i++, c = c->next; + } + if (c) { + newitem->string = cJSON_strdup(string); + cJSON_ReplaceItemInArray(object, i, newitem); + } +} + +/* Create basic types: */ +cJSON * +cJSON_CreateNull() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_NULL; + } + return item; +} + +cJSON * +cJSON_CreateTrue() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_True; + } + return item; +} + +cJSON * +cJSON_CreateFalse() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_False; + } + return item; +} + +cJSON * +cJSON_CreateBool(int b) +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = b ? cJSON_True : cJSON_False; + } + return item; +} + +cJSON * +cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Number; + item->valuedouble = num; + item->valueint = (int) num; + } + return item; +} + +cJSON * +cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_String; + item->valuestring = cJSON_strdup(string); + } + return item; +} + +cJSON * +cJSON_CreateArray() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Array; + } + return item; +} + +cJSON * +cJSON_CreateObject() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Object; + } + return item; +} + +/* Create Arrays: */ +cJSON * +cJSON_CreateIntArray(int *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} + +cJSON * +cJSON_CreateFloatArray(float *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} + +cJSON * +cJSON_CreateDoubleArray(double *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} + +cJSON * +cJSON_CreateStringArray(const char **strings, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateString(strings[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} diff --git a/3sem/cnts/contest10/t1/cJSON.h b/3sem/cnts/contest10/t1/cJSON.h new file mode 100755 index 0000000..cc1beb9 --- /dev/null +++ b/3sem/cnts/contest10/t1/cJSON.h @@ -0,0 +1,133 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +// #ifdef __cplusplus +// extern "C" +//{ +// #endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON +{ + struct cJSON *next, *prev; /* next/prev allow you to walk array/object chains. Alternatively, use + GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the + array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char + *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks +{ + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks *hooks); + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array, int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back + * to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(); +extern cJSON *cJSON_CreateTrue(); +extern cJSON *cJSON_CreateFalse(); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(); +extern cJSON *cJSON_CreateObject(); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(int *numbers, int count); +extern cJSON *cJSON_CreateFloatArray(float *numbers, int count); +extern cJSON *cJSON_CreateDoubleArray(double *numbers, int count); +extern cJSON *cJSON_CreateStringArray(const char **strings, int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new + * cJSON, but don't want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which); +extern void cJSON_DeleteItemFromArray(cJSON *array, int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem); + +#define cJSON_AddNullToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddNumberToObject(object, name, n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object, name, s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +// #ifdef __cplusplus +// } +// #endif + +#endif diff --git a/3sem/cnts/contest10/t1/gdb command b/3sem/cnts/contest10/t1/gdb command new file mode 100755 index 0000000..f55846a --- /dev/null +++ b/3sem/cnts/contest10/t1/gdb command @@ -0,0 +1,12 @@ +break parse_value +commands + silent + set $count = $count + 1 + if $count == 2 + print item->type + continue + end + continue +end +set $count = 0 +run \ No newline at end of file diff --git a/3sem/cnts/contest10/t1/gdb command copy b/3sem/cnts/contest10/t1/gdb command copy new file mode 100755 index 0000000..8b56f43 --- /dev/null +++ b/3sem/cnts/contest10/t1/gdb command copy @@ -0,0 +1,12 @@ +break parse_string if $pc == *parse_string + +commands + silent + set $count = $count + 1 + if $count == 4 + print len + continue + end + continue +end +set $count = 0 +run \ No newline at end of file diff --git a/3sem/cnts/contest10/t1/gdb-1-task.tar b/3sem/cnts/contest10/t1/gdb-1-task.tar new file mode 100755 index 0000000000000000000000000000000000000000..e3cb44b9fc7198b9157ccd949468393b1013c16f GIT binary patch literal 31232 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 Jf&ax6_#gK_i0uFX literal 0 HcmV?d00001 diff --git a/3sem/cnts/contest10/t1/gdb-1-task.tarZone.Identifier b/3sem/cnts/contest10/t1/gdb-1-task.tarZone.Identifier new file mode 100755 index 0000000..cca3dca --- /dev/null +++ b/3sem/cnts/contest10/t1/gdb-1-task.tarZone.Identifier @@ -0,0 +1,4 @@ +[ZoneTransfer] +ZoneId=3 +ReferrerUrl=https://unicorn.ejudge.ru/ej/client/view-problem-submit/Sa889e21564f40a8b?prob_id=80 +HostUrl=https://unicorn.ejudge.ru/ej/client?SID=a889e21564f40a8b&prob_id=80&action=194&file=gdb-1-task.tar diff --git a/3sem/cnts/contest10/t1/task1 b/3sem/cnts/contest10/t1/task1 new file mode 100755 index 0000000000000000000000000000000000000000..e7a47b39dc1d7796fb765c07c66d8eb2e9aa6dac GIT binary patch literal 39456 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 z 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 +#include +#include "cJSON.h" + +void +task1() +{ + cJSON *item; + char *json = "{" + "\"a\" : true, " + "\"b\" : { " + "\"c\":\"stro\\\"ka\"" + "}" + "}"; + + item = cJSON_Parse(json); + + cJSON_Delete(item); +} + +int +main(int argc, char **argv) +{ + task1(); + + return 0; +} diff --git a/3sem/cnts/contest10/t2/cJSON.c b/3sem/cnts/contest10/t2/cJSON.c new file mode 100755 index 0000000..58d37fb --- /dev/null +++ b/3sem/cnts/contest10/t2/cJSON.c @@ -0,0 +1,1126 @@ +/* +Copyright (c) 2009 Dave Gamble + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" + +static const char *ep; + +const char * +cJSON_GetErrorPtr() +{ + return ep; +} + +static int +cJSON_strcasecmp(const char *s1, const char *s2) +{ + if (!s1) { + return (s1 == s2) ? 0 : 1; + } + if (!s2) { + return 1; + } + for (; tolower(*s1) == tolower(*s2); ++s1, ++s2) { + if (*s1 == 0) { + return 0; + } + } + return tolower(*(const unsigned char *) s1) - tolower(*(const unsigned char *) s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char * +cJSON_strdup(const char *str) +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + if (!(copy = (char *) cJSON_malloc(len))) { + return 0; + } + memcpy(copy, str, len); + return copy; +} + +void +cJSON_InitHooks(cJSON_Hooks *hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc; + cJSON_free = (hooks->free_fn) ? hooks->free_fn : free; +} + +/* Internal constructor. */ +static cJSON * +cJSON_New_Item() +{ + cJSON *node = (cJSON *) cJSON_malloc(sizeof(cJSON)); + if (node) { + memset(node, 0, sizeof(cJSON)); + } + return node; +} + +/* Delete a cJSON structure. */ +void +cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) { + next = c->next; + if (!(c->type & cJSON_IsReference) && c->child) { + cJSON_Delete(c->child); + } + if (!(c->type & cJSON_IsReference) && c->valuestring) { + cJSON_free(c->valuestring); + } + cJSON_free(c); + c = next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char * +parse_number(cJSON *item, const char *num) +{ + double n = 0, sign = 1, scale = 0; + int subscale = 0, signsubscale = 1; + + /* Could use sscanf for this? */ + if (*num == '-') { + sign = -1, num++; /* Has sign? */ + } + if (*num == '0') { + num++; /* is zero */ + } + if (*num >= '1' && *num <= '9') { + do { + n = (n * 10.0) + (*num++ - '0'); + } while (*num >= '0' && *num <= '9'); /* Number? */ + } + if (*num == '.' && num[1] >= '0' && num[1] <= '9') { + num++; + do { + n = (n * 10.0) + (*num++ - '0'), scale--; + } while (*num >= '0' && *num <= '9'); + } /* Fractional part? */ + if (*num == 'e' || *num == 'E') /* Exponent? */ + { + num++; + if (*num == '+') { + num++; + } else if (*num == '-') { + signsubscale = -1, num++; /* With sign? */ + } + while (*num >= '0' && *num <= '9') { + subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ + } + } + + n = sign * n * pow(10.0, (scale + subscale * signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble = n; + item->valueint = (int) round(n); + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char * +print_number(cJSON *item) +{ + char *str; + double d = item->valuedouble; + if (fabs(((double) item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) { + str = (char *) cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + sprintf(str, "%d", item->valueint); + } else { + str = (char *) cJSON_malloc(64); /* This is a nice tradeoff. */ + if (fabs(floor(d) - d) <= DBL_EPSILON) { + sprintf(str, "%.0f", d); + } else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9) { + sprintf(str, "%e", d); + } else { + sprintf(str, "%f", d); + } + } + + return str; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; +static const char * +parse_string(cJSON *item, const char *str) +{ + const char *ptr = str + 1; + char *ptr2; + char *out; + int len = 0; + unsigned uc, uc2; + if (*str != '\"') { + ep = str; + return 0; + } /* not a string! */ + + while (*ptr != '\"' && *ptr && ++len) { + if (*ptr++ == '\\') { + ptr++; /* Skip escaped quotes. */ + } + } + + out = (char *) cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */ + if (!out) { + return 0; + } + + ptr = str + 1; + ptr2 = out; + while (*ptr != '\"' && *ptr) { + if (*ptr != '\\') { + *ptr2++ = *ptr++; + } else { + ptr++; + switch (*ptr) { + case 'b': + *ptr2++ = '\b'; + break; + case 'f': + *ptr2++ = '\f'; + break; + case 'n': + *ptr2++ = '\n'; + break; + case 'r': + *ptr2++ = '\r'; + break; + case 't': + *ptr2++ = '\t'; + break; + case 'u': /* transcode utf16 to utf8. */ + sscanf(ptr + 1, "%4x", &uc); + ptr += 4; /* get the unicode char. */ + + if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) { + break; // check for invalid. + } + + if (uc >= 0xD800 && uc <= 0xDBFF) // UTF16 surrogate pairs. + { + if (ptr[1] != '\\' || ptr[2] != 'u') { + break; // missing second-half of surrogate. + } + sscanf(ptr + 3, "%4x", &uc2); + ptr += 6; + if (uc2 < 0xDC00 || uc2 > 0xDFFF) { + break; // invalid second-half of surrogate. + } + uc = 0x10000 | ((uc & 0x3FF) << 10) | (uc2 & 0x3FF); + } + + len = 4; + if (uc < 0x80) { + len = 1; + } else if (uc < 0x800) { + len = 2; + } else if (uc < 0x10000) { + len = 3; + } + ptr2 += len; + + switch (len) { + case 4: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 3: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 2: + *--ptr2 = ((uc | 0x80) & 0xBF); + uc >>= 6; + case 1: + *--ptr2 = (uc | firstByteMark[len]); + } + ptr2 += len; + break; + default: + *ptr2++ = *ptr; + break; + } + ptr++; + } + } + *ptr2 = 0; + if (*ptr == '\"') { + ptr++; + } + item->valuestring = out; + item->type = cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char * +print_string_ptr(const char *str) +{ + const char *ptr; + char *ptr2, *out; + int len = 0; + unsigned char token; + + if (!str) { + return cJSON_strdup(""); + } + ptr = str; + while ((token = *ptr) && ++len) { + if (strchr("\"\\\b\f\n\r\t", token)) { + len++; + } else if (token < 32) { + len += 5; + } + ptr++; + } + + out = (char *) cJSON_malloc(len + 3); + if (!out) { + return 0; + } + + ptr2 = out; + ptr = str; + *ptr2++ = '\"'; + while (*ptr) { + if ((unsigned char) *ptr > 31 && *ptr != '\"' && *ptr != '\\') { + *ptr2++ = *ptr++; + } else { + *ptr2++ = '\\'; + switch (token = *ptr++) { + case '\\': + *ptr2++ = '\\'; + break; + case '\"': + *ptr2++ = '\"'; + break; + case '\b': + *ptr2++ = 'b'; + break; + case '\f': + *ptr2++ = 'f'; + break; + case '\n': + *ptr2++ = 'n'; + break; + case '\r': + *ptr2++ = 'r'; + break; + case '\t': + *ptr2++ = 't'; + break; + default: + sprintf(ptr2, "u%04x", token); + ptr2 += 5; + break; /* escape and print */ + } + } + } + *ptr2++ = '\"'; + *ptr2++ = 0; + return out; +} + +/* Invote print_string_ptr (which is useful) on an item. */ +static char * +print_string(cJSON *item) +{ + return print_string_ptr(item->valuestring); +} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item, const char *value); +static char *print_value(cJSON *item, int depth, int fmt); +static const char *parse_array(cJSON *item, const char *value); +static char *print_array(cJSON *item, int depth, int fmt); +static const char *parse_object(cJSON *item, const char *value); +static char *print_object(cJSON *item, int depth, int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char * +skip(const char *in) +{ + while (in && *in && (unsigned char) *in <= 32) { + in++; + } + return in; +} + +/* Parse an object - create a new root, and populate. */ +cJSON * +cJSON_Parse(const char *value) +{ + cJSON *c = cJSON_New_Item(); + ep = 0; + if (!c) { + return 0; /* memory fail */ + } + + if (!parse_value(c, skip(value))) { + cJSON_Delete(c); + return 0; + } + return c; +} + +/* Render a cJSON item/entity/structure to text. */ +char * +cJSON_Print(cJSON *item) +{ + return print_value(item, 0, 1); +} + +char * +cJSON_PrintUnformatted(cJSON *item) +{ + return print_value(item, 0, 0); +} + +/* Parser core - when encountering text, process appropriately. */ +static const char * +parse_value(cJSON *item, const char *value) +{ + if (!value) { + return 0; /* Fail on null. */ + } + if (!strncmp(value, "null", 4)) { + item->type = cJSON_NULL; + return value + 4; + } + if (!strncmp(value, "false", 5)) { + item->type = cJSON_False; + return value + 5; + } + if (!strncmp(value, "true", 4)) { + item->type = cJSON_True; + item->valueint = 1; + return value + 4; + } + if (*value == '\"') { + return parse_string(item, value); + } + if (*value == '-' || (*value >= '0' && *value <= '9')) { + return parse_number(item, value); + } + if (*value == '[') { + return parse_array(item, value); + } + if (*value == '{') { + return parse_object(item, value); + } + + ep = value; + return 0; /* failure. */ +} + +/* Render a value to text. */ +static char * +print_value(cJSON *item, int depth, int fmt) +{ + char *out = 0; + if (!item) { + return 0; + } + switch ((item->type) & 255) { + case cJSON_NULL: + out = cJSON_strdup("null"); + break; + case cJSON_False: + out = cJSON_strdup("false"); + break; + case cJSON_True: + out = cJSON_strdup("true"); + break; + case cJSON_Number: + out = print_number(item); + break; + case cJSON_String: + out = print_string(item); + break; + case cJSON_Array: + out = print_array(item, depth, fmt); + break; + case cJSON_Object: + out = print_object(item, depth, fmt); + break; + } + return out; +} + +/* Build an array from input text. */ +static const char * +parse_array(cJSON *item, const char *value) +{ + cJSON *child; + if (*value != '[') { + ep = value; + return 0; + } /* not an array! */ + + item->type = cJSON_Array; + value = skip(value + 1); + if (*value == ']') { + return value + 1; /* empty array. */ + } + + item->child = child = cJSON_New_Item(); + if (!item->child) { + return 0; /* memory fail */ + } + value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */ + if (!value) { + return 0; + } + + while (*value == ',') { + cJSON *new_item; + if (!(new_item = cJSON_New_Item())) { + return 0; /* memory fail */ + } + child->next = new_item; + child = new_item; + value = skip(parse_value(child, skip(value + 1))); + if (!value) { + return 0; /* memory fail */ + } + } + + if (*value == ']') { + return value + 1; /* end of array */ + } + ep = value; + return 0; /* malformed. */ +} + +/* Render an array to text */ +static char * +print_array(cJSON *item, int depth, int fmt) +{ + char **entries; + char *out = 0, *ptr, *ret; + int len = 5; + cJSON *child = item->child; + int numentries = 0, i = 0, fail = 0; + + /* How many entries in the array? */ + while (child) { + numentries++, child = child->next; + } + /* Allocate an array to hold the values for each */ + entries = (char **) cJSON_malloc(numentries * sizeof(char *)); + if (!entries) { + return 0; + } + memset(entries, 0, numentries * sizeof(char *)); + /* Retrieve all the results: */ + child = item->child; + while (child && !fail) { + ret = print_value(child, depth + 1, fmt); + entries[i++] = ret; + if (ret) { + len += strlen(ret) + 2 + (fmt ? 1 : 0); + } else { + fail = 1; + } + child = child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) { + out = (char *) cJSON_malloc(len); + } + /* If that fails, we fail. */ + if (!out) { + fail = 1; + } + + /* Handle failure. */ + if (fail) { + for (i = 0; i < numentries; i++) { + if (entries[i]) { + cJSON_free(entries[i]); + } + } + cJSON_free(entries); + return 0; + } + + /* Compose the output array. */ + *out = '['; + ptr = out + 1; + *ptr = 0; + for (i = 0; i < numentries; i++) { + strcpy(ptr, entries[i]); + ptr += strlen(entries[i]); + if (i != numentries - 1) { + *ptr++ = ','; + if (fmt) { + *ptr++ = ' '; + } + *ptr = 0; + } + cJSON_free(entries[i]); + } + cJSON_free(entries); + *ptr++ = ']'; + *ptr++ = 0; + return out; +} + +/* Build an object from the text. */ +static const char * +parse_object(cJSON *item, const char *value) +{ + cJSON *child; + if (*value != '{') { + ep = value; + return 0; + } /* not an object! */ + + item->type = cJSON_Object; + value = skip(value + 1); + if (*value == '}') { + return value + 1; /* empty array. */ + } + + item->child = child = cJSON_New_Item(); + if (!item->child) { + return 0; + } + value = skip(parse_string(child, skip(value))); + if (!value) { + return 0; + } + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') { + ep = value; + return 0; + } /* fail! */ + value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) { + return 0; + } + + while (*value == ',') { + cJSON *new_item; + if (!(new_item = cJSON_New_Item())) { + return 0; /* memory fail */ + } + child->next = new_item; + new_item->prev = child; + child = new_item; + value = skip(parse_string(child, skip(value + 1))); + if (!value) { + return 0; + } + child->string = child->valuestring; + child->valuestring = 0; + if (*value != ':') { + ep = value; + return 0; + } /* fail! */ + value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) { + return 0; + } + } + + if (*value == '}') { + return value + 1; /* end of array */ + } + ep = value; + return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char * +print_object(cJSON *item, int depth, int fmt) +{ + char **entries = 0, **names = 0; + char *out = 0, *ptr, *ret, *str; + int len = 7, i = 0, j; + cJSON *child = item->child; + int numentries = 0, fail = 0; + /* Count the number of entries. */ + while (child) { + numentries++, child = child->next; + } + /* Allocate space for the names and the objects */ + entries = (char **) cJSON_malloc(numentries * sizeof(char *)); + if (!entries) { + return 0; + } + names = (char **) cJSON_malloc(numentries * sizeof(char *)); + if (!names) { + cJSON_free(entries); + return 0; + } + memset(entries, 0, sizeof(char *) * numentries); + memset(names, 0, sizeof(char *) * numentries); + + /* Collect all the results into our arrays: */ + child = item->child; + depth++; + if (fmt) { + len += depth; + } + while (child) { + names[i] = str = print_string_ptr(child->string); + entries[i++] = ret = print_value(child, depth, fmt); + if (str && ret) { + len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); + } else { + fail = 1; + } + child = child->next; + } + + /* Try to allocate the output string */ + if (!fail) { + out = (char *) cJSON_malloc(len); + } + if (!out) { + fail = 1; + } + + /* Handle failure */ + if (fail) { + for (i = 0; i < numentries; i++) { + if (names[i]) { + cJSON_free(names[i]); + } + if (entries[i]) { + cJSON_free(entries[i]); + } + } + cJSON_free(names); + cJSON_free(entries); + return 0; + } + + /* Compose the output: */ + *out = '{'; + ptr = out + 1; + if (fmt) { + *ptr++ = '\n'; + } + *ptr = 0; + for (i = 0; i < numentries; i++) { + if (fmt) { + for (j = 0; j < depth; j++) { + *ptr++ = '\t'; + } + } + strcpy(ptr, names[i]); + ptr += strlen(names[i]); + *ptr++ = ':'; + if (fmt) { + *ptr++ = '\t'; + } + strcpy(ptr, entries[i]); + ptr += strlen(entries[i]); + if (i != numentries - 1) { + *ptr++ = ','; + } + if (fmt) { + *ptr++ = '\n'; + } + *ptr = 0; + cJSON_free(names[i]); + cJSON_free(entries[i]); + } + + cJSON_free(names); + cJSON_free(entries); + if (fmt) { + for (i = 0; i < depth - 1; i++) { + *ptr++ = '\t'; + } + } + *ptr++ = '}'; + *ptr++ = 0; + return out; +} + +/* Get Array size/item / object item. */ +int +cJSON_GetArraySize(cJSON *array) +{ + cJSON *c = array->child; + int i = 0; + while (c) { + i++, c = c->next; + } + return i; +} + +cJSON * +cJSON_GetArrayItem(cJSON *array, int item) +{ + cJSON *c = array->child; + while (c && item > 0) { + item--, c = c->next; + } + return c; +} + +cJSON * +cJSON_GetObjectItem(cJSON *object, const char *string) +{ + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) { + c = c->next; + } + return c; +} + +/* Utility for array list handling. */ +static void +suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON * +create_reference(cJSON *item) +{ + cJSON *ref = cJSON_New_Item(); + if (!ref) { + return 0; + } + memcpy(ref, item, sizeof(cJSON)); + ref->string = 0; + ref->type |= cJSON_IsReference; + ref->next = ref->prev = 0; + return ref; +} + +/* Add item to array/object. */ +void +cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + cJSON *c = array->child; + if (!item) { + return; + } + if (!c) { + array->child = item; + } else { + while (c && c->next) { + c = c->next; + } + suffix_object(c, item); + } +} + +void +cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + if (!item) { + return; + } + if (item->string) { + cJSON_free(item->string); + } + item->string = cJSON_strdup(string); + cJSON_AddItemToArray(object, item); +} + +void +cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + cJSON_AddItemToArray(array, create_reference(item)); +} + +void +cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + cJSON_AddItemToObject(object, string, create_reference(item)); +} + +cJSON * +cJSON_DetachItemFromArray(cJSON *array, int which) +{ + cJSON *c = array->child; + while (c && which > 0) { + c = c->next, which--; + } + if (!c) { + return 0; + } + if (c->prev) { + c->prev->next = c->next; + } + if (c->next) { + c->next->prev = c->prev; + } + if (c == array->child) { + array->child = c->next; + } + c->prev = c->next = 0; + return c; +} + +void +cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +cJSON * +cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) { + i++, c = c->next; + } + if (c) { + return cJSON_DetachItemFromArray(object, i); + } + return 0; +} + +void +cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +/* Replace array/object items with new ones. */ +void +cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *c = array->child; + while (c && which > 0) { + c = c->next, which--; + } + if (!c) { + return; + } + newitem->next = c->next; + newitem->prev = c->prev; + if (newitem->next) { + newitem->next->prev = newitem; + } + if (c == array->child) { + array->child = newitem; + } else { + newitem->prev->next = newitem; + } + c->next = c->prev = 0; + cJSON_Delete(c); +} + +void +cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + int i = 0; + cJSON *c = object->child; + while (c && cJSON_strcasecmp(c->string, string)) { + i++, c = c->next; + } + if (c) { + newitem->string = cJSON_strdup(string); + cJSON_ReplaceItemInArray(object, i, newitem); + } +} + +/* Create basic types: */ +cJSON * +cJSON_CreateNull() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_NULL; + } + return item; +} + +cJSON * +cJSON_CreateTrue() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_True; + } + return item; +} + +cJSON * +cJSON_CreateFalse() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_False; + } + return item; +} + +cJSON * +cJSON_CreateBool(int b) +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = b ? cJSON_True : cJSON_False; + } + return item; +} + +cJSON * +cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Number; + item->valuedouble = num; + item->valueint = (int) num; + } + return item; +} + +cJSON * +cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_String; + item->valuestring = cJSON_strdup(string); + } + return item; +} + +cJSON * +cJSON_CreateArray() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Array; + } + return item; +} + +cJSON * +cJSON_CreateObject() +{ + cJSON *item = cJSON_New_Item(); + if (item) { + item->type = cJSON_Object; + } + return item; +} + +/* Create Arrays: */ +cJSON * +cJSON_CreateIntArray(int *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} + +cJSON * +cJSON_CreateFloatArray(float *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} + +cJSON * +cJSON_CreateDoubleArray(double *numbers, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateNumber(numbers[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} + +cJSON * +cJSON_CreateStringArray(const char **strings, int count) +{ + int i; + cJSON *n = 0, *p = 0, *a = cJSON_CreateArray(); + for (i = 0; a && i < count; i++) { + n = cJSON_CreateString(strings[i]); + if (!i) { + a->child = n; + } else { + suffix_object(p, n); + } + p = n; + } + return a; +} diff --git a/3sem/cnts/contest10/t2/cJSON.h b/3sem/cnts/contest10/t2/cJSON.h new file mode 100755 index 0000000..cc1beb9 --- /dev/null +++ b/3sem/cnts/contest10/t2/cJSON.h @@ -0,0 +1,133 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +// #ifdef __cplusplus +// extern "C" +//{ +// #endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON +{ + struct cJSON *next, *prev; /* next/prev allow you to walk array/object chains. Alternatively, use + GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the + array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char + *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks +{ + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks *hooks); + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array, int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object, const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back + * to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(); +extern cJSON *cJSON_CreateTrue(); +extern cJSON *cJSON_CreateFalse(); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(); +extern cJSON *cJSON_CreateObject(); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(int *numbers, int count); +extern cJSON *cJSON_CreateFloatArray(float *numbers, int count); +extern cJSON *cJSON_CreateDoubleArray(double *numbers, int count); +extern cJSON *cJSON_CreateStringArray(const char **strings, int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new + * cJSON, but don't want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array, int which); +extern void cJSON_DeleteItemFromArray(cJSON *array, int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object, const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object, const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem); + +#define cJSON_AddNullToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object, name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddNumberToObject(object, name, n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object, name, s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +// #ifdef __cplusplus +// } +// #endif + +#endif diff --git a/3sem/cnts/contest10/t2/gdb-2-task.tar b/3sem/cnts/contest10/t2/gdb-2-task.tar new file mode 100755 index 0000000000000000000000000000000000000000..b40f33ae5b76122f12564cc2186fd8024ff19a09 GIT binary patch literal 32256 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 VeEss30$(Zcl>%QW@E=Hl{{`e0s{Q}~ literal 0 HcmV?d00001 diff --git a/3sem/cnts/contest10/t2/gdb-2-task.tarZone.Identifier b/3sem/cnts/contest10/t2/gdb-2-task.tarZone.Identifier new file mode 100755 index 0000000..ffebe14 --- /dev/null +++ b/3sem/cnts/contest10/t2/gdb-2-task.tarZone.Identifier @@ -0,0 +1,4 @@ +[ZoneTransfer] +ZoneId=3 +ReferrerUrl=https://unicorn.ejudge.ru/ej/client/view-problem-submit/Sa889e21564f40a8b?prob_id=81 +HostUrl=https://unicorn.ejudge.ru/ej/client?SID=a889e21564f40a8b&prob_id=81&action=194&file=gdb-2-task.tar diff --git a/3sem/cnts/contest10/t2/task2 b/3sem/cnts/contest10/t2/task2 new file mode 100755 index 0000000000000000000000000000000000000000..e1c7dfad70cfde93d8a2639d463c4edd670fdf9f GIT binary patch literal 39704 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 +#include +#include "cJSON.h" + +void +task2() +{ + cJSON *item; + char *text; + + item = cJSON_Parse("{" + "\"name\" : \"Ivanov\"," + "\"age\" : 25" + "}"); + + text = cJSON_PrintUnformatted(item); + + puts(text); + + free(text); + cJSON_Delete(item); +} + +int +main(int argc, char **argv) +{ + task2(); + + return 0; +} diff --git a/3sem/cnts/contest10/t2/task2.out b/3sem/cnts/contest10/t2/task2.out new file mode 100755 index 0000000..3d22ae7 --- /dev/null +++ b/3sem/cnts/contest10/t2/task2.out @@ -0,0 +1 @@ +{"name":"Ivanov","age":25} \ No newline at end of file diff --git a/3sem/cnts/contest11/01.c b/3sem/cnts/contest11/01.c new file mode 100755 index 0000000..23dfc53 --- /dev/null +++ b/3sem/cnts/contest11/01.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +int +proc(void) +{ + int pid = fork(); + if (!pid) { + write(1, "1\n", 2); + } + return pid; +} + +int +main(int argc, char **argv) +{ + proc(), proc(), proc(); + + return 0; +} diff --git a/3sem/cnts/contest11/01_ans.c b/3sem/cnts/contest11/01_ans.c new file mode 100755 index 0000000..8a95483 --- /dev/null +++ b/3sem/cnts/contest11/01_ans.c @@ -0,0 +1 @@ +proc(), proc(), proc() diff --git a/3sem/cnts/contest11/02.c b/3sem/cnts/contest11/02.c new file mode 100755 index 0000000..1b04694 --- /dev/null +++ b/3sem/cnts/contest11/02.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +int +main() +{ + pid_t pid; + pid = fork(); + if (!pid) { + pid = fork(); + if (!pid) { + printf("3 "); + + return 0; + } else if (pid == -1) { + return 1; + } else { + wait(NULL); + printf("2 "); + } + return 0; + } else if (pid == -1) { + return 1; + } else { + wait(NULL); + printf("1"); + } + + printf("\n"); + + return 0; +} diff --git a/3sem/cnts/contest11/03.c b/3sem/cnts/contest11/03.c new file mode 100755 index 0000000..f785b7e --- /dev/null +++ b/3sem/cnts/contest11/03.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include + +enum +{ + MAX_LEN = 8 +}; + +void +process_line(int line_number) +{ + char buffer[MAX_LEN + 1] = {0}; + read(0, buffer, sizeof(buffer) - 1); + long long number = strtoll(buffer, NULL, 10); + long long square = number * number; + printf("%d %lld\n", line_number, square); + + return; +} + +int +main() +{ + pid_t pid; + + for (int i = 0; i < 3; i++) { + if ((pid = fork()) == 0) { + process_line(i + 1); + exit(0); + } + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/cnts/contest11/04 b/3sem/cnts/contest11/04 new file mode 100755 index 0000000..e440e5c --- /dev/null +++ b/3sem/cnts/contest11/04 @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/3sem/cnts/contest11/04.c b/3sem/cnts/contest11/04.c new file mode 100755 index 0000000..4e4577a --- /dev/null +++ b/3sem/cnts/contest11/04.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +int +main() +{ + pid_t pid; + + int n; + if (scanf("%d", &n) != 1) { + return 1; + } + + for (int i = 1; i <= n; i++) { + printf("%d", i); + fflush(stdout); + + if (i == n) { + printf("\n"); + return 0; + } else { + printf(" "); + fflush(stdout); + } + pid = fork(); + + if (!pid) { + continue; + } else { + wait(NULL); + return 0; + } + } + + return 0; +} diff --git a/3sem/cnts/contest11/05 b/3sem/cnts/contest11/05 new file mode 100755 index 0000000..703ca85 --- /dev/null +++ b/3sem/cnts/contest11/05 @@ -0,0 +1 @@ +1 2 3 \ No newline at end of file diff --git a/3sem/cnts/contest11/05.c b/3sem/cnts/contest11/05.c new file mode 100755 index 0000000..1f4aad0 --- /dev/null +++ b/3sem/cnts/contest11/05.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +int +main() +{ + + pid_t pid; + int n; + + pid = fork(); + if (!pid) { + for (;;) { + if (scanf("%d", &n) != 1) { + return 0; + } + + pid = fork(); + if (!pid) { + continue; + } + int status; + wait(&status); + if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) { + return -1; + } + + printf("%d\n", n); + return 0; + } + } else { + int status; + wait(&status); + if (pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status)) { + printf("-1\n"); + } + } + + return 0; +} diff --git a/3sem/cnts/contest12/01.c b/3sem/cnts/contest12/01.c new file mode 100755 index 0000000..77b7168 --- /dev/null +++ b/3sem/cnts/contest12/01.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include + +// CMD < FILE1 >> FILE2 2> FILE3 + +enum +{ + EXIT_ERROR = 42, + ACCESS_FILE = 0660 +}; + +int +main(int argc, char **argv) +{ + char *cmd = argv[1]; + char *file1 = argv[2]; + char *file2 = argv[3]; + char *file3 = argv[4]; + pid_t pid = fork(); + if (pid == 0) { + + int fd1 = open(file1, O_RDONLY); + int fd2 = open(file2, O_WRONLY | O_APPEND | O_CREAT, ACCESS_FILE); + int fd3 = open(file3, O_WRONLY | O_TRUNC | O_CREAT, ACCESS_FILE); + + if (fd1 == -1 || fd2 == -1 || fd3 == -1) { + _exit(EXIT_ERROR); + } + + if (dup2(fd1, 0) == -1 || dup2(fd2, 1) == -1 || dup2(fd3, 2) == -1) { + _exit(EXIT_ERROR); + } + + execlp(cmd, cmd, NULL); + _exit(EXIT_ERROR); + } else { + int status; + wait(&status); + printf("%d\n", status); + } + + return 0; +} diff --git a/3sem/cnts/contest12/02-ai.c b/3sem/cnts/contest12/02-ai.c new file mode 100755 index 0000000..b5e6ded --- /dev/null +++ b/3sem/cnts/contest12/02-ai.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +int +run_command(char *cmd) +{ + pid_t pid = fork(); + if (pid == -1) { + perror("fork"); + exit(1); + } else if (pid == 0) { + execlp(cmd, cmd, (char *) NULL); + perror("execlp"); + exit(1); + } else { + int status; + waitpid(pid, &status, 0); + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + return 1; + } else { + return 0; + } + } +} + +int +main(int argc, char *argv[]) +{ + int cmd1_success = run_command(argv[1]); + int cmd2_success = 0; + + if (!cmd1_success) { + cmd2_success = run_command(argv[2]); + } + + if (cmd1_success || cmd2_success) { + if (run_command(argv[3])) { + exit(0); + } else { + exit(1); + } + } + + exit(1); +} diff --git a/3sem/cnts/contest12/02.c b/3sem/cnts/contest12/02.c new file mode 100755 index 0000000..4d5c56c --- /dev/null +++ b/3sem/cnts/contest12/02.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include +#include + +int +run(const char *cmd) +{ + pid_t pid = fork(); + if (pid == -1) { + exit(1); + } else if (pid == 0) { + execlp(cmd, cmd, NULL); + _exit(1); + } + int status; + waitpid(pid, &status, 0); + + return WIFEXITED(status) && !WEXITSTATUS(status); +} // 1 - при успехе + +int +main(int argc, char **argv) +{ + if (argc != 4) { + return 1; + } + + char *cmd1 = argv[1]; + char *cmd2 = argv[2]; + char *cmd3 = argv[3]; + + return !((run(cmd1) || run(cmd2)) && run(cmd3)); +} diff --git a/3sem/cnts/contest12/03.c b/3sem/cnts/contest12/03.c new file mode 100755 index 0000000..8211e4b --- /dev/null +++ b/3sem/cnts/contest12/03.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +int +check(void) +{ + int succes = 0; + int status; + + while (wait(&status) != -1) { + if (WIFEXITED(status) && !WEXITSTATUS(status)) { + succes++; + } + } + + return succes; +} + +void +run(char *cmd) +{ + pid_t pid = fork(); + if (pid == -1) { + exit(1); + } else if (pid == 0) { + execlp(cmd, cmd, NULL); + _exit(1); + } + + return; +} // 1 - при успехе + +int +main(int argc, char **argv) +{ + int succes = 0; + + for (int i = 1; i < argc; ++i) { + if (argv[i][0] == 's') { + succes += check(); + run(argv[i] + 1); + succes += check(); + } else if (argv[i][0] == 'p') { + run(argv[i] + 1); + } else { + fprintf(stderr, "Error in arguments\n"); + exit(1); + } + } + + succes += check(); + + printf("%d\n", succes); + + return 0; +} diff --git a/3sem/cnts/contest12/04.c b/3sem/cnts/contest12/04.c new file mode 100755 index 0000000..f5399f5 --- /dev/null +++ b/3sem/cnts/contest12/04.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + if (argc < 2) { + return 1; + } + + char script_template[] = "#!/usr/bin/env python3\n" + "import os\n" + "print("; + char script_end[] = ")\n" + "os.remove(__file__)\n"; + + size_t script_size = strlen(script_template) + strlen(script_end) + 1; + for (int i = 1; i < argc; i++) { + script_size += strlen(argv[i]) + 1; + } + + char *script_content; + if (!(script_content = malloc(script_size))) { + return 1; + } + + strcpy(script_content, script_template); + + for (int i = 1; i < argc; i++) { + strcat(script_content, argv[i]); + + if (i < argc - 1) { + strcat(script_content, "*"); + } + } + + strcat(script_content, script_end); + + char *tmpdir = getenv("XDG_RUNTIME_DIR"); + if (!tmpdir) { + tmpdir = getenv("TMPDIR"); + + if (!tmpdir) { + tmpdir = "/tmp"; + } + } + + char script_path[PATH_MAX]; + int r = snprintf(script_path, sizeof(script_path), "%s/%d", tmpdir, (int) (getpid() * time(NULL) % 1000000)); + if (r < 0 || r > PATH_MAX) { + exit(1); + } + + int fd = open(script_path, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd == -1) { + free(script_content); + return 1; + } + + FILE *script_file = fdopen(fd, "w"); + if (!script_file) { + close(fd); + unlink(script_path); + free(script_content); + return 1; + } + + fprintf(script_file, "%s", script_content); + fclose(script_file); + free(script_content); + + if (chmod(script_path, 0700) == -1) { + unlink(script_path); + return 1; + } + + execl(script_path, script_path, (char *) NULL); + unlink(script_path); + + return 1; +} diff --git a/3sem/cnts/contest13/01.c b/3sem/cnts/contest13/01.c new file mode 100755 index 0000000..a2c9ced --- /dev/null +++ b/3sem/cnts/contest13/01.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +enum +{ + YEAR_OFFSET = 1900 +}; + +int +main(void) +{ + + int fd[2]; + pipe(fd); + time_t delta; + struct tm *dt; + + pid_t pid = fork(); + if (pid == 0) { + pid = fork(); + + if (pid == 0) { + pid = fork(); + + if (pid == 0) { + close(fd[0]); + + delta = time(NULL); + if (write(fd[1], &delta, sizeof(delta)) == -1 || write(fd[1], &delta, sizeof(delta)) == -1 || + write(fd[1], &delta, sizeof(delta)) == -1) { + _exit(1); + } + } else if (pid == -1) { + _exit(1); + } + close(fd[1]); + wait(NULL); + if (read(fd[0], &delta, sizeof(delta)) == -1) { + _exit(1); + } + dt = localtime(&delta); + printf("D:%02d\n", dt->tm_mday); + fflush(stdout); + _exit(0); + } else if (pid == -1) { + _exit(1); + } + + close(fd[1]); + wait(NULL); + if (read(fd[0], &delta, sizeof(delta)) == -1) { + _exit(1); + } + dt = localtime(&delta); + printf("M:%02d\n", dt->tm_mon + 1); + fflush(stdout); + _exit(0); + } else if (pid == -1) { + _exit(1); + } + close(fd[1]); + wait(NULL); + if (read(fd[0], &delta, sizeof(delta)) == -1) { + _exit(1); + } + dt = localtime(&delta); + printf("Y:%04d\n", dt->tm_year + YEAR_OFFSET); + fflush(stdout); + + return 0; +} diff --git a/3sem/cnts/contest13/03.c b/3sem/cnts/contest13/03.c new file mode 100755 index 0000000..aba530b --- /dev/null +++ b/3sem/cnts/contest13/03.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include + +enum +{ + ACCESS_FILE = 0660 +}; + +int +main(int argc, char **argv) +{ + char *cmd1 = argv[1]; + char *cmd2 = argv[2]; + char *cmd3 = argv[3]; + char *file1 = argv[4]; + char *file2 = argv[5]; + + int fd1 = open(file1, O_RDONLY); + int fd2 = open(file2, O_WRONLY | O_APPEND | O_CREAT, ACCESS_FILE); + if (fd1 == -1 || fd2 == -1) { + exit(1); + } + + int fd[2]; + if (pipe(fd) == -1) { + return 1; + } + + pid_t pid = fork(); + if (pid == 0) { + close(fd[0]); + if (dup2(fd[1], 1) == -1) { + _exit(1); + } + + pid = fork(); + if (pid == 0) { + + if (dup2(fd1, 0) == -1) { + _exit(1); + } + + execlp(cmd1, cmd1, NULL); + _exit(1); + } else if (pid == -1) { + exit(1); + } + + int status; + wait(&status); + + if (WIFEXITED(status) && !WEXITSTATUS(status)) { + pid = fork(); + if (pid == 0) { + execlp(cmd2, cmd2, NULL); + _exit(1); + } else if (pid == -1) { + exit(1); + } + + wait(NULL); + } + + _exit(0); + } else if (pid == -1) { + exit(1); + } + + close(fd[1]); + pid = fork(); + if (pid == 0) { + + if (dup2(fd2, 1) == -1 || dup2(fd[0], 0)) { + _exit(1); + } + + execlp(cmd3, cmd3, NULL); + _exit(1); + } else if (pid == -1) { + exit(1); + } + + close(fd[0]); + + while (wait(NULL) != -1) + ; + return 0; +} diff --git a/3sem/cnts/contest13/04.c b/3sem/cnts/contest13/04.c new file mode 100755 index 0000000..6abfc4c --- /dev/null +++ b/3sem/cnts/contest13/04.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include + +void +ex(void) +{ + // разослать SIGKILL + // а некому. + + exit(1); +} + +void +swap(int *a, int *b) +{ + int tmp = *a; + *a = *b; + *b = tmp; + + return; +} + +int +main(int argc, char **argv) +{ + int fd1[2]; + int fd2[2]; + if (close(2) == -1 || pipe(fd1) == -1 || pipe(fd2)) { + ex(); + } + + for (int i = 1; i < argc; ++i) { + pid_t pid = fork(); + if (pid == 0) { + + if (i != 1 && i != argc - 1) { + if (dup2(fd2[1], 1) == -1 || dup2(fd1[0], 0) == -1) { + ex(); + } + } else if (i == 1) { + if (dup2(fd2[1], 1) == -1) { + ex(); + } + } else { + if (dup2(fd1[0], 0) == -1) { + ex(); + } + } + + close(fd1[0]); + close(fd1[1]); + close(fd2[0]); + close(fd2[1]); + + execlp(argv[i], argv[i], NULL); + _exit(1); + } else if (pid == -1) { + ex(); + } + + swap(&fd1[0], &fd2[0]); + swap(&fd1[1], &fd2[1]); + wait(NULL); + } + + return 0; +} diff --git a/3sem/cnts/contest13/05.c b/3sem/cnts/contest13/05.c new file mode 100755 index 0000000..75ca331 --- /dev/null +++ b/3sem/cnts/contest13/05.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int n = (int) strtoll(argv[1], NULL, 10); + + int fd1[2]; + int fd2[2]; + pipe(fd1); + pipe(fd2); + + int tmp = 1; + write(fd2[1], &tmp, sizeof(tmp)); + + if (!fork()) { + int i = 0; + close(fd1[0]); + close(fd2[1]); + + while (i < n) { + if (read(fd2[0], &i, sizeof(i)) == -1) { + return 0; + } + if (i >= n) { + write(fd1[1], &i, sizeof(i)); + break; + } + printf("%d %d\n", 1, i); + fflush(stdout); + i++; + write(fd1[1], &i, sizeof(i)); + } + + return 0; + } else if (!fork()) { + int i = 0; + close(fd2[0]); + close(fd1[1]); + + while (i < n) { + if (read(fd1[0], &i, sizeof(i)) == -1) { + return 0; + } + if (i >= n) { + write(fd1[1], &i, sizeof(i)); + break; + } + printf("%d %d\n", 2, i); + fflush(stdout); + i++; + write(fd2[1], &i, sizeof(i)); + } + + return 0; + } + + close(fd1[0]); + close(fd1[1]); + close(fd2[0]); + close(fd2[1]); + + while (wait(NULL) != -1) + ; + + printf("Done\n"); + + return 0; +} diff --git a/3sem/cnts/contest14/01.c b/3sem/cnts/contest14/01.c new file mode 100755 index 0000000..2937105 --- /dev/null +++ b/3sem/cnts/contest14/01.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include + +volatile int cnt = 0; + +void +f(int n) +{ + if (cnt == 5) { + exit(0); + } + + printf("%d\n", cnt++); + fflush(stdout); + + return; +} + +int +main(int argc, char *argv[]) +{ + sigaction(SIGHUP, &(struct sigaction){.sa_handler = f, .sa_flags = SA_RESTART}, NULL); + + printf("%d\n", getpid()); + fflush(stdout); + + for (;;) { + pause(); + } + + return 0; +} diff --git a/3sem/cnts/contest14/02.c b/3sem/cnts/contest14/02.c new file mode 100755 index 0000000..521988e --- /dev/null +++ b/3sem/cnts/contest14/02.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +volatile int mode = 0; // 0 - + 1 - * + +void +mul(int n) +{ + mode = 1; + + return; +} + +void +sum(int n) +{ + mode = 0; + + return; +} + +int +main(int argc, char *argv[]) +{ + sigaction(SIGINT, &(struct sigaction){.sa_handler = sum, .sa_flags = SA_RESTART}, NULL); + sigaction(SIGQUIT, &(struct sigaction){.sa_handler = mul, .sa_flags = SA_RESTART}, NULL); + + printf("%d\n", getpid()); + fflush(stdout); + + int res = 0, tmp; + + while (scanf("%d", &tmp) == 1) { + if (mode == 0) { + __builtin_add_overflow(res, tmp, &res); + } else { + __builtin_mul_overflow(res, tmp, &res); + } + printf("%d\n", res); + fflush(stdout); + } + + // for (;;) { + // pause(); + // } + + return 0; +} diff --git a/3sem/cnts/contest14/04.c b/3sem/cnts/contest14/04.c new file mode 100755 index 0000000..ab77eca --- /dev/null +++ b/3sem/cnts/contest14/04.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int n = (int) strtoll(argv[1], NULL, 10); + + int fd[2]; + pipe(fd); + + int tmp = 1; + write(fd2[1], &tmp, sizeof(tmp)); + + if (!fork()) { + int i = 0; + close(fd[0]); + + while (i < n) { + if (read(fd2[0], &i, sizeof(i)) == -1) { + return 0; + } + if (i >= n) { + write(fd1[1], &i, sizeof(i)); + break; + } + printf("%d %d\n", 1, i); + fflush(stdout); + i++; + write(fd1[1], &i, sizeof(i)); + } + + return 0; + } else if (!fork()) { + int i = 0; + close(fd2[0]); + close(fd1[1]); + + while (i < n) { + if (read(fd1[0], &i, sizeof(i)) == -1) { + return 0; + } + if (i >= n) { + write(fd1[1], &i, sizeof(i)); + break; + } + printf("%d %d\n", 2, i); + fflush(stdout); + i++; + write(fd2[1], &i, sizeof(i)); + } + + return 0; + } + + close(fd[0]); + close(fd[1]); + + while (wait(NULL) != -1) + ; + + printf("Done\n"); + + return 0; +} diff --git a/3sem/cnts/contest14/04a.c b/3sem/cnts/contest14/04a.c new file mode 100755 index 0000000..62bb25f --- /dev/null +++ b/3sem/cnts/contest14/04a.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include + +volatile sig_atomic_t sigusr1_received = 0; + +void +sigusr1_handler(int signum) +{ + sigusr1_received = 1; +} + +int +main(int argc, char **argv) +{ + int n = (int) strtol(argv[1], NULL, 10); + + int fd[2]; + pipe(fd); + + signal(SIGUSR1, sigusr1_handler); + + if (!fork()) { + close(fd[0]); + FILE *out = fdopen(fd[1], "w"); + + int i = 1; + while (i <= n) { + printf("1 %d\n", i); + fflush(stdout); + fprintf(out, "%d\n", i); + fflush(out); + kill(getppid(), SIGUSR1); + pause(); + if (i >= n) { + break; + } + i++; + } + + fclose(out); + return 0; + } else if (!fork()) { + close(fd[1]); + FILE *in = fdopen(fd[0], "r"); + + int i; + while (1) { + if (i >= n) { + break; + } + i++; + printf("2 %d\n", i); + fflush(stdout); + kill(getppid(), SIGUSR1); + pause(); + } + + fclose(in); + return 0; + } + + close(fd[0]); + close(fd[1]); + + while (wait(NULL) != -1) + ; + + printf("Done\n"); + + return 0; +} diff --git a/3sem/cnts/contest14/05.c b/3sem/cnts/contest14/05.c new file mode 100755 index 0000000..9eee975 --- /dev/null +++ b/3sem/cnts/contest14/05.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include + +volatile int last_prime = 0; +volatile int cnt = 0; + +void +f(int n) +{ + if (++cnt == 4) { + exit(0); + } + + printf("%d\n", last_prime); + fflush(stdout); + + return; +} + +void +exit_term(int n) +{ + exit(0); + + return; +} + +int +is_prime(int n) +{ + if (n < 2) { + return 0; + } + + for (int i = 2; i * i <= n; ++i) { + if (n % i == 0) { + return 0; + } + } + + return 1; +} + +int +main(int argc, char *argv[]) +{ + sigaction(SIGINT, &(struct sigaction){.sa_handler = f, .sa_flags = SA_RESTART}, NULL); + sigaction(SIGTERM, &(struct sigaction){.sa_handler = exit_term, .sa_flags = SA_RESTART}, NULL); + + printf("%d\n", getpid()); + fflush(stdout); + + int a, b; + scanf("%d", &a); + scanf("%d", &b); + + a = (a < 2) ? 2 : a; + + for (int i = a; i < b; ++i) { + if (is_prime(i)) { + last_prime = i; + } + } + + printf("-1\n"); + fflush(stdout); + + return 0; +} diff --git a/3sem/cnts/contest14/t1.c b/3sem/cnts/contest14/t1.c new file mode 100755 index 0000000..6d61c89 --- /dev/null +++ b/3sem/cnts/contest14/t1.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include + +volatile int count = 0; + +void +func(int sign) +{ + if (count < 5) { + printf("%d\n", count); + fflush(stdout); + count++; + } else { + exit(0); + } +} + +int +main(int argc, char *argv[]) +{ + printf("%d\n", getpid()); + fflush(stdout); + + if (signal(SIGHUP, func) == SIG_ERR) { + exit(1); + } + for (;;) { + pause(); + } + + return 0; +} diff --git a/3sem/cnts/contest2/01.c b/3sem/cnts/contest2/01.c new file mode 100755 index 0000000..f0164cc --- /dev/null +++ b/3sem/cnts/contest2/01.c @@ -0,0 +1,27 @@ +// #include + +typedef int STYPE; +typedef unsigned int UTYPE; + +STYPE +bit_reverse(STYPE value) +{ + UTYPE result = 0; + UTYPE uvalue = (UTYPE) value; + for (int i = 0; i < sizeof(STYPE) * 8; i++) { + result <<= 1; + result |= uvalue & 1; + uvalue >>= 1; + } + return (STYPE) result; +} + +// int main(void) { + +// STYPE value = 0b10101010; +// STYPE result = bit_reverse(value); +// printf("%d\n", result); +// printf("%ld\n", sizeof(STYPE)); + +// return 0; +// } diff --git a/3sem/cnts/contest2/02.c b/3sem/cnts/contest2/02.c new file mode 100755 index 0000000..a3c54d3 --- /dev/null +++ b/3sem/cnts/contest2/02.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + long long res_pos = 0, res_neg = 0; + + for (int i = 1; i < argc; i++) { + char *p; + errno = 0; + long long val = strtol(argv[i], &p, 10); + if (*p || errno || (int32_t) val != val || argv[i] == p) { + return 1; + } + // int32_t tmp; + if (val >= 0) { + // if (!__builtin_add_overflow(res_pos, val, &tmp)) { + res_pos += val; + // } + } else { + // if (!__builtin_add_overflow(res_neg, val, &tmp)) { + res_neg += val; + // } + } + } + + // if (!(res_neg && res_pos)) { + // printf("0\n"); + // } else { + // printf("%d\n", res_pos); + // printf("%d\n", res_neg); + // } + + printf("%lld\n", res_pos); + printf("%lld\n", res_neg); + + return 0; +} diff --git a/3sem/cnts/contest2/03.c b/3sem/cnts/contest2/03.c new file mode 100755 index 0000000..7fe7fd1 --- /dev/null +++ b/3sem/cnts/contest2/03.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +enum +{ + PRCN = 10000, +}; + +int +main(int argc, char *argv[]) +{ + long double a = 0; + + for (int i = 1; i < argc; i++) { + char *p; + errno = 0; + long double val = strtod(argv[i], &p); + if (*p || errno || argv[i] == p) { + return 1; + } + + if (i == 1) { + a = val * PRCN; + } else { + a = round(a * (100.L + val) / 100.L); + } + } + + if (argc == 1) { + return 1; + } + + printf("%.4Lf\n", a / PRCN); + + return 0; +} diff --git a/3sem/cnts/contest2/04.c b/3sem/cnts/contest2/04.c new file mode 100755 index 0000000..3dd3eec --- /dev/null +++ b/3sem/cnts/contest2/04.c @@ -0,0 +1,22 @@ +#include + +enum +{ + MY_INT_MAX = ~0u >> (!0), + MY_INT_MIN = ~(~0u >> (!0)) +}; + +int +satsum(int v1, int v2) +{ + int sum; + if (!__builtin_add_overflow(v1, v2, &sum)) { + return sum; + } else if (v1 > 0) { + return MY_INT_MAX; + } else { + return MY_INT_MIN; + } + + return 0; +} diff --git a/3sem/cnts/contest3/04.c b/3sem/cnts/contest3/04.c new file mode 100755 index 0000000..16f3c33 --- /dev/null +++ b/3sem/cnts/contest3/04.c @@ -0,0 +1,19 @@ +enum +{ + MY_INT_MAX = ~0u >> (!0), + MY_INT_MIN = ~(~0u >> (!0)) +}; + +int +satsum(int v1, int v2) +{ + if (v1 > 0 && (signed int) MY_INT_MAX - v1 < v2) { + return MY_INT_MAX; + } + + if (v1 < 0 && (signed int) MY_INT_MIN - v1 > v2) { + return MY_INT_MIN; + } + + return v1 + v2; +} diff --git a/3sem/cnts/contest3/05.c b/3sem/cnts/contest3/05.c new file mode 100755 index 0000000..66380f8 --- /dev/null +++ b/3sem/cnts/contest3/05.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +enum +{ + CHAR_IN_INT = 12 +}; + +struct Elem +{ + struct Elem *next; + char *str; +}; + +struct Elem * +dup_elem(struct Elem *head) +{ + if (head == NULL) { + return NULL; + } + + head->next = dup_elem(head->next); + + errno = 0; + char *p; + long n = strtol(head->str, &p, 10); + if (errno || (int) n != n || n == INT_MAX || *p || p == head->str) { + return head; + } + + struct Elem *new = calloc(1, sizeof(*new)); + if (new == NULL) { + exit(1); + } + + char *str = calloc(CHAR_IN_INT, sizeof(*str)); + snprintf(str, CHAR_IN_INT, "%d", (int) n + 1); + + new->str = str; + new->next = head; + + return new; +} diff --git a/3sem/cnts/contest4/01.c b/3sem/cnts/contest4/01.c new file mode 100755 index 0000000..b2e37f3 --- /dev/null +++ b/3sem/cnts/contest4/01.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include +#include + +enum +{ + PEN_CHAR_BIT = 12 +}; + +int +safe_write(int fd, void *buf, size_t count) +{ + errno = 0; + size_t bytes_written = 0; + while (bytes_written < count) { + ssize_t res = write(fd, buf + bytes_written, count - bytes_written); + + if (res < 0) { + if (errno == EINTR) { + errno = 0; + continue; + } + + fprintf(stderr, "Error writing to file descriptor %d\n", fd); + close(fd); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + bytes_written += res; + } + + return bytes_written; +} + +int +main(int argc, char **argv) +{ + int fdout = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fdout == -1) { + return 1; + } + + unsigned char res[4]; + unsigned tmp; + while (scanf("%u", &tmp) == 1) { + res[0] = (tmp & (0x0F << (CHAR_BIT + PEN_CHAR_BIT))) >> (CHAR_BIT + PEN_CHAR_BIT); + res[1] = (tmp & (0xFF << PEN_CHAR_BIT)) >> PEN_CHAR_BIT; + res[2] = (tmp & (0x0F << CHAR_BIT)) >> CHAR_BIT; + res[3] = tmp & 0xFF; + safe_write(fdout, res, sizeof(res)); + } + + close(fdout); + + return 0; +} diff --git a/3sem/cnts/contest4/02.c b/3sem/cnts/contest4/02.c new file mode 100755 index 0000000..6e624d5 --- /dev/null +++ b/3sem/cnts/contest4/02.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +safe_write(int fd, void *buf, size_t count) +{ + errno = 0; + size_t bytes_written = 0; + while (bytes_written < count) { + ssize_t res = write(fd, buf + bytes_written, count - bytes_written); + + if (res < 0) { + if (errno == EINTR) { + errno = 0; + continue; + } + + fprintf(stderr, "Error writing to file descriptor %d\n", fd); + close(fd); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + bytes_written += res; + } + + return bytes_written; +} + +int +main(int argc, char **argv) +{ + if (argc < 3) { + return 1; + } + + long long n; + str_to_ll(argv[2], &n); + + int fd = open(argv[1], O_RDWR); + if (fd == -1) { + return 1; + } + + int is_first = 1; + double prev; + + for (int i = 0; i < n; ++i) { + double tmp; + int r = read(fd, &tmp, sizeof(tmp)); + if (r == -1 || (r && r != sizeof(tmp))) { + return 1; + } + if (r < 1) { + break; + } + + if (!is_first) { + tmp -= prev; + } else { + is_first = 0; + } + + if (lseek(fd, -sizeof(tmp), SEEK_CUR) == -1) { + return 1; + } + safe_write(fd, &tmp, sizeof(tmp)); + prev = tmp; + } + + close(fd); + + return 0; +} diff --git a/3sem/cnts/contest4/03-test.c b/3sem/cnts/contest4/03-test.c new file mode 100755 index 0000000..b83b2c4 --- /dev/null +++ b/3sem/cnts/contest4/03-test.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include + +ssize_t +my_write(int fd, void *buf, size_t count) +{ + size_t count_1 = 0; + ssize_t count_2; + while (count_1 != count) { + count_2 = write(fd, buf, count - count_1); + if (count_2 == -1) { + return -1; + } else if (count_2 == 0) { + return (ssize_t) count_1; + } else { + count_1 += (size_t) count_2; + } + } + return (ssize_t) count_1; +} + +ssize_t +my_read(int fd, void *buf, size_t count) +{ + size_t count_1 = 0; + ssize_t count_2; + while (count_1 != count) { + count_2 = read(fd, buf, count - count_1); + if (count_2 == -1) { + return -1; + } else if (count_2 == 0) { + return (ssize_t) count_1; + } else { + count_1 += (size_t) count_2; + } + } + return (ssize_t) count_1; +} + +int +main(int argc, char **argv) +{ + if (argc < 2) { + return 1; + } + + int fd; + if ((fd = open(argv[1], O_RDWR)) == -1) { + return 1; + } + + long long num, min, shift = 0; + + if (my_read(fd, &min, sizeof(min)) < sizeof(min)) { + if (errno) { + close(fd); + return 1; + } + close(fd); + return 0; + } + + for (int i = (int) sizeof(num); my_read(fd, &num, sizeof(min)) == sizeof(min); i += (int) sizeof(num)) { + if (num < min) { + min = num; + shift = i; + } + } + + lseek(fd, shift, 0); + if (errno) { + close(fd); + return 1; + } + + if (min != LLONG_MIN) { + min = -min; + } + + if (my_write(fd, &min, sizeof(min)) != sizeof(min)) { + close(fd); + return 1; + } + + close(fd); + if (errno) { + return 1; + } +} diff --git a/3sem/cnts/contest4/03.c b/3sem/cnts/contest4/03.c new file mode 100755 index 0000000..362a24d --- /dev/null +++ b/3sem/cnts/contest4/03.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum +{ + ARGS_NUM = 2, +}; + +int +safe_read(int fd, void *buf, size_t count) +{ + errno = 0; + size_t bytes_read = 0; + while (bytes_read < count) { + ssize_t res = read(fd, buf + bytes_read, count - bytes_read); + + if (res < 0) { + if (errno == EINTR) { + errno = 0; + continue; + } + + fprintf(stderr, "Error reading from file descriptor %d\n", fd); + close(fd); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + if (res == 0) { + break; + } + + bytes_read += res; + } + + return bytes_read; +} + +int +safe_write(int fd, void *buf, size_t count) +{ + errno = 0; + size_t bytes_written = 0; + while (bytes_written < count) { + ssize_t res = write(fd, buf + bytes_written, count - bytes_written); + + if (res < 0) { + if (errno == EINTR) { + errno = 0; + continue; + } + + fprintf(stderr, "Error writing to file descriptor %d\n", fd); + close(fd); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + bytes_written += res; + } + + return bytes_written; +} + +int +main(int argc, char *argv[]) +{ + if (argc != ARGS_NUM) { + fprintf(stderr, "Wrong number of arguments\n"); + return 1; + } + + int fd = open(argv[1], O_RDWR); + if (fd == -1) { + fprintf(stderr, "Error opening file %s\n", argv[1]); + + return 1; + } + + long long num, min_num = LLONG_MAX; + off_t pt_min = -1; + + while (safe_read(fd, &num, sizeof(num)) == sizeof(num)) { + if (num < min_num || pt_min == -1) { + min_num = num; + + if ((pt_min = lseek(fd, 0, SEEK_CUR) - sizeof(num)) == -1) { + fprintf(stderr, "Error in navigate file %s\n", argv[1]); + + return 1; + } + } + } + + if (min_num != LLONG_MIN && pt_min != -1) { + min_num = -min_num; + if (lseek(fd, pt_min, SEEK_SET) == -1) { + fprintf(stderr, "Error in navigate file %s\n", argv[1]); + + return 1; + } + + if (safe_write(fd, &min_num, sizeof(min_num)) != sizeof(num)) { + printf("Error while writing"); + + return 1; + } + } + + close(fd); + + return 0; +} diff --git a/3sem/cnts/contest4/04-copy.c b/3sem/cnts/contest4/04-copy.c new file mode 100755 index 0000000..4ea7842 --- /dev/null +++ b/3sem/cnts/contest4/04-copy.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct Node +{ + int32_t key; + int32_t left_idx; + int32_t right_idx; +}; + +void +read_struct(int fd, struct Node *node, int is_le) +{ + unsigned char buf[sizeof(*node)]; + int n = 0; + while (n != sizeof(*node)) { + ssize_t off = read(fd, buf + n, sizeof(*node) - n); + if (off == -1) { + close(fd); + exit(1); + } + n += off; + } + // int r = read(fd, buf, sizeof(*node)); + // if (r == -1) { + // close(fd); + // exit(1); + // } + + int n_byte = sizeof(int32_t); + node->key = 0; + node->left_idx = 0; + node->right_idx = 0; + + for (int j = 0; j < n_byte; ++j) { + int off = (is_le) ? (CHAR_BIT * (sizeof(uint32_t) - (j + 1))) : (CHAR_BIT * j); + + node->key |= (uint32_t) buf[j] << off; + node->left_idx |= (uint32_t) buf[j + n_byte * 1] << off; + node->right_idx |= (uint32_t) buf[j + n_byte * 2] << off; + } +} + +void +inorder_traversal(int fd, int32_t idx, int is_le) +{ + if (idx == 0) { + return; + } + if (idx == -1) { + idx = 0; + } + + struct Node tmp; + if (lseek(fd, idx * sizeof(struct Node), SEEK_SET) == -1) { + close(fd); + exit(1); + } + read_struct(fd, &tmp, is_le); + + inorder_traversal(fd, tmp.right_idx, is_le); + printf("%d\n", tmp.key); + inorder_traversal(fd, tmp.left_idx, is_le); + + return; +} + +int +main(int argc, char **argv) +{ + if (argc != 2) { + return 1; + } + + int test = 1; + int is_le = 0; + if (*(char *) &test == 1) { + is_le = 1; + } + + int fd = open(argv[1], O_RDONLY); + if (fd == -1) { + return 1; + } + + inorder_traversal(fd, -1, is_le); + putchar('\n'); + close(fd); + + return 0; +} diff --git a/3sem/cnts/contest4/04-test.c b/3sem/cnts/contest4/04-test.c new file mode 100755 index 0000000..8453634 --- /dev/null +++ b/3sem/cnts/contest4/04-test.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct Node +{ + int32_t key; + int32_t left_idx; + int32_t right_idx; +} Node; + +int +convert_num_to_sys(char num[]) +{ + unsigned res = 0; + for (int i = 0; i < sizeof(res); ++i) { + unsigned cur = (unsigned char) num[sizeof(res) - i - 1]; + res ^= (cur << (CHAR_BIT * i)); + } + return (int) res; +} + +int +read_int(int fd) +{ + int res = 0; + char buf[sizeof(res)]; + int pos = 0; + while (pos != sizeof(res)) { + ssize_t off = read(fd, buf + pos, sizeof(res) - pos); + if (off == -1) { + printf("Error, can't read from file\n"); + exit(1); + } + pos += off; + } + res = convert_num_to_sys(buf); + return res; +} + +Node +read_node(int fd) +{ + Node new_node; + new_node.key = read_int(fd); + new_node.right_idx = read_int(fd); + new_node.left_idx = read_int(fd); + return new_node; +} + +void +dfs(Node head, int fd) +{ + if (head.left_idx != 0) { + if (lseek(fd, head.left_idx * sizeof(Node), SEEK_SET) == -1) { + printf("Error? can't seek throw file\n"); + exit(1); + } + Node left_node = read_node(fd); + dfs(left_node, fd); + } + printf("%d\n", head.key); + if (head.right_idx != 0) { + if (lseek(fd, head.right_idx * sizeof(Node), SEEK_SET) == -1) { + printf("Error? can't seek throw file\n"); + exit(1); + } + Node right_node = read_node(fd); + dfs(right_node, fd); + } +} + +int +main(int argc, char *argv[]) +{ + if (argc < 2) { + printf("Error: Not enough argumens\n"); + exit(1); + } + int fd = open(argv[1], O_RDONLY, 0600); + if (fd < 0) { + printf("Error: Can't open file\n"); + exit(1); + } + struct stat st; + if (stat(argv[1], &st) == -1) { + printf("Error, can't get info about file\n"); + exit(1); + } + if (st.st_size == 0) { + return 0; + } + Node head = read_node(fd); + dfs(head, fd); + close(fd); +} diff --git a/3sem/cnts/contest4/04.c b/3sem/cnts/contest4/04.c new file mode 100755 index 0000000..82193da --- /dev/null +++ b/3sem/cnts/contest4/04.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct Node +{ + int32_t key; + int32_t left_idx; + int32_t right_idx; +}; + +void +inorder_traversal(struct Node *mas, int32_t idx, int32_t *keys, int32_t *pos) +{ + if (idx == 0) { + return; + } + if (idx == -1) { + idx = 0; + } + + inorder_traversal(mas, mas[idx].left_idx, keys, pos); + keys[(*pos)++] = mas[idx].key; + inorder_traversal(mas, mas[idx].right_idx, keys, pos); + + return; +} + +int +main(int argc, char **argv) +{ + if (argc < 2) { + return 1; + } + + int test = 1; + int is_le = 0; + if (*(char *) &test == 1) { + is_le = 1; + } + + int fd = open(argv[1], O_RDONLY); + if (fd == -1) { + return 1; + } + + int n = lseek(fd, 0, SEEK_END) / sizeof(struct Node); + lseek(fd, 0, SEEK_SET); + + struct Node *mas = calloc(n, sizeof(struct Node)); + + for (int i = 0; i < n; ++i) { + struct Node tmp; + + unsigned char buf[sizeof(tmp)]; + int r = read(fd, buf, sizeof(tmp)); + if (r == -1) { + free(mas); + close(fd); + return 1; + } + if (r < 12) { + break; + } + int n_byte = sizeof(int32_t); + tmp.key = 0; + tmp.left_idx = 0; + tmp.right_idx = 0; + if (is_le) { + for (int j = 0; j < n_byte; ++j) { + tmp.key |= (u_int32_t) buf[j] << (CHAR_BIT * j); + tmp.left_idx |= (u_int32_t) buf[j + n_byte * 1] << (CHAR_BIT * j); + tmp.right_idx |= (u_int32_t) buf[j + n_byte * 2] << (CHAR_BIT * j); + } + } else { + for (int j = 0; j < n_byte; ++j) { + tmp.key |= (u_int32_t) buf[j] << (CHAR_BIT * (sizeof(u_int32_t) - (j + 1))); + tmp.left_idx |= (u_int32_t) buf[j + n_byte * 1] << (CHAR_BIT * (sizeof(u_int32_t) - (j + 1))); + tmp.right_idx |= (u_int32_t) buf[j + n_byte * 2] << (CHAR_BIT * (sizeof(u_int32_t) - (j + 1))); + } + } + + mas[i] = tmp; + } + + int32_t *keys = calloc(n, sizeof(int32_t)); + int32_t pos = 0; + inorder_traversal(mas, -1, keys, &pos); + + for (int32_t i = 0; i < pos; ++i) { + printf("%d\n", keys[i]); + } + + free(keys); + free(mas); + close(fd); + + return 0; +} diff --git a/3sem/cnts/contest4/04cc.c b/3sem/cnts/contest4/04cc.c new file mode 100755 index 0000000..9850034 --- /dev/null +++ b/3sem/cnts/contest4/04cc.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include +#include +struct Node +{ + int32_t key, left_idx, right_idx; +}; +void +inorder_traversal(struct Node *mas, int32_t idx, int32_t *keys, int32_t *pos) +{ + if (idx == 0) { + return; + } + if (idx == -1) { + idx = 0; + } + inorder_traversal(mas, mas[idx].left_idx, keys, pos), keys[(*pos)++] = mas[idx].key, + inorder_traversal(mas, mas[idx].right_idx, keys, pos); + return; +} +int +main(int argc, char **argv) +{ + if (argc < 2) { + return 1; + } + int test = 1, is_le = 0; + if (*(char *) &test == 1) { + is_le = 1; + } + int fd = open(argv[1], O_RDONLY); + if (fd == -1) { + return 1; + } + int n = lseek(fd, 0, SEEK_END) / sizeof(struct Node); + lseek(fd, 0, SEEK_SET); + struct Node *mas = calloc(n, sizeof(struct Node)); + for (int i = 0; i < n; ++i) { + struct Node tmp; + unsigned char buf[sizeof(tmp)]; + int r = read(fd, buf, sizeof(tmp)); + if (r == -1) { + free(mas), close(fd); + return 1; + } + if (r < 12) { + break; + } + int n_byte = sizeof(int32_t); + tmp.key = 0, tmp.left_idx = 0, tmp.right_idx = 0; + if (is_le) { + for (int j = 0; j < n_byte; ++j) { + tmp.key |= (u_int32_t) buf[j] << (CHAR_BIT * j), + tmp.left_idx |= (u_int32_t) buf[j + n_byte * 1] << (CHAR_BIT * j), + tmp.right_idx |= (u_int32_t) buf[j + n_byte * 2] << (CHAR_BIT * j); + } + } else { + for (int j = 0; j < n_byte; ++j) { + tmp.key |= (u_int32_t) buf[j] << (CHAR_BIT * (sizeof(u_int32_t) - (j + 1))), + tmp.left_idx |= (u_int32_t) buf[j + n_byte * 1] << (CHAR_BIT * (sizeof(u_int32_t) - (j + 1))), + tmp.right_idx |= (u_int32_t) buf[j + n_byte * 2] << (CHAR_BIT * (sizeof(u_int32_t) - (j + 1))); + } + } + mas[i] = tmp; + } + int32_t *keys = calloc(n, sizeof(int32_t)), pos = 0; + inorder_traversal(mas, -1, keys, &pos); + for (int32_t i = 0; i < pos; ++i) { + printf("%d\n", keys[i]); + } + free(keys), free(mas), close(fd); + return 0; +} diff --git a/3sem/cnts/contest4/05.c b/3sem/cnts/contest4/05.c new file mode 100755 index 0000000..92dc6c7 --- /dev/null +++ b/3sem/cnts/contest4/05.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int +main(int argc, char *argv[]) +{ + if (argc != 4) { + return 1; + } + + int fdin = open(argv[1], O_RDONLY); + int fdout = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fdin == -1 || fdout == -1) { + return 1; + } + + char *p; + errno = 0; + long long mod = strtoll(argv[3], &p, 10); + if (errno || *p || p == argv[3] || !mod || (int32_t) mod != mod) { + return 1; + } + + unsigned long long res = 0; + unsigned long long num = 1; + unsigned char buf; + int r = read(fdin, &buf, sizeof(buf)); + if (r && r != sizeof(buf)) { + return 1; + } + while (r > 0) { + for (int i = 0; i < CHAR_BIT; i++) { + num %= mod; + res += (num * num) % mod; + res %= mod; + + if (buf & (1 << i)) { + int32_t res32 = res; + + if (write(fdout, &res32, sizeof(res32)) == -1) { + return 1; + } + } + num++; + } + r = read(fdin, &buf, sizeof(buf)); + if (r && r != sizeof(buf)) { + return 1; + } + } + + if (r == -1) { + return 1; + } + + close(fdin); + close(fdout); + + return 0; +} diff --git a/3sem/cnts/contest4/test.c b/3sem/cnts/contest4/test.c new file mode 100755 index 0000000..a59ca0c --- /dev/null +++ b/3sem/cnts/contest4/test.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct Node +{ + int32_t key; + int32_t left_idx; + int32_t right_idx; +}; + +void +create_binary_file(const char *filename, struct Node *nodes, int n) +{ + int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (fd == -1) { + perror("open"); + exit(EXIT_FAILURE); + } + for (int i = 0; i < n; ++i) { + struct Node node = nodes[i]; + node.key = htonl(node.key); + node.left_idx = htonl(node.left_idx); + node.right_idx = htonl(node.right_idx); + write(fd, &node, sizeof(struct Node)); + } + close(fd); +} + +char * +execute_program(const char *filename) +{ + char command[256]; + snprintf(command, sizeof(command), "./04 %s", filename); + FILE *fp = popen(command, "r"); + if (fp == NULL) { + perror("popen"); + exit(EXIT_FAILURE); + } + char *output = malloc(1024); + fread(output, 1, 1024, fp); + pclose(fp); + return output; +} + +void +test_case(struct Node *nodes, int n, const char *expected_output) +{ + const char *filename = "test.bin"; + create_binary_file(filename, nodes, n); + char *output = execute_program(filename); + assert(strcmp(output, expected_output) == 0); + free(output); +} + +int +main() +{ + struct Node nodes1[] = {{10, 1, 2}, {5, 0, 0}, {15, 0, 0}}; + test_case(nodes1, 3, "15 10 5 \n"); + + struct Node nodes2[] = {{20, 1, 2}, {10, 0, 0}, {30, 0, 0}}; + test_case(nodes2, 3, "30 20 10 \n"); + + printf("All tests passed.\n"); + return 0; +} diff --git a/3sem/cnts/contest4/test.py b/3sem/cnts/contest4/test.py new file mode 100755 index 0000000..e5d05f3 --- /dev/null +++ b/3sem/cnts/contest4/test.py @@ -0,0 +1,32 @@ +import struct + +# Define the Node structure +class Node: + def __init__(self, key, left_idx, right_idx): + self.key = key + self.left_idx = left_idx + self.right_idx = right_idx + +# Create a binary search tree +nodes = [ + Node(20, 1, 2), # Root node + Node(-10, 3, 4), # Left child of root + Node(30, 5, 6), # Right child of root + Node(-5, 0, 0), # Left child of node with key 10 + Node(15, 0, 0), # Right child of node with key 10 + Node(25, 0, 0), # Left child of node with key 30 + Node(35, 0, 0) # Right child of node with key 30 +] + +# Write the nodes to a binary file in Big-Endian format +with open('test_tree.bin', 'wb') as f: + for node in nodes: + # Pack the data in Big-Endian format + f.write(struct.pack('>i', node.key)) + f.write(struct.pack('>i', node.left_idx)) + f.write(struct.pack('>i', node.right_idx)) + +# Verify the content of the file +with open('test_tree.bin', 'rb') as f: + content = f.read() + print("Binary content:", bytes(content).hex()) \ No newline at end of file diff --git a/3sem/cnts/contest5/01.c b/3sem/cnts/contest5/01.c new file mode 100755 index 0000000..dd05c4b --- /dev/null +++ b/3sem/cnts/contest5/01.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +enum +{ + KIBIBYTE = 1024 +}; + +int +main(int argc, char *argv[]) +{ + long long int sum = 0; + + for (int i = 1; i < argc; ++i) { + struct stat st; + + if (!(lstat(argv[i], &st) < 0 || st.st_nlink != 1 || !S_ISREG(st.st_mode) || st.st_size % KIBIBYTE != 0)) { + sum += st.st_size; + } + } + + printf("%lld\n", sum); + + return 0; +} diff --git a/3sem/cnts/contest5/02.c b/3sem/cnts/contest5/02.c new file mode 100755 index 0000000..14e7070 --- /dev/null +++ b/3sem/cnts/contest5/02.c @@ -0,0 +1,32 @@ +#include +#include +#include + +enum +{ + MAX_MODE = 0777, +}; + +int +main(int argc, char *argv[]) +{ + const char s[] = "rwxrwxrwx"; + + for (int i = 1; i < argc; ++i) { + char *p; + errno = 0; + int n = strtol(argv[i], &p, 8); + + if (errno || *p || p == argv[i] || n > MAX_MODE || n < 0) { + return 1; + } + + for (int j = 0; j < sizeof(s) - 1; ++j) { + putchar((n & (1 << (sizeof(s) - 2 - j))) ? s[j] : '-'); + } + + printf("\n"); + } + + return 0; +} diff --git a/3sem/cnts/contest5/03.c b/3sem/cnts/contest5/03.c new file mode 100755 index 0000000..a1f1ec6 --- /dev/null +++ b/3sem/cnts/contest5/03.c @@ -0,0 +1,36 @@ +#include + +enum +{ + RWX_PERMISSIONS = 0777, +}; + +int +parse_rwx_permissions(const char *str) +{ + if (str == NULL) { + return -1; + } + + const char expected[] = "rwxrwxrwx"; + + unsigned res = 0; + int i = 0; + while (str[i]) { + res <<= 1; + + if (str[i] == expected[i] && expected[i]) { + res |= 1; + } else if (str[i] != '-' || !expected[i]) { + return -1; + } + + ++i; + } + + if (res > RWX_PERMISSIONS || res < 0 || expected[i]) { + return -1; + } + + return res; +} diff --git a/3sem/cnts/contest5/04.c b/3sem/cnts/contest5/04.c new file mode 100755 index 0000000..9b6791d --- /dev/null +++ b/3sem/cnts/contest5/04.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct File +{ + char *pathname; + __ino_t st_ino; + __dev_t st_dev; +}; + +int +cmp_structs(struct File elem1, struct stat elem2) +{ + return elem1.st_dev == elem2.st_dev && elem1.st_ino == elem2.st_ino; +} + +int +cmp_mas(const void *a, const void *b) +{ + struct File elem1 = *(struct File *) a; + struct File elem2 = *(struct File *) b; + + return strcmp(elem1.pathname, elem2.pathname); +} + +int +main(int argc, char **argv) +{ + struct File *mas = calloc(10, sizeof(struct File)); + if (mas == NULL) { + fprintf(stderr, "Error! Can't calloc mas\n"); + + return 1; + } + int n = 0, capacity = 10; + + for (int i = 1; i < argc; ++i) { + + struct stat st; + if (stat(argv[i], &st) < 0) { + continue; + } + + int flag = 0; + for (int j = 0; j < n; ++j) { + if (cmp_structs(mas[j], st)) { // 1 if equal + flag = 1; + + if (strcmp(mas[j].pathname, argv[i]) < 0) { + mas[j].pathname = argv[i]; + } + + break; + } + } + + if (!flag) { + if (n == capacity) { + capacity *= 2; + + while (!realloc(mas, capacity * sizeof(mas[0])) && capacity > n) { + capacity--; + } + + if (capacity == n) { + fprintf(stderr, "Error! Can't realloc mas\n"); + + return 1; + } + } + + mas[n++] = (struct File){argv[i], st.st_ino, st.st_dev}; + } + } + + qsort(mas, n, sizeof(mas[0]), cmp_mas); + + for (int i = 0; i < n; ++i) { + printf("%s\n", mas[i].pathname); + } + + free(mas); + + return 0; +} diff --git a/3sem/cnts/contest5/05-old.c b/3sem/cnts/contest5/05-old.c new file mode 100755 index 0000000..bfb0394 --- /dev/null +++ b/3sem/cnts/contest5/05-old.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +char * +relativize_path(const char *path1, const char *path2) +{ + char *spath1 = calloc(strlen(path1) + 2, sizeof(char)); + strcpy(spath1, path1); + spath1[strlen(path1)] = '\0'; + if (spath1[strlen(path1) - 1] != '/') { + strcat(spath1, "/"); + } + + char *res; + if ((res = calloc(PATH_MAX, sizeof(char))) == NULL) { + exit(1); + } + + int i = 0; + int ptr = 0; + while (spath1[i] == path2[i] && spath1[i]) { + if (spath1[i] == '/') { + ptr = i; + } + i++; + } + + int deep1 = 0; + while (spath1[i]) { + if (spath1[i] == '/') { + deep1++; + } + + i++; + } + + if (!deep1 && path2[strlen(path2) - 1] == '/') { + snprintf(res, PATH_MAX, "."); + return res; + } + + int deep2 = 0; + i = ptr + 1; + while (path2[i]) { + if (path2[i] == '/') { + deep2++; + } + + i++; + } + + for (int j = 0; j < deep1; j++) { + res[j * 3] = '.'; + res[j * 3 + 1] = '.'; + res[j * 3 + 2] = '/'; + } + + if (deep2 == 0 && deep1) { + if (res[strlen(res) - 1] == '/') { + res[strlen(res) - 1] = '\0'; + } + return res; + } + + snprintf(res + deep1 * 3, PATH_MAX - deep1 * 3, "%s", path2 + ptr + 1); + + if (res[strlen(res) - 1] == '/') { + res[strlen(res) - 1] = '\0'; + } + + return res; +} + +int +main() +{ + const char *path1 = "/home/krosh/cmc/contest5"; + const char *path2 = "/home/krosh/cmc/contest5/subdir/file.txt"; + + char *relative_path = relativize_path(path1, path2); + printf("Relative path: %s\n", relative_path); + + const char *path3 = "/a/b/c/d"; + const char *path4 = "/a/e/f"; + + printf("Relative path: %s\n", relativize_path(path3, path4)); + + const char *path5 = "/a/f/g/h/j"; + const char *path6 = "/a/f/g/h"; + printf("Relative path: %s\n", relativize_path(path5, path6)); + + const char *path7 = "/a"; + const char *path8 = "/a"; + printf("Relative path: %s\n", relativize_path(path7, path8)); + + return 0; +} diff --git a/3sem/cnts/contest5/05.c b/3sem/cnts/contest5/05.c new file mode 100755 index 0000000..bfb0394 --- /dev/null +++ b/3sem/cnts/contest5/05.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +char * +relativize_path(const char *path1, const char *path2) +{ + char *spath1 = calloc(strlen(path1) + 2, sizeof(char)); + strcpy(spath1, path1); + spath1[strlen(path1)] = '\0'; + if (spath1[strlen(path1) - 1] != '/') { + strcat(spath1, "/"); + } + + char *res; + if ((res = calloc(PATH_MAX, sizeof(char))) == NULL) { + exit(1); + } + + int i = 0; + int ptr = 0; + while (spath1[i] == path2[i] && spath1[i]) { + if (spath1[i] == '/') { + ptr = i; + } + i++; + } + + int deep1 = 0; + while (spath1[i]) { + if (spath1[i] == '/') { + deep1++; + } + + i++; + } + + if (!deep1 && path2[strlen(path2) - 1] == '/') { + snprintf(res, PATH_MAX, "."); + return res; + } + + int deep2 = 0; + i = ptr + 1; + while (path2[i]) { + if (path2[i] == '/') { + deep2++; + } + + i++; + } + + for (int j = 0; j < deep1; j++) { + res[j * 3] = '.'; + res[j * 3 + 1] = '.'; + res[j * 3 + 2] = '/'; + } + + if (deep2 == 0 && deep1) { + if (res[strlen(res) - 1] == '/') { + res[strlen(res) - 1] = '\0'; + } + return res; + } + + snprintf(res + deep1 * 3, PATH_MAX - deep1 * 3, "%s", path2 + ptr + 1); + + if (res[strlen(res) - 1] == '/') { + res[strlen(res) - 1] = '\0'; + } + + return res; +} + +int +main() +{ + const char *path1 = "/home/krosh/cmc/contest5"; + const char *path2 = "/home/krosh/cmc/contest5/subdir/file.txt"; + + char *relative_path = relativize_path(path1, path2); + printf("Relative path: %s\n", relative_path); + + const char *path3 = "/a/b/c/d"; + const char *path4 = "/a/e/f"; + + printf("Relative path: %s\n", relativize_path(path3, path4)); + + const char *path5 = "/a/f/g/h/j"; + const char *path6 = "/a/f/g/h"; + printf("Relative path: %s\n", relativize_path(path5, path6)); + + const char *path7 = "/a"; + const char *path8 = "/a"; + printf("Relative path: %s\n", relativize_path(path7, path8)); + + return 0; +} diff --git a/3sem/cnts/contest6/01.c b/3sem/cnts/contest6/01.c new file mode 100755 index 0000000..e6c24da --- /dev/null +++ b/3sem/cnts/contest6/01.c @@ -0,0 +1,55 @@ +#include // Standard I/O functions +#include // Standard library functions: memory allocation, process control, conversions, etc. +#include // POSIX API: read, write, close, etc. +#include // Data types used in system calls +#include // Data returned by the functions fstat(), lstat(), and stat() +#include // Sizes of basic types +#include // Directory entry format +#include // String handling functions + +enum +{ + ARGS_NUM = 2, +}; + +int +main(int argc, char *argv[]) +{ + if (argc != ARGS_NUM) { + fprintf(stderr, "Wrong number of arguments\n"); + return 1; + } + + int n = 0; + + DIR *ddir = opendir(argv[1]); + struct dirent *de; + while ((de = readdir(ddir))) { + char *name = calloc(PATH_MAX, sizeof(char)); + if (!name) { + return 1; + } + + int ret = snprintf(name, PATH_MAX, "%s/%s", argv[1], de->d_name); + if (ret < 0 || ret >= PATH_MAX) { + free(name); + return 1; + } + + struct stat st; + if (stat(name, &st) < 0) { + continue; + } + char ext[] = ".exe"; + if (S_ISREG(st.st_mode) && !access(name, X_OK) && strlen(name) >= 4 && + !strcmp(name + strlen(name) - (sizeof(ext) - 1), ext)) { + ++n; + } + } + + printf("%d\n", n); + + closedir(ddir); + + return 0; +} diff --git a/3sem/cnts/contest6/02-t.c b/3sem/cnts/contest6/02-t.c new file mode 100755 index 0000000..4db6534 --- /dev/null +++ b/3sem/cnts/contest6/02-t.c @@ -0,0 +1,68 @@ +long long +stlen(char *buf) +{ + long long i = 0; + for (; buf[i] != '\0'; ++i) { + } + return i; +} + +long long +shift(char *buf, long long st, long long sh, long long len) +{ + long long i = st; + if (i + sh > len) { + return len; + } + for (; i + sh <= len; ++i) { + buf[i] = buf[i + sh]; + } + return len - sh; +} + +void +normalize_path(char *buf) +{ + long long len = stlen(buf); + for (int i = 1; buf[i]; ++i) { + if (buf[i] == '.' && buf[i - 1] == '/') { + if (buf[i + 1] == '.' && (buf[i + 2] == '/' buf[i + 2] == '\0')) { + if (i - 2 >= 0) { + int j; + for (j = i - 2; buf[j] != '/'; --j) { + } + ++j; + if (buf[i + 2] == '/') { + len = shift(buf, j, i + 3 - j, len); + i = j - 1; + } else if (!buf[i + 2]) { + len = shift(buf, j, i + 2 - j, len); + i = j - 1; + } + } else { + if (buf[i + 2] == '/') { + len = shift(buf, i, 3, len); + --i; + } else if (!buf[i + 2]) { + len = shift(buf, i, 2, len); + --i; + } + } + } else if (buf[i + 1] == '/' buf[i + 1] == '\0') { + if (buf[i + 1] == '/') { + len = shift(buf, i, 2, len); + --i; + } else if (!buf[i + 1]) { + len = shift(buf, i, 1, len); + --i; + } + } + } + } + len = stlen(buf); + if (len != 1) { + if (buf[len - 1] == '/') { + buf[len - 1] = '\0'; + } + } +} diff --git a/3sem/cnts/contest6/02-ttt.c b/3sem/cnts/contest6/02-ttt.c new file mode 100755 index 0000000..221a4e2 --- /dev/null +++ b/3sem/cnts/contest6/02-ttt.c @@ -0,0 +1,110 @@ +#include // Standard I/O functions +#include // Standard library functions: memory allocation, process control, conversions, etc. +#include // File control options +#include // POSIX API: read, write, close, etc. +#include // File control options +#include // Data types used in system calls +#include // Data returned by the functions fstat(), lstat(), and stat() +#include // Sizes of basic types +#include // Sizes of basic types +#include // Error reporting macros +#include // Exact-width integer types +#include // Mathematical functions +#include // Directory entry format +#include // String handling functions +#include // Data returned by the functions fstat(), lstat(), and stat() + +// переписать на strcmp. + +void +normalize_path(char *buf) +{ + unsigned long long pt_real = 0, pt_res = 0; + + unsigned long long len = 0; // проверить правильное вычисление длины + while (buf[len++] != '\0') + ; + len--; + + while (pt_real < len) { + printf("pt: %lld -- %d %d %d\n", pt_real, pt_real - 2 == len, buf[pt_real] == '.', + buf[pt_real + 1] == '.'); // может вызвать выход за массив + if ((len - pt_real >= 3 && buf[pt_real] == '.' && buf[pt_real + 1] == '.' && buf[pt_real + 2] == '/') || + (pt_real - 2 == len && buf[pt_real] == '.' && buf[pt_real + 1] == '.')) { + printf("meow\n"); + if (pt_real > 0 && buf[pt_real - 1] == '/') { + pt_real += 3; + + if (pt_res == 1) { + continue; + } + + if (pt_res == 0) { // impossible ? + pt_res = 1; + continue; + } + pt_res -= 2; + while (pt_res > 0 && buf[pt_res] != '/') { + pt_res--; + } + + pt_res++; + continue; + } + } else if ((len - pt_real >= 2 && buf[pt_real] == '.' && buf[pt_real + 1] == '/') || + (len == pt_real - 1 && buf[pt_real] == '.')) { + if (pt_real > 0 && buf[pt_real - 1] == '/') { + // printf("paw\n"); + pt_real += 2; + + continue; + } + } + + buf[pt_res] = buf[pt_real]; + pt_real++; + pt_res++; + } + + // if (pt_real > 1 && buf[pt_real - 1] == '.') { + // if (pt_real > 2 && buf[pt_real - 2] == '.' && buf[pt_real - 3] == '/') { + // if (pt_res > 1) { + // pt_res -= 2; + // while (pt_res > 0 && buf[pt_res - 1] != '/') { + // pt_res--; + // } + // } + // } else if (pt_real > 1 && buf[pt_real - 2] == '/') { + // if (pt_res > 0) { + // pt_res--; + // } + // } + // } + + buf[pt_res] = '\0'; + + if (pt_res > 1 && buf[pt_res - 1] == '/') { + buf[pt_res - 1] = '\0'; + } + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + char path[PATH_MAX]; + strncpy(path, argv[1], PATH_MAX - 1); + path[PATH_MAX - 1] = '\0'; + + normalize_path(path); + + printf("Normalized path: %s\n", path); + + return EXIT_SUCCESS; +} diff --git a/3sem/cnts/contest6/02.c b/3sem/cnts/contest6/02.c new file mode 100755 index 0000000..e288b87 --- /dev/null +++ b/3sem/cnts/contest6/02.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +size_t +len(const char *buf) +{ + size_t i = 0; + while (buf[i] != '\0') { + ++i; + } + return i; +} + +size_t +shift_left(char *str, size_t st, size_t shift_amount, size_t length) +{ + size_t i = st; + if (i + shift_amount > length) { + return length; + } + + while (i + shift_amount < length) { + str[i] = str[i + shift_amount]; + ++i; + } + + return length - shift_amount; +} + +void +normalize_path(char *path) +{ + size_t length = len(path); + + size_t i = 1; + while (path[i]) { + if (path[i - 1] == '/' && path[i] == '.') { + if (path[i + 1] == '.' && (path[i + 2] == '/' || !path[i + 2])) { + if (i < 1) { + if (path[i + 2] == '/') { + length = shift_left(path, i, 3, length); + --i; + } else if (!path[i + 2]) { + length = shift_left(path, i, 2, length); + --i; + } + } else { + size_t j = i - 2; + + while (j > 0 && path[j] != '/') { + --j; + } + + ++j; + + if (path[i + 2] == '/') { + length = shift_left(path, j, i + 3 - j, length); + i = j - 1; + } else if (!path[i + 2]) { + length = shift_left(path, j, i + 2 - j, length); + i = j - 1; + } + } + } else if (path[i + 1] == '/' || !path[i + 1]) { + if (path[i + 1] == '/') { + length = shift_left(path, i, 2, length); + --i; + } else if (!path[i + 1]) { + length = shift_left(path, i, 1, length); + --i; + } + } + } + + ++i; + } + + if (len(path) != 1 && path[len(path) - 1] == '/') { + path[len(path) - 1] = '\0'; + } + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + char path[PATH_MAX]; + strncpy(path, argv[1], PATH_MAX - 1); + path[PATH_MAX - 1] = '\0'; + + normalize_path(path); + + printf("Normalized path: %s\n", path); + + return EXIT_SUCCESS; +} diff --git a/3sem/cnts/contest6/03.c b/3sem/cnts/contest6/03.c new file mode 100755 index 0000000..bd82238 --- /dev/null +++ b/3sem/cnts/contest6/03.c @@ -0,0 +1,36 @@ +#include + +struct s1 +{ + char f1; + long long f2; + char f3; +}; + +struct s2 +{ + char f1; + char f3; + long long f2; +}; + +size_t +compactify(void *ptr, size_t size) +{ + if (size == 0) { + return 0; + } + + size_t count = size / sizeof(struct s1); + struct s1 *src = (struct s1 *) ptr; + struct s2 *dst = (struct s2 *) ptr; + + for (size_t i = 0; i < count; ++i) { + struct s1 tmp = src[i]; + dst[i].f1 = tmp.f1; + dst[i].f3 = tmp.f3; + dst[i].f2 = tmp.f2; + } + + return count * sizeof(struct s2); +} diff --git a/3sem/cnts/contest6/04.c b/3sem/cnts/contest6/04.c new file mode 100755 index 0000000..391d630 --- /dev/null +++ b/3sem/cnts/contest6/04.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +enum +{ + ARGS_NUM = 3, + MAX_DIRS = 1000, +}; + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +void +list_files(char *path_from, const int start, size_t max_size, int depth) +{ + if (depth > 4) { + return; + } + + DIR *dir = opendir(path_from); + if (dir == NULL) { + return; + } + + char **dirs = (char **) calloc(MAX_DIRS, sizeof(char *)); + if (dirs == NULL) { + exit(1); + } + + int cnt = 0; + + struct dirent *dd; + while ((dd = readdir(dir))) { + if (!(strcmp(dd->d_name, ".") && strcmp(dd->d_name, ".."))) { + continue; + } + + char name[PATH_MAX]; + int ret = snprintf(name, sizeof(name), "%s/%s", path_from, dd->d_name); + if (ret < 0 || ret >= PATH_MAX) { + exit(1); + } + + struct stat st; + if (lstat(name, &st) < 0) { + continue; + } + + if (S_ISDIR(st.st_mode)) { + dirs[cnt] = (char *) calloc(PATH_MAX, sizeof(char)); + memcpy(dirs[cnt], name, strlen(name)); + cnt++; + } else if (st.st_size <= max_size && !access(name, R_OK) && S_ISREG(st.st_mode)) { + ret = snprintf(name, sizeof(name), "%s/%s", path_from + start + 1, dd->d_name); + + if (ret < 0 || ret >= PATH_MAX) { + exit(1); + } + + printf("%s\n", name + (name[0] == '/')); + } + } + + for (int i = 0; i < cnt; i++) { + list_files(dirs[i], start, max_size, depth + 1); + + free(dirs[i]); + } + + closedir(dir); + free(dirs); + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != ARGS_NUM) { + return 1; + } + + int len_arg = strlen(argv[1]); + char *dir_path = calloc(PATH_MAX, sizeof(char)); + memcpy(dir_path, argv[1], len_arg - (argv[1][len_arg - 1] == '/')); + + int len_path = strlen(dir_path); + if (!len_path) { + dir_path[0] = '/'; + dir_path[1] = '\0'; + } + + long long max_size; + str_to_ll(argv[2], &max_size); + + list_files(dir_path, len_path, max_size, 1); + + free(dir_path); + + return EXIT_SUCCESS; +} diff --git a/3sem/cnts/contest7/01-old.c b/3sem/cnts/contest7/01-old.c new file mode 100755 index 0000000..b2f7622 --- /dev/null +++ b/3sem/cnts/contest7/01-old.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + const char const_str[] = "18446744073709551616"; + + char tmp_str[PATH_MAX]; + + while (scanf("%s", tmp_str) == 1) { + int64_t res = 0; + uint64_t base = 1; + + int is_overflow = 0; + + for (int i = strlen(tmp_str) - 1; i >= 0; i--) { + char ch = tmp_str[i]; + + if (ch == 'a') { + if (__builtin_sub_overflow(res, base, &res)) { + is_overflow = 1; + + break; + } + } else if (ch == '1') { + if (__builtin_add_overflow(res, base, &res)) { + is_overflow = 1; + + break; + } + } else if (ch != '0') { + fprintf(stderr, "Invalid input\n"); + + return 1; + } + + if (__builtin_mul_overflow(base, 3, &base) && i != 0) { + is_overflow = 1; + + break; + } + } + + if (is_overflow) { + printf("%s\n", const_str); + } else { + printf("%lld\n", res); + } + } + + return 0; +} diff --git a/3sem/cnts/contest7/01-test.c b/3sem/cnts/contest7/01-test.c new file mode 100755 index 0000000..b906a5f --- /dev/null +++ b/3sem/cnts/contest7/01-test.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include + +enum +{ + MAX_SYM_THREE_LEN = 64, + SYS_BASE = 3, +}; + +const char ERROR_OUTPUT[] = "18446744073709551616"; + +int +main(void) +{ + int cur_num = getchar(); + while (cur_num != EOF && isspace(cur_num)) { + cur_num = getchar(); + } + long long res = 0; + bool overflow = false; + bool printed = false; + bool read = false; + while (cur_num != EOF) { + char cur_ch = cur_num; + if (isspace(cur_num)) { + if (!printed) { + if (overflow) { + printf("%s\n", ERROR_OUTPUT); + } else { + printf("%lld\n", res); + } + res = 0; + overflow = false; + printed = true; + } + } else { + read = true; + printed = false; + if (cur_ch == '1') { + long long temp = 0; + if (res < 0) { + if (__builtin_mul_overflow(res + 1, 3, &temp)) { + overflow = true; + } + if (__builtin_add_overflow(temp, 1, &res)) { + overflow = true; + } + if (__builtin_sub_overflow(res, 3, &temp)) { + overflow = true; + } + res = temp; + } else { + if (__builtin_mul_overflow(res, 3, &temp)) { + overflow = true; + } + if (__builtin_add_overflow(temp, 1, &res)) { + overflow = true; + } + } + + } else if (cur_ch == 'a') { + long long temp = 0; + if (res > 0) { + if (__builtin_mul_overflow(res - 1, 3, &temp)) { + overflow = true; + } + if (__builtin_sub_overflow(temp, 1, &res)) { + overflow = true; + } + if (__builtin_add_overflow(res, 3, &temp)) { + overflow = true; + } + res = temp; + } else { + if (__builtin_mul_overflow(res, 3, &temp)) { + overflow = true; + } + if (__builtin_sub_overflow(temp, 1, &res)) { + overflow = true; + } + } + } else if (cur_ch == '0') { + long long temp = 0; + if (__builtin_mul_overflow(res, 3, &temp)) { + overflow = true; + } + res = temp; + } + } + cur_num = getchar(); + } + if (cur_num == EOF && !printed && !overflow && read) { + printf("%lld\n", res); + } +} diff --git a/3sem/cnts/contest7/01.c b/3sem/cnts/contest7/01.c new file mode 100755 index 0000000..2218948 --- /dev/null +++ b/3sem/cnts/contest7/01.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + const char const_str[] = "18446744073709551616"; + int ch, index = 0; + int64_t res = 0; + int is_overflow = 0; + + while ((ch = getchar()) != EOF) { + if (!isspace(ch)) { + index = 1; + int64_t tmp = 0; + if (ch == 'a') { + if (res > 0) { + if (__builtin_mul_overflow(res - 1, 3, &tmp)) { + is_overflow = 1; + } + if (__builtin_sub_overflow(tmp, 1, &res)) { + is_overflow = 1; + } + if (__builtin_add_overflow(res, 3, &tmp)) { + is_overflow = 1; + } + res = tmp; + } else { + if (__builtin_mul_overflow(res, 3, &tmp)) { + is_overflow = 1; + } + if (__builtin_sub_overflow(tmp, 1, &res)) { + is_overflow = 1; + } + } + + } else if (ch == '1') { + if (res > 0) { + if (__builtin_mul_overflow(res, 3, &tmp)) { + is_overflow = 1; + } + if (__builtin_add_overflow(tmp, 1, &res)) { + is_overflow = 1; + } + } else { + if (__builtin_mul_overflow(res + 1, 3, &tmp)) { + is_overflow = 1; + } + if (__builtin_add_overflow(tmp, 1, &res)) { + is_overflow = 1; + } + if (__builtin_sub_overflow(res, 3, &tmp)) { + is_overflow = 1; + } + res = tmp; + } + } else if (ch == '0') { + if (__builtin_mul_overflow(res, 3, &res)) { + is_overflow = 1; + } + } + } else { + if (index) { + if (is_overflow) { + printf("%s\n", const_str); + } else { + printf("%lld\n", res); + } + + index = 0; + res = 0; + is_overflow = 0; + } + } + } + + if (index) { + if (is_overflow) { + printf("%s\n", const_str); + } else { + printf("%lld\n", res); + } + } + + return 0; +} diff --git a/3sem/cnts/contest7/02.c b/3sem/cnts/contest7/02.c new file mode 100755 index 0000000..18d9812 --- /dev/null +++ b/3sem/cnts/contest7/02.c @@ -0,0 +1,54 @@ +#include +#include +#include + +enum +{ + THURSDAY = 4, + YEAR_OFFSET = 1900, + LAST_DIGIT_REM = 3, + GOOD_THURSDAY1 = 2, + GOOD_THURSDAY2 = 4 +}; + +int +main(int argc, char *argv[]) +{ + int year; + if (scanf("%d", &year) != 1) { + fprintf(stderr, "Invalid input\n"); + + return 1; + } + + struct tm t = {0}; + t.tm_isdst = -1; + t.tm_mday = 1; + t.tm_year = year - YEAR_OFFSET; + + int num_of_thursdays = 0, last_month = 0; + + while (t.tm_year == year - YEAR_OFFSET) { + mktime(&t); + + if (t.tm_mon != last_month) { + last_month = t.tm_mon; + num_of_thursdays = 0; + } + + if (t.tm_wday == THURSDAY) { + num_of_thursdays++; + + if (t.tm_mday % LAST_DIGIT_REM != 0 && + (num_of_thursdays == GOOD_THURSDAY1 || num_of_thursdays == GOOD_THURSDAY2)) { + printf("%d %d\n", t.tm_mon + 1, t.tm_mday); + } + + t.tm_mday += 7; + } else { + t.tm_mday++; + } + } + + return 0; +} diff --git a/3sem/cnts/contest7/03.c b/3sem/cnts/contest7/03.c new file mode 100755 index 0000000..f311030 --- /dev/null +++ b/3sem/cnts/contest7/03.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +check_and_sum_files(const char *dir1, const char *dir2, off_t *total_size) +{ + DIR *d1 = opendir(dir1); + if (!d1) { + return; + } + + struct dirent *entry; + while ((entry = readdir(d1)) != NULL) { + char path1[PATH_MAX]; + int r = snprintf(path1, sizeof(path1), "%s/%s", dir1, entry->d_name); + if (r < 0 || r >= sizeof(path1)) { + _exit(1); + } + + struct stat st1; + if (lstat(path1, &st1) == -1 || !S_ISREG(st1.st_mode)) { + continue; + } + + if (access(path1, W_OK) == 0) { + char path2[PATH_MAX]; + r = snprintf(path2, sizeof(path2), "%s/%s", dir2, entry->d_name); + if (r < 0 || r >= sizeof(path2)) { + _exit(1); + } + + struct stat st2; + if (stat(path2, &st2) == -1) { + continue; + } + + if (S_ISREG(st2.st_mode) && st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino) { + *total_size += st1.st_size; + } + } + } + + closedir(d1); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + off_t total_size = 0; + check_and_sum_files(argv[1], argv[2], &total_size); + + printf("%ld\n", total_size); + + return 0; +} diff --git a/3sem/cnts/contest7/04.c b/3sem/cnts/contest7/04.c new file mode 100755 index 0000000..e69de29 diff --git a/3sem/cnts/contest7/05.c b/3sem/cnts/contest7/05.c new file mode 100755 index 0000000..4769a6a --- /dev/null +++ b/3sem/cnts/contest7/05.c @@ -0,0 +1,104 @@ +#include +#include + +enum +{ + SYNODIC_PERIOD_DAYS = 29, + SYNODIC_PERIOD_HOURS = 12, + SYNODIC_PERIOD_MINUTES = 44, + FULL_MOON_YEAR = 2021, + FULL_MOON_MONTH = 5, + FULL_MOON_DAY = 26, + FULL_MOON_HOUR = 11, + FULL_MOON_MINUTE = 14, +}; + +void +add_synodic_period(struct tm *tm) +{ + tm->tm_mday += SYNODIC_PERIOD_DAYS; + tm->tm_hour += SYNODIC_PERIOD_HOURS; + tm->tm_min += SYNODIC_PERIOD_MINUTES; + timegm(tm); +} + +void +sub_synodic_period(struct tm *tm) +{ + tm->tm_mday -= SYNODIC_PERIOD_DAYS; + tm->tm_hour -= SYNODIC_PERIOD_HOURS; + tm->tm_min -= SYNODIC_PERIOD_MINUTES; + timegm(tm); +} + +struct tm +find_full_moon_after(struct tm start) +{ + struct tm full_moon = {0}; + full_moon.tm_isdst = -1; + full_moon.tm_year = FULL_MOON_YEAR - 1900; + full_moon.tm_mon = FULL_MOON_MONTH - 1; + full_moon.tm_mday = FULL_MOON_DAY; + full_moon.tm_hour = FULL_MOON_HOUR; + full_moon.tm_min = FULL_MOON_MINUTE; + timegm(&full_moon); + + while (timegm(&full_moon) < timegm(&start)) { + add_synodic_period(&full_moon); + } + + while (timegm(&full_moon) > timegm(&start)) { + sub_synodic_period(&full_moon); + } + + add_synodic_period(&full_moon); + + return full_moon; +} + +struct tm +find_fourth_monday_after(struct tm start) +{ + struct tm date = start; + date.tm_mday++; + + int num_of_mondays = 0; + while (num_of_mondays < 4) { + timegm(&date); + + if (date.tm_wday == 1) { + num_of_mondays++; + } + + date.tm_mday++; + } + + date.tm_mday--; + + timegm(&date); + + return date; +} + +int +main() +{ + int year; + if (scanf("%d", &year) != 1) { + return 1; + } + + struct tm start = {0}; + start.tm_isdst = -1; + start.tm_year = year - 1900; + start.tm_mday = 257; + + timegm(&start); + + struct tm full_moon = find_full_moon_after(start); + struct tm event_date = find_fourth_monday_after(full_moon); + + printf("%04d-%02d-%02d\n", event_date.tm_year + 1900, event_date.tm_mon + 1, event_date.tm_mday); + + return 0; +} diff --git a/3sem/cnts/contest7/input b/3sem/cnts/contest7/input new file mode 100755 index 0000000..d2b9008 --- /dev/null +++ b/3sem/cnts/contest7/input @@ -0,0 +1,20 @@ + + + a a1 10a +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +a1 +0 +0 + 00 0 +1a1a1110011100a101aa11a01010a0a011a0a10a1 +1a1a1110011100a101aa11a01010a0a011a0a100a +a1a1aaa00aaa001a0a11aa10a0a01010aa101a001 +a1a1aaa00aaa001a0a11aa10a0a01010aa101a00a +a1a1aaa00aaa001a0a11aa10a0a01010aa101a01a +1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +1aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +1 1 + +1 +1 \ No newline at end of file diff --git a/3sem/exam/2019/1 b/3sem/exam/2019/1 new file mode 100755 index 0000000..cf68a51 --- /dev/null +++ b/3sem/exam/2019/1 @@ -0,0 +1,32 @@ +В ОЗУ 16-разрядного компьютера используется контроль целостности данных по +четности. Описать возможную структуру ячейки памяти и ее побитовое содержимое +для случая хранения в машинном слове восьмеричного числа 17735. + +64 6 +128 7 +256 8 + +2 pow 10 = 1024 +2 pow 11 = 2048 +2 pow 12 = 4096 +2 pow 13 = 8192 +2 pow 14 = 16384 + +17735 - +16384 = +01351 - +01024 = +00327 - +00256 = +00071 - +00064 = +00007 + + +0010 0010 1010 0111 + +xor all = 1 - somewhere + +всё сверху хуйня, число восьмиричное +001 111 111 011 101 +xor = 1 diff --git a/3sem/exam/2019/2 b/3sem/exam/2019/2 new file mode 100755 index 0000000..d4e8d8b --- /dev/null +++ b/3sem/exam/2019/2 @@ -0,0 +1,9 @@ +Пусть дано восьмеричное число 173357, являющееся адресом оперативной памяти, +расслоенной по 16 банкам. Банку с каким номером принадлежит заданный адрес? +001 111 011 011 101 111 + +1111 0110 1110 1111 + +4 bit + +15? diff --git a/3sem/exam/2021/1.c b/3sem/exam/2021/1.c new file mode 100755 index 0000000..abad33b --- /dev/null +++ b/3sem/exam/2021/1.c @@ -0,0 +1,21 @@ +#include + +typedef struct segment +{ + unsigned int base; + unsigned int size; +} segment; + +// 8-ми сегментная +unsigned int +VirtIntoPhys(segment *segTable, unsigned int VirtAdr) +{ + unsigned int SegNum = VirtAdr >> 29; + unsigned int offset = (VirtAdr << 3) >> 3; + + if (offset > segTable[SegNum].size) { + _exit(25); + } + + return segTable[SegNum].base + offset; +} diff --git a/3sem/exam/2021/2-wrong.c b/3sem/exam/2021/2-wrong.c new file mode 100755 index 0000000..70bc902 --- /dev/null +++ b/3sem/exam/2021/2-wrong.c @@ -0,0 +1,55 @@ +#include +#include + +// Стоит добавить проверки на успешность системных вызовов + +enum +{ + BlockSize = 16, +} + +int fds[4]; +unsigned int sizes[4]; +char **list = [ "Disk0", "Disk0", "Disk0", "Disk0" ]; + +void +Ini_Raid0(void) +{ + struct stat st; + for (int i = 0; i < 4; ++i) { + fds[i] = open(list[i], O_RDWR); + lstat(list[i], &st); + sizes[i] = st.st_size; + if (i != 0) { + sizes[i] += sizes[i - 1]; + } + } + + return; +} + +void +Read_Raid0(int num, char *buf) +{ + unsigned int byte = num * BlockSize; + int now_disk = 0; + + for (int i = 0; i < BlockSize; ++i) { + while (byte > sizes[now_disk]) { + now_disk++; + } + + if (now_disk > 3) { + _exit(1); + } + + if (now_disk != 0) { + lseek(fds[now_disk], byte - sizes[now_disk - 1]); + } else { + lseek(fds[now_disk], byte); + } + read(fds[now_disk], 1, buf + i); + } + + return; +} diff --git a/3sem/exam/2021/2.c b/3sem/exam/2021/2.c new file mode 100755 index 0000000..cec16a7 --- /dev/null +++ b/3sem/exam/2021/2.c @@ -0,0 +1,43 @@ +#include +#include + +enum +{ + BlockSize = 16, +} + +int fds[4]; +unsigned int sizes[4]; +char **list = [ "Disk0", "Disk0", "Disk0", "Disk0" ]; + +void +Ini_Raid0(void) +{ + struct stat st; + for (int i = 0; i < 4; ++i) { + fds[i] = open(list[i], O_RDWR); + lstat(list[i], &st); + sizes[i] = st.st_size / BlockSize; + if (i != 0) { + sizes[i] += sizes[i - 1]; + } + } + + return; +} + +void +Read_Raid0(int num, char *buf) +{ + int now_disk = 0; + int now_block = 0; + while (now_block != num) { + if (sizes[now_disk] + + now_disk++; + now_block++; + now_disk %= 4; + } + + return; +} diff --git a/3sem/exam/2021/3 b/3sem/exam/2021/3 new file mode 100755 index 0000000..86a7082 --- /dev/null +++ b/3sem/exam/2021/3 @@ -0,0 +1,35 @@ +Что будет выведено на экран? Прокомментировать, почему? Если возможны несколько вариантов – привести все. Предполагается, что +обращение к функции вывода на экран прорабатывает атомарно и без буферизации. Все системные вызовы прорабатывают успешно. +Подключение заголовочных файлов опущено. + +int main() { + int pid; + int fd[2]; + char c = 'a'; + pipe(fd); + + if( (pid = fork()) > 0 ) { + read(fd[0], &c, 1); + kill(pid, SIGKILL); + wait(NULL); + } else { + putchar(c); + c = 'b'; + write(fd[1], &c, 1); + c = 'c'; + } + + putchar(c); + return 0; +} + +(Вес задачи: 2 балла) + +Answer: +1) начнётся с a т.к. отец заблокируется на считывании +2) сын записал б в канал, дальше либо отец может отправить его "на убийство", либо сын проработает быстрее. У сына с +3) только после смерти сына отец выведет б + +aсб +aб + diff --git a/3sem/exam/2021/4 b/3sem/exam/2021/4 new file mode 100755 index 0000000..a1874b6 --- /dev/null +++ b/3sem/exam/2021/4 @@ -0,0 +1,42 @@ +Сколько раз система обратится к содержимому индексных дескрипторов при вызове: open("/dir1/dir2/dir3/file", O_RDONLY)? +Прокомментировать, почему? Считаем, что ни один из элементов пути к файлу не является символической ссылкой. (Вес задачи: 1 балл) + +$$ Answer: +1) система будет последовательно пробегать по каждому из каталогов. + 1) будет искать, есть ли файл в каталоге. + 2) будет проверять, является ли сам файл каталогом. + +2) сначала корень. ищем в нём dir1.<#> Первое обращение. Проверяем dir1 на каталог.<#> Второе обращение +find dir2 in dir1.<#> dir2 is dir?<#> +find dir3 in dir2.<#> dir3 is dir?<#> +find file in dir3.<#> + +=> всего нам надо 7 обращений к содержимому индексных дескрипторов + + +$$ Ответ GPT: + При вызове open("/dir1/dir2/dir3/file", O_RDONLY) система обращается к индексным дескрипторам (inode) для каждого элемента пути. + +Основные этапы: + + Корневая директория /: + Первое обращение к индексному дескриптору (inode) — система обращается к inode корневого каталога /. + + Директория dir1: + Второе обращение — система читает содержимое inode корневого каталога и ищет запись для dir1, после чего обращается к inode для dir1. + + Директория dir2: + Третье обращение — система читает inode для dir1, затем ищет в его содержимом запись о dir2 и обращается к соответствующему inode. + + Директория dir3: + Четвёртое обращение — система аналогично читает inode для dir2, находит запись для dir3 и обращается к inode для dir3. + + Файл file: + Пятое обращение — система читает inode для dir3, находит запись о файле file и обращается к inode для файла. + +Итог: + Таким образом, система обращается к содержимому индексных дескрипторов 5 раз (по количеству элементов пути /, dir1, dir2, dir3, file). + +Почему: + Каждая директория в Unix-подобных файловых системах представлена как файл каталога, содержащий список файлов и подкаталогов. + Чтобы найти нужный файл, система последовательно открывает каждый inode, пока не доберётся до конечного файла. diff --git a/3sem/exam/a.execute b/3sem/exam/a.execute new file mode 100755 index 0000000..59f0e12 --- /dev/null +++ b/3sem/exam/a.execute @@ -0,0 +1 @@ +cal \ No newline at end of file diff --git a/3sem/exam/a.out b/3sem/exam/a.out new file mode 100755 index 0000000000000000000000000000000000000000..73ff10a2a870930a2931b19e0927b259236a8d21 GIT binary patch literal 16440 zcmeHOYiu0V6~1<2V!(+Va7qY}tbp(+^2Sb_G(cT8ah!}R2b^H5^g+jK@7P{tA7*#9 z*oab7<0zJ~l>DHjYO5Nl6`)2mr4OZu$422y*>gi?NpZB|!39O_efuxkD>K=^-KcRVt^s0YTN^Sdw22Ray4q z3Gy*==wy!@|4 zZu4GluhM;(<@^hBdew$RynjpUhD59>5l`htn?|>8Y1+~n&Zff~br+~#A$({|?YgyB zAxxe)PNS+GcVvl2x<=NM{qsG$zI=T4uLo~llU&GO-W&O4{d*6S4fUIR$c75VlOaMf z)#=eB8z&$4qvmjgr>ql6!b)Wo6c?3IJ_#;VhQAYBIeY3|IX+T>-&cX(Re`5Gl#9Q) z0)K4<{sj0CKK?QQqFnr&EAW2;AHv69!XV1U>8`+6fxprpgk;kk7>$~P@l-SszsFJ; zD;fibQ8-{`?P$g}lhJreW$nyBazt69)<9xJC7`iYdc@L-1VL&f6HnQLYA~JIr!}#7 zMw!-V+}0trL;(l(nFGW7%)w|pp{NlW*;~}EuFmc4=Em@*O>VW-t!)f%cI%s3mD$;| z+l*NmYbc(ztxV7E_Cz{m^+fv<7CJtZOsBZxrej*x5EovJvAjh8TdKcn@a-_dQ+lfK zcDolS&-Kp^eG9|CM(t;=F&Ez;EdN~FSF1-MQ<3+vya#9bCJyua zR`@>VYa`lC2`}>LTO6LAMY^|A&Ukq5^E>C^FBD_oyoX=m;TJqS|4G)`QRbIHl6MX% z#yvc}Poy01@cQo{D-L>i=Y8TR9`^9mhLl+kFS#JyV;&xfcgqnEe}T&?b=1SxdHB4C z#|?GM%O1YoWtBSV;bm-i)Il}KK#+kT13?CY3E|yjg2Z*Zh8iQpRN7 zt}dN4CZ4Z7uB}U(w}UR0*0%%d*D10eCQY&M=TfP3P|Gy&DHcw-GEI1jg=4Nv6O>}% zr>;yBlVaf!SEdO`v2e(hX(CcA-0#XX0Vx*la%Gx$6bn&TrU^%}u*a2YqERetb7h)n z6$>pQ<7z&{yuE(i4yCULa?&STKKV|c-0PEf`{WLv+~$)v`{X8{yxu2Y;geT+<(9v7 zPM!LyG4;AJ@t67To{pA$%PYoA+plrerB(0XKN8*@4A-xF03vSiOxvaKHD+oqBDitE zUWHr#DvapXpIa5*}06*dY zwWTwII$I`y1kBtmb@`NNvtuE z$8bj&p|IqS2!A5$+K zMFVQ?oe#)sgCy$dnphDLou?3%eJ;rz;Rx~=;C|4Ajm+Ffgl4x27(L(83;1) z|HwcUet%h?-LO8Z!t|q3&bF`uyKKqL&1j64<#qE|Mgji_d=U61@Q1*|ZGe4S>! z?9uwCW2R(}+G>_*|ERaHo9g3zShCkG#23n!p=1x)CG32Z3E>yGBhv3Y+sR%sX@4#A zV)sGGxjr(qw{W$CY#j;!nhyTPt_HFwEHuGXO!r0B&$2h_` z&Ulb+R2_>|Cg&CEOZrZfePCvE{yv8^g`5 z*E9X!Bhu|(s@^X7t>}KzUd{(O;UPA-7+B7p?sv6nQ1jl+kKjVghkToFH!&~I8$?|? z@m;0XsD_9m^YB!(kGV>HO3Cx%Xr1Si+MV^qKcMYbxzD56KZ;7Z{#UxLCv==fH6M}) z=dfIyr?veh%0Hf7&~6vI`{*UgX>GsSeJ+K63l-lbY1M^DNJxx4cuezn3q?F6s@H-q z7w1Os4R~uwp2aIt!M=z1>Xk~~cVhpg3iing{DBJm_bc#ERN(1{ZR)@OdVf>F{x$F+ z>9hym0>85QQYFuos6HT`GRIC!S#begoaOSl7JLK7?dpg`aPS4hxd<9Lr*jRfuVQ2eo!Hf zx_uyHw}jK!S|06>n|5?afymmq!NKr=I=2now3FrlZA8z)GL|-n66yYE!i?GJOxBF% zM%6$%Ig+q!D;91pZ$W$T<7PCIiH@08%Fc|b!Avx1nXz0lIR+PxWWv&3WIB>b51~J% zxpVKf-5qAftvgI?f8X)NTet1*YzK{F9cG8YT4TpvW$x;_ZTq$^^R}HkZ|~?ad$w)w z>VSuT-qA{S4TP&hgI6IcKqy0cT z;ny*=zY&@M>B$&`;tVEO?xHgioRao~sjB0o&4UsBYYe0o-hG-%=F`V)5ct{;hMU!y^bKG%XR2UCl636SvmHx~8UQpWSX|B5-kg!oyXl^h5r}_E?k5F<^sE<^Y>z8?W92~ibzpN(&W&HpX zT{xVG>Mqo1ZZ7^Z9~boZU+e_$gFnsnMV9%#U^lnq@4s|l1{KPw_{;i3Fwchm{K@ry zoBg-5ovddBLwv#HPd@(qJpztQB)?e4V{RCL;HuI>@ zf1V8l#lDjN5ud+4lt{)rPtQ}`QzV|?ub}hxU*<6`%8lU|;wK@W^ZCpCQBc;=V(-r% z&6}xxx0w)IGSa-=Tm1gNh0^Qa7;>xyTfNSx`~Cj_&g*Z490$R}j_7{N_z~g_R94`_ zkFC2Nk#nwodyxg-hHt&cU)DdvO(0Rk&XLZ^!hZ+_ja_M9)+KUoSF08-LeTl!|d2sgns|edRJ1Ff)1o0EO4$j0$`!dgMV1K_owdE}< zxqUWwRpNhx%QzMB_o6%YJhl-IILrg)3g~FcF8z`B&-vh_?;dyc7!N!-UoJXnS7drj R%lY5&8OLIc&%r0E{{YGd +#include +#include + +int +return_bit_int(int *mas, int n) +{ + unsigned int byte = mas[n / (sizeof(int) * 8)]; // (sizeof(int) * 8) == 32 + int offset = 32 - 1 - n % 32; + + return (byte & (1 << offset)) >> offset; +} + +int +return_bit_byte(unsigned char *mas, int n) +{ + unsigned int byte = mas[n / (sizeof(char) * 8)]; // (sizeof(char) * 8) == 8 + int offset = 8 - 1 - n % 8; + + return (byte & (1 << offset)) >> offset; +} + +// пусть битовый массив записан в файл. Массив - свободные блоки ФС. Вывести максимальную длину свободных блоков. + +int +main(int argc, char **argv) +{ + int fd = open(argv[1], O_RDONLY); + + int size = lseek(fd, 0, SEEK_END); + unsigned char *mas = malloc(size); + + lseek(fd, 0, 0); // SEEK_CUR == 0, SEEK_SET == 1, SEEK_END == 2 + + for (int i = 0; i < size; ++i) { + read(fd, mas + i, 1); // читаем из файла массив + } + + int max_len = 0; + int tmp = 0; // для хранения текущей длины + for (int i = 0; i < size * 8; ++i) { // пробегаем по всем битам + if (return_bit_byte(mas, i) == 1) { + tmp++; + } else { + max_len = (max_len > tmp) ? max_len : tmp; + tmp = 0; + } + } + max_len = (max_len > tmp) ? max_len : tmp; // если последний бит был 1, то надо доп проверку + + printf("%d\n", max_len); + + return 0; +} diff --git a/3sem/exam/prog-tmp.c b/3sem/exam/prog-tmp.c new file mode 100755 index 0000000..6182ba7 --- /dev/null +++ b/3sem/exam/prog-tmp.c @@ -0,0 +1,24 @@ +// на вход подаётся имя каталога. +// пробежать рекурсивно по всему каталогу и папкам в нём. Если встретился регулярный файл с именем, которое +// заканчивается на .exeсute, открыть, прочесть путь, запустить по нему прогу. + +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + DIR *d = opendir(argv[1]); + struct dirent *dd; + while ((dd = readdir(d))) { + char str[PATH_MAX]; + snprintf(str, PATH_MAX, "%s/%s", argv[1], dd->d_name); + + write(1, str, strlen(str)); + write(1, "\n", 1); + } + + return 0; +} diff --git a/3sem/exam/prog.c b/3sem/exam/prog.c new file mode 100755 index 0000000..4386f1e --- /dev/null +++ b/3sem/exam/prog.c @@ -0,0 +1,42 @@ +// на вход подаётся имя каталога. +// пробежать рекурсивно по всему каталогу и папкам в нём. Если встретился регулярный файл с именем, которое +// заканчивается на .exeсute, открыть, прочесть путь, запустить по нему прогу. + +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + DIR *d = opendir(argv[1]); + struct dirent *dd; + struct stat st; + while ((dd = readdir(d))) { + if (strcmp(dd->d_name, ".") == 0 || strcmp(dd->d_name, "..") == 0) { + continue; + } + + char str[PATH_MAX]; + snprintf(str, PATH_MAX, "%s/%s", argv[1], dd->d_name); + lstat(str, &st); + if (S_ISREG(st.st_mode) && st.st_size < strtol(argv[2], NULL, 10)) { + if (strlen(str) >= 8 && strcmp(str + strlen(str) - 8, ".execute") == 0) { + int fd = open(str, O_RDONLY); + char s[PATH_MAX + 1]; + // memset(s, 0, PATH_MAX); + s[read(fd, s, PATH_MAX)] = '\0'; + if (!fork()) { + execlp(s, s, NULL); + _exit(1); + } + close(fd); + } + } + } + + return 0; +} diff --git a/3sem/exam/raid.c b/3sem/exam/raid.c new file mode 100755 index 0000000..cec16a7 --- /dev/null +++ b/3sem/exam/raid.c @@ -0,0 +1,43 @@ +#include +#include + +enum +{ + BlockSize = 16, +} + +int fds[4]; +unsigned int sizes[4]; +char **list = [ "Disk0", "Disk0", "Disk0", "Disk0" ]; + +void +Ini_Raid0(void) +{ + struct stat st; + for (int i = 0; i < 4; ++i) { + fds[i] = open(list[i], O_RDWR); + lstat(list[i], &st); + sizes[i] = st.st_size / BlockSize; + if (i != 0) { + sizes[i] += sizes[i - 1]; + } + } + + return; +} + +void +Read_Raid0(int num, char *buf) +{ + int now_disk = 0; + int now_block = 0; + while (now_block != num) { + if (sizes[now_disk] + + now_disk++; + now_block++; + now_disk %= 4; + } + + return; +} diff --git a/3sem/exam/raid4.c b/3sem/exam/raid4.c new file mode 100755 index 0000000..aee47b0 --- /dev/null +++ b/3sem/exam/raid4.c @@ -0,0 +1,33 @@ +#include +#include + +enum +{ + BlockSize = 16, +} + +int fds[5]; +void +Write_Raid4(int num, char *buf) +{ + unsigned char tmp1[BlockSize]; + unsigned char tmp2[BlockSize]; + int num_disk = num % 4; + + lseek(fd[num_disk], num * BlockSize); + lseek(fd[4], num * BlockSize); + read(fd[num_disk], tmp1, BlockSize); + read(fd[4], tmp2, BlockSize); + + for (int i = 0; i < BlockSize; ++i) { + tmp2[i] ^= tmp1[i]; + tmp2[i] ^= buf[i]; + } + + lseek(fd[num_disk], num * BlockSize); + lseek(fd[4], num * BlockSize); + write(fd[num_disk], buf, BlockSize); + write(fd[4], tmp2, BlockSize); + + return; +} diff --git a/3sem/exam/sem2.c b/3sem/exam/sem2.c new file mode 100755 index 0000000..c5426b8 --- /dev/null +++ b/3sem/exam/sem2.c @@ -0,0 +1,24 @@ +// суть - предсказываем поведение кэша. + +#include +#include + +enum +{ + CACHE_LEN = 1024, + BLOCK_SIZE = 512, +}; + +int +main(void) +{ + unsigned addrs[CACHE_LEN]; + memset(addrs, -1, CACHE_LEN); + + unsigned addr, cnt = 0; + while (scanf("%u", &addr) == 1) { + int i = (addr / BLOCK_SIZE) % CACHE_LEN; + cnt += (addrs[i] != -1) && (addrs[i] != addr); + addrs[i] = addr; + } +} diff --git a/3sem/exam/sem3.c b/3sem/exam/sem3.c new file mode 100755 index 0000000..12a861f --- /dev/null +++ b/3sem/exam/sem3.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +struct record +{ + double dbl, int num, +} + +int +main(int argc, char **argv) +{ + int shm_key = shmget(IPC_PRIVATE, sizeof(record), IPC_CREAT | 0666); + int sem_key = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); + + record *mem = shmat(shm_key, NULL, 0); + + for (int i = 1; i < argc; ++i) { + int fd = open(argv[i], O_RDONLY); + double sum = 0; + int num = 0; + double tmp; + + while (read(fd, &tmp, sizeof(tmp)) { + num++; + sum += tmp; + } + semop(sem_key, &(struct sembuf){.sem_num = 0, .sem_op = -2}, 1); + *mem = (struct record){.dbl = sum, .num = num}; + semop(sem_key, &(struct sembuf){.sem_num = 0, .sem_op = -1}, 1); + } + + while (wait(NULL) != -1) { + } + + return 0; +} diff --git a/3sem/kr/001.c b/3sem/kr/001.c new file mode 100755 index 0000000..72c3426 --- /dev/null +++ b/3sem/kr/001.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char** argv){ + + int id_of_shm = shmget(argv[1], sizeof(double) * 2, IPC_CREAT | 0666); + float* start_of_shm = shmat(id_of_shm, NULL, 0); + + int sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); + semctl(sem_id, 0, SETVAL, 1); + + struct sembuf p = {0, -1, 0}, v = {0,1,0}; + + + for(int i = 2; i < argc; i++){ + pid_t pid = fork(); + + if (pid == 0) { + FILE* in_file = fopen(argv[i], "r"); + float sum = 0, n = 0; + float buf; + while(fscanf(in_file, "%f", &buf) != EOF){ + sum += buf; + n++; + } + + semop(sem_id, &p, 1); + start_of_shm[1] += sum; + start_of_shm[0] += n; + semop(sem_id, &v, 1); + + fclose(in_file); + + return 0; + } + + } + + + while (wait(NULL) != -1 ){ + } + printf("%f\n", start_of_shm[1] / start_of_shm[0]); + + semctl(sem_id, 0, IPC_RMID); + shmctl(id_of_shm, IPC_RMID, NULL); + + + return 0; +} diff --git a/3sem/kr/002.c b/3sem/kr/002.c new file mode 100755 index 0000000..2fff9bb --- /dev/null +++ b/3sem/kr/002.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +volatile int counter = 0; +volatile int signals = 0; + +int fd2; + +void handler(int sig) { + ++signals; + if (signals < 3) { + printf("%d\n", counter / 2); + } else { + lseek(fd2, 0, SEEK_SET); + char buf; + while (read(fd2, &buf, 1) > 0) { + write(1, &buf, 1); + } + exit(0); + } + +} + +int main(int argc, char** argv) { + signal(SIGINT, handler); + + int fd1 = open(argv[1], O_RDONLY, 0666); + fd2 = open(argv[2], O_CREAT | O_WRONLY); + + char buf; + while (read(fd1, &buf, 1) > 0) { + if (counter % 2 == 0) { + write(fd2, &buf, 1); + } + ++counter; + } + + return 0; +} \ No newline at end of file diff --git a/3sem/kr/01.c b/3sem/kr/01.c new file mode 100755 index 0000000..dffbb9c --- /dev/null +++ b/3sem/kr/01.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd[2]; + pipe(fd); + + if (!fork()) { + close(fd[1]); + dup2(fd[0], 0); + execlp("wc", "wc", NULL); + _exit(1); + } + + close(fd[0]); + int file = open(argv[1], O_RDONLY); + + char test = argv[2][0]; + char buf[8]; + while (read(file, buf, 8) == 8) { + if (buf[0] != test) { + continue; + } + printf("%s\n", buf); + + write(fd[1], buf, 8); + } + close(fd[1]); + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/kr/02.c b/3sem/kr/02.c new file mode 100755 index 0000000..389fdd6 --- /dev/null +++ b/3sem/kr/02.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int file = open(argv[1], O_RDONLY); + int file_out = open("tmp", O_WRONLY | O_CREAT | O_TRUNC, 0666); + + dup2(file, 0); + dup2(file_out, 1); + + char buf[101]; + while (fgets(buf, 100, stdin) != NULL) { + for (int i = 0; i < strlen(buf); i++) { + if (!strncmp(buf + i, "begin", 5)) { + printf("{"); + i += 4; + } else if (!strncmp(buf + i, "end", 3)) { + printf("}"); + i += 2; + } else { + printf("%c", buf[i]); + } + } + } + + rename("tmp", argv[1]); + + return 0; +} diff --git a/3sem/kr/03.c b/3sem/kr/03.c new file mode 100755 index 0000000..6a18209 --- /dev/null +++ b/3sem/kr/03.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int mas[5] = {0, 0, 0, 0, 0}; + + int num = 5, tmp; + + while (scanf("%d", &tmp) == 1) { + for (int i = 0; i < 4; i++) { + mas[i] = mas[i + 1]; + } + mas[4] = tmp; + num--; + } + + // if (num < 0) { + // num = 0; + // } + num = num < 0 ? 0 : num; + + for (int i = num; i < 5; i++) { + printf("%d ", mas[i]); + } + printf("\n"); + + return 0; +} diff --git a/3sem/kr/signal.c b/3sem/kr/signal.c new file mode 100755 index 0000000..cd6b75c --- /dev/null +++ b/3sem/kr/signal.c @@ -0,0 +1,13 @@ +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + + return 0; +} diff --git a/3sem/kr16/01-ai.c b/3sem/kr16/01-ai.c new file mode 100755 index 0000000..401e01d --- /dev/null +++ b/3sem/kr16/01-ai.c @@ -0,0 +1,20 @@ +#include +#include + +int +main() +{ + uint64_t num; + int free_blocks = 0; + + while (scanf("%lx", &num) != EOF) { + for (int i = 0; i < 64; i += 2) { + if (((num >> i) & 0x3) == 0x0) { + free_blocks++; + } + } + } + + printf("%d\n", free_blocks); + return 0; +} diff --git a/3sem/kr16/01.c b/3sem/kr16/01.c new file mode 100755 index 0000000..2499d4c --- /dev/null +++ b/3sem/kr16/01.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + long long unsigned int tmp, res = 0; + + while (scanf("%llu", &tmp) != EOF) { + for (int i = 0; i < sizeof(tmp) * 8; i += 2) { + if (!((tmp >> i) & 0x3)) { + res++; + } + } + } + + printf("%llu\n", res); + + return 0; +} diff --git a/3sem/kr16/02.c b/3sem/kr16/02.c new file mode 100755 index 0000000..cd315be --- /dev/null +++ b/3sem/kr16/02.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd[2]; + pipe(fd); + pid_t pid = fork(); + if (!pid) { + close(fd[0]); + dup2(fd[1], 1); + execlp("gpg", "gpg", "-d", "--batch", "--passphrase", argv[2], "--pinentry-mode", "loopback", "--quiet", + "--no-tty", "--no-keyring", argv[1], NULL); + _exit(1); + } else if (pid == -1) { + exit(1); + } + close(fd[1]); + wait(NULL); + + dup2(fd[0], 0); + + int tmp; + int64_t sum = 0; + while (scanf("%d", &tmp) != EOF) { + sum += tmp; + } + + printf("%ld\n", sum); + + return 0; +} diff --git a/3sem/kr16/04.c b/3sem/kr16/04.c new file mode 100755 index 0000000..85efc35 --- /dev/null +++ b/3sem/kr16/04.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include + +volatile unsigned char cell; +int fd[2]; + +void +usr_hndl(int sig) +{ + write(fd[1], &cell, 1); + kill(getppid(), SIGUSR1); + + return; +} + +void +usr_hndl1(int sig) +{ + read(fd[0], &cell, 1); + + return; +} + +int +main(int argc, char **argv) +{ + pipe(fd); + + pid_t *mas = malloc((argc - 1) * sizeof(pid_t)); + int n = argc - 1; + + int64_t size = 0; + for (int i = 1; i < argc; ++i) { + struct stat st; + lstat(argv[i], &st); + size = st.st_size; + + pid_t pid = fork(); + if (!pid) { + int file = open(argv[i], O_RDONLY); + close(fd[0]); + + signal(SIGUSR1, usr_hndl); + for (;;) { + pause(); + } + _exit(1); + } + mas[i - 1] = pid; + } + close(fd[1]); + + signal(SIGUSR1, usr_hndl1); + unsigned int adr; + while (scanf("%u", &adr) != -1) { + kill(mas[adr % n], SIGUSR1); + } + + return 0; +} diff --git a/3sem/seminars/l10/01.c b/3sem/seminars/l10/01.c new file mode 100755 index 0000000..613aa0e --- /dev/null +++ b/3sem/seminars/l10/01.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include + +// cmd < file1 >> file2 + +int +main(int argc, char **argv) +{ + char *file1 = argv[2]; + char *file2 = argv[3]; + char *cmd = argv[1]; + + if (!fork()) { + int fin = open(file1, O_RDONLY); + int fout = open(file2, O_WRONLY | O_APPEND | O_CREAT, 0666); + + dup2(fin, 0); + dup2(fout, 1); + + execlp(cmd, cmd, NULL); + _exit(1); + } else { + wait(NULL); + } + + return 0; +} diff --git a/3sem/seminars/l10/02.c b/3sem/seminars/l10/02.c new file mode 100755 index 0000000..068d4a7 --- /dev/null +++ b/3sem/seminars/l10/02.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include + +// cmd1 | cmd2 + +int +main(int argc, char **argv) +{ + char *cmd1 = argv[1]; + char *cmd2 = argv[2]; + + int fd[2]; + pipe(fd); + + if (!fork()) { + dup2(fd[1], 1); + close(fd[0]); + + execlp(cmd1, cmd1, NULL); + _exit(1); + } else if (!fork()) { + dup2(fd[0], 0); + close(fd[1]); + + execlp(cmd2, cmd2, NULL); + _exit(1); + } else { + close(fd[0]); + close(fd[1]); + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/seminars/l10/03.c b/3sem/seminars/l10/03.c new file mode 100755 index 0000000..5c1dd00 --- /dev/null +++ b/3sem/seminars/l10/03.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int n = strtoll(argv[1], NULL, 10); + + int fd1[2]; + int fd2[2]; + pipe(fd1); + pipe(fd2); + + int tmp = 1; + write(fd2[1], &tmp, sizeof(tmp)); + + if (!fork()) { + int i = 0; + close(fd1[0]); + close(fd2[1]); + + while (i < n) { + read(fd2[0], &i, sizeof(i)); + if (i > n) { + break; + } + printf("Channel %d: %d\n", 1, i); + i++; + write(fd1[1], &i, sizeof(i)); + } + + return 0; + } else if (!fork()) { + int i = 0; + close(fd2[0]); + close(fd1[1]); + + while (i < n) { + read(fd1[0], &i, sizeof(i)); + if (i > n) { + break; + } + printf("Channel %d: %d\n", 2, i); + i++; + write(fd2[1], &i, sizeof(i)); + } + + return 0; + } else { + close(fd1[0]); + close(fd1[1]); + close(fd2[0]); + close(fd2[1]); + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/seminars/l11/01-2.c b/3sem/seminars/l11/01-2.c new file mode 100755 index 0000000..02bd4b2 --- /dev/null +++ b/3sem/seminars/l11/01-2.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + key_t key = ftok("/dev/null", 0); + + int semid = semget(key, 2, 0666 | IPC_CREAT); + int shmid = shmget(key, sizeof(int), 0666 | IPC_CREAT); + + int *shm = shmat(shmid, NULL, 0); + + pid_t pid = fork(); + if (!pid) { + while (scanf("%d", shm) != -1) { + semop(semid, &(struct sembuf){.sem_num = 0, .sem_op = 1}, 1); + + semop(semid, &(struct sembuf){.sem_num = 1, .sem_op = -1}, 1); + } + + semctl(semid, 2, IPC_RMID, NULL); + exit(0); + } else if (pid == -1) { + exit(1); + } + + pid = fork(); + if (!pid) { + for (;;) { + if (semop(semid, &(struct sembuf){.sem_num = 0, .sem_op = -1}, 1) == -1) { + break; + } + + printf("$ %d\n", *shm); + + if (semop(semid, &(struct sembuf){.sem_num = 1, .sem_op = 1}, 1) == -1) { + break; + } + } + exit(0); + } else if (pid == -1) { + exit(1); + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/seminars/l11/01.c b/3sem/seminars/l11/01.c new file mode 100755 index 0000000..2ec3b6d --- /dev/null +++ b/3sem/seminars/l11/01.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + key_t key = ftok("/dev/null", 0); + + int semid = semget(key, 2, 0666 | IPC_CREAT); + int shmid = shmget(key, sizeof(int), 0666 | IPC_CREAT); + + int *shm = shmat(shmid, NULL, 0); + semctl(semid, 0, SETVAL, 1); + semctl(semid, 1, SETVAL, 1); + + pid_t pid = fork(); + if (!pid) { + for (;;) { + semop(semid, &(struct sembuf){.sem_num = 0, .sem_op = -1}, 1); + semop(semid, &(struct sembuf){.sem_num = 1, .sem_op = -1}, 1); + + int r = scanf("%d", shm); + if (r == -1) { + break; + } + semop(semid, &(struct sembuf){.sem_num = 0, .sem_op = 1}, 1); + } + semctl(semid, 2, IPC_RMID, NULL); + exit(0); + } else if (pid == -1) { + exit(1); + } + + pid = fork(); + if (!pid) { + for (;;) { + if (semop(semid, &(struct sembuf){.sem_num = 0, .sem_op = -1}, 1) == -1) { + break; + } + + printf("$ %d\n", *shm); + if (semop(semid, &(struct sembuf){.sem_num = 0, .sem_op = 1}, 1) == -1) { + break; + } + if (semop(semid, &(struct sembuf){.sem_num = 1, .sem_op = 1}, 1) == -1) { + break; + } + } + exit(0); + } else if (pid == -1) { + exit(1); + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/seminars/l11/02.c b/3sem/seminars/l11/02.c new file mode 100755 index 0000000..d017dfd --- /dev/null +++ b/3sem/seminars/l11/02.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// пинг понг для n процессов + +int +main(int argc, char **argv) +{ + int n = (int) strtoll(argv[1], NULL, 10); + int max_n = (int) strtoll(argv[2], NULL, 10); + + for (int i = 0; i < n; ++i) { + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/seminars/l3/01.c b/3sem/seminars/l3/01.c new file mode 100755 index 0000000..56bb5b5 --- /dev/null +++ b/3sem/seminars/l3/01.c @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + + char *fin = argv[1]; + char *fout = argv[2]; + + // printf("fdin: %d\n", fin); + + int fdin = open(fin, O_RDONLY); + if (fdin == -1) { + return 1; + } + + int fdout = open(fout, O_WRONLY | O_CREAT | O_TRUNC, 0777); + for (;;) { + char c[1024]; + int r = read(fdin, c, 1024); + if (r == -1) { + return 1; + } + if (r == 0) { + break; + } + write(fdout, c, r); + } + + close(fdin); + close(fdout); + + return 0; +} diff --git a/3sem/seminars/l3/02.c b/3sem/seminars/l3/02.c new file mode 100755 index 0000000..4b7e5df --- /dev/null +++ b/3sem/seminars/l3/02.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fdin = open("in", O_RDWR); + if (fdin == -1) { + return 1; + } + + double num1, num2; + + // Read the first double + if (read(fdin, &num1, sizeof(double)) != sizeof(double)) { + close(fdin); + return 1; + } + + // Read the second double + if (read(fdin, &num2, sizeof(double)) != sizeof(double)) { + close(fdin); + return 1; + } + + // Move the file pointer back to the beginning + if (lseek(fdin, 0, SEEK_SET) == -1) { + close(fdin); + return 1; + } + + // Write the second double first + if (write(fdin, &num2, sizeof(double)) != sizeof(double)) { + close(fdin); + return 1; + } + + // Write the first double second + if (write(fdin, &num1, sizeof(double)) != sizeof(double)) { + close(fdin); + return 1; + } + + close(fdin); + + return 0; +} diff --git a/3sem/seminars/l3/03.с b/3sem/seminars/l3/03.с new file mode 100755 index 0000000..f74e7bf --- /dev/null +++ b/3sem/seminars/l3/03.с @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + int fdout = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fdout == -1) { + return 1; + } + + unsigned short x; + + while (scanf("%hu", &x) == 1) { + unsigned char buf[2]; + buf[0] = x >> 8; + buf[1] = x & 0xff; + write(fdout, &x, 2); + } + + close(fdout); + + return 0; +} \ No newline at end of file diff --git a/3sem/seminars/l3/04.c b/3sem/seminars/l3/04.c new file mode 100755 index 0000000..18b4053 --- /dev/null +++ b/3sem/seminars/l3/04.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fdin = open(argv[1], O_RDONLY); + if (fdin == -1) { + return 1; + } + + unsigned int res = 0, tmp; + unsigned char num[4]; // не пишем в int, т.к. неизвестно, какой порядок байтов + + while (read(fdin, num, 4) == 4) { + // unsigned int tmp = (unsigned int) num << 24 | (unsigned int) num << + // 16 | + // (unsigned int) num << 8 | (unsigned int) num; + for (int i = 0; i < 4; i++) { + tmp = tmp << 8 | num[i]; + } + res += tmp; + } + + printf("%u\n", res); + + close(fdin); + + return 0; +} diff --git a/3sem/seminars/l3/in b/3sem/seminars/l3/in new file mode 100755 index 0000000000000000000000000000000000000000..f5b833a0dfbfa54015892540f67c4a12d497eaf1 GIT binary patch literal 16 VcmY!|G%_(VG+{6_GS&lP695;y0^I-r literal 0 HcmV?d00001 diff --git a/3sem/seminars/l3/out b/3sem/seminars/l3/out new file mode 100755 index 0000000..81bb6ee --- /dev/null +++ b/3sem/seminars/l3/out @@ -0,0 +1 @@ +123 234 \ No newline at end of file diff --git a/3sem/seminars/l4/01.c b/3sem/seminars/l4/01.c new file mode 100755 index 0000000..e41445f --- /dev/null +++ b/3sem/seminars/l4/01.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include + +void +premission_to_char(char *m, int n, mode_t mode) +{ + for (int i = 0; i < n; ++i) { + if (!(mode & 1)) { + m[n - i - 1] = '-'; + } + mode >>= 1; + } +} + +int +main(int argc, char *argv[]) +{ + struct stat st; + + for (int i = 1; i < argc; i++) { + if (lstat(argv[i], &st) < 0) { + continue; + } + + char type; + if (S_ISREG(st.st_mode)) { + type = '-'; + } else if (S_ISDIR(st.st_mode)) { + type = 'd'; + } else if (S_ISLNK(st.st_mode)) { + type = 'l'; + } else { + type = '?'; + } + + char m[] = "rwxrwxrwx"; + for (int j = 0; j < 9; j++) { + if (!((st.st_mode >> j) & 1)) { + m[8 - j] = '-'; + } + } + + printf("%c%s %lu %hu %lu %ld %s\n", type, m, st.st_nlink, st.st_uid, st.st_size, st.st_ctime, argv[i]); + } + return 0; +} diff --git a/3sem/seminars/l4/02.c b/3sem/seminars/l4/02.c new file mode 100755 index 0000000..244ff34 --- /dev/null +++ b/3sem/seminars/l4/02.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include +#include + +int +acs(const char *name, int mode) +{ + struct stat st; + + if (lstat(name, &st) < 0) { + return -1; + } + uid_t uid = getuid(); + if (uid == 0) { + return 0; + } + + uid_t st_mode = st.st_mode; + if (st.st_mode == uid) { + st_mode >>= 6; + } else if (st.st_gid == getgid()) { + st_mode >>= 3; + } + st_mode &= 7; + + // for (int i = 0; i < 3; ++i) { + // if (st_mode ^ mode & 1) { + // return -1; + // } + // st_mode >>= 1; + // mode >>= 1; + // } + + if (st_mode & mode == mode) { + return 0; + } + + return -1; +} + +int +main(int argc, char *argv[]) +{ + struct stat st; + + for (int i = 1; i < argc; i++) { + if (lstat(argv[i], &st) < 0) { + continue; + } + + char type; + if (S_ISREG(st.st_mode)) { + type = '-'; + } else if (S_ISDIR(st.st_mode)) { + type = 'd'; + } else if (S_ISLNK(st.st_mode)) { + type = 'l'; + } else { + type = '?'; + } + + char m[] = "rwxrwxrwx"; + for (int j = 0; j < 9; j++) { + if (!((st.st_mode >> j) & 1)) { + m[8 - j] = '-'; + } + } + + printf("%c%s %lu %hu %lu %ld %s\n", type, m, st.st_nlink, st.st_uid, st.st_size, st.st_ctime, argv[i]); + } + return 0; +} diff --git a/3sem/seminars/l4/03.c b/3sem/seminars/l4/03.c new file mode 100755 index 0000000..d93f743 --- /dev/null +++ b/3sem/seminars/l4/03.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + struct stat st; + + if (lstat(argv[1], &st) < 0) { + exit(1); + } + + if (S_ISDIR(st.st_mode)) { + char *file = calloc(strlen(argv[1]) + 30, sizeof(char)); + + snprintf(file, strlen(argv[1]) + 30, "%s/%s.uid", argv[1], argv[0]); + + sprintf(file, "%s/%s.uid", argv[1], argv[0]); + + int fd = open(file, O_WRONLY | O_CREAT | O_TRUNC); + uid_t uid = getuid(); + write(fd, &uid, sizeof(uid_t)); + + close(fd); + } else if (S_ISREG(st.st_mode)) { + int fd = open(argv[1], O_WRONLY | O_TRUNC); + write(fd, st.st_uid, sizeof(uid_t)); + + close(fd); + } else { + exit(1); + } +} diff --git a/3sem/seminars/l5/01.c b/3sem/seminars/l5/01.c new file mode 100755 index 0000000..cbdbe5f --- /dev/null +++ b/3sem/seminars/l5/01.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + DIR *dir = opendir(argv[1]); + unsigned long long sum = 0; + struct dirent *de; + while (de = readdir(dir)) { + char *name = calloc(PATH_MAX, sizeof(char)); + snprintf(name, PATH_MAX, "%s/%s", argv[1], de->d_name); + + struct stat st; + if (lstat(name, &st) < 0) { + continue; + } + if (S_ISREG(st.st_mode)) { + sum += st.st_size; + } + } + + closedir(dir); + + printf("%d\n", sum); + + return 0; +} diff --git a/3sem/seminars/l5/02.c b/3sem/seminars/l5/02.c new file mode 100755 index 0000000..d2ccdbc --- /dev/null +++ b/3sem/seminars/l5/02.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + DIR *dir = opendir(argv[1]); + struct dirent *de; + while (de = readdir(dir)) { + char *name = calloc(PATH_MAX, sizeof(char)); + snprintf(name, PATH_MAX, "%s/%s", argv[1], de->d_name); + + struct stat st; + if (lstat(name, &st) < 0) { + continue; + } + if (!(S_ISREG(st.st_mode))) { + continue; + } + + if (access(name, 3)) { + continue; + } + int len = strlen(name); + + if (name[len - 1] == '~' || (len >= 4 && strcmp(name + strlen(name) - 4, ".bak") == 0)) { + unlink(name); + } + } + + closedir(dir); + return 0; +} diff --git a/3sem/seminars/l5/03.c b/3sem/seminars/l5/03.c new file mode 100755 index 0000000..b966b78 --- /dev/null +++ b/3sem/seminars/l5/03.c @@ -0,0 +1,66 @@ +// подкаталог пустой +// совпадают айдишники +// есть права у остальных на запись +// rmdir + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + DIR *dir = opendir(argv[1]); + struct dirent *de; + while (de = readdir(dir)) { + if ((de->d_name[0] == '.' && strlen(de->d_name) == 1) || + (strlen(de->d_name) == 2) && !strcmp(de->d_name, "..")) { + continue; + } + char *name = calloc(PATH_MAX, sizeof(char)); + snprintf(name, PATH_MAX, "%s/%s", argv[1], de->d_name); + + struct stat st; + if (lstat(name, &st) < 0) { + continue; + } + if (!(S_ISDIR(st.st_mode))) { + continue; + } + + if (st.st_uid != getuid()) { + continue; + } + + if (!(st.st_mode & 2)) { + continue; + } + + int num_files = 0; + DIR *dirt = opendir(name); + while (readdir(dirt)) { + num_files++; + if (num_files > 2) { + break; + } + } + + if (num_files > 2) { + continue; + } + + closedir(dirt); + rmdir(name); + } + + closedir(dir); + return 0; +} diff --git a/3sem/seminars/l6/01.c b/3sem/seminars/l6/01.c new file mode 100755 index 0000000..05e4753 --- /dev/null +++ b/3sem/seminars/l6/01.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct Files +{ + char *pathname; + __ino_t st_ino; + __dev_t st_dev; +}; + +int +main(int argc, char **argv) +{ + struct stat st; + if (lstat(".", &st) == -1) { + printf("stat error\n"); + return 1; + } + + DIR *dir = opendir(".."); + struct dirent *de; + while ((de = readdir(dir))) { + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { + continue; + } + + struct stat sttmp; + + char buf[PATH_MAX]; + snprintf(buf, PATH_MAX, "%s/%s", "..", de->d_name); + if (lstat(buf, &sttmp) == -1) { + printf("lstat error\n"); + return 1; + } + printf("%s\n", de->d_name); + if (sttmp.st_dev == st.st_dev && sttmp.st_ino == st.st_ino) { + printf("%s\n", de->d_name); + } + } + + return 0; +} diff --git a/3sem/seminars/l6/02.c b/3sem/seminars/l6/02.c new file mode 100755 index 0000000..1d73378 --- /dev/null +++ b/3sem/seminars/l6/02.c @@ -0,0 +1,33 @@ +#include +#include + +void +f(int *y, int *m, int *d, int offset) +{ // offset in seconds + struct tm t = {0}; + // struct tm* tptr = calloc(1, sizeof(struct tm)); + t.tm_isdst = -1; + t.tm_year = *y - 1900; + t.tm_mon = *m - 1; + t.tm_mday = *d; + time_t time = mktime(&t); + time += offset; + localtime_r(&time, &t); + *y = t.tm_year + 1900; + *m = t.tm_mon + 1; + *d = t.tm_mday; + + return; +} + +int +main(void) +{ + int y = 2021; + int m = 1; + int d = 1; + f(&y, &m, &d, 65 * 60 * 60 * 24); + printf("%d-%d-%d\n", y, m, d); + + return 0; +} diff --git a/3sem/seminars/l6/03.c b/3sem/seminars/l6/03.c new file mode 100755 index 0000000..9adadcd --- /dev/null +++ b/3sem/seminars/l6/03.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +main(int argc, char **argv) +{ + long long year, day, dw, res = 0; + str_to_ll(argv[1], &year); + str_to_ll(argv[2], &day); + str_to_ll(argv[3], &dw); + + struct tm t = {0}; + t.tm_isdst = -1; + t.tm_mday = 1; + t.tm_year = year - 1900; + + while (t.tm_year == year - 1900) { + mktime(&t); + if (t.tm_mday == day && dw == t.tm_wday) { + res++; + } + t.tm_mday++; + } + + printf("%d\n", (int) res); + + return 0; +} diff --git a/3sem/seminars/l6/04.c b/3sem/seminars/l6/04.c new file mode 100755 index 0000000..045a289 --- /dev/null +++ b/3sem/seminars/l6/04.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +main(int argc, char **argv) +{ + long long year, mth, res = 0; + str_to_ll(argv[1], &year); + str_to_ll(argv[2], &mth); + + struct tm t = {0}; + t.tm_isdst = -1; + t.tm_mday = 1; + t.tm_mon = mth - 1; + t.tm_year = year - 1900; + + while (t.tm_mon == mth - 1) { + if (t.tm_wday > 0 && t.tm_wday < 5) { + res += 8; + } else if (t.tm_wday == 5) { + res += 6; + } + t.tm_mday++; + mktime(&t); + } + + printf("%d\n", (int) res); + + return 0; +} diff --git a/3sem/seminars/l7/01.c b/3sem/seminars/l7/01.c new file mode 100755 index 0000000..f62b1d1 --- /dev/null +++ b/3sem/seminars/l7/01.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fd = open(argv[1], O_RDWR | O_CREAT, 0666); + + struct stat st; + lseek(fd, 0, SEEK_END); + stat(argv[1], &st); + char *addr = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + for (int i = 0; i < st.st_size / 2; i++) { + char tmp = addr[i]; + addr[i] = addr[st.st_size - i - 1]; + addr[st.st_size - i - 1] = tmp; + } + + close(fd); + munmap(addr, st.st_size); + + return 0; +} diff --git a/3sem/seminars/l7/02.c b/3sem/seminars/l7/02.c new file mode 100755 index 0000000..2db52c7 --- /dev/null +++ b/3sem/seminars/l7/02.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fdin = open(argv[1], O_RDONLY); + int fdout = open(argv[2], O_RDWR | O_CREAT, 0666); + + off_t len = lseek(fdin, 0, SEEK_END); + char *fin = mmap(NULL, len, PROT_READ, MAP_SHARED, fdin, 0); + + ftruncate(fdout, len); + char *fout = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fdout, 0); + + memcpy(fout, fin, len); + + close(fdin); + close(fdout); + munmap(fin, len); + munmap(fout, len); + + return 0; +} diff --git a/3sem/seminars/l8/01-1.c b/3sem/seminars/l8/01-1.c new file mode 100755 index 0000000..979a868 --- /dev/null +++ b/3sem/seminars/l8/01-1.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + long long deepth; + str_to_ll(argv[1], &deepth); + + // long long i = 1; + + // while (deepth > 0) { + // printf("Deepth: %lld\n", i++); + + // if (deepth == 1) { + // break; + // } + + // if (!fork()) { + // deepth--; + // } else { + // wait(NULL); + + // break; + // } + // } + + for (int i = 1; i <= deepth; i++) { + if (i == deepth || fork() > 0) { + wait(NULL); + printf("Deepth: %d\n", i); + + break; + } + } + + return 0; +} diff --git a/3sem/seminars/l8/01.c b/3sem/seminars/l8/01.c new file mode 100755 index 0000000..828b869 --- /dev/null +++ b/3sem/seminars/l8/01.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +void +make_proc(int deepth, int max_deepth) +{ + if (deepth == max_deepth) { + return; + } + + printf("Deepth: %d\n", deepth); + + pid_t pid = fork(); + if (pid < 0) { + fprintf(stderr, "Fork failed\n"); + exit(1); + } else if (pid == 0) { + make_proc(deepth + 1, max_deepth); + exit(0); + } else { + wait(NULL); + } + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + long long deepth; + str_to_ll(argv[1], &deepth); + make_proc(0, deepth); + + return 0; +} diff --git a/3sem/seminars/l8/02.c b/3sem/seminars/l8/02.c new file mode 100755 index 0000000..6d4157f --- /dev/null +++ b/3sem/seminars/l8/02.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + long long deepth; + str_to_ll(argv[1], &deepth); + + for (int i = 1; i <= deepth; i++) { + if (fork() == 0) { + int fd = open(argv[2], O_CREAT | O_WRONLY, 0666); + + lseek(fd, (deepth - i) * sizeof(int), SEEK_SET); + write(fd, &i, sizeof(int)); + + close(fd); + + return 0; + } + } + + return 0; +} diff --git a/3sem/seminars/l8/03.c b/3sem/seminars/l8/03.c new file mode 100755 index 0000000..ee7da25 --- /dev/null +++ b/3sem/seminars/l8/03.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +main(int argc, char *argv[]) +{ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + long long deepth; + str_to_ll(argv[1], &deepth); + + truncate(argv[2], sizeof(int) * deepth); + int fd = open(argv[2], O_CREAT | O_RDWR, 0666); + int *addr = mmap(NULL, sizeof(int) * deepth, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + for (int i = 1; i <= deepth; i++) { + if (fork() == 0) { + addr[deepth - i] = i; + + return 0; + } + } + + // for (int i = 1; i <= deepth; i++) { + // wait(NULL); + // } + + while (wait(NULL) != -1) + ; + + munmap(addr, sizeof(int) * argc); + + return 0; +} diff --git a/3sem/seminars/l9/01.c b/3sem/seminars/l9/01.c new file mode 100755 index 0000000..b6c3503 --- /dev/null +++ b/3sem/seminars/l9/01.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +int +main(int argc, char *argv[]) +{ + for (int i = 0; i < 3; ++i) { + pid_t pid = fork(); + + if (pid == -1) { + return 1; + } + if (pid == 0) { + char buf[8] = {0}; + read(0, buf, 7); + + // long long t; + // str_to_ll(buf, &t); + + int t = (int) strtol(buf, NULL, 10); + + printf("%d\n", t * t); + return 0; + } else { + continue; + } + } + + while (wait(NULL) != -1) + ; + + return 0; +} diff --git a/3sem/seminars/l9/02.c b/3sem/seminars/l9/02.c new file mode 100755 index 0000000..46ba3c8 --- /dev/null +++ b/3sem/seminars/l9/02.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include + +// 8-ми сегментная таблица сегментов +// 32-х разрядная система + +typedef struct +{ + int size; + int base; +} segment; + +unsigned int +f(segment *segtable, unsigned int VAdr) +{ + int bit = 3; + unsigned int segnum = VAdr >> (32 - bit); + unsigned int segoff = VAdr & ((1 << (32 - bit)) - 1); + + int addr = segtable[segnum].base + segoff; + int size = segtable[segnum].size; + + if (segoff >= size) { + return 25; + // exit(1); + } + + return addr; +} + +int +main(int argc, char *argv[]) +{ + segment segtable[8] = {}; + + return 0; +} diff --git a/3sem/seminars/l9/03.c b/3sem/seminars/l9/03.c new file mode 100755 index 0000000..94cac4e --- /dev/null +++ b/3sem/seminars/l9/03.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#include + +// инвертированная сегментная таблица сегментов +// 32-х разрядная система + +typedef struct +{ + pid_t pid; + unsigned int VirtNum; +} page_record; + +unsigned int +f(page_record *pagetable, unsigned int VAdr, int size_segtable) +{ + pid_t pid = getpid(); + + unsigned int pagenum = VAdr >> (12); // 12 - размер страницы + + for (int i = 0; i < size_segtable; i++) { + if (pagetable[i].VirtNum == pagenum && pagetable[i].pid == pid) { + return i << (32 - 12) + (VAdr << 20 >> 20); + } + } + + return -1; +} + +int +main(int argc, char *argv[]) +{ + return 0; +} diff --git a/3sem/seminars/l9/04.c b/3sem/seminars/l9/04.c new file mode 100755 index 0000000..2dcc4e9 --- /dev/null +++ b/3sem/seminars/l9/04.c @@ -0,0 +1,16 @@ + +// по номеру начального размер блока и указатель на таблицу файлов +// вывести размер файла + +unsigned int +f(unsigned int n, unsigned int *table) +{ + unsigned int size = 0; + int first_block = table[n]; + while (first_block) { + size++; // размер блока + first_block = table[first_block]; + } + + return size; +} diff --git a/3sem/seminars/l9/in_01 b/3sem/seminars/l9/in_01 new file mode 100755 index 0000000..b453c1e --- /dev/null +++ b/3sem/seminars/l9/in_01 @@ -0,0 +1,3 @@ +000007 +000010 +000009 diff --git a/3sem/templates.c b/3sem/templates.c new file mode 100755 index 0000000..1841bb2 --- /dev/null +++ b/3sem/templates.c @@ -0,0 +1,171 @@ +/** + * @file templates.c + * @brief This file contains various template functions and includes necessary headers for file operations, memory + * management, mathematical computations, and system calls. + * + * The following libraries are included: + * - stdio.h: Provides functionalities for file operations such as fopen, fclose, fprintf, fscanf, printf, and scanf. + * - stdlib.h: Provides functionalities for memory management, conversions, and other utility functions such as exit, + * malloc, free, atoi, strtol, strtoul, atof, strtod, abs, labs, llabs, div, ldiv, and lldiv. + * - fcntl.h: Provides file control options such as O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, + * O_NONBLOCK, O_SYNC, O_DSYNC, O_RSYNC, O_FSYNC, O_ASYNC, O_CLOEXEC, O_DIRECTORY, O_NOFOLLOW, O_NOCTTY, O_TMPFILE, + * O_DIRECT, O_LARGEFILE, O_NOATIME, O_PATH, and O_NDELAY. + * - unistd.h: Provides access to the POSIX operating system API. + * - sys/file.h: Provides file control options. + * - sys/types.h: Defines data types used in system calls such as mode_t, off_t, pid_t, uid_t, gid_t, dev_t, ino_t, + * nlink_t, blksize_t, blkcnt_t, fsblkcnt_t, and fsfilcnt_t. + * - sys/stat.h: Defines the structure of the data returned by the functions fstat(), lstat(), and stat(). + * - limits.h: Defines the sizes of basic types. + * - errno.h: Defines macros for reporting and retrieving error conditions through error codes. + * - stdint.h: Provides a set of typedefs that specify exact-width integer types. + * - math.h: Provides mathematical functions. + * - dirent.h: Defines the format of directory entries. + * - string.h: Provides string handling functions. + * + * The following functions are implemented: + * - void safe_read(int fd, void *buf, size_t count): Reads data from a file descriptor safely, handling interruptions + * and errors. + * - void safe_write(int fd, void *buf, size_t count): Writes data to a file descriptor safely, handling interruptions + * and errors. + * - void str_to_ll(char *str, long long *num): Converts a string to a long long integer, handling errors. + * - void endian_swap(void *src, void *dst, size_t size): Swaps the endianness of a block of memory. + * + * The main function: + * - int main(int argc, char *argv[]): Template main function that checks the number of arguments, opens input and + * output files, and closes them. + */ + +#include // Standard I/O functions +#include // Standard library functions: memory allocation, process control, conversions, etc. +#include // File control options +#include // POSIX API: read, write, close, etc. +#include // File control options +#include // Data types used in system calls +#include // Data returned by the functions fstat(), lstat(), and stat() +#include // Sizes of basic types +#include // Error reporting macros +#include // Exact-width integer types +#include // Mathematical functions +#include // Directory entry format +#include // String handling functions +#include // Data returned by the functions fstat(), lstat(), and stat() + +// Function declarations +int safe_read(int fd, void *buf, size_t count); // Reads data from a file descriptor safely +int safe_write(int fd, void *buf, size_t count); // Writes data to a file descriptor safely +void str_to_ll(char *str, long long *num); // Converts a string to a long long integer +void endian_swap(void *src, void *dst, size_t size); // Swaps the endianness of a block of memory + +int +safe_read(int fd, void *buf, size_t count) +{ + errno = 0; + size_t bytes_read = 0; + while (bytes_read < count) { + ssize_t res = read(fd, buf + bytes_read, count - bytes_read); + + if (res < 0) { + if (errno == EINTR) { + errno = 0; + continue; + } + + fprintf(stderr, "Error reading from file descriptor %d\n", fd); + close(fd); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + if (res == 0) { + break; + } + + bytes_read += res; + } + + return bytes_read; +} + +int +safe_write(int fd, void *buf, size_t count) +{ + errno = 0; + size_t bytes_written = 0; + while (bytes_written < count) { + ssize_t res = write(fd, buf + bytes_written, count - bytes_written); + + if (res < 0) { + if (errno == EINTR) { + errno = 0; + continue; + } + + fprintf(stderr, "Error writing to file descriptor %d\n", fd); + close(fd); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + bytes_written += res; + } + + return bytes_written; +} + +void +str_to_ll(char *str, long long *num) +{ + errno = 0; + char *endptr; + *num = strtoll(str, &endptr, 10); + + if (*endptr || errno || endptr == str) { + fprintf(stderr, "Invalid number: %s\n", str); + exit(1); // TODO: по-хорошему заменить на внешний обработчик ошибок + } + + return; +} + +void +endian_swap(void *src, void *dst, size_t size) +{ + for (size_t i = 0; i < size; i++) { + ((char *) dst)[i] = ((char *) src)[size - i - 1]; + } + + return; +} + +// template main function +enum +{ + ARGS_NUM = 4, +}; + +int +main(int argc, char *argv[]) +{ + if (argc != ARGS_NUM) { + fprintf(stderr, "Wrong number of arguments\n"); + return 1; + } + + int fdin = open(argv[1], O_RDONLY); + if (fdin == -1) { + fprintf(stderr, "Error opening file %s\n", argv[1]); + + return 1; + } + + int fdout = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fdout == -1) { + fprintf(stderr, "Error opening file %s\n", argv[2]); + close(fdin); + + return 1; + } + + close(fdin); + close(fdout); + + return 0; +} diff --git a/compile.sh b/compile.sh new file mode 100755 index 0000000..0a67b30 --- /dev/null +++ b/compile.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Check if the correct number of arguments are provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +CPP_FILE=$1 +ARGUMENT=$2 + +# Format the C++ file with clang-format +clang-format -i -style=file "$CPP_FILE" + +# Compile the C++ file +g++ "$CPP_FILE" -o run + +# Check if the compilation was successful +if [ $? -ne 0 ]; then + echo "Compilation failed" + exit 1 +fi + +# Run the compiled program with the provided argument +./run "$ARGUMENT" \ No newline at end of file diff --git a/contests/1contest/1.cpp b/contests/1contest/1.cpp new file mode 100644 index 0000000..896778b --- /dev/null +++ b/contests/1contest/1.cpp @@ -0,0 +1,14 @@ +class Sum +{ +private: + int a, b; + +public: + int + get() const { + return a + b; + } + + Sum(int a, int b) : a(a), b(b) {}; + Sum(Sum sum, int b) : a(sum.get()), b(b) {}; +}; diff --git a/contests/1contest/2.cpp b/contests/1contest/2.cpp new file mode 100755 index 0000000..1d3a446 --- /dev/null +++ b/contests/1contest/2.cpp @@ -0,0 +1,27 @@ +#include + +class A { +private: + int x; + bool to_print; +public: + A() { + x = 0; + to_print = false; + } + + A(const A& a) { + std::cin >> x; + int t; + std::cin >> t; + x += t; + to_print = true; + } + + ~A() { + if (to_print) { + std::cout << x << std::endl; + } + } + +}; \ No newline at end of file diff --git a/contests/1contest/3.cpp b/contests/1contest/3.cpp new file mode 100755 index 0000000..9f5ee07 --- /dev/null +++ b/contests/1contest/3.cpp @@ -0,0 +1,36 @@ +#include +#include +#include + +int main() { + int c; + c = getchar(); + + bool is_num = false; + + while (c != EOF) { + if (c == '0' && !is_num) { + int old = c; + c = getchar(); + + if (!(c == EOF || !isdigit(c))) { + continue; + } + + putchar(old); + } else if (isdigit(c)) { + is_num = true; + } else { + is_num = false; + } + + putchar(c); + c = getchar(); + } + + if (c != '\n') { + putchar('\n'); + } + + return 0; +} \ No newline at end of file diff --git a/contests/1contest/4 copy.cpp b/contests/1contest/4 copy.cpp new file mode 100755 index 0000000..07082b4 --- /dev/null +++ b/contests/1contest/4 copy.cpp @@ -0,0 +1,33 @@ +#include + +int main() { + int x1_1, y1_1, x1_2, y1_2; + int x2_1, y2_1, x2_2, y2_2; + std::cin >> x1_1 >> y1_1 >> x1_2 >> y1_2; + std::cin >> x2_1 >> y2_1 >> x2_2 >> y2_2; + + double k1, k2; + k1 = static_cast(y1_2 - y1_1) / (x1_2 - x1_1); + k2 = static_cast(y2_2 - y2_1) / (x2_2 - x2_1); + + if (k1 == k2) { + if (y1_1 - k1 * x1_1 == y2_1 - k2 * x2_1) { + std::cout << 2 << std::endl; + } else { + std::cout << 0 << std::endl; + } + + return 0; + } + + double b1 = y1_1 - k1 * x1_1; + double b2 = y2_1 - k2 * x2_1; + + double x_intersect = (b2 - b1) / (k1 - k2); + double y_intersect = k1 * x_intersect + b1; + + std::cout.precision(6); + std::cout << std::fixed << x_intersect << " " << y_intersect << std::endl; + + return 0; +} \ No newline at end of file diff --git a/contests/1contest/4.cpp b/contests/1contest/4.cpp new file mode 100755 index 0000000..60e960e --- /dev/null +++ b/contests/1contest/4.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + +int main() { + double tmp, arip = 0, squar = 0; + int n = 0; + while (std::cin >> tmp) { + ++n; + arip += (tmp - arip) / n; + squar += (tmp * tmp - squar) / n; + } + + std::cout << std::setprecision(10); + + std::cout << arip << std::endl << std::sqrt(squar - arip * arip) << std::endl; + + return 0; +} \ No newline at end of file diff --git a/contests/2contest/1.cpp b/contests/2contest/1.cpp new file mode 100644 index 0000000..defab24 --- /dev/null +++ b/contests/2contest/1.cpp @@ -0,0 +1,12 @@ +class C { +public: + static const char c; + static void f() {}; +}; + +// const char C::c = '+'; +// int main() { +// C ob; +// C::f(); +// return 0; +// } \ No newline at end of file diff --git a/contests/2contest/2.cpp b/contests/2contest/2.cpp new file mode 100644 index 0000000..74041e0 --- /dev/null +++ b/contests/2contest/2.cpp @@ -0,0 +1,42 @@ +class C +{ + int x; +public: + C() { x = 0; } + C(double tmp) { x = 0; } + C(int tmp) { x = tmp; } + C(const C o1, const C o2) { x = o1.x + o2.x; } + C(const C* o) {} + friend C + operator+(const C& o1, const C& o2) { + return C(o1.x + o2.x); + } + C + operator++() { + return C(++x); + } + int operator~() const { return ~x; } + int + operator*(const C* obj2) { + return 0; + } +}; + +/* +C +func1(const C& v1, int v2) { + return C(v2 + v1, ~v1); +} + +void +func2(const C* p1, double p2) { + C v1 = p2; + C v2[2][2]; + C v3 = func1(func1(func1(&p1[3], p2), ~p1[2]), ++v1 * v2[1]); +} + +int +main() { + return 0; +} +*/ \ No newline at end of file diff --git a/contests/2contest/4.cpp b/contests/2contest/4.cpp new file mode 100644 index 0000000..0f51e31 --- /dev/null +++ b/contests/2contest/4.cpp @@ -0,0 +1,28 @@ +#include +using namespace std; + +class BinaryNumber +{ + string str; +public: + BinaryNumber(const string& s = "0") { + str = s; + } + operator string () const { + return str; + } + const BinaryNumber& operator++() { + std::string::iterator i = str.end() - 1; + while (*i == '1' && i != str.begin()) { + *i = '0'; + --i; + } + if (i == str.begin()) { + str.insert(str.begin(), '1'); + } else { + *i = '1'; + } + + return *this; + } +}; diff --git a/contests/2contest/5.cpp b/contests/2contest/5.cpp new file mode 100644 index 0000000..a3c19e9 --- /dev/null +++ b/contests/2contest/5.cpp @@ -0,0 +1,56 @@ +#include +using namespace std; + +class Row +{ +public: + int* const cells = new int[3]; + + int* + begin() const { + return cells; + } + + int* + end() const { + return cells + 3; + } + + int& operator[](int ind) const { + return cells[ind]; + } +}; + +class Matrix +{ +public: + const Row r[3]; + + const Row* + begin() const { + return r; + } + + const Row* + end() const { + return r + 3; + } + + int& + operator[](int ind1, int ind2) { + return r[ind1][ind2]; + } +}; + +// int +// main() { +// Matrix m; +// m[1, 1] = 5; + +// for (const auto& row : m) { +// for (auto cell : row) { +// cout << cell << " "; +// } +// cout << "\n"; +// } +// } diff --git a/contests/3contest/1.cpp b/contests/3contest/1.cpp new file mode 100644 index 0000000..d29e0ca --- /dev/null +++ b/contests/3contest/1.cpp @@ -0,0 +1,81 @@ +#include +#include + +namespace numbers { + class complex { + double c_re, c_im; + public: + complex(double r = 0, double i = 0) : c_re(r), c_im(i) {} + explicit complex(const std::string& s) { + sscanf(s.c_str(), "(%lf,%lf)", &c_re, &c_im); + } + double re() const { + return c_re; + } + double im() const { + return c_im; + } + double abs2() const { + return c_re * c_re + c_im * c_im; + } + double abs() const { + return sqrt(abs2()); + } + std::string to_string() const { + char buf[100]; + sprintf(buf, "(%.10g,%.10g)", c_re, c_im); + + return std::string(buf); + } + complex& operator+=(const complex& other) { + c_re += other.c_re; + c_im += other.c_im; + + return *this; + } + complex& operator-=(const complex& other) { + c_re -= other.c_re; + c_im -= other.c_im; + + return *this; + } + complex& operator*=(const complex& other) { + double r = c_re * other.c_re - c_im * other.c_im; + double i = c_re * other.c_im + c_im * other.c_re; + c_re = r; + c_im = i; + + return *this; + } + complex& operator/=(const complex& other) { + double r = (c_re * other.c_re + c_im * other.c_im) / other.abs2(); + double i = (c_im * other.c_re - c_re * other.c_im) / other.abs2(); + c_re = r; + c_im = i; + + return *this; + } + friend complex operator+(const complex& C, const complex& other) { + return complex(C.c_re + other.c_re, C.c_im + other.c_im); + } + friend complex operator-(const complex& C, const complex& other) { + return complex(C.c_re - other.c_re, C.c_im - other.c_im); + } + friend complex operator*(const complex& C, const complex& other) { + return complex(C.c_re * other.c_re - C.c_im * other.c_im, C.c_re * other.c_im + C.c_im * other.c_re); + } + friend complex operator/(const complex& C, const complex& other) { + double r = (C.c_re * other.c_re + C.c_im * other.c_im) / other.abs2(); + double i = (C.c_im * other.c_re - C.c_re * other.c_im) / other.abs2(); + + return complex(r, i); + } + }; + + complex operator-(const complex& C) { + return complex(-C.re(), -C.im()); + } + complex operator~(const complex& C) { + return complex(C.re(), -C.im()); + } +} \ No newline at end of file diff --git a/contests/3contest/4.cpp b/contests/3contest/4.cpp new file mode 100644 index 0000000..aaeae0f --- /dev/null +++ b/contests/3contest/4.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace numbers; + + +int main(int argc, char** argv) { + complex C(argv[1]); + double R = std::stod(argv[2]); + int N = std::stoi(argv[3]); + std::vector record; + for (int i = 4; i < argc; i++) { + record.push_back(argv[i]); + } + + complex I, z, next = C + R; + double h = 2 * M_PI; + double s = h / N; + for (double i = 0; i < h; i += s) { + z = next; + next = C + R * complex(std::cos(i), std::sin(i)); + I += eval(record, (z + next) / 2) * (next - z); + } + + std::cout << I.to_string() << std::endl; + + return 0; +} diff --git a/contests/4contest/1.cpp b/contests/4contest/1.cpp new file mode 100644 index 0000000..226a4cd --- /dev/null +++ b/contests/4contest/1.cpp @@ -0,0 +1,15 @@ +#include +#include + +void process(const std::vector& from, std::vector& into, int step) { + auto iterf = from.begin(); + auto itert = into.rbegin(); + + while (iterf < from.end() && itert != into.rend()) { + *itert += *iterf; + ++itert; + iterf += step; + } + + return; +} \ No newline at end of file diff --git a/contests/4contest/2.cpp b/contests/4contest/2.cpp new file mode 100644 index 0000000..8c921c3 --- /dev/null +++ b/contests/4contest/2.cpp @@ -0,0 +1,35 @@ +#include +#include + +void process(std::vector& mas, int64_t limit) { + auto itert = mas.end(); + int dst = 0; + + for (auto it = mas.begin() + mas.size() - 1; it != mas.begin() - 1; --it) { + dst = it - mas.begin(); + + if (*it >= limit) { + mas.insert(itert, *it); + itert = mas.end(); + } + + it = mas.begin() + dst; + } + + return; +} + +// #include + +// int main() { +// std::vector mas = { 1, 4, 3, 2 }; +// int64_t limit = 3; + +// process(mas, limit); + +// for (const auto& val : mas) { +// std::cout << val << " "; +// } + +// return 0; +// } \ No newline at end of file diff --git a/contests/4contest/3.cpp b/contests/4contest/3.cpp new file mode 100644 index 0000000..28305a7 --- /dev/null +++ b/contests/4contest/3.cpp @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +void process(const std::vector& mas1, std::vector& mas2) { + std::set set1(mas1.begin(), mas1.end()); + + if (set1.empty() || mas2.empty()) { + return; + } + + for (auto it = mas2.end() - 1; it != mas2.begin() - 1; --it) { + int dst = it - mas2.begin(); + + if (std::find(set1.begin(), set1.end(), dst) != set1.end()) { + mas2.erase(it); + } + } + + return; +} \ No newline at end of file diff --git a/contests/5contest/1.cpp b/contests/5contest/1.cpp new file mode 100644 index 0000000..61e4bb1 --- /dev/null +++ b/contests/5contest/1.cpp @@ -0,0 +1,36 @@ +#include +#include +#include + +bool comp(unsigned int a, unsigned int b) { + int res1 = 0; + while (a != 0) { + res1 += a & 1; + a = a >> 1; + } + + int res2 = 0; + while (b != 0) { + res2 += b & 1; + b = b >> 1; + } + + return res1 < res2; +} + + +int main() { + std::vector v; + unsigned int tmp; + while (std::cin >> tmp) { + v.push_back(tmp); + } + + std::stable_sort(v.begin(), v.end(), comp); + + for (auto x : v) { + std::cout << x << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/contests/5contest/2.cpp b/contests/5contest/2.cpp new file mode 100644 index 0000000..c36fe1e --- /dev/null +++ b/contests/5contest/2.cpp @@ -0,0 +1,28 @@ +#include +#include +#include + +int main() { + std::map> mp; + + std::string name; + int grade; + while (std::cin >> name >> grade) { + mp[name].push_back(grade); + } + + for (auto x : mp) { + std::cout << x.first << " "; + + double tmp = 0; + int n = 0; + for (auto i : x.second) { + tmp += i; + ++n; + } + + std::cout << tmp / n << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/contests/5contest/3.cpp b/contests/5contest/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/contests/5contest/4.cpp b/contests/5contest/4.cpp new file mode 100644 index 0000000..453da20 --- /dev/null +++ b/contests/5contest/4.cpp @@ -0,0 +1,26 @@ +#include +#include + +int main() { + long long mod = 4294967161; + + std::map, long long> mp; + + long long r, c, v; + while (std::cin >> r >> c >> v) { + if (!r && !c && v == mod) break; + + mp[std::make_pair(r, c)] = v; + } + + while (std::cin >> r >> c >> v) { + mp[std::make_pair(r, c)] += v; + mp[std::make_pair(r, c)] %= mod; + } + + for (auto x : mp) { + if (x.second) std::cout << x.first.first << " " << x.first.second << " " << x.second << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/contests/5contest/5.cpp b/contests/5contest/5.cpp new file mode 100644 index 0000000..b3c7164 --- /dev/null +++ b/contests/5contest/5.cpp @@ -0,0 +1,26 @@ +#include +#include + +int main() { + long long mod = 4294967161; + + std::map, long long> mp; + + long long r, c, v; + while (std::cin >> r >> c >> v) { + if (!r && !c && v == mod) break; + + mp[std::make_pair(r, c)] = v; + } + + while (std::cin >> r >> c >> v) { + // mp[std::make_pair(r, c)] *= v; + mp[std::make_pair(r, c)] %= mod; + } + + for (auto x : mp) { + if (x.second) std::cout << x.first.first << " " << x.first.second << " " << x.second << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/contests/6contest/1.cpp b/contests/6contest/1.cpp new file mode 100644 index 0000000..8af70ff --- /dev/null +++ b/contests/6contest/1.cpp @@ -0,0 +1,21 @@ +#include + +template +typename Container::value_type process(const Container& container) { + using ValueType = typename Container::value_type; + + if (container.empty()) { + return ValueType{}; + } + + auto it = container.rbegin(); + ValueType sum = *it; + + for (int i = 0; it != container.rend() && i < 5; ++i, ++it) { + if (i == 2 || i == 4) { + sum += *it; + } + } + + return sum; +} \ No newline at end of file diff --git a/contests/6contest/2.cpp b/contests/6contest/2.cpp new file mode 100644 index 0000000..30117d6 --- /dev/null +++ b/contests/6contest/2.cpp @@ -0,0 +1,16 @@ +// #include +// #include +#include + +template +Container myfilter(const Container& container, Predicate pred) { + Container result; + + for (const auto& x : container) { + if (pred(x)) { + result.insert(result.end(), x); + } + } + + return result; +} diff --git a/contests/6contest/3.cpp b/contests/6contest/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/contests/6contest/5.cpp b/contests/6contest/5.cpp new file mode 100644 index 0000000..feb8f5b --- /dev/null +++ b/contests/6contest/5.cpp @@ -0,0 +1,19 @@ +#include +#include + +template > +void selection_sort(ForwardIt first, ForwardIt last, Compare comp = Compare()) { + for (auto fit = first; fit != last; ++fit) { + auto min_it = fit; + + for (auto sit = std::next(fit); sit != last; ++sit) { + if (comp(*sit, *min_it)) { + min_it = sit; + } + } + + std::swap(*fit, *min_it); + } + + return; +} diff --git a/contests/7contest/1.cpp b/contests/7contest/1.cpp new file mode 100644 index 0000000..55d9366 --- /dev/null +++ b/contests/7contest/1.cpp @@ -0,0 +1,5 @@ +class Figure { +public: + virtual double get_square() const = 0; + virtual ~Figure() {}; +}; diff --git a/contests/7contest/2.cpp b/contests/7contest/2.cpp new file mode 100644 index 0000000..0179c63 --- /dev/null +++ b/contests/7contest/2.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +// class Figure { +// public: +// virtual double get_square() const = 0; +// virtual ~Figure() {}; +// }; + +class Rectangle : Figure { + double a; + double b; +public: + Rectangle(double a = 0, double b = 0) : a(a), b(b) {} + double get_square() const { + return a * b; + } + static Rectangle* make(std::string s) { + std::istringstream ss(s); + double a, b; + ss >> a >> b; + + return new Rectangle(a, b); + } +}; + +class Square : Figure { + double a; +public: + Square(double a = 0) : a(a) {} + double get_square() const { + return a * a; + } + static Square* make(std::string s) { + std::istringstream ss(s); + double a; + ss >> a; + + return new Square(a); + } +}; + +class Circle : Figure { + double r; +public: + Circle(double r = 0) : r(r) {} + double get_square() const { + return M_PI * r * r; + } + static Circle* make(std::string s) { + std::istringstream ss(s); + double r; + ss >> r; + + return new Circle(r); + } +}; \ No newline at end of file diff --git a/contests/7contest/5.cpp b/contests/7contest/5.cpp new file mode 100644 index 0000000..e30358c --- /dev/null +++ b/contests/7contest/5.cpp @@ -0,0 +1,36 @@ +class Figure { +public: + virtual bool equals(const Figure*) const = 0; + virtual ~Figure() {} +}; + +class Rectangle : Figure { + int a; + int b; +public: + Rectangle(int a = 0, int b = 0) : a(a), b(b) {} + bool equals(const Figure* fig) const { + const Rectangle* rect = dynamic_cast(fig); + if (rect) { + return a == rect->a && b == rect->b; + } + + return false; + } +}; + +class Triangle : Figure { + int a; + int b; + int c; +public: + Triangle(int a = 0, int b = 0, int c = 0) : a(a), b(b), c(c) {} + bool equals(const Figure* fig) const { + const Triangle* tri = dynamic_cast(fig); + if (tri) { + return a == tri->a && b == tri->b && c == tri->c; + } + + return false; + } +}; \ No newline at end of file diff --git a/contests/8contest/1.cpp b/contests/8contest/1.cpp new file mode 100644 index 0000000..b1395ed --- /dev/null +++ b/contests/8contest/1.cpp @@ -0,0 +1,30 @@ +#include + +class A { + std::string s; +public: + A(const std::string& s) : s(s) {} + ~A() { std::cout << s << std::endl; } +}; + +void f() { + std::string s; + + if (!(std::cin >> s)) { + throw 0; + } + + A a(s); + f(); +} + +int main() { + try { + f(); + } + catch (...) { + + } + + return 0; +} \ No newline at end of file diff --git a/contests/8contest/2.cpp b/contests/8contest/2.cpp new file mode 100644 index 0000000..fbc0305 --- /dev/null +++ b/contests/8contest/2.cpp @@ -0,0 +1,60 @@ +/* +Некоторая рекурсивная функция func от трех целых аргументов a, b, k (a, b >= 1, k >= 0) определена следующим образом: + + func(a, b, k) == a + b при k == 0 + func(a, b, k) == a при k > 0, b == 1 + func(a, b, k) == f(a, f(a, b - 1, k), k - 1) при k > 0, b > 1 + +На стандартном потоке ввода подаются тройки чисел: два 64-битных знаковых целых положительных числа a, b и 32-битное целое неотрицательное число k. Для каждой тройки чисел на стандартный поток вывода напечатайте значение описанной выше функции. + +Параметры на входе будут таковы, что вычисление завершится за разумное время. Для вычислений достаточно 64-битного целого знакового типа. + +Для возврата значения из рекурсии используйте исключения. Выход из рекурсивной функции с помощью явного или неявного return запрещен. + +Напишите свой класс (например, Result) для передачи результата вычислений вместе с исключением. Не используйте выбрасывание исключений базовых (например, int) типов. + +В комментарии в начале программы опишите, что из себя представляет эта рекурсивная функция. +*/ + +#include +#include + +class Result { + long long val; +public: + Result(long long val) : val(val) {} + long long value() const { return val; } +}; + +// Функция определена по условию. Выкидывает результат в виде exception +void f(long long a, long long b, int k) { + if (k == 0) { + throw Result(a + b); + } + + if (b == 1) { + throw Result(a); + } + + try { + f(a, b - 1, k); + } + catch (const Result& result) { + f(a, result.value(), k - 1); + } +} + +int main() { + long long a, b; + int k; + while (std::cin >> a >> b >> k) { + try { + f(a, b, k); + } + catch (const Result& result) { + std::cout << result.value() << std::endl; + } + } + + return 0; +} \ No newline at end of file diff --git a/contests/8contest/3.cpp b/contests/8contest/3.cpp new file mode 100644 index 0000000..688bbd8 --- /dev/null +++ b/contests/8contest/3.cpp @@ -0,0 +1,91 @@ +/* +Реализуйте класс S следующим образом: + + Класс хранит целое число (типа int). + Число считывается со стандартного потока ввода в конструкторе. + Число выводится на стандартный поток вывода в деструкторе. + Следующая программа: + + using namespace std; + void func(S v) + { + if (v) { + func(move(v)); + } + } + + int main() + { + func(S()); + } + + считывает последовательность целых чисел и выводит на стандартный поток вывода их сумму. + Если входная последовательность пустая, программа не выводит ничего. + +Проверка на переполнение не требуется. + +Глобальные переменные, static, mutable запрещены. + +Сдаваемый на проверку класс должен подключать необходимые заголовочные файлы. +Examples +Input + +1 2 3 + +Output + +6 +*/ + +#include + +class S { + int v; + int sum; + bool last; + bool first; +public: + S(S&& s) { + int val; + first = false; + + if (std::cin >> val) { + v = val; + last = false; + sum = s.sum + v; + } else { + last = true; + sum = s.sum; + } + + } + ~S() { + if (last && !first) { + std::cout << sum << std::endl; + } + } + S() : v(0), sum(0), last(true), first(true) { + int val; + + if (std::cin >> val) { + v = val; + last = false; + sum = v; + } + } + + operator bool() const { + return !last; + } +}; + +// using namespace std; +// void func(S v) { +// if (v) { +// func(move(v)); +// } +// } + +// int main() { +// func(S()); +// } \ No newline at end of file diff --git a/lectures/BlackHole.cpp b/lectures/BlackHole.cpp new file mode 100644 index 0000000..f5c6826 --- /dev/null +++ b/lectures/BlackHole.cpp @@ -0,0 +1,165 @@ +// #include +// #include +// #include + +class BlackHole { + int mass; +public: + BlackHole(size_t mass) : mass(mass) {} + + size_t get_mass() const { + return mass; + } + + template + void consume(T* arg) { + if (arg == nullptr) { + std::cout << "There is nothing to consume" << std::endl; + return; + } + + size_t arg_mass = sizeof(*arg); + if (std::is_const::value) { + std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl; + } else { + std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl; + } + + mass += arg_mass; + delete arg; + + return; + } + + void consume(void* arg) { + throw std::runtime_error("Black hole has tried to consume void"); + + return; + } + + void consume(const void* arg) { + throw std::runtime_error("Black hole has tried to consume void"); + + return; + } + + void consume(BlackHole* arg) { + if (arg == this) { + throw std::runtime_error("Black hole has tried to consume itself"); + + return; + } + + size_t arg_mass = arg->get_mass(); + if (std::is_const::value) { + std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl; + } else { + std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl; + } + + mass += arg_mass; + delete arg; + + return; + } + + void consume(const BlackHole* arg) { + if (arg == this) { + throw std::runtime_error("Black hole has tried to consume itself"); + + return; + } + + size_t arg_mass = arg->get_mass(); + if (std::is_const::value) { + std::cout << "Black hole consumed " << arg_mass << " const bytes" << std::endl; + } else { + std::cout << "Black hole consumed " << arg_mass << " non-const bytes" << std::endl; + } + + mass += arg_mass; + delete arg; + + return; + } + + template + void consume(T arg) { + throw std::runtime_error("Black hole has tried to consume non-pointer"); + + return; + } + + ~BlackHole() = default; +}; + +/* +Требуется реализовать класс BlackHole. + +1) Конструктор класса должен принимать аргумент типа size_t, задающий массу чёрной дыры. + +2) У класса должен быть метод get_mass() возвращающий текущую массу. + +3) У класса должен быть шаблонный метод consume(arg), предназначенный для "поглощения" указателей (см. ниже) и способный принимать аргументы любых типов. + +Вызов consume должен вести себя следующим образом. + +1) Он должен выбрасывать исключение типа runtime_error (тексты исключений следует взять из примера вывода ниже) в следующих ситуациях: + +- При передаче ему аргумента, не являющегося указателем + +- Если переданный указатель указывает на void (константный или неконстантный) + +- Если чёрная дыра пытается поглотить саму себя + +2) Если в качестве аргумента передан нулевой указатель, следует напечатать "There is nothing to consume" и ничего не делать. + +3) Если ни одно из выше перечисленных условий не сработало, то аргумент считается корректным указателем и для него нужно выполнить следующие действия: + +- Определить "массу" аргумента. Для BlackHole масса определяется через вызов get_mass(), для остальных - через размер указываемого типа в байтах. + +- Напечатать "Black hole consumed N non-const bytes", где вместо N нужно подставить массу аргумента. Если в качестве аргумента передан указатель на константный тип, то вместо non-const следует печатать const. + +- Добавить массу аргумента к текущей массе чёрной дыры. + +- Удалить аргумент через вызов delete. + +При подстановке решения студента, следующий код должен работать: +*/ + +// int main() { +// BlackHole hole(100); +// std::cout << "The initial mass is " << hole.get_mass() << " bytes" << std::endl; + +// hole.consume(new int64_t); +// hole.consume(const_cast (new int64_t)); +// hole.consume(new int32_t); +// hole.consume(static_cast(nullptr)); +// hole.consume(new BlackHole{ 50 }); +// hole.consume(new std::array); + +// try { +// hole.consume(5); +// } +// catch (std::runtime_error& err) { +// std::cout << "Error: " << err.what() << std::endl; +// } + +// try { +// hole.consume(&hole); +// } +// catch (std::runtime_error& err) { +// std::cout << "Error: " << err.what() << std::endl; +// } + +// try { +// hole.consume((void*) nullptr); +// } +// catch (std::runtime_error& err) { +// std::cout << "Error: " << err.what() << std::endl; +// } + +// std::cout << "The total mass is: " << hole.get_mass() << " bytes" << std::endl; + +// return 0; +// } \ No newline at end of file diff --git a/lectures/Count copy.cpp b/lectures/Count copy.cpp new file mode 100644 index 0000000..86ec507 --- /dev/null +++ b/lectures/Count copy.cpp @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include + +/* +Количество слов + +Напишите программу, которая для заданного ДКА и заданной максимальной длины N выводит общее количество слов не длинее N, допускаемых данным ДКА. + +На вход программе подаётся описание ДКА в виде непустых строк следующих следующих видов. + +1) Переход из состояния номер 1 в состояние номер 2 по символу "a": + +[1] a [2] + +2) Обозначение того, что состояние номер 3 является допускающим: + +[[3]] + +3) Явное объявление состояния под номером 4 (например, на случай если оно не фигурирует ни в каких переходах и не является допускающим): + +[4] + +После описания ДКА идёт пустая строка, за ней число N. + +Номера состояний - это целые неотрицательные числа, в алфавит ДКА входят только строчные символы латинского алфавита. + +Число N не может быть больше 100, а ответ помещается в тип size_t. + +Начальным состоянием считается то, которое было первым объявлено в описании ДКА (либо в явном виде, либо при описании перехода). +Примеры +Входные данные в файле noMore.in + +[0] a [1] +[1] a [0] +[1] b [0] +[[0]] + +4 + +Результат работы в файле noMore.out + +7 +*/ + +int main() { + std::regex state_declaration_pattern(R"(\[(\d+)\])"); + std::regex transition_pattern(R"(\[(\d+)\]\s*([a-z])\s*\[(\d+)\])"); + std::regex accepting_state_pattern(R"(\[\[(\d+)\]\])"); + + std::map> state_transitions; + std::set accepting_states; + int start_state = -1; + + std::ifstream Input("noMore.in"); + std::string line; + + while (std::getline(Input, line)) { + std::smatch match_result; + + if (start_state == -1 && std::regex_match(line, match_result, state_declaration_pattern)) { + start_state = std::stoi(match_result[1].str()); + } else if (std::regex_match(line, match_result, transition_pattern)) { + start_state = start_state == -1 ? std::stoi(match_result[1].str()) : start_state; + state_transitions[std::stoi(match_result[1].str())][match_result[2].str()[0]] = std::stoi(match_result[3].str()); + } else if (std::regex_match(line, match_result, accepting_state_pattern)) { + accepting_states.insert(std::stoi(match_result[1].str())); + } else if (line.empty()) { + break; + } + } + + int max_length; + Input >> max_length; + Input.close(); + + size_t total_count = 0; + std::vector> dp_table(max_length + 1); + dp_table[0][start_state] = 1; + + for (int length = 1; length <= max_length; ++length) { + for (const auto& [current_state, count] : dp_table[length - 1]) { + for (const auto& [transition_char, next_state] : state_transitions[current_state]) { + dp_table[length][next_state] += count; + } + } + } + + for (int length = 0; length <= max_length; ++length) { + for (const auto& [state, count] : dp_table[length]) { + if (accepting_states.count(state)) { + total_count += count; + } + } + } + + std::ofstream Output("noMore.out"); + Output << total_count << std::endl; + Output.close(); + + return 0; +} diff --git a/lectures/Count.cpp b/lectures/Count.cpp new file mode 100644 index 0000000..e470c31 --- /dev/null +++ b/lectures/Count.cpp @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include + +/* +Количество слов + +Напишите программу, которая для заданного ДКА и заданной максимальной длины N выводит общее количество слов не длинее N, допускаемых данным ДКА. + +На вход программе подаётся описание ДКА в виде непустых строк следующих следующих видов. + +1) Переход из состояния номер 1 в состояние номер 2 по символу "a": + +[1] a [2] + +2) Обозначение того, что состояние номер 3 является допускающим: + +[[3]] + +3) Явное объявление состояния под номером 4 (например, на случай если оно не фигурирует ни в каких переходах и не является допускающим): + +[4] + +После описания ДКА идёт пустая строка, за ней число N. + +Номера состояний - это целые неотрицательные числа, в алфавит ДКА входят только строчные символы латинского алфавита. + +Число N не может быть больше 100, а ответ помещается в тип size_t. + +Начальным состоянием считается то, которое было первым объявлено в описании ДКА (либо в явном виде, либо при описании перехода). +Примеры +Входные данные в файле noMore.in + +[0] a [1] +[1] a [0] +[1] b [0] +[[0]] + +4 + +Результат работы в файле noMore.out + +7 +*/ + +int main() { + std::ifstream inputFile("noMore.in"); + + std::string line; + std::regex firstLinePattern(R"(\[(\d+)\])"); + std::regex subsequentLinePattern(R"(\[(\d+)\]\s*([a-z])\s*\[(\d+)\])"); + std::regex finalLinePattern(R"(\[\[(\d+)\]\])"); + std::regex emptyLinePattern(R"(\s*)"); + std::regex numLinePattern(R"(\d+)"); + + // Read the first line + int start_num = -1; + std::map> transitions; + std::set final_states; + + int n = 0; + + // Read subsequent lines + while (std::getline(inputFile, line)) { + std::smatch match; + if (std::regex_match(line, match, firstLinePattern)) { + if (start_num == -1) { + start_num = std::stoi(match[1].str()); + } + } else if (std::regex_match(line, match, subsequentLinePattern)) { + if (start_num == -1) { + start_num = std::stoi(match[1].str()); + } + int fromState = std::stoi(match[1].str()); + char symbol = match[2].str()[0]; + int toState = std::stoi(match[3].str()); + transitions[fromState][symbol] = toState; + } else if (std::regex_match(line, match, finalLinePattern)) { + final_states.insert(std::stoi(match[1].str())); + } else if (std::regex_match(line, match, emptyLinePattern)) { + continue; + } else if (std::regex_match(line, match, numLinePattern)) { + n = std::stoi(match[0].str()); + } else { + break; + } + } + inputFile.close(); + + size_t ans = 0; + std::vector> dp(n + 1); + dp[0][start_num] = 1; + for (int k = 1; k <= n; ++k) { + for (const auto& [state, count] : dp[k - 1]) { + for (const auto& [symbol, nextState] : transitions[state]) { + dp[k][nextState] += count; + } + } + } + for (int k = 0; k <= n; ++k) { + for (const auto& [state, count] : dp[k]) { + if (final_states.count(state)) { + ans += count; + } + } + } + + std::ofstream outputFile("noMore.out"); + outputFile << ans << std::endl; + + outputFile.close(); + + return 0; +} \ No newline at end of file diff --git a/lectures/DataBuffer-Data.cpp b/lectures/DataBuffer-Data.cpp new file mode 100644 index 0000000..4605bc8 --- /dev/null +++ b/lectures/DataBuffer-Data.cpp @@ -0,0 +1,110 @@ +#include +#include + +int increment_counter() { + static int counter = 0; + return counter++; +} + +struct Data { +public: + int value; + Data(int x = 42) : value(x) {} + Data(const Data& data) { + value = data.value; + } + ~Data() { + // std::cout << "~Data() called " << std::endl; + increment_counter(); + } + Data& operator=(const Data& data) { + value = data.value; + + return *this; + } + friend std::ostream& operator<<(std::ostream& os, const Data data) { + os << data.value; + return os; + } +}; + +class DataBuffer { + Data* addr; + size_t size_buf; + friend void std::swap(DataBuffer& a, DataBuffer& b); +public: + DataBuffer(size_t size) { + // std::cout << "called11!" << std::endl; + size_buf = size; + addr = new Data[size_buf]; + } + DataBuffer(const DataBuffer& data_buf) = delete; + const DataBuffer& operator=(const DataBuffer& data_buf) = delete; + DataBuffer(DataBuffer&& data_buf) noexcept : addr(data_buf.addr), size_buf(data_buf.size_buf) { + // std::cout << "Move constructor called!" << std::endl; + data_buf.addr = nullptr; + data_buf.size_buf = 0; + } + DataBuffer& operator=(DataBuffer&& data_buf) noexcept { + // std::cout << "Move assignment operator called!" << std::endl; + if (this != &data_buf) { + delete[] addr; + addr = data_buf.addr; + size_buf = data_buf.size_buf; + data_buf.addr = nullptr; + data_buf.size_buf = 0; + } + return *this; + } + ~DataBuffer() { + // std::cout << "called1!" << std::endl; + delete[] addr; + } + size_t size() const { + return size_buf; + } + Data& operator[](const size_t ind) { + return addr[ind]; + } + const Data& operator[](const size_t ind) const { + return addr[ind]; + } +}; + +namespace std { + template<> + void swap(DataBuffer& a, DataBuffer& b) { + std::swap(a.addr, b.addr); + std::swap(a.size_buf, b.size_buf); + } +} + +void print_buffer(const DataBuffer& buffer) { + for (size_t i = 0; i < buffer.size(); i++) + std::cout << "buffer[" << i << "] == " << buffer[i] << std::endl; +} + +int main() { + { + DataBuffer buffer_1{ 5 }, buffer_2{ 3 }; + + std::cout << "buffer_1.size() == " << buffer_1.size() << std::endl; + std::cout << "buffer_2.size() == " << buffer_2.size() << std::endl; + + for (size_t i = 0; i < buffer_2.size(); i++) + buffer_2[i] = i + 1; + + std::cout << "buffer_1[0] == " << buffer_1[0].value << std::endl; + std::cout << "buffer_2[0] == " << buffer_2[0].value << std::endl; + + std::swap(buffer_1, buffer_2); + // DataBuffer buffer_copy = buffer_1; // forbidden! + + std::cout << "buffer_1.size() == " << buffer_1.size() << std::endl; + std::cout << "buffer_2.size() == " << buffer_2.size() << std::endl; + + print_buffer(buffer_1); + } + std::cout << "~Data() called " << increment_counter() << " times" << std::endl; + return 0; +} \ No newline at end of file diff --git a/lectures/Reverse.cpp b/lectures/Reverse.cpp new file mode 100644 index 0000000..6c4081c --- /dev/null +++ b/lectures/Reverse.cpp @@ -0,0 +1,45 @@ +#include + +class C +{ + unsigned long long x = 0; + bool last = false; + +public: + C() { + if (std::cin >> x) { + return; + } + + last = true; + } + + ~C() { + if (last) { + return; + } + + std::cout << x << " "; + } +}; + +void +f() { + C c; + + if (std::cin.eof()) { + return; + } + + f(); + + return; +} + +int +main() { + f(); + std::cout << std::endl; + + return 0; +} diff --git a/lectures/Sort copy.cpp b/lectures/Sort copy.cpp new file mode 100644 index 0000000..276fd47 --- /dev/null +++ b/lectures/Sort copy.cpp @@ -0,0 +1,81 @@ + +/* +Сортировка + +Необходимо реализовать функцию filter_sort, которая принимает контейнер с произвольным доступом к элементам и три лямбда-функции. Первая лямбда задаёт критерий фильтрации элементов контейнера, вторая - порядок первичной сортировки элементов, третья - вторичной сортировки. Файл с решением должен содержать только реализацию шаблонной функции filter_sort. Тип элементов контейнера при тестировании может быть любым. + +После подстановки вашей реализации, приведенный ниже код должен работать (при тестировании код отличается) и выдавать для примера ввода ниже пример вывода ниже: + +*/ + +#include +#include +#include +#include +#include +#include + +struct Student { + std::string full_name; + int group_no; + + void print() const { + std::cout << group_no << " " << full_name << std::endl; + } + + static std::optional read() { + Student student; + if (!(std::cin >> student.group_no)) + return {}; + std::cin >> std::ws; + if (!std::getline(std::cin, student.full_name)) + return {}; + return student; + } +}; + +// Your filter_sort is here! + +template +void filter_sort(T& mas, Filter filter, PSort psort, SSort ssort) { + auto it = std::remove_if(mas.begin(), mas.end(), [filter](auto a) { return !filter(a); }); + + std::stable_sort(mas.begin(), it, [ssort](auto a, auto b) { return ssort(a, b); }); + std::stable_sort(mas.begin(), it, [psort](auto a, auto b) { return psort(a, b); }); + + mas.erase(it, mas.end()); +} + +int main() { + std::vector students; + while (auto student = Student::read()) + students.push_back(*student); + + filter_sort(students, // the container + [](Student& stud) { return stud.group_no >= 0; }, // filter + [](Student& stud_1, Student& stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort + [](Student& stud_1, Student& stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort + ); + + for (auto& student : students) + student.print(); + + return 0; +} + + +/* +Примеры +Входные данные + +-100 Иванов Иван +300 Забугоркина Афродита +0 Смирнова Настя +0 Смирнова Анастасия + +Результат работы + +0 Смирнова Анастасия +0 Смирнова Настя +300 Забугоркина Афродита +*/ diff --git a/lectures/Sort.cpp b/lectures/Sort.cpp new file mode 100644 index 0000000..ba10612 --- /dev/null +++ b/lectures/Sort.cpp @@ -0,0 +1,90 @@ + +/* +Сортировка + +Необходимо реализовать функцию filter_sort, которая принимает контейнер с произвольным доступом к элементам и три лямбда-функции. Первая лямбда задаёт критерий фильтрации элементов контейнера, вторая - порядок первичной сортировки элементов, третья - вторичной сортировки. Файл с решением должен содержать только реализацию шаблонной функции filter_sort. Тип элементов контейнера при тестировании может быть любым. + +После подстановки вашей реализации, приведенный ниже код должен работать (при тестировании код отличается) и выдавать для примера ввода ниже пример вывода ниже: + +*/ + +// #include +// #include +// #include +// #include +// #include +// #include + +// struct Student { +// std::string full_name; +// int group_no; + +// void print() const { +// std::cout << group_no << " " << full_name << std::endl; +// } + +// static std::optional read() { +// Student student; +// if (!(std::cin >> student.group_no)) +// return {}; +// std::cin >> std::ws; +// if (!std::getline(std::cin, student.full_name)) +// return {}; +// return student; +// } +// }; + +// Your filter_sort is here! + +template +void filter_sort(Container& container, Filter filter, PrimarySort primary_sort, SecondarySort secondary_sort) { + auto it = std::remove_if(container.begin(), container.end(), [=](auto& item) { return !filter(item); }); + container.erase(it, container.end()); + + std::stable_sort(container.begin(), container.end(), [=](auto item1, auto item2) { return secondary_sort(item1, item2); }); + std::stable_sort(container.begin(), container.end(), [=](auto item1, auto item2) { return primary_sort(item1, item2); }); + + return; +} + +// int main() { +// std::vector students; +// while (auto student = Student::read()) +// students.push_back(*student); + +// filter_sort(students, // the container +// [](Student& stud) { return stud.group_no >= 0; }, // filter +// // [](const Student stud_1, const Student stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort +// [](Student& stud_1, Student& stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort +// // [](const Student stud_1, const Student stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort +// [](Student& stud_1, Student& stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort +// ); + +// // filter_sort(students, // the container +// // [](Student& stud) { return stud.group_no >= 0; }, // filter +// // [](Student& stud_1, Student& stud_2) { return stud_1.group_no < stud_2.group_no; }, // primary sort +// // [](Student& stud_1, Student& stud_2) { return stud_1.full_name < stud_2.full_name; } // secondary sort +// // ); + +// for (auto& student : students) +// student.print(); + +// return 0; +// } + +/* + +Примеры +Входные данные + +-100 Иванов Иван +300 Забугоркина Афродита +0 Смирнова Настя +0 Смирнова Анастасия + +Результат работы + +0 Смирнова Анастасия +0 Смирнова Настя +300 Забугоркина Афродита +*/ \ No newline at end of file diff --git a/lectures/Tree.cpp b/lectures/Tree.cpp new file mode 100644 index 0000000..8d95aca --- /dev/null +++ b/lectures/Tree.cpp @@ -0,0 +1,137 @@ +// #include +// #include + +// class ASTNode; + +// class NodeOwner { +// ASTNode* node = nullptr; +// public: +// explicit NodeOwner(ASTNode* node) : node(node) {} + +// NodeOwner(const NodeOwner&) = delete; +// NodeOwner& operator=(const NodeOwner&) = delete; +// NodeOwner(NodeOwner&& other) { std::swap(node, other.node); } +// NodeOwner& operator=(NodeOwner&& other) { std::swap(node, other.node); return *this; } + +// ASTNode* operator->() { return node; } +// const ASTNode* operator->() const { return node; } +// operator bool() const { return (bool)node; } + +// ~NodeOwner(); +// }; + +/* + +Реализации классов ASTNode, ASTNumberNode, ASTPlusNode и ASTMinusNode. +Реализации операторов operator+ и operator-. + +*/ + +class ASTNode { +public: + virtual void print() {} + virtual int get_value() { return 0; } + virtual ~ASTNode() {} +}; + +class ASTNumberNode : ASTNode { + int value; +public: + ASTNumberNode(int value) : value(value) {} + static NodeOwner create(int value = 0) { + return NodeOwner(new ASTNumberNode(value)); + } + + void print() { + std::cout << value; + } + + int get_value() { + return value; + } + + ~ASTNumberNode() = default; +}; + +class ASTPlusNode : ASTNode { + NodeOwner left, right; +public: + ASTPlusNode(NodeOwner left, NodeOwner right) : left(std::move(left)), right(std::move(right)) {} + static NodeOwner create(NodeOwner left, NodeOwner right) { + return std::move(NodeOwner(new ASTPlusNode(std::move(left), std::move(right)))); + } + + void print() { + std::cout << "("; + left->print(); + std::cout << " + "; + right->print(); + std::cout << ")"; + } + + int get_value() { + return left->get_value() + right->get_value(); + } + + ~ASTPlusNode() = default; +}; + +class ASTMinusNode : ASTNode { + NodeOwner left, right; +public: + ASTMinusNode(NodeOwner left, NodeOwner right) : left(std::move(left)), right(std::move(right)) {} + static NodeOwner create(NodeOwner left, NodeOwner right) { + return std::move(NodeOwner(new ASTMinusNode(std::move(left), std::move(right)))); + } + + void print() { + std::cout << "("; + left->print(); + std::cout << " - "; + right->print(); + std::cout << ")"; + } + + int get_value() { + return left->get_value() - right->get_value(); + } + + ~ASTMinusNode() = default; + +}; + +NodeOwner operator+(NodeOwner left, NodeOwner right) { + return std::move(NodeOwner(ASTPlusNode::create(std::move(left), std::move(right)))); +} + +NodeOwner operator-(NodeOwner left, NodeOwner right) { + return std::move(NodeOwner(ASTMinusNode::create(std::move(left), std::move(right)))); +} + + +// NodeOwner::~NodeOwner() { +// if (node) +// delete node; +// } + +// int main() { +// // static_assert(std::is_same::value, "ASTNumberNode::create() must return NodeOwner value"); +// // static_assert(std::is_same::value, "ASTPlusNode::create() must return NodeOwner value"); +// // static_assert(std::is_same::value, "(NodeOwner + NodeOwner) must return NodeOwner value"); + +// auto expr_1 = ASTPlusNode::create( +// ASTNumberNode::create(1), +// ASTMinusNode::create( +// ASTNumberNode::create(2), +// ASTNumberNode::create(3) +// ) +// ); +// expr_1->print(); +// std::cout << " = " << expr_1->get_value() << std::endl; + +// auto expr_2 = ASTNumberNode::create(4) - ASTNumberNode::create(5) + ASTNumberNode::create(6); +// expr_2->print(); +// std::cout << " = " << expr_2->get_value() << std::endl; + +// return 0; +// } \ No newline at end of file diff --git a/lectures/Vector.cpp b/lectures/Vector.cpp new file mode 100644 index 0000000..3b9c94b --- /dev/null +++ b/lectures/Vector.cpp @@ -0,0 +1,69 @@ +// #include +// #include +// #include +// #include + +// struct Element { +// int value; +// Element(int value) : value(value) {} +// }; + +// Реализация функции make_safe_vector() + +template +std::vector> make_safe_vector(T&& container) { + std::vector> result; + + for (auto& el : container) + result.emplace_back(std::move(el)); + + container.clear(); + + return result; +} + +// int main() { +// std::vector unsafe_vector; +// unsafe_vector.emplace_back(new Element(0)); +// unsafe_vector.emplace_back(new Element(42)); +// unsafe_vector.emplace_back(new Element(900)); + +// auto safe_vector_1 = make_safe_vector(unsafe_vector); +// unsafe_vector.push_back(new Element(99)); + +// auto safe_vector_2 = make_safe_vector(safe_vector_1); + +// auto safe_vector_3 = make_safe_vector(std::list{new Element(1), new Element(2), new Element(3)}); + +// std::cout << "unsafe_vector: " << std::endl; +// for (auto& el : unsafe_vector) { +// std::cout << el->value << std::endl; +// delete el; +// } + +// std::cout << "safe_vector_1: " << std::endl; +// for (auto& el : safe_vector_1) +// std::cout << el->value << std::endl; + +// std::cout << "safe_vector_2: " << std::endl; +// for (auto& el : safe_vector_2) +// std::cout << el->value << std::endl; + +// std::cout << "safe_vector_3: " << std::endl; +// for (auto& el : safe_vector_3) +// std::cout << el->value << std::endl; +// } + +/* +unsafe_vector: +99 +safe_vector_1: +safe_vector_2: +0 +42 +900 +safe_vector_3: +1 +2 +3 +*/ \ No newline at end of file diff --git a/lectures/t.cpp b/lectures/t.cpp new file mode 100644 index 0000000..0467998 --- /dev/null +++ b/lectures/t.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +#include + +int main() { + std::map> trans; + std::set accept_states; + int init_state = -1; + + std::ifstream Input("noMore.in"); + std::string str; + while (std::getline(Input, str)) { + if (str.empty()) break; + if (str.find("[[") != std::string::npos) { + int state; + sscanf(str.c_str(), "[[%d]]", &state); + accept_states.insert(state); + if (init_state == -1) { + init_state = state; + } + } else if (std::count(str.begin(), str.end(), '[') == 2) { + int left_state, right_state; + char symbol; + sscanf(str.c_str(), "[%d] %c [%d]", &left_state, &symbol, &right_state); + if (init_state == -1) { + init_state = left_state; + } + trans[left_state][symbol] = right_state; + } else { + int state; + sscanf(str.c_str(), "[%d]", &state); + if (init_state == -1) { + init_state = state; + } + } + } + + int N; + Input >> N; + + std::vector> dp(N + 1); + dp[0][init_state] = 1; + + for (int k = 1; k <= N; ++k) { + for (auto& [state, count] : dp[k - 1]) { + for (auto& [symbol, right_state] : trans[state]) { + dp[k][right_state] += count; + } + } + } + + size_t ans = 0; + for (int k = 0; k <= N; ++k) { + for (auto& [state, count] : dp[k]) { + if (accept_states.count(state)) { + ans += count; + } + } + } + + std::ofstream Output("noMore.out"); + Output << ans << std::endl; + + Output.close(); + Input.close(); + + return 0; +} diff --git a/seminars/1.md b/seminars/1.md new file mode 100644 index 0000000..5ad517f --- /dev/null +++ b/seminars/1.md @@ -0,0 +1,221 @@ +## Мини-отступление + +```cpp +#include +C f() { + C local var; + + // return local_var - криво + return std::move(local_var) +} +``` + +Благодаря std::move можно не создавать вторую переменную для возвращаемого значения. Входит в стандарт с c++17 и оптимизируется автоматически в c++14. + +--- + +# Перегрузка операций + +## Дружеские функции + +```cpp +class C { + int a; +public: + ... + friend void f(C &x); +}; + +void f(C &x) {cout << x.a} +``` + +функция также может относиться к другому классу + +## Перегргузка операций + +Нельзя перегружать: + +- \# +- :: +- ?: +- . +- .\* +- sizeof +- typeid + +### Бинарные операции + +```cpp +class C{ + double re; + double im; +public: + C (double x = 0.0, double y = 0.0) : re(x), im(y) {} + bool isEqual(C &obj) { + return re == obj.re && im == obj.im; // неявная подстановка this-> + } + + bool operator ==(C &obj) { + return re == obj.re && im == obj.im; + } + + // нужен const, чтобы можно было делать o3 = o1 + 10.0 + C operator+(const C& obj) { + return C(re + obj.re, im + obj.im); + } // o3 = o1 + o2 +}; + +void main() { + C o1, o2, o3; + + o1.isEqual(o2) == (o1 == o2); // the same + + o3 = o1 + o2; + o3 = o1 + 10.0 + +} +``` + +либо для дальнейшей работы и `o1 = 10.0 + o2` изменим перегрузку операнда: + +```cpp +friend C operator+(const C& obj1, const C& obj2) { + return C(obj2.re + obj1.re, obj2.im + obj1.im); + } +``` + +### Унарные операции + +```cpp +C operator-() { + return C(-re, -im); +} // o3 = -o1 +// !! не перегрузит никак бинарную + +``` + +Посткремент и инкремент: + +```cpp +C& operator++() { + re++; + im++; + return *this; +} + +C operator++(int NU) { // not used var + С tmp(re, im); + re++; + im++; + return tmp; +} + +void main() { + o3 = ++o1; + o3 = o1++; +} +``` + +`o3 = (o1++)++;` не проработает!! (изменит временную переменную) + +### Перегрузка =, [], () + +> не перегружаются как дружественные! + +```cpp +C &operator=(const C &obj) { + re = obj.re; + im = obj.im; + + return *this; +} // по умолчанию так перегружается +``` + +## Итоговый пример + +```cpp +int +main() { + string s1("abcd"), s2("qw"), s3; + s2[1] = 'A'; + s2.print(); + s3 = s1 + s2; + + s3.print(); +} +``` + +Итоговый код, чтобы условие выше выполнялось: + +```cpp +#include +#include +#include +#include + +class string +{ + int len; // количество памяти + char* str; + +public: + string(const char* s = "") { + len = strlen(s) + 1; + str = new char[len]; + strcpy(str, s); + } + + char& + operator[](int n) { + return str[n]; + } + + string + operator+(string s) { + string tmp; + tmp.len = s.len + len - 1; + tmp.str = new char[tmp.len]; + + strcpy(tmp.str, str); + strcpy(tmp.str + len - 1, s.str); + + return tmp; + } + + string + operator=(string s) { + if (s.str == str) { + return s; + } + + delete[] str; + len = s.len; + str = new char[len]; + strcpy(str, s.str); + + return *this; + } + + // ~string() { delete[] str; } почему-то с ним не работает (?) + + void + print() { + std::cout << str << " " << len << std::endl; + } +}; +``` + +версия присваивания получше: + +```cpp +void string::swap(string& a) { + std::swap(str, a.str); + std::swap(len, a.len); +} + +string& string::operator=(string a) { + swap(a); + + return *this; +} +``` diff --git a/seminars/2.md b/seminars/2.md new file mode 100644 index 0000000..a887e6d --- /dev/null +++ b/seminars/2.md @@ -0,0 +1,204 @@ +# + +## Про оптимизации + +```cpp +A obj = A(10); // A(const A&) +obj1 = obj; // A(A&) +``` + +при отключении оптимизации будет: + +- преобразования +- копирования +- деструктор + +На экзе во всех задачах _вероятно_ отключена оптимизация + +```cpp +A f(...) { + A local; + return local; +} +``` + +будет создаваться 2 переменные. + +## Перегрузка (продолжение) + +### Приведение типов + +```cpp +operator double() { + return re; +} +double x = 3.1, y; +y = C1 + x; // !error - не понятно, к какому типу +y = double(C1) + x == C1 + C(x); +``` + +### Ввод/вывод + +```cpp +friend ostream & operator<<(ostream &os, C&a) { + os << "re=" << a.re << ...; + return os; +} + +int main() { + C obj(1,2); + cout << obj; // ostream and class + return 0; +} +``` + +### Перегрузка вызова функции + +```cpp +struct Pred { + bool operator()(int v) { + return v < 10; + } +}; + +void f(int *mas, int n, Pred(c)) { + for (int i = 0; i < n; ++i) { + if (c(mas[i])) { + mas[i] *= 2; + } + } +} +``` + +--- + +## Перегрузка функций + +Алгоритм для поиска наиболее подходящей функции для вызова + +1. по количеству параметров +2. отбросить недопустимые преобразования +3. точные совпадения (на typedef): + 1. T <-> T& + 2. T[] <-> \*T + 3. T -> const T +4. можно расширить тип (например к инт): + 1. unsigned char + 2. unsigned short + 3. short and etc + 4. float -> double (нет лонг дабл) +5. стандартные преобразования + - Любой числовой приводится к любому числовому типу + - Любой указатель приводится к указателю на void + - 0 к любому указателю или любому числовому +6. пользовательсткие преобразования + +--- + +```cpp +const int ci = 1; +void f(int y) {...} + +f(ci); // всё ок +``` + +--- + +алгоритм (фактически): + +- отбрасываем неподходящие +- по каждому параметру берём множество подходящих функций +- смотрим персечение + +```cpp +struct A { + operator int() { return 1; } + void f(double d, char c); // 1 + void f(double d, int j); // 2 + void f(A a, const char *p); // 3 + void f(int i, const char *p); // 4 +}; + +int main() { + A a; + + f(a, 0); // 3 & 2 => 0 + f(a, 'a'); // 12 & 1 => 1 + f('a', 0); // 4 & 2 => 0 +} +``` + +## Статические члены класса + +```cpp +class A { + int a; + static int b; +public: + A(int x) : a(x) { } + static void f() { + cout << b; + } +}; + +int main() { + int A::b = 77; + A::f(); + return 0; +} +``` + +требования: + +- работа только с статик полями +- вызывать только статик функции +- нельзя как const или virtual объявить (void f const { } // может менять статик и mutable поля) + +```cpp +class A { + static int x; + int y; +public: + int f(int x) const {}; +}; + +int main() { + const A a; + a.x = 3; + cout << a.y << a.x << a.f(1); +} +``` + +--- + +```cpp +struct A { + int n; + int k; + A (A &a) { n = a.n; } + int f() { return k; } + A (int a) { n = a; } +}; + +int main() { + A a = A(1), b; + cout << A::f() << " " << a.k << a.n << endl; // 5 53 +} +``` + +```cpp +struct A { + int n; + static int k; + A (const A &a) { n = a.n; } + static int f() { return k; } + A (int a = 3) { n = a; } +}; + +int A::k = 5; + +int main() { + A a = A(1), b; + cout << A::f() << " " << a.k << b.n << endl; // 5 53 +} +``` diff --git a/seminars/3.md b/seminars/3.md new file mode 100644 index 0000000..c96935d --- /dev/null +++ b/seminars/3.md @@ -0,0 +1,259 @@ +# Третий семинар + +## Шаблоны + +```cpp +// template +template +void swap(T& a, T& b) { + T tmp; + tmp = a; + a = b; + b = tmp; +} +``` + +Можно применять и от нескольких неизвестных параметров + +```cpp +template +void transfer(T fromAccount, T toAccount, K code, int sum) +{ + std::cout << "From: " << fromAccount << "\nTo: " << toAccount + << "\nSum: " << sum << "\nCode: " << code << std::endl; +} +``` + +Пример кода для абсолютного значения: + +```cpp +template T abs(const T& x) { +// template T abs(T x) { + return x >= 0 ? x : -x; +} +``` + +Суммирование элементов массива + +```cpp +template T sum(T* mas, int N) { + T res = 0; + + for (int i = 0; i < N; ++i) { + res += mas[i]; + } + + return res; +} + +int main() { + double mas[5] = {...}; + std::cout << sum(mas, 5); + + return 0; +} +``` + +```cpp +template T sum(T* mas, int N) { + T res = 0; + + for (int i = 0; i < N; ++i) { + res += mas[i]; + } + + return res; +} + + +int main() { + double mas[5] = {...}; + std::cout << sum(mas); + + return 0; +} +``` + +## Что-то про стэк + +Вторая задача: + Суть была реализовывать динамически расширяемый массив + +```cpp +template +class st { + T st[SIZE]; + int top = 0; +public: + void push(T a) { + if (top == SIZE) { + // error + } else { + st[top++] = a; + } + } + T pop(); +} + +template +T st::pop() { + + return st[--top]; +} + +``` + +Если указать стандартное значение для каких-то параметров, вызов обычный + +## Библиотеки + +### Контейнеры + +#### Последовательности + +- list - двунаправленный список +- vector +- deque - очередь + +На их основе создаются: + +- stack +- queue + +#### Ассоциативные массивы + +- map - отображения +- multimap - ключ может несколько раз встречаться +- set - уникальные упорядоченные ключи +- multiset - совпадающие ключи + +### Итераторы + +`#include ` - подключение библиотеки + +- value_type - тип значений в контейнере +- size_type - аналог size_t +- reference/ const reference - ссылки на элемент +- pointer/const pointer - указатели + +Исполняют роль указателей + +Для каждого контейнера определён: + +- iterator - идёт от начала +- reverse_iterator - идёт с конца +- const_iterator - не меняет значений +- const_reverse_iterator - не меняет значений, ревёрс + +```cpp +begin(), end(); +rbegin(), rend(); + +cbegin(), cend(); // для константных +``` + +Виды итераторов: + +- input +- output +- forward +- bidirectional - list, map, set +- random_access - для vector deque, можно индексировать, += n + +```cpp +#include + +int main() { + vector v1; // длина 0 + vector v2(5); // длина 5, занулены + vector v3(10, '*'); + int m[] = {1, 2, 3, 4}; + vector v4(m, m + 4); + // vector v4(m.begin(), m.end()); +} +``` + +```cpp +for (int i = 0; i < v.size(); ++i) + cout << v[i] << " "; // только для random_access контейнера + +v[i] == v.at(i) // выдаёт out_of_range, если нет элемента +``` + +Печать элементов в прямом и обратном при помощи итераторов + +```cpp +#include +#include + +// прямой с помощью прямого +void f1(std::vector mas) { + std::vector::std::iterator iter = mas.begin(); + while (iter != mas.end()) { + std::cout << *iter << " "; + iter++; + } +} + +// обратный с помощью реверсивного +void f2(std::vector mas) { + std::vector::std::reverse_iterator iter = mas.rbegin(); + while (iter != mas.rend()) { + std::cout << *iter << " "; + iter++; + } +} + +// обратный с помощью прямого +void f3(std::vector mas) { + std::vector::std::iterator iter = mas.end(); + while (iter != mas.begin()) { + --iter; + std::cout << *iter << " "; + } +} +``` + +Или же код нормального человека: + +```cpp +for (auto x : v) cout << x << " "; +``` + +### Алгоритмы + +Некоторые методы контейнеров: + +- `size_type size()` - количество элементов в контейнере +- `bool empty()` - пустой ли контейнер +- `void clear()` - очищает контейнер +- `void push_back()` - добавляет в конец value_type<> +- `void pop_back()` - удаляет последний элемент +- `reference back()` - возвращает ссылку на последний элемент +- `reference front()` - возвращает ссылку на первый элемент +- `iterator insert(iterator p, value_type<>)` - вставка перед позицией p, возвращает на новый элемент +- `iterator erase(iterator p)` - удаляет, куда указывает, возвращает итератор на некст элемент +- `iterator erase(iterator p1, iterator p2)` - c первого до последнего (не включительно) + +для list, deque + +- `void push_front(value_type<>)` +- `void pop_front(value_type<>)` + +Для bidirectional итераторов можно использовать + +- `advance(p1, 3)` для плюса +- `n = distance(p1, p2)` для вычитания + +```cpp +void f(vactor& mas) { + auto iter = mas.begin(); + + while (iter < mas.end()) { + ++iter; + + if (iter != mas.end()) + iter = mas.erase(iter); + } +} +``` diff --git a/seminars/4.md b/seminars/4.md new file mode 100644 index 0000000..e965967 --- /dev/null +++ b/seminars/4.md @@ -0,0 +1,180 @@ +# Шаблонные функции с контейнером на вход + + -> написать шаблонную функцию, которая ищет макс значение в константном или неконстантном контейнере + +```cpp +#include +#include +#include + +using namespace std; + +template +typename T::value_type Max(const T& c) { + // используем константные итераторы cbegin + typename T::value_type max = *c.cbegin(); + + for (const auto& it : c) { + if (*it > max) { + max = *it; + } + max = *it > max ? *it : max + } + + return max; +} + + +int main() { + list l = { 1, 2, 3, 4, 5 }; + cout << Max>(l) << endl; + + vector v = { 1, 2, 3, 4, 5 }; + cout << Max>(v) << endl; + + return 0; +} +``` + +Шаблонная функция, которая удваивает все элементы в контейнере +Из [1, 2, 3] делает [1, 1, 2, 2, 3, 3] + +```cpp +// работает, но херня, много памяти жрёт +template +void dbl(T& c) { + T res; + auto it = c.begin(); + while (it != c.end()) { + res.push_back(*it); + res.push_back(*it); + ++it; + } + + c = res; + + return; +} + +// работает, всё правильно +template +void dbl(T& c) { + auto it = c.begin(); + // typename T::iterator it = c.begin(); - порой могут вот так просить на коллоквиуме + + while (it != c.end()) { + it = c.insert(++it, *it); + ++it; + } + + return; +} + +``` + +вход функции: 2 итератора, реверсирующая данную коллекцию +Было [1, 2, 3] Стало [3, 2, 1] + +```cpp +template +void rever(T b, T e) { + if (b == e) return; // для проверки на пустой контейнер + + --e; + + while (b != e) { // просто сравнивать нельзя у листов + swap(*b++, *e); // нативный свап + + if (b == e) break; + + --e; + } + + return; +} +``` + +функции подаётся 2 итератора, предикат и стандартное значение +Предикат - объект с перегруженными круглыми скобками + +```cpp +template // T - указатель P - предикат +void f(T b, T, e, P pred, typename T::value_type val) { + +} + +// пример предиката +struct Pred { + bool operation()(int v) { + return v % 3; + } +} + +int main () { + vector v = {...}; + + f(v.begin(), v.end(), Pred(), 9); + + return 0; +} +``` + +## Лямба-функции + +Неименованные функции, которые можно просто вставить в выражение + +```cpp +int x = 5; +auto ef = [x]() { cout << x; } // тут не обойтись без auto +ef(); +auto ef = [](int a) { cout << a; } +ef(x); +``` + +В квадратных скобках - привязка к внешним элементам + +- [] привязки нет +- [=] привязываются все внешние +- [&] по ссылке привязываются все внешние + +В круглых - к тем, что передаются + +## Алгоритм remove_if + +```cpp +vector v = {2, 4, 5, 7, 9, 10}; +auto end = remove_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; }) +``` + +remove_if перемещает в хвост все значения, для которых предикат (лямбда-функция) верна. Возвращает указатель на начало хвоста +Вывод: [5, 7, 9, 2, 4, 10]. end указывать будет на '2' + +## 2 задание 3го контеста + +> есть уже complex, complex stack. Добавление в стек через операцию << + +посчитать польско-инвер запись для комплексных чисел. Если попадается z - значение по умолчанию + +> map - словарик. Содержит элементы 'ключ' - 'значение' + +```cpp +complex eval(const vector& args, const complex& z) { + complex stack st; + map> mp; { + {"z", [&st, &z]() { st = st << z; }}, // если попалось z, добавили в стек + {";", [&st]() { st = ~st; }}, + ... // все прочие +/-/... операции + } + + for (const auto& iter : args) { + if (s[0] != '(') { // если строка не (re,im) + mp[s](); // просто вызвали нужное + } else { + st = st << complex(s); + } + } + + // ответ на верхушке стека + return +st; +} +``` diff --git a/seminars/4.pdf b/seminars/4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f7266717a700ea4d87f56bc463ff1c46552d7a2b GIT binary patch literal 88196 zcma&N18^@v-=G`YIk9cqwr%`l+qP{RC$??dc5>pJ*xB>$-Ky_?b$7RJ)yz~)_tRb7 zQ#Cz3&##+IQB<6ciJldPZ0Yj+0EUT>k4n3i~)p9Fbu+SgbecbPPPD>|AN^53lb6f5A^?_ zvLb|xFbuNN|MRNxpL97{LRJ_C6(K?wCs)(|eO*ldug;5G+PM7dCWE-mzYd9-8rz%v zD%XmZ-e|g8?^JVF^&6Cm=c) zK@Lm?TuPs^ z$N1FGBqX;L%kleJJ0bAT@&j+rEDbK?H~u3qAj);n*Z0GC!qNBR^mZ4V=l5nmcvhTO zq6)L{l|u*;e#*i4c>ZuQG$ZTy{>efpjXNpzu>o0e1@%v_ zMI=ZbU^KbZQy%M3fN(YGOXnx%!wv-c6&>OdeNYKf9w*MwyzPd6^fc10T8(A;0W?H9P|HxAYz z%kjp$V#ai>OpR#KHOY%cDul5zH_mlvNMc$G&8TND4LYu#JeRgan68YuYl$(n&qRc0 z2lCOztGBIcjX^1>;oi>V#zj#I94TkkS8sok&%pHJM77{Dk|0E_47@5QgW-cUxo`zr z3=gICLXd|N;mvO>L4#KyCq<*>RZNZVS%|8r{_EPkxiEq7t;aj(?q#G&3D+$PD(=58 zB75SETUknVZ#AegEVVpp1ADH@lEetIdL5W>T0t{uB&!7xmH{gAmw=NBYb#A@+~Nzj zD0a4!?E{M-C$ayd__@bykd|+nrA#9xpR5Sh7L6};L6{`fPp;n%#m9yF*$-itnD9|q za$U%mt~j;Xp{P<4cY_}mNN9dCBKukjT2G4(#ip(p{@#^e`V}k`Y+swc=nUr55vRLm zh3~E=;wCm;Usb+aD*}NSYQ8@8yZMSNYM_i!QDPL_Mxx5> zUA(3Uo^n`C<7pVk$}KJ6EjPf19Gge{jiPXqE}FY>`_h;DaaG}_*qz2^RV#)}xkXic z(bjC#7FN&DixUoI?fGp4Do>Xx?3GeKuo1wKxV`af?WUS1ZfpiKbx%1wQKItHtl7=k z+H}F#oGqV`goumPxNc>hjLVN?B9Zx+);z-Cmh&zSez`S#+k8Bi?x;iB@1FSW@e+Kt zy(tQ1mT?kdU8aly?s#%N9U>T&%PgB|5E&VuBuOh}=v5cs7?7z&{R*5RYA$zXg+-e) zfL85EaR~Q8Z-T+h$%(DA4-3HloBqNjfHElIsR}@&YHKFi(@Gs++1|VpmkAoF-jFLSRKYi=2}7PF#`hO&Zrj1lEF4 zq-hm(4PeNVX%Ht2$>>d_V#*pPA)3=_CZjLPN3I1o=LQGu0R_8KrGjfLVlSKc(n~-f z!7;p9f?HG%8o`-(vZGb8YGRuOVMUXe0##y9u};J@L+wB@jP(yx$f(ttN;=g1A7dX1~E)P6S*^)27)s){GukJ zwV}CGLS;gxZv>W|Jx?nv3xpU9O1INj4d|C&qL8cAHYd&U?eyuef!0kKICLUm!~%4HPq=oCTGfO5iU*RHaGh#F(KK*_)Zug^ zdcb0I4_>yDf|a=7V35?smkn>6;!Im4b)(_e*Msr~*b+_?`Fdb=_rcM$)scvki8}Y8 zZ05Al1di_&hOkpn6;c;b9)!&Azq!N8Iq%Z4lKAUeWQ7P1CC#PPrfF=vlYUl*X5BN; zvL6wj6Fr%YvMH@grLo3iij`WmV8e~6)KSn5C^R(@H8q4>GY3i5&`K&zSsa#q#oMR< zGFBpCjJmYQnnHR=LNBEX(#!=+#0~;Ac{b3^oCkD-bC3qIrkA(l?KHhV`OpAwDavN* z4l&f#b!7*Y{t8|Is2uv*gP_H_E3JP-srxk4Qm*!(RecDd%Xd`E(=;KYVUrAET9T6U z<#IlEM4+U}^9trzBy)NZ#quK$qv>N$MaRtGnW@kXdQ%13NQ+jXAD4ehFYMOuKp0rf z;4TFSBR9-b3F*=z5i8K_e-|zHZrjT1S}KY9W20%O3>jnQn6+Oi7*|7C`y%vcFPT*| z!aIZEkU_26OI2?w4u9fDMxV9u#JG8xW){zv6D5ZaHJp02LK3MP8;n@Ow40@v7cE6k zLrZ`wmb2jd1p_B@Vbtq2^e|+DB_>k$1;q416xySF@9w*XuA%z)h4tZoAHJaL&zWA0 zF`ugBIR`(vqn$KS`{ys>4%RToWse&#omqdw8E1#e&GZYb%AQ=Kb70HB5ik@B==jBz#t`2UWNB(-3)WVecOY1MLACR`)O||wp{L<8z6u0O){+RZe?_fjnSY|9Rx}Zfa9-`!g3h4o9 zvI^^%CtU*QRC6L>&RuC}FpWQRiF2)9royW;s0*7TUOwQG59OkC;hr61S`yDQ*^E2_ zfwh89qm%HO4n(Ek;w&!H+al4mjjy{*7$rD%*34i>PzO5u(o`gH2jf$=b=WyJmi`-O zg355;J(MS5Vr9t|x|JXhFL}er_&DeQ$*C=%`Ebw_|5Rp;?qtGW>9d%_0(OO$8U0l3 zE-i|k9=eIV#k1R&%>g+maMLb_u$G{~p_xOxt36%CW(OVP&Bsgz|)PAdGB8p+gBWWr0#RDCajfsOeCx~9Oq1>(PRuc+W- z-Mp3b7Ymu_>CbDyE}rh87B1*j5V>66cmW5nu~<<~3H z4pfV@ASPZBkJepM4Xsk#EMO<-lJN;3$RK6W>}W>u?g-TRf8YIl+%JErg0!rBH;T>Pvp0l^rcwcZDJWugN}$A)fn!oem!34AHWgQBs8bG835}HW+q{V zC!jE$^XLP+q26L)-wR&=2gCAL+3p&c%qhJdlN~Dg_p0;Q%dsE|m>!r-OT*R{avX z4@OdLJma|7(kV_>yZidOH|unog~&+|m??8C=qi+dg!G6pdS8YoFM z*H?RteW}5R&ZRY9AyQj$LY1Bctr3F(Yh#6YwYu;RZ-B7TN&L#Ta!TZ@iL}Ga^HtjA zQqSu(wA$$UF3A}YAx&uujklU4K_Gu6T^=X_7;EOwCy(G3}ii|_}C$vGF3z`^?WevTfAUJ|$Otd3#!}V}nxitmE`TDDJ zh5FC>fTBQ{gPljT(XMlvm}dFc3H}_^M$*5s=oB03y^S}e9Qq$(3_bTxe?f6g0yz0Q z0=Vn>3|~OxM0z&)Be*<}J!pD@XrY?(@Go|>`+5+YuCmT?BHETX2`G;kk$%J97*-)Rf@sUv4bMH#FN(LR6&nl9=MY0EUPQ zq%d0)4t%0}f*;qp*tn|n6EE4QFfP|hVVeCchHih%?DD!$Xg$SsU4~q{5isoGYB4{h zmYI{iZfiLAr5Zo$&Ax1zZm8aa_;9qd*>=XMs>?bp*(FHq3;&xbPr26-G8M6W%Tjh4 z3KG7G{NdM=FY4lQYtAtH@#y!wxV`oAX+AX}T$1?8FIbPL9uS_~{Vgu!tN+f5S z5|4!LLIu2}?p{4tt?Mj(teRfFon$5add^kDOH4%|Q$2H5FtncWk zT6K2q>?^`#BK?T-ZX9^z^A;NE?m`I>6OO)(g`E&Twae})nd?#VOs8&x(1^!sbfUBvHUYYs8LZ)s@mNAB|NHzZZ+ z;EA7fM1SEMJe=?Q{oR{Y7^lx0H2Od3BJ{EFPr3m8_`bd0X%LnCY~7s*Afo&IoQwej zX9BJKlP*ZuhW9B`>89A~lS&i&T*y3RMdkfAq8T8W@V>_IZCoR?$$F?_Vk}^$QNM&0 zSV>k)zL-JMK6pOAo`j@1xIc{{&aa_B4Vg-5IfIhiTnY%CAoz*^2~K`vPlDa$`OFgStYpL?pEa|n;{ zxEY*=8YWZBo|pr}1Q-t)nSjA+;*S?~LyHsr_8ng@m}CI7NB4I7kGvGGE-nLJH?#^# zbYL1Rav$)NFou5XK4(ti8>tTwkV6>ldfsw->c#96N@JH{4U=LAJ%%G$tc}PoMPOf7 z8?j4aX3Qp>BTc5ws6>qz5LnQHNPWvvGh_)W2HnT_fe68_rmUcp2Z%2V1K4Cz1Qmmg z8Y$rR&}U5Pq>jMlQ2>Olm$Ocyz=D`t z&X@@~=g@&@T-+U)7h#PGWHqBKk%T-La1}5Eq;pL1rZAyHoX`rZrvT3_MyB!#PcPU`rpGK2T#o6fUocq(VBbm|eq`>-%d z`R0Tc&c&CUJy=W?5vrs@8qHbeh@LaUP8*dCPj!fxL&}dbED`i7iR3>D_P53yCbYaN zi@E5$jvq+Ue4XByFpT^7iX@Et>OqY4?Q?n&T-amsG)e?+&wYY8%g5oY1B6L48wZZa zq)6dc1aTLy0x9iDRRIBL)6z*YL$0C%Ca*xt z4rp1KcY~j2^j?lrG z-Zdh;geV4Ak!TcsnO&4XE3zPsUNXMx@AfJQMi9AAg8XSf5p)~BA{S5g!#S@!!Nwggc*xFu({}73=9?@HRxmnG^!-U z>Ej+lMRzBjauouk7^Griq_&MvT`2|oD}(C3C4A^l$ge-;sTs}cF@rdzn8rXs0%FJP z(7GW&m~lP(Pafknhaef1ddzf+swx966@pPFj9HD;xpYFOfZ_2JJYy3#axg9^RQH9k zdA$YT)c(dAnZ99~`ojP)e`ab{$m4qS;&f~|>i!YXV_vX8Dk!n-#%)X`O)wz__3#ud zFiwy#w1R>`pwsX_BgI_15McAhF#w~4&Nl<#Ca$|vqvt+|;-3RoF{CmbVNVwAc_j&1 zPf1SdH-a-6&+!NgQ2O9|LWO*4M%w&z7q3`NG@oFa7*pP!1E@y_8+|A;Nc@ zBQT_a-|$eWe)gHB^jIe^8kLoD$wJt-F%F)eNzQd55nH5Vdos?Z;&;f5)dxz!j5FO#DE@GUs@<`acB%_iv4@X@P}W^D5%DYqUJ(JBW9AJzNL4t55q^w zLvO!{I^WidVVEtx3&<~&GbonIzqhf2lcN6;y59WtEyz0eNF?$>lLs(wo%8~PicSKj z$yjzs;ep(W1f9F2#Y)S5{DkY-nC}L%aYhUWLmn-7NE%oq2XbD)>%p#Z-^xJE%ZULQ zXEs1~%SLPCsD_BFzi)S%+2-lnwVmP>0db^DWL-Rf=j^g>5h^p+zp`@Bj1inkYd;Uk z)RkB+N?|A#oo-z(Ht5N<x%}z-6ePKKW5H<^@rFzQ8 z`RST>XZKj{s(Nm-jn-*;Y`3kh?!Gx!Md{65WqQBHbo1?XCI-;jC&xtWs`1L6P8c&e z&Z$?80Y4Sp^x!l&A1zT9b5g8-QYU~v6N~9~jWz|eqhGi-QShP>9#x;~FSQ_(I4M%V zJTH2%<;|SuY8Q?sikD>U%`F+_I==T^+<)u6iM253;_XCDpoDvrsvd2sQ_;VzoEl7J z(PCUl#dGiY$Yx`hdxb}gUjK5Oyf{^hT)BRosJPmn*g(sB*2RC=;IRmO({k`_Mt;{j zO!(7%PDY-{0~`TB(?FvSMKYhV&4`&|}7&~v}g z@s0+WK4*Y%nod`HlwTOa)5Kfa%U|geX;* z{v{R!mJnn+blq}y@K5@-!;DRaw+W7_uA>7|`ag10J6T+tR~M>aFbKf)K_hC75&e4) z#dK54aQ+fg99nfpMGnZ9rW%QDPd%7`3xq)>X|`zqtfvj4di&i4m(2>!#Avq8Or0y4 zwTTr5cJ#eRDD3KH$nq7b_FA-*&MW!V$LU~u51+=CO$?&=X}xr|ovKpB((ty;Ar4@~ z`>EAiIUUhBX2pxAlO}{oF0N&_)Tb~lcGL7_EY1QTKw5*-*HY| zqx$Mf_scVT<&X=pV8gp1s2Qi9*D}ck(V}5)W6a6a?e*SIjZV^6SyNw@ZPYrMvBRG- z(Sf>cxU<|%WH9AZ+F>tAI=3;UqZQZaPF}8qIhHfcX?kt|Tb>wA7n`@#>In@z`B0m= z@4zgk!x*ep1O3J<9bouWUf7h0*soOqCKSNV?sXreKF~LUjc2P?0InZSGqQyV`AZKj z?3oNwSlzw%r(Pat6xka4cXiWg5IGR?1>&0zovCcJz&CiG6eeRI-;0G3$kx@>b-DUR~h1 z)VJ_b6ll5MFPKhLHThXQc93T`94G@bwIQ&LNU{#p4l~S^2na&?q_;?&#~$-mh%lv% zu>MW8n}S>Q>pbF>{MbBL zd=LAmeXev?B-QhGv))0TN?AxYrSdR|eofE3GQUP=8|FpK28U0O!c$4N7ue^SPOd1q zn{~HNn^SrDBNUY=FG_A|=G9Gve>rJDY6B{|uRrh){R?hDxWA6$X6OOX*=2T|R+IAzl1IXoqzL#iTONG257Svo}>=)498+pZ1F%yf&VM zIr-@(DzQ9%1?4^lWLg!5rblY&U6fhsvppa^=6L!0y7g zkbe0sHotYZcyj3IUyP;=G->4GjPB3rSELQ1=wyf*t5P8byl`h_A~up73tNiITB|n% z(YyGSv}J6OTI3GB`c4ljA?a6^$opM8YCIX@St$&^0P(riUAS>sJr! z%X0(fcFWL)6N^FosdshkdPUFVwxA=X6WxL~ih=E`rk9sy0^LBe9w9A}B1%IK<25tQ zZ6S67t~(8D%wS^0vU{l;7grcBO*L!dFgBYS_oWwnI^4RI>qbbXC9DT-SGDV}SjVst z(tIuDR?;jdE^4&*Oo?BnMS1A_6b#k;!&nU9X^DCJaD0K-U(MfKeEdps2M-=J=o;XA~8+@TK z3~mCH*Dc}# z2mwoUIL8GE(6n)KC;$&KU_;9vDggT-$n=XSpu*B03eYVOqPR;ic-n>!D_-tu>;l)) z3qR_0d22}ADvzWLaf@i_b#zSxbU1{)sFFjC)xW5M_Zm!f_m|h$3mwTGk%?P?X0Y)Y zslWf`d_heP3#&=bUvk959V%O=reBiP*>#$Ah`F_+PWA8U_k;Iy`0zY6%k4UWu&Tl( zd?B_X!(z5ugdj7unilcqJ5(*juFPm!fX~_USBc8NoLW}N5YO3tw=(Rg&^J5N1MD-~ z=4Pr=U#C|MnQC{>Ob+WA0PAiMTR7cZ zC8K-mq2btQ$disOr-pi3$1{XjynRbblSmDkR6E{F=w>d=A~k)chRYtZ0-Z8>xp{YZ zzDvO=EjeF9gLyMcCer0kn#IJAI{CrU$D;d7hcJgU7$VrOM#{BP!nZzGPh zBlh+Q?aju}$c3QaD6sa1TA*$xK)|s3*=WJGfA(?*07wS@ht)h)$6{aPXHw3XDHRy!-R8R-SJ#L#E&R z4G$rWIT`(&ji|f<`}y(ovE&a$^yU9A<2E_;w(t8X2q+V%61ZA2U>=CP@BUwWJv`M( zh1r8Y5|3hm#PCHF6BrBL*A&kE0gWZ!O)M(v6eWd96^hS6yb|zv4+i&Qa5pEAU*eKI zBydXHv$GG3${?+!2u5~&8X!~x=Or?*KmCU4{YK%jXgewDtwZoL%^E6|u2k<|Mbm2T`;ra%?hp;G< z9_F0AM!%oT6ohV;AoTvrB1T;r1JiFboy;$LujMsv46^6B{|qj;Au!jn5s3vVvEN-y zcq$zdSx$Ha%Xa$B2`>Vs z1@DhZ1obfMy{2?!1V*N`$hb==3xS3SiCiM)((qS1Ej`vvovq?HUCAd*3K1aI{Z>l+ zVz2PX3X%Z&cFt=R1dK|WEie!O-3gb91YRJ9{|dX1Y}gMb?g26&q0yeE1*RB&s~eFB z4MxH5w)phWMxhMnmGLVAf=umbDOnz+NX`|9 ztK=}}rWGCA-(my_$I{l(Z;6_8V%~}jdU5jmu4_ z^!kMpBtQU#AnlU~=^(7SQ~*cVF9!;Q0*l5151p2hP#Di>2r$P2iokV=qZI)G1|>7c z8Qd2+P6G}&$D5%Q2?9TFx0GbWFuIZz2?FVi$_#@OSyJRTT~hQrC@T!ecy2k!$ZL$u z6zBMrdB~ysZ}!C6)Uwt{?NF=?v^#@=zOIiLjuQ{A1XH2GJ5OZcj#(rLpwpAio z^&yyZ2Y};`83<>3?ZFA=7=r<32V3Ce7=p6>pPE@hV$&zyE^SY^$aeTq|4c z=Z;YHvD_&v29gIxkV@7E!3Xf&_3Oy~05ig1p(xrdfK>rouvhFOg0Q7MD7RC9I!sYQ z^#j30Q;5nsKtK-G@0t!ru9(1KBhksTX2%QigBDvA>XzQ-K@k3N{FSBv(cex* zWfY&Wh;$p6z(Wi~DTMZ5lB$bfQ!NGhi_!SF4Ij?u-jZX59JF8q&V~b51TKJ(B%ExC zq6oO4pWKku%$BAFD5M2E8id0+l?Bbh=+NVY1hklxW^MzC6ptNCD(Of}*qk)Mi_xeY zJ4^;_MFE=jsq?YaLGBCcGntk9L6b~iVjp2uPqI}uAPN#o$qk|c9wgYWO{{{Jx*$|> z7gA&KmXakF#sZiL8Ld_?atj1)aY)mdm6O0{Nj0H>5*4Eg0R=a8K9~)5@UfV3o)5PB z!d!LNR-BCOYF-8Zim7+ZQi-20MfD~x#7XUayeD6vdHp@?Nle<(F+GtF!?iH0-=Kkc2gO@<_0p;H zn|$kAG3ZB&7F^Rnv*3KXlQ@Y3p8!}U&qdzB*@No_^}aNmc=-2-^Kj*__Zt05$&M@a z``{EBS~}3Pr{5*}5twiG8o1zrJMxWftFlg|_`+54cy_e%Xoh(0#;Bzu&|&_qoO|XC zhr%FL`B;l)wWoBMS4B6nJ$t=2x!XCEqlLvR6By?(c((DC$@7-I{pB<}PVp5=Q5crv zI-LR5kh0x36TKo>gdUkR!KiC{2(|tnaUH_f+TCpI!!0v_mh_uU5aLEDq(_Sk;E$gc zA+M$gqOuy;U~~8-|0sBNwGgZafR|q3ouV3G!U%_^jo^4 z%icl1|CV;8Z2Z1dS`Pj+#a=WMX0g=%)ICJ-25Dm&kX#yHOYVk+wY7X?(V+55!AmE^ zy~&9}Vapq(w|@sF-(}yCU!jA*c*VOoc*g0aQGje=odBvC5Z|ciQ^cGv)B#6)XQ%d0M z5oG?GksTMrblofR>P!DV?C+U|K|XUq2D4EtZT`#M#?k&N(Yr-3l|y!Xt)$JS3$iQM zkQ}*Ur5reFY~>NAni-5Mc>}mD6OX3EC-eRxJM{1M_nu_eQA)nk&q?bI{{e@BK;+9P zaC{tMd5I(J?bWkjFgGrPaE@zFq9V(oDVQ)phO997n%2RS9XGIco5mSWqRD#|$A?u3 zb5m1!_9VZD`mf<6Qw|9rbr8+5z$d{5iS}M5Y1-m|ATjeSAOSUph=nQccBUnvsMk*j zkVyJ=9OJnGdiCL0unC+slDN*qx2EhbQ^NuXq75i3jz3}RxFMCT1JO?HGdKi2?V+u7 zqSS$8W-HbZyfvEuR^*QHFZHuwz0v5z=!sKw6H>>4HfURU->k6`$fSEYac8}Rv5$}=s}oP zcgV6J6ZC0!j4fPXcdVR^uST#l;;#qg?Nd^jEZh@@AzAH(#-&# zb*6bNE6tMcf${+XuC_EbYfwN$DHd!z>gQ}o?w}j1_2NK4?=vN3FzWp5NV`P&uKxhT zroc$&YDB^T!YsDLCtyaxTTny8UC93a>ag8YqZPL}^r~r8=;|A_*i0dSem35;(aLY2 z(5F8(+?;C{v!kn4j8#gg3F)6$85*B&NU9X($x3oPL(vzvq9AA&ST(B46umAj-=o8| z%LK}Of~wt%1Wv|6`;wu{AqiROnBTxS=%fty;mhlW@O6JNGOlGl;WyP@&%ekMxuK=v zNJN;)n>$Wb@5whG(SL|v-iVA$_! zzS{3Avd$sz=V)*>wJu32(sZ0DE*yiX1Vo%8lzG@i)KPR86br=bNp&aG^C-71k{w(n zT4|_`9pVP5(UgZoG0)TL-pZ-#d@9tcAKn4Y7BhsbT=vle&uMF)Kie=5WGw^7a}0MR zQ$NO*q0o2!0X=^7bK{HbN70N5>e$g=PTZ-tTrYNK`PH>z?PUgYFJvMO(vtT1ovqcL zKP@Y#?X9i%o!k`#09Tg8m_Zg;?ESVX^q1qz7iRc&t0Bq7jkLf?N6_INp zW$UNhosu8z>dFi15;(_CO0^om5gAFcPcP*ucyn=()V8l3(hNzOdemznI0_6FyeTow zw%I|W=o~|P`EWPg2k|lia$K)40P@Ovq*sX$u%n(9tV6v`E1c~*?oe;Xbb3bMTL?yq z5)S$yIZ^ zpztY0!-6r2)TVaNIY!=ClSRdhLaCQSOaj&)^m-xo2cf$>yrbr;@}~N^AO|6*;Q(a) zqc<*bpn4k3<5rzziW%rKSc~adfYHr;R>P=mRNWt2LR5aZOnyFW8qSN~p)sg-+ zT{Mkqvpscie&%Gr#X8nxLW+_*4CbOa7v?0=a~N|-PazyMEDPpj zLjCoX3DmTF80Y%LGacO$H-yft4Rh-qj`p-5>tiMrAcVPiNpmnp1%S(96f-crjV7c? zU;Zh>mNal3YvSNdf`yXm#F#{+w6QTBAWFT5n#P|!AZ{cEXiglsu{Ehj#lgDT6^GCX zF^9y->@^&0^TwGVKY%fPVQ(y)QA>e3p48PEQ0sMwse?D7GZ3+}C(f=nN*msHCC1$>_fjFT50ro_?bC%9z~B+;+Y^6e<<+gY zJ@f9~In-#jEu?0r2W2q2O#rHQmV~;*LlJ&Pmo|C5B& z>MjL^r>hL2mVR7%rHA6XRc(Y5TuqT5b46Py_M9$;x9gQ{Mvk+R7c+q{9dUXJz14Ir7>DR*IQo6x%3Z~ z&4LHqP89BE+}^=|#E`ANAB&QnNMzA!S|WPRz7K&ds2>RcGaIlCO;x#jeF%azhN*U z%|U<@PZg~Bhz*^MRney7+%XL`aK5xuWdgX(e6GS37UTwea?WLN8OOd|sQNEfg#Y4cCjYnfaF1y^JC%fFweaWNQ5tFfpA|~1n zW*-X{IG2ijUuy3=2wHA;)mnx7p5~Y5tu$}x`<0KX%<&5D^e+-qyInB?Dze$@XY~R~ zTXm+e-JwT6+@L47+%`UHE>mZg-i>)ev?=IBdR(`eQFQF-nS$M~P>wvt=mh~T+wo1F zyzHtpI{+{o-q+QPT4Rg?Bz>?cZ8zYQ>QE!PF0|FQE0mPBtHzgX(oI@YrZ|L&G^De4 zW$2tg^EzH`w>NH`8!b4pUHKQevnwiHNHeKjd7JCydV9hwIh*kiqizy|?*YEqcinDk zS?YO&$lWMq&4|p2IbNr^JI{j-0#!ZiaD)61yGh7mHE%HKs;op2OZu@MA{2VII zOWtuCaYIyZJNlMt$o)NA>(65QTLtk}oDT+G|e=XuuKN>EAp@P1#N;k!Fo z71^0*(3Y$9{F|^&D|BzSk1d?swVMxQFM^uCWQ;kb0w(%2w;9E6!@wpg@l;EFgYXs^ zfZf1>Y^es%v?Za0hlcJO6?&(e&S_tg2>NT7$^EQhYD@H4!J3&z-6kTiRcbv(y5a)w zFMdXkj|QUoa;mTxk8GO1#W~)d5SR|f=`%mS!|(M*JS6|c?1|lV+xEpcvwI2Dp|o9p z(ZdKuH-Yk!5$t+NOn37(|E>Y=Ob<>+zSDi{$*HxT+Se0l1#mDNZi^nZxs*>rpQ*P4 zm}Acomj$L{iyYk*Nfe(Hi zizvY>cg35IQWeNkBZQY4zDJ4W80cqBwjGTVQROBOb~IUaBs9P7gNp|~(ZA_@@AYGK zSHA4uq_>B*JCDpAu_z#1j}9|mkRcY)O9mvx8?G{{ z+<7EDnrp3koUZl8magkf&mAq-ll%0&G3ET|i3@S(H6!xX+E@DSycaxuT9jtW73PL| zIG#BluETHLiBI0KpN;W7bJ(8E#b>dfx~eqz$`p}y>gxQWa-%ULUmc6QH-Hn%jBZz0Q%8X<%+?t&hwA_JdqMMjsN!Gz&FrW>iW~bjOz8CMrvnw3f2?Tc6HH8Jh>ME@>c9RBs(yJjnCm6El1VNcMZLHgWvoKgbJXw$~lMrT0)Ji9dH*T7Z@ zNDOYk;X$vx@O+d)stOu-ybe3VnW^b>)jr!OO6@~z_#GpdYT0Hc!R9n%H~KI=8l7*) zOD>CjU*s6?)Q?o!Vl`EDs5SapH*|=}u*UBuGG*o6vyOz@MSVmk_Zpv1=|PG%1FvPF z|GE$1yL*a%68v>?wyZl$Z+H<$9(eNg(Rw2Ru3Ox%(TU%kOFAnPs|-yzmKV z8m~kc^88-RSwq2!ZV7aVtLp7MNJK+{V2U+&KM`@kmo1oW_N(lp;#Gd;_s#eisS11w zSgAduSA&9w%?3`e&>br!& zm)rEBZp{xpacE0f)17&ip!SFWgApOjbPIT0f%~)3crz{YNW6h!(`y%MT*ri`yjd!o z7OyXx#QnO^qExCUS>fCV5-9Pu)*t`L!a+~@tGp~w$66hz%{^)Eul;s6(@5F%bF_|* z{bf6{-%H)RbKuE=t0ah6pzf8g9ZrG3esh;t;;;4VAINw3+ayyNtxFpMuO!MeiQ{ea z*F^acb|zmrls$on1KWCOQ8eR>UcVeauD{Nj_*$d<$Yg(caA^ml!J=-T+@4i zqO8{s1_AlE)3tmB13%WKxgV)dAJ$}LZI-Tl6tVkxpWwnd`*H>ho{{rw3Px${$_bBy z;6=N^xvjDDcxCFJ^7Cs0itsag|NM*s6d{hFC`2g?qU{UzfHl`zp(cDa#DzeK20e`zUL9B3Q|$Q z)*e|IgG2_IA9fh8!!3GHuBK;v=5zFqo%o@mw=eq`&4r|r(f-;hdd3) z6CamY-QM#G%sShqMc@zr<$&!ab{lE=Wq4?l!9Urv$lCMJbD|6*8_-4hCo(^|LEJQ} z0Sdw5S845037gmZWK-~c6bcVbH_>4t6Y&en1PW2-xJq#g73;QWUiGVGp0!8ZLEx^3 zD92I|F=BFZGZIUzuxv8h<%tg#v@ctH$oHK=p*ucrb_HkCM0sk+-8!jkGd;EpIcCgxXm+mx>L_&E`6 zWZ2yXk&i6R-~XzE%D<|H5ea=~1(!HD8rnISsV z`ZV}X^7lEG4y4Kbnd0dz@Z2UtIu02ywll1vj0>E>DiLpZV>;PhKYrLK#qjtjznSoq zZIJ{>O;wuD?AXl5{|?;f!>tI2Ot5kwjIh0WQx2hL7V7GNd0YDPeIZJ!!VT(*hZ@jRF9RH;6c^NF-JeZG zPmaLz#9>q+UelQioS^P7eF}`Q4Ck;`py~8tMll+_$ytU41V6-3^nPRWdZ|*>(K-}#3=b)_RY?jS9 zcNjm5(DQ_Rk-@At>z_I*BfW@q23mc!T!os{u-gl${s(nm0aeGcZHq&2cgRM9`^E_n z+}+*Xf*4+NK>ArK(Ay9Rf639iB2`J0?`?n&OwJul;Z8ROGC>8>v6s#R-Mcg>!) z+Eqe10RBiH0?cO-dNTk4?gj_;QyovQ)0K3r-3)r(WN-N^QzN&6eqQNn7u)_(sJ93N zB%Ox-xSoOB+Gdi`e?+DIF6B?Fu#lIHRf=kFFFq^TtgiZ?!=Oh6K6w&rSr7TPF zwj%L*D?#(?R~3wW2-QLvF0d4mYBfA-9hd9$=55~Vs}$lAG~FJ#yHT~)D(#0O!fNr& zI9@XX?1)>;U4J!iF&}wik|{j@B6NBch|~?O`l3?5^ri#HTvL5BrR&W{2(l*w0QzHi z7{YW2b=t1CB8gD>zWavd)6xcD*x;(9qj{rlsR63p6@18;1zQSrgT&-?9+I7j#IxeM z{u7^>&Bb+-g_Zk6HP2rpX_*hG95|A;?i-5}hGL@n!ELpB%ZsB;Dq6Vr$iQGv2n6mM zQ_m>TNw+WA=u;`^CAh*Rk;;~p9T z=FI3$jrkgLu~fVa81oE#i%@C9SOc;D!Kw{9cuMI$t50AdMKQvmn4CHn z4b1QiHslTtJsi<q8^&vNmp+H_I%7fT5-IMMYK!(ejvG3U+Jm2xNB6~ zE1n};IGXb7elLmofq9bs``$==+G}~O!4b!uyU>R$})GyyhP_8o*T$%#sJnY4|quqo04| zBq%W3xPUKXbD*}SZJ+eF+O)n1BIqBcOt?}^-PJw1K6dl5hdJ|kX51!eMyd*)Wacvy zGoNM*Zp`;>u%fAp{Z&Kw+p?gTP+gf(j=ilw{}7gX&yqc@)0xgD>{piCHPxGth~Qxj z=&=sva7qMtADs(}u{h=>;Hb`co(adaheTc{ak)v@p^w`m*yxSc-@6jrK~_c9xv1J+ zqWbEt3!$G`?3~<4XxjkSjZfzuW+ZdyJ$;xK10jS=lC#ypr?5&eSp2A{nc)* z`N(Q;P5~U>*Rv3!sJKW_z;CeAla9y3hcY1pkmyYKsjdvH7Lo;SkA@@awT}eAaS%aw z;H#t@Yqyv{)eB>*O{Cz1%7*M*siqx4O~_9DfZ}I{_Wp!U#$M-Yl7rBD48bMga^0|y zaf3MiN#!vc8Hd+lw3xHdQ?(7f$Ga(AI=Xc$9V8ppeQqk9-`evJ8$QTSi@%)@>#UfK z@((;VkB_eqpWU_|x$@mWFD!9SwJtli*qDFFcwVQhrnobGymf0A+hx}KI+k#9+vM8r zlpZ#9cXW&Q^^uF2e(cVaLL6sJ*)}t+unzpl8EHeeqFWPYEG>6hpSFgs*)?*>0gS zXpPPc=Nz^wlBsFD;)NJ{7f)ymErJ$RYhW5c|ALvwm(X|mG96kA16ZC;EY}cgi^oDJ zySH)HIU@4y69JLE?NE`EtAiTja~gL{pUI>;y@V80hvxvJ%OPfL7+y1!q^4HBx7+_&SH+Z?GNo2NqT+9HAD_BQKlJ$&5c&!H6!P1cy$u+C1`Cvi^UomP;2v)ZFP(o zm_AIDNs4*ZmepllUzbwXLRq2r!tE+EyGvoKHRa@9jx09eWShq`hjwL=1~F&OjL&QI z_G!pHf=}Cy#xEX8|7HLwyT3F6Fv=U4fxPr6nmF1yI~bWb0zgiTKn{zHluVoeAfO%O ztB6tA#LWr7C}9IiDEQ}I=+C``4m_iXo0FK5)1wO`P*yP@;L!zxF1XV}~bTt!OCr7|{-$bB7ltAu_ zjGW{R9KN3g`8fLH5WvFnN5PL$dUT$|{22bzk<60srLMy1GTy7(6I%38KB$Az_us-!fSHR7JZRIEa>)-{?;z^1lbrKYs%BbU7`tBDYt?CcF zUMzu85%y+ggPYi&Q$&N?`A!EC^Fyyou;DVB{pX%HGP&N5PnK4?8my<<}VBU~nz0X;uQV$7Q)!Whllc1X-JpjOg3N)F^oW>1zt2-lYBZSU!x4xfHN&d$3ZRCp~sZ=@5ms9-Y09{?8<%+V`3-Au=-%& zi8#fC6zYCGGwV9ppn5~!ulLkP`T47ar%!Qs4YZ!(*zC2NL{oE56@?Psg=U%E%&O>X zsVOitQ#O(LkU9=umfeQ9LAuGZj`qEk))`UeP8>NqN>=7#F47JP&r-2_;cQ%%bGDva z5&dz#p7?mUKg^y66_KWw>McPC)*5%(JCRtXxHMiOg;CZwqD&ct*=fzop9?e9wI|xo ztl3o~E05Gk)`DsA_!~auJ3s=``e^AZD@e2a@v%}C(AP%ddb!c&G9d9wzgW;^(+=sX`dkL4$3M2C2#t5&TjX~k1DNJllaNu*_gmOoC!rljsP-U zj&q!(0Tp}|zA@|jo-OEPqzG;%<=ySP)hkZu#BFH40{UL5tOieQ_+Fd+GO1%gH9RB)L!G`+A#EG>1X~2%jcrkiQ_nA6G}+~mZAjDmCrWX~F~Hs#Jb$Jl z#&3NkDqAjrksm{x*s;20Oh-j2-jAr9%Hx-TZDwsr3fIc0praJ)duV7}q+7Kk(&3QB zD;RoTfVl2VNnD-He zr~8JypZuXS@FB0>(&Fo)393)z0dsv%_FihL5HR!R(v;rPAkx*oPrC~Zgc0D&`>0OW ziT61`dJVoZt>hImp}9caZEz_Ap~9J|z{@#bPscfPY{Gf=MCf;Oz8Wtb>O1IaYP{O% zYHDrR5r}P{vLQU150o+Dedvu7$wq3F3c+a5BJG_gKedBnoN4W*FqjKGETbQnQB+wD z>I_N0pGS^cohQ^oJ=#9Zhd#2m0`S>tp*^i8Y45TjSXr$iIHsnD*3UM2ALia{vWySlrN<96Uh zcZQa_9Fn7g-Asw1lhTG7*`_VYAj~+9*89L^;Ml^fIj+Ku-HwVTGlcQ5|`H3 zW=G_WMhFN7=DaxEqNz3=+PFgEV?{_&G?i;)om2$tG{|OaN29@iP2hTQc28dj6*;?F;%->S^h)_3@B3ir(`DlF(d#fA4# z6@nXQGp1&IL5$|iJWjglFjaCmE@_26?R2p#I^}%pYTBcj4_f)}jaD43yIT}0EgGSK zBK%_ZU~QjOCBvS&=u0e$RvYts~d zO4c!75FIbK?XEhu!q#yz%j5OJ(#mcPod%CXN8I}uMRDkw zadm{lgV^C~^v{$r52KMTz;ri0X*J@$Qadc7cfhvkPRXGUr*bGVJT5{iY&JbBz>{KM z!<(}1J~d0v5xLT#DY3*_h@!!~C{|<9I*zs^LqZJQhjkgZzrD2=m`_-k zn{}4p48?|ViBJcx;<<}Z1T`>R?i6#cv9(g?rWXJ3LAUQh=fU(Yl`-HOj^4wO$C!%H zgMe+<&?RjvKbKF*oMoTx{n6f(YP0gSBYjv=-~GFm>&hi^)kU9`0}I&NT;S|rGmW@I zzd&-Nn1m#AA$W+Nux)}8MyW%F2Yt?4T#pZ=YvXjG4ethUM z8L;CU=3ukXL;~OY1!pHjW@oXQFZ`=H&t`5uz4>DQ+~j0BFN=Rj_pj}QeVHxSwlAD*3~)M(qf-n@u-&qbP5 zo$I1E<$Cc}&)=ik?XGD#b#bl0In$r`3LLt|B@S!!wcDbOz``$lhU+7FIp%NI5k^WDBB7BUh8XP$l&`o!dUfImg20t7YTF``8hP)wGx zp;ePAn`0c`8p*kirt0OJ1!wO*oVD7xI5PV-u4lV&Y*{B=SGiwPi8 z5iumS8_JUq&%Ew6+(fuRB9H@WFMi6HkjbeVXg0f}>hbE!29-Ft2HA0U)S9u`P<6yJ zUK<-PFJ8V(qBwIgm|e{AiE9xV?`=)*OZ`kK5O)SkQ^;~onI#^Nh=|_H-u)`8NMA&5 zBB+|zhZz#OXM;I|<1nBK{o&h9uk38I3Jq%BV8XaQTk+?hApbAw{ zz^pLC)YY9xu9z)0DTF`-)Q-Y4Jrxo65P}?Yc_^v3StkZL<>kqTUH{16@sX8m`la89D=Ks2bcCciN5Frd0Z41 zojr7k4UV+n*c18$JGW}2reEX=uX4Z{AKlmSj2B^S#SqM z^*KQ`_TlnF4np@&%j&pkIVmyj3EQDfSsbQSIraNFgNt|7-_Y1VI-e^Ex@q~mA2cKVZs5y!;R{}Y<1@7ru)V$p+FaZ2wVHx(G~&P z_Jwc-*Bb@yU@Oe6(Bqe`2i~;yr`U&$t1J#oLDF>CtFwXP&gwP6R>t3lbw=* zts}jniJ7yt!DF1YftlkY93kLn1VSP~xF$OnJmX{T#}GXW7YO1|ax$?|1z{9yAoRlE zrMQWOnYj}PP5@<+0HF{TMgq2G)+Ub*+8-|@_#FtPX9oc$^gvE701GG6BU;MN0RllE z<3Rv~2@BvmK=BB}{)KS-u&neCgyS*oA36SR3V`K1KmuBDYT#({nBZ3}QgSwQ`VJxs zNeDltc`ObDbb&(3c4893G6pX}II%IPbrw$U-%l&KJAxW0VQXsl2nT~CV*zq)<_@3| z0O7ADAW!#l4#p-97Pe*ps=u;`wjst5f6vv-=)Ixo6D_PS($&V39phw z*)tNj`6=oKUq<83lZNnc-P7iWbD;S|HW*0{CT2ou;Ng2yZsRXtgg#3o>K1p;scwXh z?CaoeM=q^fV0)+0B3eVfk*(f`)ht2u z@{_iM5WiOl-`3u=|-Bs`biPy(JexW$UI#ikTIm_5hvS4=o=eeL1T z1>O5tt6Z!I7Gclccjs>~sByLyfqm0}VoW&I7d*gP-GiOQ3uV#yR5f_ThrKV@7QB;+ z<)lVhT-`dsvk2e8!x?~ywdI016PLK*A@D*3tKXvv@>4e0?tsn>;VmD^XN@5u9-U-f zdV{EZI#uMo##_Q2JQw8qgA)XXXFWv!-v7WKko|ueSXeoJ>VFX>siHL|xcN=YrWd65 zRYPNPa^>%9A6($AbF}E8jo!Y2sF%vzn6y>1WN&1ye%gfj^!7n#<<$KCn5rE`OxW%M zPXjv$B|ft@}rAh z%zqa1g4ZKy>t=X- z#SuMK9l5W-!iKUM6EK6pvZ$Rg#;IUFdvEM$3;X91|dnQ!HEj#(!}!{fmbQ;O~+HnSbI2 zswhZAw===j-(YzH7_j}0JVqzjg0>&@2*guzkDx<*p@dVwzQ7VX;s;xm;8cnOJXr|2 zpLioAx+SEAA|;(CbG_C2rQW%s>@hS5X$rYNRUHC1ixnu%TCx z3Wr*Fb;tWE&$8T&Fz3y*xtm_~A58|=c5r_5qvAsszi=Z}Wml)@9|F{HU=c<^Pa8u z0)P8Keef5y^TSJ>f3h8B&Y#|+$jE;|Yh!}D@qot;9>PU5O*?(%_36e3fx>10_RDM3 z9qHj0h{#z_KDXt=#`mNxMuoq|D0qP&@C$p9I7f`janxQg`j;XDUaVt?6le*{$gKr|s*a?} zV&t2#4E5uUjzd#w4M4}U+uX10D_P0(iwklASoN_lcg$9{!}x3re$n(FUP1j+ z(}66kKixJIWgHklw+#p=1#;9p_*kB?ZldK~-0lA!zYV*RnQfJa7$7r7PP!>hOT1sN6>eZ)59qoUb zmUJ$=J9ztM!USE_K3^O@yYsDy^-i5k{T6Az0~`FeaDB^a-m?O-%V3_|=Ft-S;x{!r zHw-Tfv+L@gO~s8oJ*85}*2ub=c%q4uzqfNc=jXrBxl@x(mn+g8+87%2Y`Se1%fJWje37~04W1*(x~I??sI1+;P_`eYH2>5>Ru0Y|l}$!js*L=* zvM~;0-9quo$w~KTY~IhoQl00^fMZKU>&vVodrA5rB`s{cJV0SbdGWBwf;`NRBtU%D zMMb)5;PZ(rvp#s8`+a?RGeHqrB#(vjip_SBP)ya4Z5VVsIJUQGZ3^YI#@-XoSaJ2s zrPpr+vHS(2ps~p1(9Ldb(Syk=oCw2H(stt^gcH^ zlvK3hXtap1bfqhFQJLf#@Evr1Q3mEB^v;(~iiRSkXl8o`GvX6tl!`#;exz%!e_o4e zkSpSOhxT2L6vFWd?o|$6t5>V^IH1EW^40?f-?q*=KR8>T%3G)SgkN0&8f>@B8YwS=kKHybUexf$yZ$h?zC z_!zI~`G&5rKCBXZb(j@vd(~e)r{a;ly1RARJqGsA^wCIKfdm;z|mq2KMr0NOL*hjQDgE)x%+s&J-wSbZ?I$E zjgP-jk{_mw|D+@=tUt|=L=@`np_$?ObKk)12Np-}a7A=|seKqvA1X(u&o=>I{vtk& z#F!Ay&YH;>NDk*?a4dWY5wk!qC(i6`MJ%M6R#0u6h%(pE8V+*xlPvwP&Lr;?Rrgl% z0-9K!2*GmG#2}?bls5@0Y%OVCTNRJn#@xX58h0vg1eQhY7{&4#ynC*8--_bd_B5W+#PJt` z`^~8(hz{_hb*U&yM6Ur58&2T8T97LY+~l04`?DT=Z0Pl=p6)_f^+-$93qoVn#P0RM zi68m}z;IpDlMjHa1k{)FuYy}cGPG(fD@EclEZtQPq+#z+p*LeiO{#ie&b$&cms?Mh=i6i}t$~31q%i9*EsLmr5qAm-umc6k-zQ%rR ziwgn6p|;?r{;wm6sB+1UY;iG1Y4wfqub~`8_||!_ZH?ui zX$WKd@(^o(KadtJ4$rMSwzHNN**ew9^X_P5_j%q>UU2G=?(|x6sKlc52>YQFY*K2_ zAZIq@6FocAjdR;c88fq~w#)QNN(_G^zv$K9oM5uD z{xoKaDE-x|e7-`oZ!X5$+X*f2LA|<}+SQjA?l!K*p5r7A53I3wbVG-u#HHbZBXGAc`!yoFhhuQAgxOEU zS!uPHNyi{Qbl&sMJ}t7oBp!)w+kZ10WId2a`Yn>sFh%%N=p9UeEYk)7M689R%5?7W zCwzuDyf8&yRyZsudX+lGxRdAOmWJa()K9^gS&Rpi?9@ZH{et%s6i{)FZ;&XRjP41iksoP4xD$uSv|BrMoK2KZJ%*zuJnZhpV61Da)yP-MW8pb~ks=rnxM+ z3uZ(TPiWd&nPSF74AbEf;AbRol&AyfvGy|S(6AK$EWm>ztwy)(Olbck>$68iT?S7= z6^%C9ldUj@UXoe97xawW#x?N0Gju~nRRna&V}za;p%*&ngF5(vYvo1$DScG68yQ6c z`}0m@((pBGq^_YSQbi4IZfGgWJj5fpm@w`UvlJ*xcO9)1QC^<-`w!J0zckjK-!adD%Maa255au{)-`A}A%%S+HbQt|Y4SsWa&%*MPar1&6;2}v6>rdc) z(y1FD4kRosky9V^Rs)c6j13S-+-z}6pct~Ct^4vh*ePK=4eN~&=8<4s!cD%qmw-jP zu<9}MtLk;+xi~`%RI9aRxwqH{89%^~(lpk+mquv7ugzRxClX-XOk6d{l}VbF&P0Uj zmyo>#~69W zo{|v&{zSaew>j2Dvfpt9{JwWnqlQ{pE?Visu<(bM!{icjbScD2pO-u7Z(=)f7SD2A zZ|r>b5Qb6p8vk8ZtiL%GW@G>9K}tngBASo{v0;k#@`Xw|H28r{OO1-GQrfqB-_U6+kG@)}s&hQ> zCnV8bjI)t15YBRzI=|S%8dNpHQ;0};C9UoqN5A#S=HxuZst*seWcV!iYT0hs5v3173N4+BqJ^3Uc4+A&ZE z!7jDbBcf-X0&#Ly5{dPwzTTCb$@eCLos(0N!DfzQtzk#Ex|FOmsMWm!@^FvJC<`0V zKQgY_PA4+5o12~SGVxX53zj?^RfwF!2U&`)&t6E`xi6VyHPeAsF%}z5`cX7IRaNjX z5B+jFOexdZCv0!dtehy~EO(dFY-cQ2V6i(uJxZ0h)uUeM95T8X^(v)%6u&$ojBbPR z-GX5dwuw9*tWX|1eZp(Q&FJupjA!wN;zoRG+7BA|z>VmEhl;JQ(8{>VPuOeg-os_5 z6e=8zy;h;`jhoEnO2&X};5pP6>~Tmbl$FNb#et#>JA?J3*GzOi8k9$FpP?VfCCf>T*D1K-x4O$o9nb0$@R$F2Yh+6 z7`I{U*=)2_Nol{_YcPusP{Rl!(imPi%OJu-!UpMr8Cit{mZ0nFt@T=bmFbP36Pg=E7) z;-~MJ7~DD%YLg&)n8yA^ z3X)QIQg|l}9V>W)u|1gR|3ZSlIT;7C{4^O?QT$tiu}D;xX);+3(;x{BGb`~V2w3Br zYc1rWQA{9H5&>oPsODKN>EC-wcq?Zen4=ba_|)@u`pH5rgk&*<%~bFZCyS08Vmu}9 zyWubz+6==gA*C6fL|tBd$@)m>@lEcz;Klr{I+cySOi>9`N{@Ir?!}S%^s5~%R%R|p zJJ|)qR6tXAm-ZT0@nR-i83~<1T+r7$rc(4_l`rP*!t<1lPum-kJ6|n{7Wm~k3L2ql z5PnqFR;Pk9F_infzBO9%*(jf0d)#3tP%CvtRY`%6VmU>-j<6o<%>fmxw-H zC7)@J=ySVgJid&gAGofQxnba6ufGM?Q-2Hfi*EQ`V1Vf-MV3+Ia%f{h+`WSLY{6e4 zzalncp-y?I*6__X#6mBr!A5X*-60o1*_2?%ZeX+pDblOR;GSYPg1fSqn>`^4t=gDa_T!0IysucnT6fbOQ=`@)p}Y8wWEGhgu(LC zO@FdHaV8!%=~4&tI(H5m2Se36=BD?fha(x0_ve|yl50szW=ZW1-mmlV#EB}mVW!(W z;kI5a)f&z$n*-kM`|pyAl_(GPz_@c*YNJ2Ti(N%H621FK&qzC_O6=&y#fi>?sTbb` zbF|xjSRWe&P-NUUMy~KN-zlxTk`T+xKw7ex(LaepFe#YJpj}NBl{8NXV0#Cr zBZkv8Bz#W76||{pF340-awuNX)$dDZhy;w784|0 zF~_ydhqJI(eOG~V6{Cm!3#t7ss_^p{id2-O%9a3+5Ei4pWK*mAv85$;;*A|_bB`k# zZhCUy=W%V|xb`?Tt?L0S`st0H;XudPC?}HRiFS)y4L;X$hC>sE{QGt%1;W8}7YPQ$ zy)rjn#IK!xXWwLlXLX`n1eA}%3fvyLD@uy<4J2&L_-_ zxL$({hlW8(L(J|etZzq1;H8mgb)y7Fz_6&K)>gx5oQb11fQC>dgfpy4M-X=75GjYC zkI!13d`Uw{O={0C@gBkkMll_2moRQdBi*3lfaPNzy&<$9O|r%A7d&Bhc&&>ovAM-S%su2r!$wpnl zgwP>!FcY@+3S`yIdCB12@ixK~_h_}F@I#*8aFwn4 zdOlS<|LMq0*hVJ;)OG)Nzo}d-MVBQXv`>SR{oW@yhJ}ZM}&waYk#s z8Of5f!7&tkLs{umglb8NYWOL=!#OVnw|9@>GCa4~CZ4Ynh!4xAl$1q_P9@5&;qJD} z%txDzc(tbZ@};h>#CelEI~d)6_;tTxkuNIMyBrvku}Ap zVxNA*_{m>%&2OR(Z0tV)$d8!bD(Jn_4W@Pr^-;_)$ozKbSuPflpDs(}DcYin4zs2e zFtxDHJKD($y+8EBk#RV@AWgg{*JMm_WEl43PXEXVeg1GGxSCM<0QL>fe3X{#$-df^ zICzIlxEkD;6ihYf%MBFUT?;4=sRuW?IqO=I27_`X9^b9#y;l@Dsf1JeCsr>1w>5x<~fa6B?R7f z2x!z{dvVvfJlBB}#N4@-u52n^44rq$)~*c;P`8{H(}YPmsZk3SVnR`i8<@FUUj7P& zt|azptu=|(n1ANupvI@|=jY)PeT znSLALROFUT!DQ7E8GTu{;O9z4bmpQQe21|OBRlYQ%=Q{zLl}zj__-D=Z;F{>E}iavvkcFc)QTbKLGdaq zK#43(nVvfluVfS!M;^f|p=CAUn73+pkv%Smk13#O-Z)sG zl=#GCmjXT|B0_3yfyzP9`x49i^c5i>|H1wMo zlx@d%4uN(HnoqyGu8Q-~s|OqA@DIw2hSKlBVV>imcI&&rbJCD|j&vwq98})2FMH)K zGz}JT2BzOB;=ZmHAnA%_(Zz}SS{B|W&WQ75%9YNCm-U*Y)X(eTL`2YlKqH*X6(U{Z zd4Izjr8&Iy;j8yyPD4m5!LaSq8c^l>(hg&RA%>XGgfT?-QzQn&#T;-rYGS6zOI!`HX?wN+eewcGg4F zm|5irbkGOO*$5?uBU->x*yFmHT9MV{f5^%GGA8Fkf+9jqFJ{5`4p)n8fDHah7m+r$ z8xQ)4%>Z8fZ5(5@dh7=SHzy|viLa}Qe4#>R*k*^lBIY^=4BcNoe3?KOWZeFCUE5U5 zf4vzL_lsWm%?U8)PZKX-Ijh(P{yE4sek=(d)8rX*oY)XkmkG1)SVIYNb*e0QtmSK%dYsO z0eKfB=8o=3!}e|IrR=;CNnaplL%7qEO^YY1?&f)ButOE+9`P8Syvmo5%b0eb;`HZS z4a*g-t!c72FMw~P@SRNEhjxZKidHhz?e_9T?2+w!x{g@9I`T@3pnG)Zx?Bys?{L%I%tm|?bT^*EQSwQ&rlUrn*@|9-Whk4qMq}l zG30-3UmlfFb1U0bTX;=8EqzDvBr{c__%4 zCu4(g#VA>zrqiV+$z?}BF&Wz_(^kJjk%E+=uN`9Ij>qwtRFT)sggGJ-lX7o)f_mvH z(@l5Lkf$hLY9g62qoHgF!UiH925zU+Dga0*zBX*)5~4wn5}COmcaa^PxG!0o1`r-} zd4R5EI&(w53XM&)q;l9usWHyRmmCY-0j3^}bGR;{)=y1AGp`%ht!8i5(;@ zpXHne7zb5v8nO)}er+{+y{BU}pX$zJYEe-n@MTqIU`(3k+8c~!wV3S}+VjIa=5Jc* z-yG#XILm*~tyK&`YrUQSCR_g(y7b>rFQ0Qse0U}9os`s43W`I!Lp|MkoxJKMs+(MibMz~Pa~ zEp71UF$*h*5B^xzAH?oQ*B6{@08UOIfS!Yc9hB`q5Uc;D!hY9n(9-$GLjIN$hzAX- z2k5k#g|U-4h(ycwCwKa>dXF0$=rVsD|Gj5pd%WxY&IaUsd`kJ}jfM5`X7%51Y)pUG zg@yfBHQ;0if?D+JEB?AA|8&)#a{xIWpRfPkSiduX{tiDL0l9v!B|qo-E5yqAI7Rw< z`?0-$on-}m_u}_AcF>bIJBR@faw7OsE_N;s02}+?asn+Q_#vL1>ru9kX&(Q7yc+v= z{~Tl3jX5kUwMAq1KHRf>jX0T z-)|WZq!7QK`p2vN?(w4u{rU<(4v;sY|EM8A&fjSVkn^9)_}x1GPtpMeg#W4bg1@8N zK*4`1<9|}Czw!WuA2kyw{8$U1@S|S*74u*BKw*&gCQzDR)dVQ=pR5EZ!ue;JKoNm| z9X*!xSUynXzq41MDEp(A6~@P#-lKo1?~bNGd08GuL(r|s>~V1TzF^{yfC%6_d;WU> zWV+wU(%%Ch3j{unT;BsA0|JHr3J3zekJjH~K&J71IQ%03O7?gw{~iDt0PxTIq1mIZ z0{>M5ka_|ihyU-%K-&17wD3nj6u|m8kbVz<^nmqWH2`({_Z!>y7*OxBK8~^91E3CJ zeH@Vg2!N9Ps|KL%Vf|MPK)vxDH2WhNsDOXf0Mr-XF_rHzAn~*Ps|KJR_D&-j$!*vB#Z557L|%}4;mpe+^rm@ zq<(dK7Fn8e?QO})LmdH;)sPt&I7FR7aDrw-f*S7ql5=z*Htlj6~v8EssK>#zC9i*ZIU(k!Xw6_YB3>-Y1{c+32W zhvyd?JZBq4=iK@j+?uw5lP0>6tVrdhy6-=#+tl+<=zxc1h|ItR3}vo1W8~Li2o`Fw zvQZd0Zn!KQoYKussYjHSE^*-sk2u9HYK48nbmTZK8-$^wqx}%yn0%1}*K5Db**}{* zBqNKRD9;PI!`$?|(`AB~Pc(GrrjuoGb*S(myGG?M!GT-!UAr_9lpYGHr#9rdonUi#Oiadm|tMX3V`4 zhlXc1!?9h#QCGhgrll(}VXC+^N`e9J4VI+xZSo|oT#Xjku$*UJXGj*D?wu$qj^PAS zHw8CDc@k#XFl#TBK9IxyU~}{8%=~43Sp9VeD!2Ll#N?oFJ=dIidug9iMe;zHA)np& zbFG9h>sRJ^RJg3~Jd$T!L^xIWeaX#t<~eMU+gCp;**c{^RTTig)XxE}x@_%GTs#mT zp{YG@ZyfR|j#qW8f1T^LUnR*%T6U9K zx;R1q@H}zv8!~JT>F0QMs-d{-{HzbhcKt+t0)d|zo)^BVqlFMP95Xl=WR#<@5V9!9 zAG>q;78dQzCnlO04+yiEe1(xDn=y)51*TM7Z`DWXMgz;nJc?V1TlxWNoi1x5|A6FF zDIMopzyNDXv%xiWfBA%EsY%S~y+>wIwb2&E_JBu&dzb6b8>DuBp+ymyY8Bhh+8s~h z#-}V+Hn9o?tiN5~yg6sKX=G_>{!lT{+e{nL`sse@z$!k5j(D}K$AJz%sj>@IcvOju z_%*`Yblmtod7HRO0)l5&IR>1OYp2E~B5l(#N|fjRI?s8J>}ZKz4s*dZ5v_Pk+PxVyEPQlI4%C*NjWxJk_|-|L77MrL#7s=(|6=bgpyF!QZBc@| zyE_Dz#$7`2AOV60mtes?I0Sds;O_2DaCZpq4#5epA^YF&&)#`w-&+uN~X&(qTH@xw-n;qpt)By(mUBR=qPSZ{%EmjUo8^uF^iQ zSda8aW#KC$kb@6L@wn&siY_@lJ?mB5%Vm=6gzAYyF`D-KA1uFc#@E5LO9!`)(|ee$ z2kaOZV>-}bL>)>K7K+njs0@GR&w1y@!k()()Mr8){*jxK8S53rw@Dj`1qTZ{CgYmO zkFU$>&52C~xGAMFUTNy0k>&A5Onw){pi1QPH2ZMl}<(CjV;2;Pk zXNGRtroH!+PMEspNQpE2C@hyW zioNElDr{py_!99pAtTjp+VApH!9qFEYQ(DYTdCv9WBUk0 zm(~sj5C<05ptb~(+;ZiWnS&iEh;#3a&IN_CSWT0??bd^ToK8c6HU`Sc?jgX1wvWZL zq|9%8Ej(^HHfNLO57x3=Obk$J40FvHuH~YgNSLcDM~~)YWvgna_3ahy#M{t5Avke`G4?>Qgk3lGD)p-TKEMhpg<< zB?JJx!_*y`UzBj+*M5TQ%{`A4Py9i~4=rE7^Qxd19mc%@P!oJK<1MAFGoR2#sUm*U zZ=dE`f7EaP9zxH`%%lwTAu`F2vawakG1Zj)o0FSmqH7Yp4*+5q4JP(`9xjLmCX@DNT3+=vnlcEb=Z>Ubxmf)>6suYwixT}nTL37 zr_R8r-ir)^RvPA1#L3#ui3!+TCA<*%g9kG27hJIT zNLBrEac9x8@05#2p5u-ZV8*R0q%O1HTH&%k^?h>hLL`!#8aoQ>DP3qDe?1?v*n*Yr zn!~kj#t{Z?s?I8Jtg5Ure>X<}F^iCcP0a!|N|-S;r>aAA6K&vbfl@TMG4_PejGUNl2k{9ubJMB$JwA_+IcGch!naOjrV77tpQSO6GUTToMF8sA?Mbd}J8~>_mm?hr(=G=(5NtrAnhV-r`l-z)T2; z_jwXFh-_~*$i%)dk0u8q6O3`*%Df@0X>R*!@=iqm>SJsByNGg|TX)sBD)2c}Wpm%U z_r&uLE7GJsm*<9K#}8{wd^XNp&At+jmSjk<+%MjVR24FrhgZrERNH^WJRq64xt8Ft z`PPt47>ROjksA@wfy2n%ly26Wkf5KBHQ0D7sIyIrY3!Z`@&m`<$0Nq<<4@hZ&_`!o z`r&Bj`kQHk*Qg;rh*`44EMdcf+ecp^PQP>=%uh1DtL{A$A|8J2n5Fudm73Le zVHn%HlDw6_b zjCid3+>#?TYmtpg)iP*|aQ9f3K7y6E$ArezOAjUyzYeIb-%~EEV=S`LjNCdDo0OhI zJ|y(rqjtwP-4bt#;V8jDsU{KZCLVOLU?PKqal%y1MNKSwX!ANuwD7ao0$CDO8;gNR zKkVd|$&QV|vb4+rANjH_dD@GrDw~SCOLAZlYeC^GJ+dYv-qEK#Sk|Znp?Z^PV1qWu z)CE82c8>gL4C@>1M3cr|zj(3ezD9DegY+0L$t zQa#?TT7+2(-f5EW+>uxc2cg#OtesjMbZy;^WGrIltZPeG{h{EqSjL;VL%;R)xFSb< z;I!+OTbe4uXU8FQZ2~FJqo2;c>PZy0XGm<{aS?G;h(HK-7@t)QVNOO`Mjo+8B#8hvD#*B zqfKb*2(?s z!9-!4hZwSWogd5ZqBBg@8RAM73>jNbo4RyzB$#TIxP-AA??TN6!7CTf*HhvUQr$Rn zvVH6D(CiL!po`}An@;(M4n)r zqUg7IE+Bt4YnhCZq1ns`db$7?EQH>A2v_tCK8gw#@uf$ggNH>tBH8;}`+%2h#8-Mb zmBDgMA$5tlj*77j!!4JEOP-qIBkFA5UNH;nznv4Oo{+U5fyc(75v*zDn^0Ns7FaJP zXi6&MHHw395^FS?hLPt)z_j8Gp(5An)oZ6{RoMEth>`r7e9TVV%0|9GqtZy*3`r*z zJSG=`RLxWonn{N9HA60kxLmFFsX5 zl8^*SCDbA9lgdPoEbM10Qi+g*h7?AO@2)hkVr9}}SAkLLjLMUFP>b7A>5+SqSECi4 zdo&-slB1Fbj_BIHdk(wC(Om64)7^D7=Tyz>wm4*$*cJ^kz%=Wf`?-p}hXt!u6^p?%;X6+1b^l4;u&z{-*e7(A9!9fvst9Lw7sxu>i81E{ISS-3A6E#sNAVG{I!> zbkfspC&qGf>I^gfrWY_078&*_CCd2_{>$6Yyr*^-Iw%A!JSolFzo>C$G4%m`3aS4w}%%k_-kGN-c2~3)^`8k_5qZ_ z`epv1C;^Pnf^OQ!aBX8Km)PNplH6pvd1MR0eDewmZm}u}l7~kLHgkZhPmK6>%}X@< zoAudo2mcRE3f|J@iEJf{ZsxU!j1vM@bVxZF%Ul%{J@6q*3r=zw_Py~PavecUWvFzu z1u@MWX_~ZA9HwfBBRiIT|9;(#yXE5=*rwa*oN_!zjQx+!%#-|b%W`0kvTDi8(vhtn zr&X3DcJS~D+TWn09e+^E)+?B_53C|mFmQ>~3Nsf$*)x^B6)DsRb3*h9?j(g>fXD<{ z3`?aYSUz4Kqcx`I;x_SxA+4aB?1jvi@)zbcW?oe-oFf*FGXXg;3O1O|;`q$#ivUS_ z#Ga4v%_~HTE4^N!;v%ciX4PXYaJz9QuU_avHM)>Kh+KTi<|uQ7;FQ%icFG1T(!B>E zJFUn7e}YIWBu8h#g(B3(n?>Mj{buUgS>oE(o70~puTL^5Airs(r&XRmXe1WSUtA5E z3S1Uo%uiu-?t*Zq*LqlQ_HBZ2%`R4vT*NV+A^)8nONbc2cu!ahP~&|FGt1gZ}f{k+PQkq&UAbF6a;9p zDg?Ml7p%qF+}439JUs zlxO6~5|&B5&@nM~>ujcLTLL2b^Z=A5}}iLmLo#pB9hWOINQr z6X&Gn5jgL+w<{8^B0&6bEX-G=90PveZiC;+?+3m>;wNj8&$0 zn)HyXdg0l+G4a&7!Ifb<&#&0IYBPB|%=j&7pTh&NBh13vkk^Hnj$kqo0Qw`_7N=^U zr|EubAeNDPpF3FtoWX~^w!v$0LvCl^S^_M5#LFY?QV#<(3+I{k3HXKLv{?S}LEE6rVb zJPR-7TP>^AiR}K^+?!pa&6{1Pm`#yu4LA&LmrZ48Q38z^8rBp_lp=Q-UtIyQXYv3(GasS5Q}BuI?clHl@xmo@p%K|-^-4(hUHc+`j$9j; zS=c(Yy4QX?)3g;RxBx9CZp9~Nds-rJnK#UR=H9%`j2&yyC@0aE7w={jakmu{_2v$F z35{i$(Acfsa!a}8Wn2v1c=L}(Kz;lwl6I!^IfCk`Zq2&1Gs=->#B+n!Vg4&SdhY6bl2`TubdiV|y2S=IOX<%&nxdQ-M zFu2OX%<@V{7~Ml!NVh|OwIDcnNT-K5o>;Z4m`me1&@wO_fBZKl{h#C-~(j|KvI3Tof;{!$cEJQ4tt%K8gBE#JOr2`fp^3 zIR4O|@*f?R|D$zSIR4Np!ul)vd8PQ177rvIc;IS)f4$<2l32ZO9Rkh5$6&$isfTm2 z)!maV#*1nUhj#mFP-OC;wYOg5ib^v;;0Rf*J`T;UpDw1@%+t&;rn<_VU;mBukXUEg zNz%Lvjmc9KvZBL2%=Y5cXX|ah78Cm(+L%cKHA&$Q$ypU8t3jwK$kKXES?Sf_1xu`CS#n^Y5Mw+uHh>=?2${xo%T~awKsH zazyb94#OxK)-Wp0WHx*WM^R?CQ1)a&S@l%D)0;T$B7L?GBH+TqEM;lEx#0K`Ru;#^ zx)&@?6fRmtvmPg02|_E)D(%Hx?B)L0kP-C>B4XQb&w#o>MdESvvC>>vQ_80UeZHlA z9G?*BtQiQX!Skh?+{<%`-rNs>ml$1|${(DX_^M0A3hbv2bn?}S)eOGZaP35BVHAi9 z^6KCjrLH#)JtHm`H=j8W0|J+oPwtsgEMnjyM^_yG8ANmk}T`FQ_W(HnVm;j1D z*Z7z#p4a%`=>c1ZO}-`Zhs%O&2hAT|1U+?!QnBd2pbB%jUuQj zu~i(3JJBiYXQox^cb`+6wiCn$*mLuilfn(bV4N)B!3lBorl`jiZh<~m#!OZ*gEgIT zS7h8Y!18X-=*7#bM0}A1vU(utZ1Q>H43oAt?_Hz!1%@{~P4f3-ua}Svi-qfsKA5wN z9p_jXqHrc&Vadm&S;(kX2S{oP`}s z-1<7dP_;FGsISV~>$cht?FRM-HYdqM1JJL>)Hj1sqWn10IESubcDUq$izuGM{QuGF5#{<4LR)6!98i<6g?U zoONi>9EIS70?g}(gM|;NjhXRdeK9GiVlI}+*N+R}0}X~?eW-+DYCN%Iu#yywm+uoC zuBB77`F!gU$NiCe) zsV}@J`L5&TdyKtcjJ?Tf))DQ%slMskDk6QPQ6-v{aH^HGg+R*|_;KJBhkx&-akNzF z2zv0I98T;_IE|31R-De)%rCi&dv$XdpJ@Y3Nq5dQic;xP0*=53a;=EyK7cic&84B2 zL&Ei==4R5T^>LA6pxvEWrjB#~CI;W8yp0y5ou~+GF$g_Ki%TH3^7)2U7~$1{we7Hx zQWJGvTiSD6N!~j1?I7G-ks(+47D zR8Xma(1I!gU1j;@U>nCmtEv%KQSRx?%p)f?B%8n{$bIwtmc5G~P#{?RNN_}n0yCe! zTEhGNrn~*2D}ePsdN2QNdM})R=on!67qKXXzxl{8NiweVX=1$3A3uPso{D0znKulP zZX!Z2t;n(L5b!z6M`a+opYvlQlu#CI2cY?+qC$xtki1+4&p?DKhS3f&H!wuiASHYt zL3uX~nHpNi8%Z1$=}1kriG_>3$~^@^t_SC+Vvrzn(LSE^3X8>3hpUof_@O4%QLNFs zfC>sl9Xc8ePA!Iz3@zandS1-?vy zcNle72(I=qT0X>vD&;r?*_aheI`HbQ_R3x)*%+I(QbjCRX@?YxGTp2<9@wR1M1xcA z^A2}lOfDa7f75IK5Q+ZF!v2sDtcM^xSeuJ>1QN8mdG;L<3exvSl?9r;RF-hTNo)kl z_-KRz)_34|QKAvNQV6olKpjijBDa+WAD{1~jhOpjg(H=3ZZ?k#Cxm!38KVdheq-7n zBGO;Q2`ZTYPvrT(LWww7p#Fu9s3?V=lfWEqU}oq!=p~*MkDbZXerA|MO&9Q!kO-vC zC;fvuJ5@?x{TsXf5L0pe8VfPZjOf7x?Yo+yX!RmW*CgYLIR|X{Q+2kO!J3r2U+yGR z28)F+dNu{QAuqJP&)0#N(f7Q3y`K>Bs@f9$t*2U*4Tn9KKftJ|+QVG%8@VMG9xNG+ zuKM6jv{Q2Z#>hWKTmQb!bMOyU5r)%=ZQdy7@0ed7YE1+a^Bt%9MggP4QMfXh3!Y}O zx;cz3`o`&LQfB+bV2UtZ&Gn_P36?-A8 z%(cu_)rt_AaqkQ48&)bGCRy-N@)7E@WhEIj1pl~@WaK`z+k@Kno@OzZ^wW4?3$s4g zP!+J>p;ZKvBoJS7tw>s2B;WP-&@Nk7-bktKTQE8$YagbxT(`kMJAh8kYj^dZg0&kr zap80DtjqU8!zyLVKe*}H7Epe>xeAm(+rLGs6w07o%*hq$fjvGn-uF`@*x?e6FR`;N zr3o@wB|Gpb9JSZjm#lMTMBR*+t5Iq%{OEJx)qU_o_C5fWX)PLJg>J))XN#zsS5xJk z99+)#xPvG(Bo~#Ypox_=oj4!9;^p21n2FAfuc!5iRR=50ybN>m#j*SnX31i+8*^4> zci+Cld8f5G{id1!5KRHtSpPo9Q39?pFA>87W2GBBG z@t}!vi<(2T2*%%_6NR&I0;|DDwkp;4-6;28zVdB&^bW=!6^l9#xdAjAJhBH>fvlcT zd>p6D$vIS49`tCwWwK<1hJ*<*7;RSh6Lby%gC3we35o;V zmaWR43TA=J-;5nSn_9ZzO-w>Dc?n9uX1hJ)13hRt%NPUALAd=MKC~ z&bfMK;C_bF2N+$X6+3o_kx9uO*j<-arN$rN>@GG1p(DvLAcdN?8}oND_PFH_*LDvd zKirB(FD3C#b9K(p$#160_<3vxBhYf+e5{pE`62G0gAuN!;*Dx?IPFyM;fsB_%1})% z8Rz649_MmsxC;3?=n=s3Jr8~BNpIv*G){c2ZknF%Br?{%CZTrDsYE9YjFFb7$?F7% zwxMs{_sQ5H7vaO!t+X_Six%^MDbPrpsLagVi7`9PiBISPH%EBbpMsD$?=|JW5kB7C z!s(Px{zgdXnX32)YY_nEUxaRz6eW~_y3dPOFY5%a;1q?2Ge@?Ck6UA2x*sYDrBnMU zCozFgEe1jspdqgkFk-@AxG@j=KSVK^pdIw~=a`fc`ql=C3KAuszC=cm+hS^DgSNOJ z20)$d_vU~8y236PLLFEp_yty5CC@oy^vVvU_)~ZUSOvyM&QL7{H!i7ap12vkwaFnp z-k01Og}5M;CZG-$@8=+RU5mX~NWW#U7lvnd4uF>$HOg}ix%bL{K}=r7q+0jVh;C@7 zu`O{M{zhy0%M^u?&um|sjeqw_A?8_OL3{8jmCb!qnaxAh?aFe=o7U!4SkBOqow7!H zM@ZX|SYhI|YGuiUeL9Oc^kZ2w(ML`3`Qb72#d(o)+vCr-)+tzeD>wo5!D!d7(YeTi z&`-cJD!)0OlDyv1C+_qbBN-aohlo@>c2D_0$ZnD>)}cz}zUOl8zOeq7Xl(Ez<-5pH zQIW!xUR&Pl1f(-~PQQnb4HJ%vU2_6K9*6GC|MHxNsy?)cHtZe`aA>Om$vnfH4xk zG27~hpAAUCgs&l$r`iH?@hcqy1fpzgJ+`B{j0xVD#Q=mLVe0D?@@P{Px!iiNyQQc-IZEjF+SFCy)%d~6 zrTpVjFD{1;_q!3#(jkOv-R-po6-~_1?KEviJTBZK z2#llwPakRJs^a$F+w_^!`v-%UmFrhMjwkJL;A$^$e-S~%aucUFGSY)Ow~sT1Q3EZU z5vby*Lo%Z}Fn~?OC@kW3qNb|C%rq&;TVX(1dB#zJ8J1=nU?v>~nYRnNM)Ta{7ZC~KBNEg6pMjzx_+{)$ch zWxDQ?S?(Qn`!^=>2f<6GGwhGFQHA&K287!c*c$yQbR!|mcm@+(+e1!w0>THW$RH0C zYF-oWL4PSG4kQ)(WXZu6(8FzgP1o8L`;kj(`84%}VCtY)<+A>V=C0p-km9CbYW;XL z?o?y9H!Fq3LK%cEw*JUYgsB(Z^7e~Y@vM;g!j2SYwr)zwx2~cpA5h9ONA>RpvboA0 z_N1xn29|ZtdmPvZH45`Bin7TBP2sMU9{Qa^lznY(RTfGGNcx9pd6wo|XBgoRnm2ya zntzA|0lx}A0WZaWwPqWJ+5EC10h&$Tk4HPya1G`bY~&;s#UV;&oQWmd2oC=%GAvN( z*0`{^?wQ>hyFq^K@l&oPy|HnXOm+RSJJj9M`txl1NX;y?9~CNZ5h6oP3NRu3C{2Y) z@y#b)E(rlDxA9ZqajoiDMlQL2emQE7C4JBX3Hf10Uy`y80p($}gkW+tG(}#zzykRAcCl zeLJpC-NWlBJg8=&QE3(}87zlfAKkH;Uii_cHI!4Cxc3D+z=%a;pA%=|Be^)5h`aD@ z3X@xWLPyW{|IA^0WAgweIKOQEo38SQ5SH~^KQ6U04U$du~BbPlsyQa`}zz!qWls*?!pL*^LZwJJ6+>4F4BbKciase zhGq;28ky2bXN?Tw}7V52&$u|kd&7ncZ!wC^zM z6I1n;*loism`W4~w(oZ9?HCV1SYT^p^iG=6;t-sFu<&C-u^@cxnAjO>+fYMjsm4M! zz*ni@C8T{Zeb2K{zP`9yIvu3Ir(;-Dk%ejy3$c6@ac=%z37K{)*|ApxO@K)N^*F)% zs?QbrVMeyw@|&G#jBcbFPtQ&V3-u%&HEN!8Y=vNRr589u3xW*VMlvh9s&zr!Hr;_7 zwef{l<4W!sFYk+Dzmnq`8@KO-GXzJR2MO$p>U9s07PcE-wxLFI(iZ-`E&eu{{vQw! zVP@v|ML-0oAHqq@0lX3XseZ__CIpZ>{J*Fl@^{UM|GCd>Ks}2m^^PZ<5&+Ya*Ws@R z8<4#HQ@!Nrl>Dwo4{PXeiH$OjfJpCgp=YOY$#=o-p z|4&W>Sf5k{0IW}n4*(z;|LOJrNxcF9WYj<9|D{p@06eJ_0G_op0Dvc*0s!Di@c_v8 z0>1uLYXBgp{$~mZXPOZK9|h)mr4hK?YUgG zXIt5xZ3Xg;fyX^7Z2*80Hvjks_UE#JUF#|DcUl(!_P@&f%f9DwfMI*UUvM!0RzKmH z&i};rf2yo!O8w7-81Xad`8ffsx@Yp|&jd5^v#QR|1P4$x2H0_bCOCF8Dp9OnAOu;QO%4SxOxIMDuS0q``R*L;8G2oZDq(*j_l00;VC1&BWF`TAGl z6>!Y{Ga*L&JhGn)0M-*wVd)=-0qY5PE%+)C?8t1&!F3H`w&{nw?&{}=Wu<@%dzRNBD8$kv#c z`EOVcxQ7Ywr2cy7Gyf(Cnd=Xon9OXyM20BI388ipLj(6Z;tz)>{?bB~Aj|mhSnZXg zCJRS5;FU*`@sd#5PXj{r#PGdDD1Tct0f2i*WNdgN;~h*`FxERfjD6hJ99l};1ks%C zdV+Vj3K+Ft6$stpii>S#`j0{gbMA1o8aqL-%Fc>5@pbdJkNLi#`OFFn3GB$p3z#NFm4BbyJZne&qx1fw&j9`w}i`gc#HjJ$+3IP>!cnQfYe9LEW7 zY5c!FmcCd_N#wHigp_#4L_;?VKEVOT2(<{S%_&|#@J$HYLl|p2%--u`Mgo_QR-+&o zpaos@{2aG$*>PBw3oQ|LXXK*D9z%~ZF<5O?;D8U(xgm&c&q%Gs|m^}L&}0LQegtP zS=A#hraxv*`J7%;b}*ZWpuoO5qvfQGwcLd7)G<>7pGh+6hX>=`ccH}v5gN0m~a`BgrJrJeHq0O6T2V*E`bJq_GHxWcgf8tEz{FBK~KQ;|8{ z2}sYl&}Rusy|cs{opEB2_JmL(&g_6dbYpFdGc}zyXEs?|=r`WM+l0#)Jaz zzp1)%nss7|?XYc$3r6UyjcpFi%|a!gFV4!E;f0GHS-9gWd%nY6_A z1ehCwbXbHw*?nI}gyCniqQq*rk3#u}4mA%5Mn4c#NAAP8lbs!2Ne{ePI*H5C zkFs09pg+X#vTFse&{%7(Ki@CCoN-@(0+KV;|Gff%YJPuKgB-s^&9kyUi@#O@C6{Y~ zRCM;Tw@g(`O5)5L6+UIw_3y2@G>BEvb0S^>HJ2?s1_1yT|9-M^I>CxqCNW4ATr7|e z)>u@(Gv*Kd035$WApFA^;NI3xwy*#R@jq?xVzL&hil`SxjLZ1Ug(@|(*oWR%C1?op zecQ@YT2R+(uy56C>^a1<1Qx^fcjo*d*5vr*n$I>+j{sck18-YYG6SQ!xwn2G76p08 zorSI#<0pjl!}GIgbJEGuO^ZI=%Q?#7W?*^QUlT}>Xp-;XR$MefbEe4K!tdfZE`;PJ zfPV8ktDf%Xf6(WD4G3cksz+#Jg70#c`3Q$yrnPVfE)=N$$R7E^0o-X@XU9t9obaS& z)Nf6{z@8CLfq?AhH|@+dcNb;(xOI zYL{ljfQ2^`@~f*KfvPz{0k7e{MEXVxl9um?WZ!_4L7C=b55z-!(iSkLvD4WPHYzc4 zB~X%C64xPio?-nk)<#S|Q#V*>2+bEN97ztr5I;xOTA8m%Ua@Ac4lf&mZz%jy@It3D zXbcZu*7fMrQ`9ms6VuwKv)I&pu|(2s-Dg}-x*wGj@iHe)w%Hy{c*CIAZ=s24Va)Ug z4L^r(_$?>QL|MZ67jD0XC^A&sUW(EEYI5qERt*&Nhqe}OnVpGl<(`kYaXy9;D?#f3 ztIaw@4fWwPJ|m;v+_s}8==+_jZZ50MyW^C|Z!LELPKH5eyo(wKF(li5_C3o>?+d4= zp^sY}+L|@Rn?8jn#wgZ*2b;hP`t;5uh2Z|vwu`vOKkpHV25;F@k+uy*TWAdS!lPmhGc`GFqBActl*OXrend+HHU~o{u zJpnKt_7#3JzI$i&3q;vKs}g2>QU`Jl9U0Up$y6hbH{8kp#l-`~0MDJwf@ItZO~ z1ZAD`O|infSh{*}YduaozH-aYX(-rt-OJxDI)aBL^AVl&fG!vsA!4)L-F>5%o`s`( zaS~yIbA`0T|AOSeXFKpSE6s-p#LdogUPsvk&fH}l-!x{(R0onSUV(c1{$MCtZ6=bg zP+@USmh6fWOs)uAk`&l^yj3ZY!SbBx|vjTQ8*SbF?{vgv~K!T5A>mc!9ZR=nj3@%t~t{ zeYM%3*mwH@`XgL=a0#I%X)&6KGlN4r zE8yXx<+GvaY>*?tTKbYQ0|5)Uhc@NK!(SZ1i-L~9IuvEmS<`G*K~~q$pqSRdEkay?TvTPiZn{go zcM%z>AH575-Zgi>mWI_LCr2g z{gFPAQ3F@#ly*~FB3Z*45P0>`-bMd|yH*@4uzBwz&pYNi%S?zt2V<}aq#^xON+)B8 zqB1WW&~BsmM>@t>3?l0uQaPaL(AHD6!7+l6nFc%jeM3j@I_WL=1FDJzK)Ps0)jafR z8n9wAP$Kq3;Flhzy1)vZ2nm$>m219lUPY>HfoGaJ!58~~pw>{zgJl%v86~V&TMn&R zEIvbg#yQ5N>c$0th9HFIA=P?2G8^3H@Z$4OdGR-9j&RRvvXFa* z12yt+7Jai_&`Ch)cf5LGLKt(=>0!Phg0VPySo(5AgGd$k+tVP-r$vtrq!GgMOmT@%u z_;N!9=>)1dqcrATj$(w88p+x5duSq?N11jQGG(p*z@1z!Uw-;(ba+$+U6#QBL+T$qzPg@gmqOYM@E-m~9#ZTx4XB!`awt9NT*eHgGlwrf^)9$~@;Hr&$?$^_)STGq zxeg)e46{gU9Wy(-l!T)(Zw8r4FUVg;jsp?*(jwpiSsG;s5!-A((c`?CM?fQwA6(XQ z$My@2+8!wkxKC0%^m)cfZ}z3(#$(%Vt7!30c{Oudg4}KfCXwpC_Dhg-I{7;brJEfO?Sziltj$}} z)=wQo|7bO?0|6xu-c>`DcU~ar0tTYDM1x+-MdG zd{K0RNWZAJk!s`2&OL6(6JJE+&PZnsOoI{k%Lp5hgiBE*KcZQ1=EW|qVj_$R!-~{3 zZEQ_a=t&{%Bikw-G07t$2r>+t&YH>5IxW*kQeQz8;?a6V&xI4zK>k=ozP$1_Kf3}G zbkr1IPm4wyzqK)TVy7QLj61K=0731xhhM^be;gznuOO(JkMwRF&u)3i_&)LIEwYbf z<|)xqUOyCCm=L8;`(9S;X8~&jp-LvW8E+3y@Ejl24%fDOVGVLYSP3>RDYaS9OF*wR zhE=iWJ{5l~QNKW6>)*d>y6{K~m`Dus_ZyV>HL#0{D!V^`X40SDxm_(u~cY z8k)FTHkpsqS6h)4WFtE~h2T&~gW?MVh+lL|audRUqr@b3@(P<^O)w-5)~PTmwxRE& z5;EOLcNv}0lMj+6v_Ln{>lzyNDR+%J7z{dDc(C*nMEXL5c2>}^^@Lk}qSnh0vRAA4 z8tlw9u@jKv!9sc&1@aYsHr_iaxip0@L?ueEHI?%dA!H{zOLSA4rkvP?1f-`C^qW=T z0H~EpFwd%B#Pl)G=yv5|i3aioWrt=_KNdK3OlG)U+)89!6>F!y5Z;}1fD8tjxn8kp zlx!}05F~wJ`MVTlNW4># zfVnrb=dknD>cNqZb;n}=>fN_V90KS!+C2kf&^|>!` zA-{4@A_)dIA(yxu9BGd)`=v&}l+_Yexps9a7)laoonY;dM51M7rnxGo0I@2>bORS<_#n9YUU z%!jU8UwXz+)@tdbt@zOtHp9t8Sy#S&c?&L;%)>p8Dy4xFI!TDzEIE^FsRgNQ^q$@t zM^g(6MWUc*tn)B%h}d-4_&^OGfU3<{qVf^>qdl=qLv5LTy8Y|Y)Ajz|m^d(0e4Ruj z#QBhuCyXxPp_Bf4$HQYBUC-eB& zg8nLAJHcB<)5U5wOYNr0d5xmVx5JDhq~3VBOsv?QXh-G^|WWIUto&<_%qWF zly^Ifuu$COY&zJniYIpeu#K#?G*OjSV_X|Y8Sbe9Ct z4}*yeRWs*S-@KO=vl#&yVajpKl}&XvoJokvy<|4L`QX$RLwikO)=TMnkVI?E5Ud5B zIbwmQSvZCqi-G(lGwK^&3d+5zVN`?!{Opkav_^xw#kkGV2AyIHuEr1jkwUGQ?{hFP?s<1sU940*DhLU5ddtFq+c`>_ zisf$4ZhI~2L>HIgz<)SPa!ufmA28BGG>euxO$~8GQX~oMxZ_xPILkxucui_)7`moE zt5T{@4(&~B#1&iZ;A zG#4BvYu>0zZ|KlA2b(!+HzXrHn<+AV>jw&R|UQemO5_ zUC^R-NF1VCSp5e>w3Qo<;dm^Pe*C&nRC(v8n;&;XC10ksTli~kzb@@_94(ehFf@%;8D&d6b{bOp1&pXBRAM^m=Wtjn0D(&g0_ zH|c>y0-AlCXdF#>3#D z9oC47{&*P)BC?#*!(VYFK0vqCB9Ib3^OgG^Y&cfCd#ThtjzFL) z7-Tk79)jE?%{6!>WH5FC$Xo}Pw%Ogf!!nk$rfRd%Rlg9Dq5pV5se#Gh!8YS!8&T$~tk7U4)xwNlw z(}1?NUS#(FYVWPXqU_qWaY`BlX%HlpW`>!ey9A|Mx=Xr4x?7MGX{5UmB&0i(ZUHHk z21&mepZD3Xz_Z`)`Tp4Zw}1P1@i?5huUYqsYhCNU*Sgla&U0^NiX{K&vxi{sSG@If z-G*bK1y4N{Ci|psCF(y8Kg*Ji_Tc*DD_Hz7(1<`P7lqOG)GqJ zNeSg<*La8DsW*VZ++D>twfXg!ouIA+lO}}Pq6#UV;IXq0w$xESXX4u1urRb}j}?9K zQF-k;0>^m)y|YGIw(!=<)jI?d%>B00FR)r(K58cf12gSNzy;(ge%yfvOrnpjd@&0kyvTiLvZJ6bWEH1D<5)~VZ*u~wPt&%u}e9M zI%`;Y?6eMCX`4fvqgDWuEsII`(u9xb537Mt{qekz#fQ6HZd+Ol@W(XgdHOt)%rksp><`Yrn#i1W8;y5-cW%oP-&!rHJoB?}0tR`?TqO>q^~S)WIK-5Z;IDmN<8JxnIc>Zrj$+PwWYElEv(s zlV4UJU!s4cuTj9#Q$I3vKQ^49HBi-}^zT$Yagrl(I~nlR-h9V*nTS>fVaKz5kP}KqEov$Rw1HxaFn0 zwpX1SZ{j0f_PdeVfj=*|pW+wEAq1?zi?CE?P$lep;!`3?4wbfdJ{DHn9?2@@<2 zhE0V^cBC{>#P|s?rh(KmgYUv2WP4rA$xZhEd~rv&KCG9aVe_%uLDlLKV%eZ&OheO& zTtADhO~w=nf&*vk9Kw^A0|;Hrh@a4da4|r5mftBitVa>_Fs}A;-gF=9oh%Tyf1hto z)iBa*d+kNS%nVN_rHZ4ZH|O6nq;q#n?sXYTn{!{YHjW;EzV)(hxgm z7QTvm5};PI`B@1=csV~IW_ktkngnEeIY)rcN%0py;sx8yN;oxErUdI) z;Xl{;uD4O?y-$Q=6{1yrhh9z_b=m)jfWYx_{uhlQY*B4_(!yAG7d&kR6BUE3Niw?F z!|z{mK4(l9hZAZ;N{6*3wMtlJF;sOOtKZWTTYWkWhwCty;))+CeZxq*2qyH2FL?iQ zPF5*~JR)z1gkZu;Jlz*>vMQ3Om9~0TTGfM3a=STBO~}4VH2Vc2vTFR^i=Y1C4;Dj* zb&^#D^E4c&35Eq-uA&m6895@kxYw_m^djY-ztQ0Jp1ESFe`C1go^P#OfY$xqQC^mX z@ypHv4|NawCf?(S{H*5!n9qmcU(EW{wW&sY!9-3HW;tO57aF5bC~3Rb_~2ls z-|<4!!}~oNGzh#OsB%6Z-#K(7){8U)ns~V`KRIMDY=6_uX?@Xt2+4hQ)=)OsvJjS} zp3%aJ!a>rP+kCvI%O;zWS@c5`$Ack?OtZyE+sBYsUe$)7tF4>TUwBpA`%R~b5TlKP zd=YzWeio%gw;l25H+5{K@T>tDi44rglrdS;%P4sdG;K75jkHc4t+#mHV@v<3>=MNN zVaN0|p=Hq1wY|_dC2`QhYs=NvKUI2S11)+f&szQ1B=o4)^-Oos^`!rbjWNmkx4k0LN1uT=w52Jfm}K$o))D|kn27?Pk9`3`CN>DeM#66V=WKn)+2xCDTVhXXer zethrpbHLHtYhl{3OuPOh*;=eqpuc5(c7G)7j_+nXUHJamSeJO|2ZI-rn+zWT@L{%w z-#+zC)x0bA95ikDf#SA3E~k6?H3m_9C0gPB0~Be+nHoRsFM1^5orR+sH5`p9hIk!W zluX39ia640c16nN)o2Jr$0;9tUSD)a7xsSgUa@s z_qeX6I9FYzDG5U_bh|D4(5y`^^SqZtti;4fK3v&HlAs=h7`fxMik-f-n?XfhEce{7`{C87+oTJ%exnwrP zj`o|gL{nlv*B@%!Tr{DiVfWqB7pG6F>U>1|kd|?4;CngmJ@U|GTB62P$jNaz-YMup zze33L>>mz#A_6C#rcW_ zhT~G&m&JE%35|(ZBvLmNnEHK>ka*m^e0xrjv||kp#hiye(Eyjq@8H*sjoy`S7Q~HC8iF4U+7H)nKFHWNZH(&KL73N0H|1_Pl zr(di>slC4>AiasXi-r;_?3Ce&U0sljX*p z7Z*f@-fKWhY)vH4dBIiW+oyTnPl>x=48`ubu@Q-FLhLp`NT_?kSuBA4G#t7)#n2> z!K>|aQ{CYCQ*7sMWa7%q(%5l0=R&rm`}>FAo7DM)_!dXG(!=WR=m&+w=CrP@tCs=Tqh47&IbiO^&$Wi4A` zQmi`q9k8iq`i(Ikr3xKSWPV2I_2x-j934mxjedfCzO%e0$(*O5?1b-rZ1@w#2VNFC z-yfwT4F+VdvQ1Why8B?vSbQr?W&m5<84;U*Nu_bd6`ePAi@vVc1Tn30`iO%7HGOf7 z!4jQ}0GGz!93(H}+7*C8WW`OYU+5(_D0m2-Z8YvUKFv&();@61Z!TmJboEuRtmDf_ zF^2OEa_1u6@V!xyDnqQN z1gC2sU4x--$TxmFTx^re+CKvLe5CX-?Mb}etpz8zY&5U>e0r97A#TprYo$s??B8WJ zW&wVfGM}O9AQ2f-pXF@IWXq)C9>|H}A~ldBCgOrJOU}P+-O6QcDi!?x;qR)y|hGP&Vi$~h+_~(Ln`QbjqL^;$lNI6q zvr#jK_Kmvk!s-eyqQ{b2d@qBZ)KlQAm>1R*)+tXazX{D(mS`DujnQoJ;9uxg;s^ZN#B^q>O3AtBk_6{!~VyQe)w0Wtq-me5q_#OKp%E^Wp|3H z*_P|;U2Aw}$gwbN^BN}K-K}4=*L65}2t70QvhxMMS;M^k)g>L*2gM+E-lX{C0!IS0 z-X*2rOS#}dA+@&ibhnn`dj0*?psdEl?ya|SBWqtZFiV|nNm)~xdVA|@l|NS~b(hY) z7g^wT5-2vm0-uH&d(hX&n7*qdpv86GlkI(u`xV>h1uH#eFRr!^ZA~ehIbFEw)8W2q zJ%UjeL3*4uu#U9skeN4D+%jrQKjwoAMge;h!qSu`$Cae|&Z@Id@v9{ds`J5h&E8m2 z(pc&{3ojmvJW;MIHGlqi)CMl7%CzTl&a>}SD`Axm745JH0SDeyn*>7yC-O1M2vdk? zEI)_6r1Lo%s`^U-3-PN-C6*n5!8CKfk(n816TL5^aBEBh?_ zC_tJpj@^A>X8b$a6*B5H$^JZvL&naH*^iNY5ySnyltA8e05_zAh}KZu-M(5kfhm|tqSwf&=e zQrGQhZWF`?e9*(Ws=JoHO8CYg}j5Ub~}12Va=5XqDz=w;;DR0 zTnCvU8qh2&Lc(9gaKv%%Kw*g9)DFPdM;Qj4rPGtP?r}_6Q@x8~ld=Y~+MQ$INL~oM z>LhYD@?^c=3+x|CEow0x&5G8IpMP9lQ{ntwUM_*my?r2f3bZ!^=JOc)J9 zln^IJ8Y<3Uq{Hg%Q8*D&}2%jEK#D$DsDybdh%z_~_wLwBkHopG}xAx@q z7ln~K$D^!jRSt0rgv#`t74DXw$XG~OOgV~_2}?RHKnAt};-DfWe;&2j>KAybzB~$I z${E=uQ>@_l=@(1VKU%4>ULjWw5T-K-Rjy5b?xTHyc=Dp~v_J0)c1rTVCu_>{we9^2 z6_y91WlTu{$S>g4z|mPP1UP#ieZQc`u{r0v93r=Fi5@8`Do4zAqxXD02u0nqZfwW> zhTJ=}XI)O76+o=2C(cF)q!R&}$>LSe^MEBr2Ol^23i&jnXB7c{P7IsR^1o)>$si!2 zB6xI9P_~m6PHW4j&?}<~F@UH%ow$|GK&yiPh^2eaRx^D&nB(X{$~y=@y%o>lax1Nt zW0UygM}M{oY?*$n+z$#7rrJfNfMtjM)GvL#ldFljbah{ixN2U-zYiO}`#c)uDHwh* z_RPbn%PeKSH2k3*vqE=FeFtrsPG0ck$hNj*CBZbKWd{FqE1Ox?X?2#0X)RWeZAJ_u zK?W-C(FYsu+(u4&*-2j=n)DQT_cb2ks4M9wndFPBZBN?c1|lw39?!do@t@(SzW2D8 zN=_$)Y@|7Q?QTtbV_VRhxgI~?o-=014vUITe`oMDBoz_mnc9H2rPNRJ2F9*({jCX4 z-1J%G^MX88y!uf04+n23<`yNeCUD;Ouo(lgvumGn*J$?HWP&Z4aPMb0bDEj7pvjFc z?fk6QrDXR;w~TrDB3b&KUBdLI7RL9dxJgJGQpwT02C|g8R7Ri2=T1AQgeq@g&xu5rEh7m6~`3F~&@ zX7PA%q!jsW1wyYLa+72$L=IR~by^tFKSvir@grxLTWE6wJ#N0Yi;IPvfJz38yW1;v zn)#`I*&)w3r#{x>ZeOqQ5W?MN`ntYJ(=DO`&gIM>MP#P>6TLqE3}Hvgl${R6^coPJ z^2GtvXCgqU!3NsNY3 zKiR3mpVHxVgEAzPE#NOOgjWgLuT=B6*#)*S?|Q8;^Q&Vh>384-#XM$g3Ax9861e`t zIJXnzbJIK>FHeA>_&&o;1>rw4{f69in<1@b_eo+oy2PiMpCK zlbH;{+Z~eG)lhSOTHi^078|+D1)0cq!z%mepza^;Pnv=ra7nd){{5qjQP5~;5nM7^ zx`h{Z+$T!=VmJAI!QE`-e!Xe}sxgFTcux{6dvXYn;-!phH=Z%JeX_dvxP43{sBbDy zBJdUGv;Hea({vvD)pR-QDI`q}hpBuDOh0Xpysvu_O;}DD&sfkUWdUB*NCnlXO_%^b zv9q@(b|_4|wndL51g9|RF|zFTWi97IWq4;*MWYnXXv|0l0K$7m%sud9RI;>UkeC>OCHvL--qp}cPxg%!hAPa`BO6&vqEGi>JL?qjbSPvs?p!`JY2bvD|k ziB@RvxHt_ys35Vf(8bP0E=6PLn_?B!05%IfF(YSi3-_0kT0Z1+#|rMN$vbm(%Ztz7 zk$mFwi1E_BkNq;ZXGGV!QdnTygycz3rsHjlBTL5$II_AC!L#P2?AMVi+nn#bA;Us^B%7~LVm>?G@3IS!kn>ri;kQ*VrCzh`wV-(MHYKRa7>I__U8 zN)E2D=EKEPQ2={F#x^)TSGj=VS1k}k_vTBFtWj4d+US^&2NA0zv`Y;!e8LL#e6gmy z)ypp_h{X5#*q81@K}mx0F3q0OMk_GCCh7$NcB&=QGAQVoekGH~4~trL>!AW8$%x~P z(1I~kvfS6asZv6N7*9yS8VqIOaqbGpPsHb`OtP-zd2lUEvl!n-5;^(*@Gx|neM|-q zQ5vxXlUtZx-nBvz>ctPKHi54$^n1tn)|hVfp-8v}_`%tj>bU%txRm^iiZ75{Pda!` z$V>(C=woIJ(VB=C;bCEeahGzAg2mPOC^X8O8bRE5jQ5Vcf5uO-I3A;|0I4d*?YxPB z`x>Aslf#^6PA`v4a-8J`zv^<@jSUn^RW;2waca7mSK+?O9Z1vR-mV>kSIUzvNq?uO z7++Ud**wNuk?VX_T%c6A{ay;M(H%6_nCF2q@ku&apf^PmR8;$L4yf|V!=nmw2bDN0 zqf(%g*X&EjCqN{Fa9X$omE(DxHR_RED-CX!r~(=VuGHfdg`P0JdL+fWIqeE?cm4ON zUXGnL=d*oBG=E^WNH*5El$@Jf-<^qkcPl;2gOWx}BD6prPv{O8VtfX2y3Re>Y+>GA>yv0}bN zG?!iFCQCb)QhFkf(X11RWvA^i*~j%~Jfboa9T5D3%w&vy zJ(Oo3;fYgnVsge07_M?U&ZR~lVWkHM=y%HP&er;vUL?N;VGO@ilU-2@zsFbesN%%v ztXJug)VJQCR}ros9Q>qsV?49Ibok<>r!GYaCNAx9yyYZ-jB`N1c87_KSt-og2a(<7 zC+edWL57)zmhGb>3KD#8Jb%pSj|Chl?l&XIiJEDLpaseXE?~!0BTl0vr49$C8OrjX z96LzQTz$P9h%((P@U+=6Jln1aVK4W+;!LvT6gd>3El1BbY8Rhns-3ic6m2E7%lA5c zNy=NyJpi5<+ot02x{~@QP0ZYjM;u3cU%!@hx#iy-nQE1M9et3K!#Hf>QuKJvQST#D zN=P+Bu19lq@Ase-*#RQXT&sbFdfSzn$TvTzCo)NkUo{N`jiaR<(P;9gm$Ywgmz!$O z@Z_4ze{jOoc&@dr{WLCpOMN?H=%iFiw;fZL-^*#xBDNVlyoj%8OcmEWel*tR#hvH+ z1R8PB=B0g@5yiH-vU?p97BO)VACAYzgnY8ctUEDTWhwPwxZPiqpEto^<=#&0Asy`{ zRg*0+fw0Kw)Tvw$BBTYPlF&B|Wm;m!MaT&VPA&0yw}%s5r}Nsln|0ig>h9IWNwFA$x$O5bC;h z4ZG(+8UoXWWHy5CM{6xA0fJY_=m!{l;xbb#GOhmlg2?cCcW_Wd_+CZ}_O~Pq zgI5hvYU8IsmUIu96No___mH`;5WU44i})yjn)lgQ@t-M3;{}I9K5OiODpc?*Grzu; zw7@|{Yx)?)Jr^)Zejmcl-B2!NMy^1tNE9EqyDxts>7E$Y9rR<3N}0X3_>i*ex!+T@ zG6`;AU}i+j+sv>eJ^g%i_Irb1p)O*FktlmVrz5AMs#opsk1L(%xf_}(6xW0cG6m;f z&k+JVTYH_3j+|odZNSSN^;X4u*lTNRKAs_DN6qzJ-rmCfrkt)7yp1E1L6nN`zT%$a zSmduc8wVJxe`f?Pm36z1q76MO31I$K9$ADTsxirteeVtGC7VG*E$QvJCm`UrnB;#( zK8YDS7}}fLI@;L(f#)HsZ)Hr$CT(tDY_IQVZeuNDV{HTd#ZuqYff9nwChTBnZ0!gQ zg=c4l0J$L`bT(K9FcAv~0AOY3X6J^2izqo7Td6`ZEm+yv**PE_=xn0;wvxu?re=;% zxBxCz4sIYAh|VVEsBdX*C~R$NX-o`iPhHwI40aUQCC}>cEF*`Jp0TwBwC?Ei9J1lwu2>4HMRc?e*{h=9Xu!M-d zgE8#4+wE6!GH`UWg(^l=N(`0)rayLQv!uk7Z5~UB$>`fsvPl_1)nM-E_Dihf<^a`! zl(mTsB_AJ~qOqyDgQLA0CA~1TX2uNYY;yKS#`fmcrj+!5-UbyaIoaA;8e74%2@MiO zXH%op1i->IAW)PB04so-lY;}=VllN}zy3!fe+y{)SJ4@u>+#RpvGZZjaKXSG&oC`# zwy@C9+B>)!vwlS9?eEUvRJ%*dyKue*+O+gWSm`4&E+*f12$D)7>K1Xq!w~!`p9rX^ z{TLZ&S3gZUb*D5HTdd=CX&T`NmwB~^sHqKay3x)=>O^1WMg*pp^2j=y6nTQQmgrCy ztq^NJs@0wiJ?&l_Ow!#DmWx1n)HQs2h!#nKIJ!$D9-s3m+ zNfa@=z@j|9S>&aC9eYCBd>_KdV9QyQR$}c{LGdEXu{Gzq{VTWF`%>hgw2A|v9AaS` zVva(JtKq$Q)LB)JHvPC1(WUHs@iC<9R&g#Uwx{o;4&q&i;rrUeAbDmHi^t%NX4*f- z#fOO0h`p>g%GG^@&mSd~GxJacxa{&EY$|~-lYZDtEmp||7^-Q({%}voK=!l#X8h{| z(Y?fV;NF=@2^q%%;7w(^P2RE{+Mr%jzo552Prcdg5%^n(^*_fStk?fxTQDJX9Q@~2 zC~j?NV+1pr|FAU{$v+36kv?=BKrPdOQu7bHSA?31vW<$hIrJW5s1^N+75aT}{8pWR zWjFujm=ZuBEROFV;YRsZom>&P+^-+$md-dIi z$G!qX7H-RS**^T zOp0O_z&494k2j8ycn3Nng`Gh|paZkKf_o3mx<9OCD~UtG|?KYQOTIz*X9fLX~@F(-rLKfiV1W*K|Mc0;MOqHR-mM z1EIJ_f2%uzoZ#O98Tg?HABa?_jZlP-@+cq5=DbwdyT?B#5uW#V;zau9V||s>-mRpg zf0yNXul&)^f&)dOxmE{oKe_>WrNXQHCQeq#9vV%$7jRYM2P6T-ei#kIg1rk(Vyn}! zoLD5uxrm+9RxiTe`!bPOqtn)&1dEp#+x#p({> z;%|~KpGh$#5kJx<^+WE?O0|p7DaGz~1wC%;GiddF*+u?{#8BC}cH{nlGq!aU*Y~D$ z{5l-w(k=1)Iji)38!0B<+$FCj&H4PbsVwZm9wzE>e?Ao{)G$w)x7lg?whB#w`8n^5 z1DInDLEqBxGDx(>PEgv+vx_wn)yrp+_S0+2_V|-zpy_^rC(g1D%vM02A3PtXmr*Y&U{Z>> zx(9J|)Iowz4?j~O@KgtWm0xW-YIw!B9+P;MrroHVn9w|VA<}$+a;oE9x;QEL3TfQ+ zudL*6LJn{Mt^qTMD?hCygF@vFGdTJte`a%}XnA71XaCa*F0_Kk8N=TvDB(3GvBXN+ zlBgES){nOEq61-duu+n-v!WfbHGAhL;u6uaIr>c0bg|c2(Ntg}2u$1f533 zbCH|HzoAbByz#uy!8nGHNR#_6MN1@;F7}*yrgXZja`wF%x-i`=I8deNP;5yL&;1&{ zH2_%rsHu2I2Gw+8-V%w|nSt-yo|RT|==&|7X9j*Ba-7Wop-@-HeVh zvqipKN(M3c;gY0yGXgdKorp~zacqZm!l1U;h&k#849l7Lr;yir%d;*~5nIiEeMiHj zmT983jCW9;%a;8xLVN5#9<`b}hsvZ@zjFlCP+{skl*R3;n)AndPHlscCW(#eqCO}@ zIx^g4T8#xBNO|Rmzu~(Wv`4hp*pIBuOKtQGgkXYWMwK(=?$xQ^2FUu(x_{vu`C&Y0 za_P(W(qlro6UWNk1aR*h-cCfxHFd9hUTJxkLCGX)k%$le%0mAx`os-< zCWWW=cm4o^S&F+58v>OnK5LruCffzE*@^mt$4Z=ikqzV;54O@(YUV;VY;~Iy7*R^k?<%6t<1{j0ZlAlxKko;IOdi+|1o}y!%zzh@=k{+{1B{ z7nSp8%#JZ|O4KUpV~z>+XBt( z>8p|UO3|}(fCB330nHxxb984FDG8^I;N8$XbGujeenh9;qLmX3qf5h<{BPz3@P}r2 z%r!N7MT%%mLW8(HajRx_s^s=YPQ%1v>4?8Srxs)oCjea_#D6QU)=0-7q;TZfP$CUq z|2f>Q<1C|XMkru*PE9Z!*! zLKc&Ip^~B%(2@H z1vxy>H*ajMlx!g9V!X{?86jT7ygU>lvv(4*d*R8&)togy2zdPnKAP6zd#Vrz=4<3U zJ!?tEt}@=1S!5xv2%7gl0QO&!n0Jl!%gFMh8VgSIRa$u;sLah~3MijOh5KD0)vREB z->?iR0Xbq04k0si9-5|x%nXhNen;-)%s4oIsFHzxf^S+f7O?J46yXX^b)%zDD?R(} z&K27%DdB|V+D}s|`(y`e=$tg1bTRdS{LJmj`^w`AK5Ai=_OC4Gx25{Onh~>uuT7y; zVxC4JQK1H%r1@c}#{{FUZ}u7yLQWPr^pa&8_fRfexmEOh7#*FE_o}_hmp|bAwCnG5 z%Ls?=T=id6;u!hJj>JqtmdDLT-rA|wTk5FC%HNfc?gYvwb8tNLDwlkggs`cQN<{Qf z$VAw&O*=Z6- z^;-D_6gXCD&GHTt`Jja>FUtU~?v;D|F(YGO`Fo)C*pWFQd&>|HI?UXI!WdnIomS2PCvncNo*_WytP*h_*Fo zf|S7-rxB+`Jp~*TLU0D7sM++>U9&?>j~9vR2nB}jD&w#o(15M+wRq%RNOZW0k>2w7 zs5q6uy?TYjRi*X~ZtPo2fc?HJfw`+VEr5OVX$qeZM$mnKVf%@Jd1ZHx)0%Q5vkfAt zo-RM3dy$`_W+Xo!)F#apL0KFSO-xh@so*T$RpN~_MOH$O@nn&yb92n|(%23?!LbNw zl2rfD;~ThK#gDkcL)oC5Z?5>vnB|G|F(Wp?)b?(eP9~+`ObtJZ6Zh zmT{(f@5TQv*d~F0$D_I77+sYz9!HP6lBRHjD;}rM>7(_F`tk#dq)HDb{RPSATil6r zM|{uuznKtO9Vvc`Ag16EeZ~;C;b#_KTSP(zo+NjZ=9)rn@68xzdSe6U(Pju@B=xiF z%s?WX->!O#^ccB~sbLcA}hq7Uu^D zphado%di#{O6V%hNC;qNyEqwdm&wEkCHdZPkd^p-hJ@Uw*^S8q6JU|e$Lf4^Prp@) zOmRG;8q*`en;YY?8Te%Op6&MmGqiQML;k|2yJYu=`mlcpZ4{|()FdzMx@{URlnr^V zL_CC}kwHZ7R^NP9PXweHvE+4T+~Tq9-Z-TZ;0TsqZ({r?S!8P`l0{@9@`2>JPo0(M zNWQm*_WgGHmVif1CDgrBn-!sZ1s!tJb$H`!Es4#kG>*?PdYvoH3ZC)wcw#iTKOpK+ z>wlG(T+?>0pX$^bzi=1X&{OO$)c2d0;6HVrK>d+0Cy0!`qrExQk;n=FK#@>>{r!O= z#Bx&t^B|hrJ2;A(>D$Ackkb19_|6XgM_zxpB%!#mP#_`*6oiO{69RzV^`E%@e)G6M zQGfsc58U+s4zcv_J76042hh~5&p&?o^*_{z{==aM^%4JJ(|<~!Zas4o6JvX0YeQqG zOYi>+@S=a0`QHPQ^>01@@6t0w9ERNu5r<)SL&RaY;1F>bE;vLSh6@f6hv9<5`Wzw- z!yEtOoA_S>gaM&Afq!5`!}9#YPY%QMg5~{(oAr+?=(`CBb3guZ1;rQy{)to#D-#F> z!2k0%Vd&MbU9w-fh(fPmD~&(y6Ng^G=FZR^wBNP~ej(WZ4Zr4p{WbynZxeujHL<_R zxfm;4*+Gda23r)--U-QH@BLKPl6-FSctk8#C3_59_94qB1L1Kd@+abuWzkTsl(UB) z46;@Vj?p%fzu}p2y1$r}O>y72|iohsmxb*h1NPruD#83s;NUA^iVkAz|=o(zTXz2-_|tN z;=qq&7vn@iNWiSbi=27(g=ubRP%Xev^L4R>b1>E^F zxceG!d^M3JJU&xv=)CPt-Jhm$7A$&qE{5A}qntJ*Bw!nPsCx#lPZ_rG7gH$q-(2&5 zLNWiw&j$X5JkA1zh=V2sLviPTP=Gin5c5AI5Gceg6ix0w!C?ln|4k1#kmEP>XV*6} z@=pn&$lh}v=xjI-vVC0B4xt<33*MR?IcQ`-JDAE6xt4KtrE!@(DH&gg?u8IuI$S#2%#IED z=BtHG6w4f;<-bzp-}K~iab4$4Qh6GCp9ynr5=wgJl)+}3=G^2OzIRzCix$8iP7x~d zQ~7gl31{jza!(F5tD?)SU{8@Bmw@x`mAj-Y*871%Y zysYc1nZO=*dDtQOY+WYMZhWL_SL*S28j+~hN%#O5=r}75x*x>uZbZs*Aux9;_Tq8| zX!5#!%_(4q<^?jVs+&;cg^`Kri|^AGb=!8tQTUOu4sf%{RQPxzvb8df4809-)X76|R&P+boSOx7zLvYmt zg^@rtKz(a0N^#RAUrcvH-(_nl$&m%&12s4n@jRWOSj_E8&Her2LEy3yHJloWdfX#! z)2GDnn}Rr(I^W)ZUFXpji*sWyk3lsaEuNgS)+4sQNIBY_xbg@m2Gj@;x}M30PE4O7hr!{}r}19vcbk0d0N;?p$#vhO-9fZII~VxrkGg!X zdjCA;`y}15*j3j3YT~+};4;Ye#8w4Mh#g!2feKat6~WiSu9tfUh_Uh1(MdQoIOOpp zSb16!lm=D^BoMu7ruuk;7~(k%OT7FV2X5jxWAf+@yLclEFoWAeu{>(ESRLx1j=*qQ zpn;UTmQ&bPPGNfrj@wWSx2ED{kZBzLE}Au34+W$6gQAwk$+igo#Z(pAbH+uLx72X0 zrNly9x{({q@5&N~K3Vv8Zc<=Nv+5!NWR&kYx@eK&av{moVXT&D7|?cRo`lB@s}DOQ zSsuB|4GXY3C|Vr}I&LR2iXF5aR`n^!lVqKH4Eu4RTj$3mTEUk%ahtLim9f^O-|yJ0 z9>QlGYWf%|yUgf()%2*qVq}?+&25y_#aelC@3YXLpJCS#(vSv1F0Undr{}=vPfMn7 zZJLsp%FZo^lG#9Uz15cWyLF%Pd;e^?f=J1Oy|Ihp3D|fb41jNI4X+8w^o} z0(B#Vk{}v8H0V`wYw5YsK9m$dDP<34LL5LQfg3e8GDB7h>p<#VZ&mSgd}{{}w~|6~ z`B#C$w z0K%P-53H-LgRq z`?EmTD}3D)ar%41CmbInwU~)E>eF79GZ*>PSc%K`dso@JU}pbVjw*k6w~yJQxX4HM z9;<(}c3(jFdWama7kYh(i|4CK8wR_lO&#x>)l)GBKQ<_?sjHed>3$+5)84y8aC3JV z{|gQN_Bj6U@D4z399a7Gs^ox@{IGCx{5|&o^iaS|e4&^5LryP3x^tY>j%K!ZKZ>;KH3#5N9k^grsk^iUn zCs6GFRzslJpA=&Mx0HYW4itxBf&Y2+`zP=}TmrvK|L%971ovM%4}PuOVM}{hYkV+Ks6TP~Qw=`)^4HxAHKi`p&KOZ)QgGYD=-L}$bN>n4hnh29TrHXzh ze|BJ2|vQ1gUOmg*_a3gXr z3cEtzqUu~q;1C&%WA!}bL8y9-UpWHqqt^p*+U=~bpB|an7DY6kb>i@tU5!r+`80CR zs&`cMD^;fqMi>a#eB#qgjIeY!E2Jj|M|z~pIE!Q^PZOw67V|T3ND_J{cJWv&e z|Dl)1`Nr)-r{dy{{C*{z~g z>Y#rSSQhWNeL952ePMHiDJkA!$%KNNb#QQsL7;r6=PxFhP&TT+W%Z!zv@GIE-1hAN z%&$l2FMLR~ka|zJUP&!qv}tSpb2QkJEg^f=_!8B#*SOgHQfF(W_QgHM zesWjj8qG0O4xc9i|iXm5iaE^97+za@k+@}NJ z*uon%Po}3Tx_UCDrega#sB3^5eY=#D8$F%fKr8#?FzP-j>du#8f9k~|9G9}IX)mym6$C5AZgZR2v^G6NFqb*<>}pdNcW{|t#>F54%yx4Jameue0I5$g_qu|wUu;m zR0IDSKaIH2`ua3^u}hkXCpjFchQej zYI)}6iB!kTmnG{ zp-rXf+vjJ9jFf3Pf7OS7^UO0l=-Tl+?U%yOJ1C)N<*&lHt?!0Q5zd688aMjhuVs-r zM~skF%v4BD620;qXV%;h-rHN?8{rJn$} za;4M=bjBlEF`U0j?_149g`PfrVGWaa{{jaJGyM*XpudjYBgJ7#BSouIGKlmRTsnGP$ zt6yh-eqS}Y+8djoL)T#-0Qx^pBtbu*(U1@jgwllaKV-1oS=b+?^*>}lE)Lj2?wSmG zstM*dx+Y@>bAkUN9c)MMS~?Jvn;crzYcdFk9Y#QWUB<}{f;Qrsj1$NKBcr-5@Y9rwR-{FAlLz`n=%-;^)(q6 zl+^O348RS(l^-ma^=AE`9K^7F^=tV7xw&rX9>@)?%&m0LDAgM>b}#_SU41=2b}&1X z_WGs_0yC~_<+6jhZ}ky$ryFK=*V92bKsVb9CDnzoT3=7c0lw8o&|bTxQ+Cc@rwOj# z%L%$&1}7Jc-uikvE_N96*bN!9kef1Y;O(|?gKx<|0N^dXfB-Ny_v>YV09?1~2ZH)M zZk7w>7KAxMuGJ3&HMN`e2ZB0nZ;ne4j1cYSy&&){8;3?Q!(95;%K&k~*xIhkz`ytp zZ^&SL_BYc(2k=c9g-C7|K$2 zOU7~QIRu7|w_Eo@IB(wz;o`Wd7cd9tmaf1Y;9GVN=D0nk!JOdRdf|k?i0H4kjq8_7 z?}m&Md`o}azfSyIPsa@g-O?2|g!@(*+|bJ0EEihko3;yqcG1oLfO4F|T#nbuh0fD& z-wWir)o&2?+s_vWba>pX3k1vsxjFVB(0;qwzYqxE)>wc*fgNtz9|Zb$t8I{9doO+j>)p)>;)aEuU#}mS{nnV~ z1asZ84NmC$?N(hNoVWUo6FQN&)m|>(E!*Jaf&xq2tP2-}^Hw{chjwo18H&Det1jG7 zAd4IMaX}xQH`8&kvvb}Ymt0VLz9j>Jz`xz=Xs-_iwy;Ns9u8JAcZbICL+6fciZ(Wm klz+PDf8k3&Tl5R{!ogAB-tpHo6KW*mX8-^I literal 0 HcmV?d00001 diff --git a/seminars/5.md b/seminars/5.md new file mode 100644 index 0000000..f4f653c --- /dev/null +++ b/seminars/5.md @@ -0,0 +1,61 @@ +# Наследования + +```cpp +class A { + int a; +public: + A(int x = 0) : a(x) {} + void f() { cout << a; } +}; + +class B : public/private/protected A/*, C*/ { // private by default + int b; +public: + B(int x = 0, int y = 0) : A(x), b(y) {} + void f() { + cout << a << b; // error. A is private + } +}; +``` + +```cpp +int main() { + A obj_a, *pa; + B obj_b, *pb; + pa = &obj_a; + pb = &obj_b; + + // при открытом наследовании + pa = pb; + pb = (B*)pa; + + // при закрытом наследовании + pa = (A*)pb; + // pb = (B*)pa; - невозможно + + *pa = &obj_a; + pa->f(); // вызов из a + *pa = &obj_b; + pa->f(); // вызов тоже из a, т.к. не виртуальная функция +} +``` + +в ситуации любого наложения функций, происходит перекрытие имён + +```cpp +class A { + void f(); +} + +class B : A { + void f(int) { f(); } // error +} +``` + +конструкторы не наследуются + +## консруктор копирования + +```cpp +B (const B &a) : A(a) {} +``` diff --git a/seminars/6.md b/seminars/6.md new file mode 100644 index 0000000..33f3b9c --- /dev/null +++ b/seminars/6.md @@ -0,0 +1,187 @@ +# Семинар 6 + +## RTTI - Run Time Type Identification + +- typeid +- dynamic_cast + +### typeid + +> `typeid` возвращает тип объекта/указателя. Если указатель на класс с виртуальными функциями, вернёт именно тип объекта. Иначе - указателя. + +Для `type_info` переопределённые операции и методы: + +- == +- !- +- .name + +```cpp +class A { +public: + virtual void f() {} +}; + +class B : public A {}; + +int main () { + A *pa = new B; + B *pb; + std::cout << typeid(*pa).name; // 1B (1 символ в имени) + if (typeid(*pa) == typeid(B)) { + pb = (B*)pa; // небезопасное приведение + } +} +``` + +## Dynamic cast + +```cpp +class A { +public: + virtual void f() {} +}; + +class B : public A {}; + +int main () { + A *pa, a; + B *pb, b; + pa = &b; + // безопасно приводит, вернёт не NULL в случае успеха + pb = dynamic_cast(pa); +} +``` + +```cpp +class A { +public: + virtual void f() {} +}; + +class B : public A {}; + +int main () { + A *pa, a; + B *pb, b; + A &pr = a; + // B &rb = dynamic_cast(pa); // выкинет bad_cast +} +``` + +## Исключения + +`try - throw - catch` + +`terminate()` - в случае, если ничего не обработалось + +приводится в `catch` указатели к константным могут + +```cpp +int f() { + try { + ... + throw 10; + ... + throw "abc"; + ... + throw A(); + ... + } catch (int a) { + ... + throw ...; // тогда обработается функцией выше + ... + } catch (const char* s) { + ... + } catch (A &x) { + ... + } catch (...) { // все остальные исключения + + } +} +``` + +В случае возвращение класса, который наследуется от базового, "ловить" надо сначала производный, после - базовый +Деструктор для создаваемого класса вызывается только после фулл обработки исключения (если catch сам вызвал throw) + +```cpp +int f() throw(int, char) { + try { + ... + throw 1.2; + ... + } catch (double) { + ... + } +} +``` + +`unexpected()` - вызывается, если мы на внешнюю функцию передаём исключение типа, который не указан + +```cpp +// никакие не передавать вовне +int f() throw(); + +after c++17 only: +int f() noexcept; +``` + +### Алгоритм обработки исключений + +- создание временного объекта типа возвращаемого исключения +- уничтожение объектов в `try` блоке +- выход из `try` +- подбор нужного обработчика +- если больше исключений нет - деструктор временного объекта +- если не обработано - выход к внешнему обработчику + +```cpp +5.14. Что напечатает следующая программа? +struct S { + S ( int a) { + try { + if (a > 0) throw *this ; + else if (a < 0) throw 0; + } + catch ( S & ) { + cout << “SCatch_S&” << endl; + } catch (int ) { throw ; } + cout << “SConstr” << endl; + } + S (const S & a) { cout << “Copy” << endl; } + ~S ( ) { cout << “Destr” << endl; } +}; +int main ( ) { + try { + S s1( 0 ), s2 ( 5 ); + cout << “Main” << endl; + } + catch (S &) { cout << “MainCatch_S&” << endl; } + catch ( ... ) { cout << “MainCatch_...” << endl; } + + return 0; +} +``` + +Результат отработки программы: + +```text +Sconstr +Copy +Scatch_s& +Destr +Sconstr +Main +Destr +Destr +``` + +1 +14 +15 +CatchB +bad_cast +63 +63 +3 +... +End diff --git a/seminars/codes/1.cpp b/seminars/codes/1.cpp new file mode 100644 index 0000000..63896ff --- /dev/null +++ b/seminars/codes/1.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +class string +{ + int len; // количество памяти + char* str; + +public: + string(const char* s = "") { + len = strlen(s) + 1; + str = new char[len]; + strcpy(str, s); + } + + char& + operator[](int n) { + return str[n]; + } + + string + operator+(string s) { + string tmp; + tmp.len = s.len + len - 1; + tmp.str = new char[tmp.len]; + + strcpy(tmp.str, str); + strcpy(tmp.str + len - 1, s.str); + + return tmp; + } + + // string + // operator=(string s) { + // if (s.str == str) { + // return s; + // } + + // delete[] str; + // len = s.len; + // str = new char[len]; + // strcpy(str, s.str); + + // return *this; + // } + + // ~string() { delete[] str; } почему-то с ним не работает (?) + + void + print() { + std::cout << str << " " << len << std::endl; + } +}; + + +int +main() { + string s1("abcd"), s2("qw"), s3; + s2[1] = 'A'; + s2.print(); + s3 = s1 + s2; + + s3.print(); +} diff --git a/seminars/codes/4.cpp b/seminars/codes/4.cpp new file mode 100644 index 0000000..95a0cad --- /dev/null +++ b/seminars/codes/4.cpp @@ -0,0 +1,96 @@ +// -> написать шаблонную функцию, которая ищет макс значение в константном или неконстантном контейнере +#include +#include +#include + +using namespace std; + +template +typename Container::value_type Max(const Container& c) { + typename Container::value_type max = *c.cbegin(); + + for (auto it = c.cbegin(); it != c.cend(); ++it) { + if (*it > max) { + max = *it; + } + } + + return max; +} + +template +void dbl(T& c) { + auto it = c.begin(); + + while (it != c.end()) { + it = c.insert(++it, *it); + ++it; + } + + return; +} + +template +void rever(T b, T e) { + if (b == e) return; + + --e; + + while (b != e) { + swap(*b++, *e); + + if (b == e) break; + + --e; + } + + return; +} + +struct Pred { + bool operator()(int x) { + return x % 3; + } +}; + +template // T - указатель P - предикат +void f(T b, T e, P pred, typename T::value_type val = {}) { + while (b != e) { + if (pred(*b)) { + *b = val; + } + ++b; + } + + return; +} + +int main() { + list l = { 1, 2, 3, 4, 5 }; + cout << Max>(l) << endl; + + f(l.begin(), l.end(), Pred()); + for (const auto& elem : l) { + cout << elem << " "; + } + cout << endl; + + // dbl(l); + // rever(l.begin(), l.end()); + // for (const auto& elem : l) { + // cout << elem << " "; + // } + // cout << endl; + + vector v = { 1, 3, 3, 4, 5 }; + cout << Max>(v) << endl; + + // dbl(v); + rever(v.begin(), v.end()); + for (const auto& elem : v) { + cout << elem << " "; + } + cout << endl; + + return 0; +} \ No newline at end of file diff --git a/seminars/markdown-cheat-sheet.md b/seminars/markdown-cheat-sheet.md new file mode 100644 index 0000000..c94cb27 --- /dev/null +++ b/seminars/markdown-cheat-sheet.md @@ -0,0 +1,119 @@ +# Markdown Cheat Sheet + +Thanks for visiting [The Markdown Guide](https://www.markdownguide.org)! + +This Markdown cheat sheet provides a quick overview of all the Markdown syntax elements. It can’t cover every edge case, so if you need more information about any of these elements, refer to the reference guides for [basic syntax](https://www.markdownguide.org/basic-syntax/) and [extended syntax](https://www.markdownguide.org/extended-syntax/). + +## Basic Syntax + +These are the elements outlined in John Gruber’s original design document. All Markdown applications support these elements. + +### Heading + +# H1 +## H2 +### H3 + +### Bold + +**bold text** + +### Italic + +*italicized text* + +### Blockquote + +> blockquote + +### Ordered List + +1. First item +2. Second item +3. Third item + +### Unordered List + +- First item +- Second item +- Third item + +### Code + +`code` + +### Horizontal Rule + +--- + +### Link + +[Markdown Guide](https://www.markdownguide.org) + +### Image + +![alt text](https://www.markdownguide.org/assets/images/tux.png) + +## Extended Syntax + +These elements extend the basic syntax by adding additional features. Not all Markdown applications support these elements. + +### Table + +| Syntax | Description | +| ----------- | ----------- | +| Header | Title | +| Paragraph | Text | + +### Fenced Code Block + +``` +{ + "firstName": "John", + "lastName": "Smith", + "age": 25 +} +``` + +### Footnote + +Here's a sentence with a footnote. [^1] + +[^1]: This is the footnote. + +### Heading ID + +### My Great Heading {#custom-id} + +### Definition List + +term +: definition + +### Strikethrough + +~~The world is flat.~~ + +### Task List + +- [x] Write the press release +- [ ] Update the website +- [ ] Contact the media + +### Emoji + +That is so funny! :joy: + +(See also [Copying and Pasting Emoji](https://www.markdownguide.org/extended-syntax/#copying-and-pasting-emoji)) + +### Highlight + +I need to highlight these ==very important words==. + +### Subscript + +H~2~O + +### Superscript + +X^2^ \ No newline at end of file