init
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
ColumnLimit: 120
|
||||
TabWidth: 4
|
||||
IndentWidth: 2
|
||||
...
|
||||
@@ -0,0 +1,25 @@
|
||||
# debug: clangd --check=modules/iue-io/ccsv.h
|
||||
# debug: clangd --check=task1.hpp
|
||||
# debug: clangd --check=task1.test.cpp
|
||||
InlayHints:
|
||||
Enabled: No
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: No
|
||||
---
|
||||
CompileFlags:
|
||||
Add:
|
||||
# - --target=x86_64-w64-windows-gnu
|
||||
# - --target=x86_64-pc-linux-gnu
|
||||
- -Wall
|
||||
- -Wno-unused-function
|
||||
- -Wno-unused-variable
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.c, .*\.h]
|
||||
CompileFlags:
|
||||
Add: [-std=c11]
|
||||
---
|
||||
If:
|
||||
PathMatch: [.*\.cpp, .*\.hpp]
|
||||
CompileFlags:
|
||||
Add: [-std=c++20]
|
||||
@@ -0,0 +1,3 @@
|
||||
task1
|
||||
task2
|
||||
task3
|
||||
@@ -0,0 +1,3 @@
|
||||
task1.main.c
|
||||
task2.c
|
||||
task3.c
|
||||
@@ -0,0 +1,16 @@
|
||||
## source: https://docs.github.com/en/get-started/getting-started-with-git/configuring-git-to-handle-line-endings
|
||||
|
||||
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files you want to always be normalized and converted
|
||||
# to native line endings on checkout.
|
||||
*.h text
|
||||
*.hpp text
|
||||
*.c text
|
||||
*.cpp text
|
||||
*.py text
|
||||
*.ipynb text
|
||||
*.md text
|
||||
*.txt text
|
||||
*.csv text
|
||||
@@ -0,0 +1,358 @@
|
||||
# custom
|
||||
|
||||
build
|
||||
doc
|
||||
.cache
|
||||
.vscode
|
||||
.idea
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ttps://github.com/github/gitignore/blob/main/C.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# source: https://github.com/github/gitignore/blob/main/Python.gitignore
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# jetbrain IDEs: https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# VSCODE source: https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
@@ -0,0 +1,4 @@
|
||||
[submodule "modules"]
|
||||
path = modules
|
||||
url = https://sgit.iue.tuwien.ac.at/360050/modules
|
||||
branch = main
|
||||
@@ -0,0 +1,59 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
# define project metadata
|
||||
|
||||
project(exercise8 LANGUAGES C
|
||||
DESCRIPTION "exercise8"
|
||||
HOMEPAGE_URL "https://sgit.iue.tuwien.ac.at/360050/exercise8")
|
||||
|
||||
# setting required language standards
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED True)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
# misc settings
|
||||
|
||||
# avoid ctest dashboard targets
|
||||
set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)
|
||||
# generate a compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# make all symbols visible on windows (which is default on unix)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# options
|
||||
|
||||
option(BUILD_TESTING "enable testing with ctest" ON)
|
||||
|
||||
# testing
|
||||
|
||||
include(CTest)
|
||||
|
||||
# find math library and link to all targets
|
||||
|
||||
find_library(MATH_LIBRARY m)
|
||||
link_libraries(${MATH_LIBRARY})
|
||||
|
||||
# get/setup dependencies
|
||||
|
||||
include_directories(modules)
|
||||
|
||||
# include own targets
|
||||
|
||||
add_executable(task1 task1.main.c
|
||||
task1.main.c)
|
||||
target_link_libraries(task1 PRIVATE ${MATH_LIBRARY})
|
||||
add_test(NAME task1 COMMAND task1 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
set_property(TEST task1 PROPERTY PASS_REGULAR_EXPRESSION "8")
|
||||
|
||||
add_executable(task2 task2.c task2.test.c
|
||||
task2.test.c
|
||||
task2.h
|
||||
task2.c)
|
||||
target_link_libraries(task2 PRIVATE ${MATH_LIBRARY})
|
||||
add_test(NAME task2 COMMAND task2 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
add_executable(task3 task2.c task3.c task3.test.c)
|
||||
target_link_libraries(task3 PRIVATE ${MATH_LIBRARY})
|
||||
add_test(NAME task3 COMMAND task3 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Hausübung 8 (3 Punkte)
|
||||
|
||||
**Ausgabe**: Donnerstag 16. Mai 2024, vormittags.
|
||||
|
||||
**Abgabe bis**: Montag 27. Mai 2024, Ende des Tages.
|
||||
|
||||
**Abgabe via**: git-Repository mit dem Namen **`exercise8`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
|
||||
|
||||
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
|
||||
|
||||
# Aufgabenstellung
|
||||
|
||||
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
|
||||
|
||||
- Sprache C: Kompilierbefehle
|
||||
- Sprache C: Strukturen und Funktionen
|
||||
- Sprache C: Übergabe von Feldern an Funktionen
|
||||
|
||||
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
|
||||
@@ -0,0 +1 @@
|
||||
-Imodules
|
||||
@@ -0,0 +1,187 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 1: Ein eigenes kleines C-Programm (*array as function parameter*) (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Erstellen Sie in [`task1.main.c`](task1.main.c) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
|
||||
"\n",
|
||||
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
|
||||
"\t```c\n",
|
||||
"\t#include <stdbool.h> // bool, true, false\n",
|
||||
"\t#include <stdio.h> // printf\n",
|
||||
"\t...\n",
|
||||
"\t```\n",
|
||||
"- Definition/Implementierung einer eigenen Funktion, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint task1_func(...) {\n",
|
||||
"\t ...\n",
|
||||
"\t}\n",
|
||||
"\t``` \n",
|
||||
"- Definition/Implementierung einer `main`-Funktion, die Ihre selbst geschriebene Funktion verwendet, z.B.:\n",
|
||||
"\t```cpp\n",
|
||||
"\tint main(){\n",
|
||||
"\t ...\t\n",
|
||||
"\t int res = task1_func(...);\n",
|
||||
"\t ...\t\n",
|
||||
"\t return 0;\n",
|
||||
"\t}\n",
|
||||
"\t``` \n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.c`](task1.main.c)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.c`](task1.main.c)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 2: Reimplementierung von C++ Funktionalität in C (1 Punkt)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Sie reimplementieren die Funktionalität zweier Klassen, die Sie schon in Hausübung 4 (C++) implementiert:\n",
|
||||
"\n",
|
||||
"- [`exercise4::task2::BBox`](https://sgit.iue.tuwien.ac.at/360050/exercise4/src/commit/2e408ac941971e07971485282ef086d22cb0d974/task2.hpp#L13) \n",
|
||||
"- [`exercise4::task2::Circle`](https://sgit.iue.tuwien.ac.at/360050/exercise4/src/commit/2e408ac941971e07971485282ef086d22cb0d974/task2.hpp#L35)\n",
|
||||
"\n",
|
||||
"Diesmal verwenden Sie die Sprache C:\n",
|
||||
"\n",
|
||||
"- Statt Memberfunktionen kommen freie Funktionen zum Einsatz\n",
|
||||
"- Funktionsüberladungen werden durch Postfixe/Präfixe bei den Funktionsnamen realisiert\n",
|
||||
"- Typen aus der C++ Standardbibliothek (hier z.B. `std::array<double, 2>` ) werden durch eigene Typen ersetzt\n",
|
||||
"- Funktionalität aus der C++ Standardbibliothek (z.B. `std::cout`) wird mit entsprechender Funktionalität aus der C Standardbibliothek ( `printf` ) ersetzt."
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Strukturen/Funktionen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.h`](task2.h)\n",
|
||||
"- Ihre Implementierung erfolgt in [`task2.c`](task2.c)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task2.test.c`](task2.test.c) "
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Aufgabe 3: Übergabe von Feldern von Strukturen an Funktionen (1 Punkt)\n",
|
||||
"\n",
|
||||
"Sie implementieren zwei Funktionen an die ein Feld von Strukturen (aus Aufgabe 2) übergeben wird:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "c"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"```c\n",
|
||||
"// todo: implement\n",
|
||||
"unsigned int task3_count_inside(const struct BBox* box, const struct Circle circles[], unsigned int size);\n",
|
||||
"\n",
|
||||
"// todo: implement\n",
|
||||
"struct BBox task3_common_bbox(const struct Circle circles[], unsigned int size);\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.h`](task3.h)\n",
|
||||
"- Ihre Implementierung erfolgt ebenfalls in [`task3.c`](task3.c)\n",
|
||||
"- Die zugeordneten Tests finden Sie in [`task3.test.c`](task3.test.c)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Kompilieren/Testen\n",
|
||||
"\n",
|
||||
"So testen Sie Ihre Implementierung (direkter Aufruf von `gcc`):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"mkdir build\n",
|
||||
"# compile\n",
|
||||
"gcc -g -std=c11 task1.main.c -o build/task1 -lm\n",
|
||||
"gcc -g -Imodules -std=c11 task2.c task2.test.c -o build/task2 -lm\n",
|
||||
"gcc -g -Imodules -std=c11 task2.c task3.c task3.test.c -o build/task3 -lm\n",
|
||||
"\n",
|
||||
"# run tests\n",
|
||||
"./build/task1\n",
|
||||
"./build/task2\n",
|
||||
"./build/task3\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Alternativ (mittels CMake-Configuration):\n",
|
||||
"\n",
|
||||
"```shell\n",
|
||||
"# prepare\n",
|
||||
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
|
||||
"# compile\n",
|
||||
"cmake --build build --config Debug --target task1\n",
|
||||
"cmake --build build --config Debug --target task2\n",
|
||||
"cmake --build build --config Debug --target task3\n",
|
||||
"cmake --build build --config Debug # all\n",
|
||||
"# run tests\n",
|
||||
"ctest --test-dir build -C Debug -R task1 --verbose\n",
|
||||
"ctest --test-dir build -C Debug -R task2 --verbose\n",
|
||||
"ctest --test-dir build -C Debug -R task3 --verbose\n",
|
||||
"ctest --test-dir build -C Debug # all\n",
|
||||
"``` \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.15"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
Submodule
+1
Submodule exercise8/modules added at 63b4f08052
@@ -0,0 +1,44 @@
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
bool isprime(unsigned int num) {
|
||||
// Handle edge cases (0, 1, and even numbers greater than 2)
|
||||
if (num <= 1 || num % 2 == 0 && num > 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Efficiently check divisibility only up to the square root of num
|
||||
for (unsigned int i = 3; i * i <= num; i += 2) {
|
||||
if (num % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int count_primes(unsigned int values[], int size) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (isprime(values[i])) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int main() {
|
||||
unsigned int arr1[] = {1, 20, 21, 43, 32, 42, 2344, 42433, 6, 2, 0, 22, 45, 47, 1033, 1247};
|
||||
int size1 = sizeof(arr1) / sizeof(arr1[0]);
|
||||
|
||||
unsigned int arr2[] = {21, 22, 44, 33, 7, 3, 1, 23, 46, 48, 1034, 1248};
|
||||
int size2 = sizeof(arr2) / sizeof(arr2[0]);
|
||||
|
||||
int primes1 = count_primes(arr1, size1);
|
||||
int primes2 = count_primes(arr2, size2);
|
||||
|
||||
int total_primes = primes1 + primes2;
|
||||
|
||||
printf("Total number of primes: %d\n", total_primes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/// @file
|
||||
/// @brief Task2: function definitions
|
||||
|
||||
#include "task2.h" // struct Matrix, matrix_mult
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
/// @todo Include C standard library headers as needed
|
||||
|
||||
/// @note This implementation is provided as declared and specified in task2.h
|
||||
struct Matrix matrix_init(size_t m, size_t n, const double* data) {
|
||||
struct Matrix res = {.data = malloc(sizeof(double) * m * n), .m = m, .n = n};
|
||||
double* A = res.data;
|
||||
for (size_t i = 0; i != m * n; ++i)
|
||||
A[i] = data[i];
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @note This implementation is provided as declared and specified in task2.h
|
||||
void matrix_print(const struct Matrix* mat) {
|
||||
size_t M = mat->m;
|
||||
size_t N = mat->n;
|
||||
const double* A = mat->data;
|
||||
|
||||
for (size_t m = 0; m != M; ++m) {
|
||||
for (size_t n = 0; n != N; ++n)
|
||||
printf("%lf ", A[n + N * m]);
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/// @note This implementation is provided as declared and specified in task2.h
|
||||
void matrix_clear(struct Matrix* mat) {
|
||||
free(mat->data);
|
||||
mat->m = 0;
|
||||
mat->n = 0;
|
||||
}
|
||||
|
||||
/// @todo Implement function 'matrix_zeros' as declared and specified in task2.h
|
||||
struct Matrix matrix_zeros(size_t m, size_t n) { return (struct Matrix){.data = NULL, .m = 0, .n = 0}; }
|
||||
|
||||
/// @todo Implement function 'matrix_identity' as declared and specified in task2.h
|
||||
struct Matrix matrix_identity(size_t n) { return (struct Matrix){.data = NULL, .m = 0, .n = 0}; }
|
||||
|
||||
/// @todo Implement function 'matrix_transpose' as declared and specified in task2.h
|
||||
void matrix_transpose(struct Matrix* a) {}
|
||||
|
||||
/// @todo Implement function 'matrix_mult' as declared and specified in task2.h
|
||||
void matrix_mult(const struct Matrix* a, const struct Matrix* b, struct Matrix* c) {}
|
||||
@@ -0,0 +1,51 @@
|
||||
/// @file
|
||||
/// @brief Task2: Structure definitions and function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
/// @brief Two-dimensional matrix with 'm' rows and 'n' columns.
|
||||
/// @note: the values ares stored in a contiguous block in memory in row-major layout
|
||||
/// @note: row-major storage order is used, access of element (i,j) -> data[j + n*i]
|
||||
struct Matrix {
|
||||
double* data; ///< pointer to a dynamically allocated contiguous memory block fitting m*n values
|
||||
size_t m; ///< number of rows (first dimension)
|
||||
size_t n; ///< number of columns (second dimension)
|
||||
};
|
||||
|
||||
/// @brief Initalize a matrix from the values in a buffer
|
||||
/// @param m first dimension of the matrix
|
||||
/// @param n second dimension of the matrix
|
||||
/// @param data contiguous memory holding the values to copy (in row-major format)
|
||||
struct Matrix matrix_init(size_t m, size_t n, const double* data);
|
||||
|
||||
/// @brief Prints a Matrix to the console
|
||||
/// @param mat Matrix to be printed
|
||||
void matrix_print(const struct Matrix* mat);
|
||||
|
||||
/// @brief Resets a matrix (deallocates memory and sets its size to 0 x 0)
|
||||
/// @param mat Matrix to be reset
|
||||
void matrix_clear(struct Matrix* mat);
|
||||
|
||||
/// @brief Initializes an matrix with zeros
|
||||
/// @param m first dimension of the matrix
|
||||
/// @param n first dimension of the matrix
|
||||
struct Matrix matrix_zeros(size_t m, size_t n);
|
||||
|
||||
/// @brief Initializes a square identity matrix
|
||||
/// @param n dimension of the identity matrix
|
||||
struct Matrix matrix_identity(size_t n);
|
||||
|
||||
/// @brief Transposes a matrix
|
||||
/// @param mat Matrix to be transposed
|
||||
/// @note this function might swap/replace the block of memory owned by the matrix
|
||||
void matrix_transpose(struct Matrix* mat);
|
||||
|
||||
/// @brief Performs a matrix-matrix mutliplication: a*b = c
|
||||
/// @a first matrix (left factor)
|
||||
/// @b second matrix (right factor)
|
||||
/// @c Result of the multiplication is stored in this Matrix:
|
||||
/// - the dimensions of this matrix must be 'a.m x b.n' when calling this function
|
||||
/// - the values will be overwritten with the result of the multiplication
|
||||
void matrix_mult(const struct Matrix* a, const struct Matrix* b, struct Matrix* c);
|
||||
@@ -0,0 +1,220 @@
|
||||
/// @file
|
||||
/// @brief Task2: tests
|
||||
|
||||
#include "task2.h" // struct Matrix, matrix_mult
|
||||
|
||||
#include "iue-num/numerics.h" // iuenum_isclose
|
||||
|
||||
#include <assert.h> // assert
|
||||
#include <stdbool.h> // bool, true, false
|
||||
#include <stdio.h> // printf
|
||||
|
||||
// helper function
|
||||
bool isclose(const struct Matrix* a, const struct Matrix* b) {
|
||||
if (a->m != b->m)
|
||||
return false;
|
||||
if (a->n != b->n)
|
||||
return false;
|
||||
for (size_t i = 0; i != a->m; ++i)
|
||||
for (size_t j = 0; j != a->n; ++j)
|
||||
if (!iuenum_isclose(a->data[j + a->n * i], b->data[j + b->n * i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing 'matrix_zeros' for 3x3
|
||||
struct Matrix mat = matrix_zeros(3, 3);
|
||||
double data[3][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
struct Matrix expected = matrix_init(3, 3, &data[0][0]);
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_zeros' for 4x3
|
||||
struct Matrix mat = matrix_zeros(4, 3);
|
||||
double data[4][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
{0, 0, 0},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 3, &data[0][0]);
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_identity' for 3x3
|
||||
|
||||
double data_expected[3][3] = {
|
||||
{1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 0, 1},
|
||||
};
|
||||
struct Matrix expected = matrix_init(3, 3, &data_expected[0][0]);
|
||||
struct Matrix mat = matrix_identity(3);
|
||||
|
||||
// matrix_print(&mat);
|
||||
assert(isclose(&mat, &expected));
|
||||
// matrix_print(&expected);
|
||||
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_identity' for 4x4
|
||||
|
||||
double data_expected[4][4] = {
|
||||
{1, 0, 0, 0},
|
||||
{0, 1, 0, 0},
|
||||
{0, 0, 1, 0},
|
||||
{0, 0, 0, 1},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 4, &data_expected[0][0]);
|
||||
struct Matrix mat = matrix_identity(4);
|
||||
|
||||
// matrix_print(&mat);
|
||||
assert(isclose(&mat, &expected));
|
||||
// matrix_print(&expected);
|
||||
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_transpose' of a 3x3 identity
|
||||
|
||||
struct Matrix mat = matrix_identity(3);
|
||||
|
||||
double data_expected[3][3] = {
|
||||
{1, 0, 0},
|
||||
{0, 1, 0},
|
||||
{0, 0, 1},
|
||||
};
|
||||
struct Matrix expected = matrix_init(3, 3, &data_expected[0][0]);
|
||||
|
||||
// matrix_print(&mat);
|
||||
matrix_transpose(&mat);
|
||||
// matrix_print(&mat);
|
||||
// matrix_print(&expected);
|
||||
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_transpose' for 4x2
|
||||
|
||||
double data[4][2] = {
|
||||
{11, 12},
|
||||
{21, 22},
|
||||
{31, 32},
|
||||
{41, 42},
|
||||
};
|
||||
struct Matrix mat = matrix_init(4, 2, &data[0][0]);
|
||||
|
||||
double data_expected[2][4] = {
|
||||
{11, 21, 31, 41},
|
||||
{12, 22, 32, 42},
|
||||
};
|
||||
struct Matrix expected = matrix_init(2, 4, &data_expected[0][0]);
|
||||
|
||||
// matrix_print(&mat);
|
||||
matrix_transpose(&mat);
|
||||
// matrix_print(&mat);
|
||||
// matrix_print(&expected);
|
||||
|
||||
assert(isclose(&mat, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
}
|
||||
|
||||
{ // testing 'matrix_mult' using a left multiplty with a row permuting matrix
|
||||
|
||||
double data[4][2] = {
|
||||
{11, 12},
|
||||
{21, 22},
|
||||
{31, 32},
|
||||
{41, 42},
|
||||
};
|
||||
struct Matrix mat = matrix_init(4, 2, &data[0][0]);
|
||||
|
||||
double data_permute[4][4] = {
|
||||
{0, 0, 0, 1},
|
||||
{0, 0, 1, 0},
|
||||
{0, 1, 0, 0},
|
||||
{1, 0, 0, 0},
|
||||
};
|
||||
struct Matrix permute = matrix_init(4, 4, &data_permute[0][0]);
|
||||
|
||||
double data_expected[4][2] = {
|
||||
{41, 42},
|
||||
{31, 32},
|
||||
{21, 22},
|
||||
{11, 12},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 2, &data_expected[0][0]);
|
||||
|
||||
struct Matrix product = matrix_zeros(permute.m, mat.n);
|
||||
|
||||
// matrix_print(&permute);
|
||||
// matrix_print(&mat);
|
||||
matrix_mult(&permute, &mat, &product); // left multiply with permuation matrix
|
||||
// matrix_print(&product);
|
||||
|
||||
assert(isclose(&product, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
matrix_clear(&permute);
|
||||
matrix_clear(&product);
|
||||
}
|
||||
|
||||
|
||||
{ // testing 'matrix_mult' using a right multiplty with a column permuting matrix
|
||||
|
||||
double data[4][2] = {
|
||||
{11, 12},
|
||||
{21, 22},
|
||||
{31, 32},
|
||||
{41, 42},
|
||||
};
|
||||
struct Matrix mat = matrix_init(4, 2, &data[0][0]);
|
||||
|
||||
double data_permute[2][2] = {
|
||||
{0, 1},
|
||||
{1, 0},
|
||||
};
|
||||
struct Matrix permute = matrix_init(2, 2, &data_permute[0][0]);
|
||||
|
||||
double data_expected[4][2] = {
|
||||
{12, 11},
|
||||
{22, 21},
|
||||
{32, 31},
|
||||
{42, 41},
|
||||
};
|
||||
struct Matrix expected = matrix_init(4, 2, &data_expected[0][0]);
|
||||
|
||||
struct Matrix product = matrix_zeros(mat.m, permute.n);
|
||||
|
||||
// matrix_print(&permute);
|
||||
// matrix_print(&mat);
|
||||
matrix_mult(&mat, &permute, &product); // right multiply with permuation matrix
|
||||
// matrix_print(&product);
|
||||
|
||||
assert(isclose(&product, &expected));
|
||||
matrix_clear(&mat);
|
||||
matrix_clear(&expected);
|
||||
matrix_clear(&permute);
|
||||
matrix_clear(&product);
|
||||
}
|
||||
|
||||
printf("task2.test.c: all asserts passed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "task3.h" // task3_count_inside, task3_common_bbox
|
||||
#include "task2.h" // struct Vec2d, struct BBox, struct Circle
|
||||
#include <stdbool.h> // for bool (true/false)
|
||||
|
||||
/// @brief Count the number of Circles fully contained inside a bounding box
|
||||
/// @param box Bounding box
|
||||
/// @param circles Array of Circles
|
||||
/// @param size Length of the 'circles' array
|
||||
/// @return Number of circles fully contained inside 'box'
|
||||
unsigned int task3_count_inside(const struct BBox* box, const struct Circle circles[], unsigned int size) {
|
||||
unsigned int count = 0;
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
const struct Circle* circle = &circles[i];
|
||||
// Check if circle center is within box boundaries
|
||||
bool inside_x = (circle->c.x - circle->r >= box->min.x) && (circle->c.x + circle->r <= box->max.x);
|
||||
bool inside_y = (circle->c.y - circle->r >= box->min.y) && (circle->c.y + circle->r <= box->max.y);
|
||||
if (inside_x && inside_y) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// @brief Generates the smallest bounding box containing a sequence of circles
|
||||
/// @param circles Array of Circles
|
||||
/// @param size Length of the 'circles' array (Assertion: size >= 1)
|
||||
/// @return Smallest bounding box containing all circles
|
||||
struct BBox task3_common_bbox(const struct Circle circles[], unsigned int size) {
|
||||
struct BBox res;
|
||||
// Initialize with first circle's data (assuming at least one circle)
|
||||
res.min.x = circles[0].c.x - circles[0].r;
|
||||
res.min.y = circles[0].c.y - circles[0].r;
|
||||
res.max.x = circles[0].c.x + circles[0].r;
|
||||
res.max.y = circles[0].c.y + circles[0].r;
|
||||
|
||||
for (unsigned int i = 1; i < size; i++) {
|
||||
const struct Circle* circle = &circles[i];
|
||||
// Update minimum bounds if circle's center falls outside current box
|
||||
if (circle->c.x - circle->r < res.min.x) {
|
||||
res.min.x = circle->c.x - circle->r;
|
||||
}
|
||||
if (circle->c.y - circle->r < res.min.y) {
|
||||
res.min.y = circle->c.y - circle->r;
|
||||
}
|
||||
// Update maximum bounds if circle's edge falls outside current box
|
||||
if (circle->c.x + circle->r > res.max.x) {
|
||||
res.max.x = circle->c.x + circle->r;
|
||||
}
|
||||
if (circle->c.y + circle->r > res.max.y) {
|
||||
res.max.y = circle->c.y + circle->r;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/// @file
|
||||
/// @brief Task3: structure and function declarations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "task2.h" // struct Vec2d, struct BBox, struct Circle
|
||||
|
||||
/// @brief Count the number of Circles fully contained inside a bounding box
|
||||
/// @param box Bounding box
|
||||
/// @param circles Array of Circles
|
||||
/// @param size Length of the 'circles' array
|
||||
/// @return Number of circles fully contained inside 'box'
|
||||
unsigned int task3_count_inside(const struct BBox* box, const struct Circle circles[], unsigned int size);
|
||||
|
||||
/// @brief Generates the smallest bounding box containing a sequence of circles
|
||||
/// @param circles Array of Circles
|
||||
/// @param size Length of the 'circles' array (Assertion: size >= 1)
|
||||
/// @return Smallest bounding box containing all circles
|
||||
struct BBox task3_common_bbox(const struct Circle circles[], unsigned int size);
|
||||
@@ -0,0 +1,68 @@
|
||||
/// @file
|
||||
/// @brief Task3: tests
|
||||
|
||||
#include "task3.h" // task3_count_inside, task3_common_bbox
|
||||
#include "task2.h" // struct Vec2d, struct BBox, struct Cirlce
|
||||
|
||||
#include "iue-num/numerics.h" // iuenum_isclose
|
||||
|
||||
#include <assert.h> // assert
|
||||
#include <stdio.h> // printf
|
||||
|
||||
bool detail_isclose_vec2d(struct Vec2d a, struct Vec2d b) {
|
||||
if (!iuenum_isclose(a.x, b.x))
|
||||
return false;
|
||||
if (!iuenum_isclose(a.y, b.y))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool detail_isclose_bbox(const struct BBox* a, const struct BBox* b) {
|
||||
if (!detail_isclose_vec2d(a->min, b->min))
|
||||
return false;
|
||||
if (!detail_isclose_vec2d(a->max, b->max))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
{ // testing 'task3_count_inside'
|
||||
struct Vec2d min = {-1.6, -0.6};
|
||||
struct Vec2d max = {3.6, 2.6};
|
||||
struct BBox box = {min, max};
|
||||
|
||||
struct Circle c1 = {{0.0, 1.0}, 1.5};
|
||||
struct Circle c2 = {{1.0, 1.0}, 1.5};
|
||||
struct Circle c3 = {{2.0, 1.0}, 1.5};
|
||||
struct Circle c4 = {{3.0, 1.0}, 1.5};
|
||||
struct Circle c5 = {{4.0, 1.0}, 1.5};
|
||||
|
||||
struct Circle circles[5] = {c1, c2, c3, c4, c5};
|
||||
|
||||
unsigned int res = task3_count_inside(&box, circles, 5);
|
||||
|
||||
assert(res == 3);
|
||||
}
|
||||
|
||||
{ // testing 'task3_common_bbox'
|
||||
|
||||
struct Circle c1 = {{0.0, 1.0}, 1.5};
|
||||
struct Circle c2 = {{1.0, 1.0}, 1.5};
|
||||
struct Circle c3 = {{2.0, 1.0}, 1.5};
|
||||
|
||||
struct Circle circles[3] = {c1, c2, c3};
|
||||
|
||||
struct BBox res = task3_common_bbox(circles, 3);
|
||||
|
||||
struct Vec2d exp_min = {-1.5, -0.5};
|
||||
struct Vec2d exp_max = {3.5, 2.5};
|
||||
struct BBox exp_box = {exp_min, exp_max};
|
||||
|
||||
assert(detail_isclose_bbox(&res,&exp_box));
|
||||
}
|
||||
|
||||
printf("task3.test.c: all asserts passed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user