Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 1 addition & 11 deletions .github/workflows/build-and-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,4 @@ jobs:
- uses: actions/checkout@v5
- name: Check format
run: |
find . -path ./build -prune -o -type f -name '*.[c|h]' -print | xargs clang-format-18 --style=file --dry-run -Werror
- name: Configure
run: |
# -DCMAKE_EXPORT_COMPILE_COMMANDS=ON is important for clang-tidy
cmake . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- name: Build
run: |
cmake --build build
- name: Lint
run: |
run-clang-tidy-18 -p=build
find . -path ./build -prune -o -type f -name '*.[c|h]' -print | xargs clang-format-18 --style=file --dry-run -Werror
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ project(C_Homework C)

add_subdirectory(src/CheckHowLintersWork)

add_subdirectory(src/CountingTask)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_compile_options(-Wall -Wextra -Wpedantic)
5 changes: 5 additions & 0 deletions src/CountingTask/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
add_library(cyclicList cyclicList.c)

add_executable(counting counting.c)

target_link_libraries(counting PRIVATE cyclicList)
17 changes: 17 additions & 0 deletions src/CountingTask/counting.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "cyclicList.h"
#include <stdbool.h>
#include <stdio.h>

int main()
{
printf("Введите n и m через пробел\n");
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
Comment on lines +7 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще можно просто два scanf попросить, он их прочитает, если бы они были через пробел или через перенос строки (\n)

List* list = newList();
for (int i = 1; i <= n; i++) {
insert(list, i - 1, i);
}
printf("%d\n", findTheSafeIndex(list, m));
return 0;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Список (ну или то что от него осталось) не удаляется при выходе

}
164 changes: 164 additions & 0 deletions src/CountingTask/cyclicList.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include "cyclicList.h"
#include "stdio.h"
#include <stdbool.h>
#include <stdlib.h>

// структура обычного элемента в списке
typedef struct ListNode ListNode;

typedef struct ListNode {
int value;
ListNode* next;
} ListNode;

typedef struct List {
ListNode* head;
} List;

List* newList()
{
List* new = calloc(1, sizeof(*new));
return new;
}

bool insert(List* list, int index, int value)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще при добавлении можно не использовать список, в задании же всё равно заполняются последовательно

{
if (list == NULL) {
return false;
}
if (isEmpty(list)) {
ListNode* newNode = calloc(1, sizeof(ListNode));
newNode->value = value;
newNode->next = newNode;
list->head = newNode;
return true;
}
if (index == 0) {
ListNode* newNode = calloc(1, sizeof(ListNode));
newNode->value = value;
ListNode* current = list->head;
while (current->next != list->head) {
current = current->next;
}
newNode->next = list->head;
list->head = newNode;
current->next = newNode;
return true;
}

ListNode* current = list->head;
int counter = 0;
while (1) {
if (counter == index - 1) {
ListNode* newNode = calloc(1, sizeof(ListNode));
newNode->value = value;
newNode->next = current->next;
current->next = newNode;
return true;
}
current = current->next;
counter++;
Comment on lines +50 to +60

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут можно написать for (int i = 0;;i++), получится то же самое

}
return false;
}

bool removeElement(List* list, int index)
{
if (list == NULL || isEmpty(list)) {
return false;
}
if (index == 0) {
ListNode* elemToRemove = list->head;
if (elemToRemove->next == elemToRemove) {
free(elemToRemove);
list->head = NULL;
return true;
}
ListNode* current = list->head;
while (current->next != elemToRemove) {
current = current->next;
}
Comment on lines +77 to +80

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вообще чтобы вот так не искать хвост, его можно хранить в самом списке

list->head = elemToRemove->next;
current->next = list->head;
free(elemToRemove);
return true;
}

ListNode* current = list->head;
int counter = 0;
while (1) {
if (counter == index - 1) {
ListNode* nodeToDelete = current->next;
current->next = nodeToDelete->next;
free(nodeToDelete);
return true;
}
current = current->next;
counter++;
}
return false;
}

bool deleteList(List* list)
{
if (list == NULL || isEmpty(list)) {
return false;
}
while (!isEmpty(list)) {
removeElement(list, 0);
}
free(list);
return true;
}

bool isEmpty(List* list) { return list->head == NULL; }

bool oneElement(List* list) { return list->head->next == list->head; }

void printList(List* list)
{
if (list == NULL || isEmpty(list)) {
printf("Список пустой\n");
return;
}
ListNode* current = list->head;
do {
printf("%d ", current->value);
current = current->next;
} while (current != list->head);
printf("\n");
}

int getLength(List* list)
{
if (list == NULL || isEmpty(list)) {
return -1;
}
int counter = 0;
ListNode* current = list->head;
do {
counter++;
current = current->next;
} while (current != list->head);
return counter;
}

int findTheSafeIndex(List* list, int m)
{
ListNode* current = list->head;
ListNode* prev = NULL;
while (!oneElement(list)) {
for (int i = 0; i < m; i++) {
prev = current;
current = current->next;
}
if (current == list->head) {
list->head = current->next;
}

prev->next = current->next;
free(current);
current = prev->next;
}
return list->head->value;
}
Comment on lines +146 to +164

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

То есть индексы вообще не нужны? Тут они нигде не упоминаются, вообще тогда можно сделать так, чтобы removeElement принимал в себя ListNode, и удалял его из списка

76 changes: 76 additions & 0 deletions src/CountingTask/cyclicList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#pragma once
#include <stdbool.h>

// структура содержащая указатель на первый элемент списка
typedef struct List List;

/*
* функция создания нового списка
* ничего не принимает
* возвращает указатель на список
*/
List* newList();

/*
* функция вставки элемента по заданному индексу
* принимает на вход указатель на список, желаемый индекс и значение
* возвращает булевое значение, сообщающее, удачно ли прошла операция
*/
bool insert(List* list, int index, int value);

/*
* функция удаления элемента по индексу
* принимает указатель на список и индекс элемента
* возвращает булевое значние, сообщающее, удачно ли прошла операция
* внутри себя освобождает память удаляемого элемента
*/
bool removeElement(List* list, int index);

/*
* функция удаления всего списка
* принимает указатель на список
* внутри себя вызывает функцию removeElement
* возвращает булевое значение, удачно ли прошла операция
*/
bool deleteList(List* list);

/*
* функция проверки, пустой ли список
* возвращает true если пустой, false, если нет
* на вход принимает указатель на список
*/
bool isEmpty(List* list);

/*
* функция проверки, один ли элемент в списке
* возвращает true если да, false, если нет
* на вход принимает указатель на список
*/
bool oneElement(List* list);

/*
* функция вывода списка в консоль
* принимает только указаетль на список,
* ничего не возвращает
* печатает элементы списка через пробел
* в случае переданного пустого или несуществующего списка сообщает об этом
* пользователю
*/
void printList(List* list);

/*
* функция, возвращающая длину списка
* принимает на вход указатель на список
* проходится по всем элементам
* возвращает его длину
*/
int getLength(List* list);
Comment on lines +51 to +67

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Неиспользуемые функции


/*
* функция алгоритма Иосифа
* на вход принимает указатель на список и m (каждого m-того война
* будут убивать) возвращает значение последнего оставшегося элемента - места,
* куда нужно встать, по условию задачи функция создана исключительно для
* реализации алгоритма из файла counting.c.
*/
int findTheSafeIndex(List* list, int m);