Skip to content

Commit

Permalink
add first homework
Browse files Browse the repository at this point in the history
  • Loading branch information
nmheim committed Feb 19, 2024
1 parent beb2150 commit 535d522
Show file tree
Hide file tree
Showing 8 changed files with 331 additions and 5 deletions.
10 changes: 8 additions & 2 deletions .vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default defineConfig({
{ text: 'Organization', link: '/organization' },
{ text: 'Lectures', link: '/lectures/' },
{ text: 'Labs', link: '/labs/' },
{ text: 'Homeworks', link: '/homeworks' },
{ text: 'Homeworks', link: '/homeworks/' },
{ text: 'Exams', link: '/exams/' },
],

Expand All @@ -39,7 +39,13 @@ export default defineConfig({
]
},

{ text: 'Homeworks', link: '/homeworks' },
{
text: 'Homeworks',
link: '/homeworks/',
items: [
{ text: '01: ASCII Art', link: '/homeworks/hw01' },
]
},



Expand Down
27 changes: 27 additions & 0 deletions homeworks/blocks.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

\documentclass[border=0pt]{standalone}
\usepackage{graphicx}
\usepackage{fancyvrb}
\usepackage{xcolor}
\usepackage{bm}
\usepackage{pgf}
\usepackage{tikz}
\usepackage[vlined,algoruled,linesnumbered]{algorithm2e}


\definecolor{myGray}{rgb}{0.85,0.85,0.85}

\begin{document}

\begin{tikzpicture}
\draw[fill=red,opacity=0.5] (5,0) rectangle (5.2,-5.2);
\draw[fill=red,opacity=0.5] (0,-4.8) rectangle (5,-5.2);
\draw[xstep=0.5,ystep=0.8] (0,0) grid (5.4,-5.5);
\draw[thick] (0,0) rectangle (5.2,-5.2);
\node at (0.25, -0.4) {\Verb|@|};
\node at (0.75, -0.4) {\Verb|x|};
\node at (0.25, -1.2) {\Verb|;|};
\end{tikzpicture}


\end{document}
259 changes: 259 additions & 0 deletions homeworks/hw01.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
# ASCII Art - Homework Assignment 01


This homework assignment aims to practice applications of higher-order functions for processing
lists of elements. You are supposed to implement a function generating an ASCII art from input
images following the [specification](#specification). Examples of such a
transformation are depicted in the figures below.


<div style="display: flex;">
<div style="width: 51%; border: 0px solid black; padding: 20px 0;">
<img src="/img/grad.png" style="width: 50%; padding: 20px 0; margin-left: auto; margin-right: auto;" />
</div>

<div style="width: 35%; border: 0px solid black; line-height: 1px">

<div class="language-">
<pre class="vp-code" style="background: var(--vp-c-bg)">
<code style="line-height: 1">
<span class="line"><span> ;;;::::,,,,... </span></span>
<span class="line"><span> o;;;;::::,,,.... </span></span>
<span class="line"><span> ooo;;;;:::,,,,.... </span></span>
<span class="line"><span> xoooo;;;::::,,,.... </span></span>
<span class="line"><span> xxoooo;;;;:::,,,,... </span></span>
<span class="line"><span> xxxxoooo;;;::::,,,,. </span></span>
<span class="line"><span> %%xxxxooo;;;;::::,,, </span></span>
<span class="line"><span> %%%%xxxoooo;;;;:::,, </span></span>
<span class="line"><span> ##%%%xxxxoooo;;;:::: </span></span>
<span class="line"><span> ###%%%%xxxoooo;;;;:: </span></span>
<span class="line"><span> @####%%%xxxxoooo;;;: </span></span>
<span class="line"><span> @@@###%%%%xxxxooo;;; </span></span>
</code>
</pre>
</div>

</div>
</div>
Example of a gradient image (left) and its transformation (right).


<div style="display: flex;">

<div style="width: 51%; border: 0px solid black; padding: 20px 0;">
<img src="/img/oko.png" style="padding: 20px 0; margin-left: auto; margin-right: auto;" />
</div>

<div class="language-" style="overflow-x: initial; width: 50%">
<pre class="vp-code" style="font-size: 0.4em; overflow-x: initial; background: var(--vp-c-bg)">
<code style="line-height: 1">
<span class="line"><span>::::::;;;;;;;;;;;;;;;;;oooooooxxxxx%%%%%%%%%%############%%%%%%%xxxxxxxxxxooooo;;;;;;:::::,,,,,,. </span></span>
<span class="line"><span>::::;;;;;;;;;;;;;;;;;oooooooxxx%%%%###############%%###%%%%%%%%#%%%%%%xxxxxxoooooo;;;;;:::,,,,,,. </span></span>
<span class="line"><span>::;;;;;;;;;;;;;;;;;;oooooxxx%%######%%%%#######%%%%%%%xxxx%x%%%%%%%%%%%%%xxxxxxooooo;;;;::::,,,,, </span></span>
<span class="line"><span>:;;;;;;;;;;;;;;;;;ooooxxx%%%#######%%%###############%%%%%%xoxooooxxxxx%%%%%xxxxxoooooo;;::::,,,, </span></span>
<span class="line"><span>;;;;;;;;;;;;;;;;;oooxx%%%##################################%xxxxxo;:::;oxxxxx%%%xxxxxooo;;;;::::, </span></span>
<span class="line"><span>;;;;;;;;;;;;;;;ooox%%%###################################%%%%%xxxoxoooxo;::;ooxx%%xxxxoooo;;;:::: </span></span>
<span class="line"><span>;;;;;;;;;;;;;ooox%%%%%%###################%###############%#%xxxxxxoxooo:;;:,,,;oxx%%xxxoooo;;;:: </span></span>
<span class="line"><span>;;;;;;;;;;;ooox%%%%%%%%###%%####%%%%%%%%%%%###%%%%%%%%%%%%##%%%%%%xoooooxooo;;;;o;ooxxxxxooooo;;: </span></span>
<span class="line"><span>;;;;;;;;;;oox%%%%%%%%%%##%%%%%%%x%%%%############%%%%xxoooxx%%%%%xxxxx%xxxxxxxo::,.,:;xxxxxooo;;; </span></span>
<span class="line"><span>;;;;;;;;ooox%%xx%%%%%%%%%%%%xxxx%%###%#############%%%%xo;;;;;ooxx%%xxx%x%xxoooo;:,,:;oxxxxoooo;; </span></span>
<span class="line"><span>;;;;;;;ooxxxxxxxxxx%%%%%%xxxxx%###%%%%%%%%%%%%%######%%%xo;:,,,,::;ox%%xxxxxxxxooo;:,,,:;oxxooo;; </span></span>
<span class="line"><span>;;;;;;ooooxxxxxxx%%%%%%xxxxxx%##%%%%%%xxx%xx%x%%%%%%%%%#%xo;,... .,,;oxxxxxxooo;ooxo;oo;;ooooo;;: </span></span>
<span class="line"><span>::::;;;;ooooxxxx%%%%%xxxxxx%###%%xxxx%xooxxxxxx%xxx%%%%%%%%x;. .,,;oxxxxxxxoo;;;xooooo;;;;;; </span></span>
<span class="line"><span>::::::;;;ooxxox%%%%%xxxxox%##%xxxxxxxxxxxx%%x%%%xxxxxx%%%%xx:: ,:;oxxoxoxxxxox%xo:;;;;;;; </span></span>
<span class="line"><span>,,,,:::;;ooxx%%%%%%xxxxoox%#xxxxxxooxxx%#######%%%%%xoxx%%;,. . .,:ooxooooo;::;;;;:::;::: </span></span>
<span class="line"><span>,,,,:::;ox%%#%%%%%xxxxoox%#%xooxxo;ox%%@@@@@@@@@#%%%%oox;. . ..,;ooooo;;;;::::::;::;: </span></span>
<span class="line"><span>.,,,::;o%%%%%%%%%xxxxxoox#%xo;oo;;ox%@@@@@@@@@@@@@#%%x:: ,,, .,:;oo;;;;;;;;:,,,,,,, </span></span>
<span class="line"><span>..,,,;%%%%%%%%%%xxxxxooo%%xoo;xo;;x%@@@@@@@@@@@@@@@%x.., :xo, .,:;;;;::::::::::,,,, </span></span>
<span class="line"><span>...,:x%%%%%%%%%%xxxxooox%%xooooo;;x#@@@@@@@@@@@@@@@#x;.:;,:;;x%%;. .,:;:::,,,,,,:::::: </span></span>
<span class="line"><span> ..,oo%%x%%%%%%%xxxxoooo%%xo;;;;:ox#@@@@@@@@@@@@@@@#%xxoxooxox%%o. .,:,,,,,,,,,,,,,,, </span></span>
<span class="line"><span> ,:;oxx%%%%%%xxxxooooox%%;::::,:o%@@@@@@@@@@@@@@@##xoxx%x%x%%%x. ..... ........... </span></span>
<span class="line"><span> .::;o:o%%%%%%xxxooo;ox%xo::::::o%@@@@@@@@@@@@@@#%%xooxxxxox%%o. .. ......... </span></span>
<span class="line"><span> ..,:oo;x%%%%%xxxxooo;o%%o::,:,,;o%@@@@@@@@@@@@##%xxooxxxx%%%%: .. ....... </span></span>
<span class="line"><span> ...,:ox%%%%%%%xxxxoo;oxxx:::;:,:ox%#@@@@@@@@@##%%oooxxxxx%%%x. ... .. </span></span>
<span class="line"><span>........,,:o%%%%%%%xxxoo;o%%o;,,;::;oox%%######%%xxoo;oxx%xx%%%, ... </span></span>
<span class="line"><span>,...,.....,,:;oxxxxxxxxooox%%;;;:;::;;ooxxxxx%%xooooxoxxxxx%%%: .... </span></span>
<span class="line"><span>::,,,,,,,,,,,:::;;oooxxoooox%%xo;::;:::;;;ooooooo;ooxoxx%%%%%:. .... </span></span>
<span class="line"><span>:::::::::::,,::::;;:::;;oooox%%xo;:;;;;oo%oooooooox%ooxox%%x:. ...... </span></span>
<span class="line"><span>::;;;;;;;;;::::::::::::::::;;ox%xx::;;;xxxxxxxxxoooooxx%%x;,. ....... </span></span>
<span class="line"><span>::;;;;;;;;;;;;;;;;;;:::::::::::;oxxxooooxxxxxx%xxox%%%xx;,. .......... </span></span>
<span class="line"><span>::;;;;ooooooooooo;;;;;;;::::::::::::;xx%%%%xox%x%%%%xo;:,......,,........ . .. </span></span>
<span class="line"><span>,::;;o;ooooooooooooooo;;;;;:::::::::,,,,:;;oooooxoo;;:,,,,,,..,,,,,,,,,...,. ., </span></span>
<span class="line"><span>,:::;;;;oooooooooxxoooooo;;;;;;::::,,,::,,,,,,,,,,,,:,:::,:,:,,,,,,.... . .. , </span></span>
<span class="line"><span>,,:::;;;ooooxxxxooxxxxooooooo;;;;:::::::::,,,,,,:,,,,,:,,,,:,,,,:...,. .... </span></span>
<span class="line"><span>,,,:::;;;;oooxxxxxxxxxxxooooooo;;;;;;;:::::,,:,,:::,::,,,::,::,,,,,..... . </span></span>
<span class="line"><span>.,,:::;;;;;oooxxxxxxooxxxxxoooooo;;o;;;;:;;::::::::,:::::,::,,,::,,,.,.. . </span></span>
<span class="line"><span>..,,:::;;;;;oooooxxxooooxxxxxxooooooo;;;;;;;;;:;;;::::::::,,,,..,,.. ... .. </span></span>
<span class="line"><span>...,,:::::;;;;;ooooooooooooooxxooooooo;;;;;;;;;;;;;:::::::,,,,,,,........ . . </span></span>
<span class="line"><span>...,,,,:::;;;;;;ooooooooooooooooxxoooooo;;;;;;;;;::::::;:,,,,,,,,....... </span></span>
</code>
</pre>
</div>
</div>



## Specification

The implementation has to be done in the programming language `racket`. In order to work with
images, it has to import the library `2htdp/image`.

::: warning Important:
All your code is required to be in a single
file called `hw1.rkt`. The file should behave as a module providing two functions
`img->mat` and `ascii-art`. Thus your file should start with the following lines:


```scheme
#lang racket
(require 2htdp/image)
(provide img->mat ascii-art)
```
:::

To test your implementation you need to work with images. The images can be either loaded from a
file for example as follows:

```scheme
(define img (bitmap "grad.png"))
```

or can be created by the function provided by the library `2htdp/image`. For instance
```scheme
(define img (circle 20 "solid" "blue"))
```
defines a blue disc of radius 20. For further details see:
https://docs.racket-lang.org/teachpack/2htdpimage.html


## Functions to be implemented

The first function `(img->mat img)` is a helper function transforming color images into matrices of
intensities. To do that you need a couple of functions. First, the function `(image-width img)`
returns the width of the image in pixels.

Second, the function `(image->color-list img)` transforms the image into a list of pixels colors,
reading from left to right, top to bottom. For instance,
```scheme
(define img (triangle 5 "solid" "violet"))
> (image->color-list img)
(#(struct:color 255 255 255 0)
#(struct:color 255 255 255 1)
#(struct:color 238 130 238 149)
#(struct:color 255 128 255 2)
#(struct:color 255 255 255 0)
...
)
```
The colors should be converted into a grayscale intensity by the following function:
```scheme
(define (RGB->grayscale color)
(+ (* 0.3 (color-red color))
(* 0.59 (color-green color))
(* 0.11 (color-blue color))))
```
Now applying the function `RGB->grayscale` to the list of colors, we get a list of intesities:
```scheme
> (map RGB->grayscale (image->color-list img))
(255.0 255.0 174.28 180.07 255.0 255.0 174.69 174.28 174.1 255.0
171.46 174.28 174.28 174.28 172.69 174.28 174.28 174.28 174.28 173.69)
```


The function `img->mat` should return a matrix of intensities. So your task is to take the above list of intensities and transform
it into a matrix, i.e., a list of rows where each row represents a horizontal line of pixels in the image. As the width of the above triangle image is 5, the output should look like
```scheme
> (img->mat img)
((255.0 255.0 174.28 180.07 255.0)
(255.0 174.69 174.28 174.1 255.0)
(171.46 174.28 174.28 174.28 172.69)
(174.28 174.28 174.28 174.28 173.69))
```

As a second function, you are supposed to implement the function
```scheme
(ascii-art width height chars)
```
returning a function of a single argument `img`. The returned function takes an image
`img` and transforms it into a string approximating the input image. Thus the function is going
to be called e.g. as follows:
```scheme
(define chars " .,:;ox%#@")
((ascii-art 5 8 chars) (bitmap "grad.png"))
```
`chars` argument is a string of characters we want to use to approximate intervals of intensities.
Let $d$ be the length of `chars`.
An intensity $i$ should be represented by a character whose index $k$ in `chars` is computed by
the __*index formula*__:
$$
k=\left \lfloor{\frac{d(255-\lfloor{i}\rfloor)}{256}}\right \rfloor
$$
The notation $\lfloor{x}\rfloor$ denotes the maximum integer number below $x$, which can be computed
in racket by the function `floor`. Thus for the highest intensity $255$, we have $k=0$, and for
the lowest intensity $0$, we have $k=d-1$. The reason there is the inner floor function
$\lfloor{i}\rfloor$ is that $i$ might be slightly larger than $255$ due to rounding errors.

The function returned by `ascii-art` should split the matrix of intensities into blocks. The size of
blocks is given by the arguments `width` and `height` The separation of the matrix into blocks is
depicted in Figure~\ref{fig:separation}. In case the width (resp. height) of the matrix is not
divisible by `width` (resp. `height`) the incomplete blocks have to be removed from the matrix as is
illustrated by the red area in the figure below:

<img src="/img/blocks.svg" style="width: 50%; margin-left: auto; margin-right: auto;" />

Once the matrix is separated into blocks, intensities in each block have to be averaged. The average
intensities are then transformed into the corresponding characters by the index formula,
i.e., applying the function `list-ref` to `chars` and the index computed by
the index formula. Finally, the resulting matrix of characters is transformed into a string composed
of the characters in each row, followed by the newline character `"\n"`.

## Examples

Consider the following simple image composed of four gray rectangles of different intensities. The
function `(make-color r g b)` creates a color object with respective RGB components. The function
`above` places its image arguments on top of each other and analogously `beside` next to each other.
```scheme
(define example
(above
(beside (rectangle 2 1 "solid" (make-color 0 0 0))
(rectangle 3 1 "solid" (make-color 75 75 75)))
(beside (rectangle 2 3 "solid" (make-color 180 180 180))
(rectangle 3 3 "solid" (make-color 225 225 225)))))
```
Evaluating the function `img->mat` on this image results in
```scheme
((0 0 75.0 75.0 75.0)
(180.0 180.0 225.0 225.0 225.0)
(180.0 180.0 225.0 225.0 225.0)
(180.0 180.0 225.0 225.0 225.0))
```
After splitting into blocks of size 2x2 (the last column is omitted as the matrix width is 5)
and computing average intensities we obtain

```scheme
((90.0 150.0) (180.0 225.0))
```
Assuming that our characters approximating intensities are
```scheme
(define chars " .,:;ox%#@")
```
the above intensities are represented by the following characters
```scheme
((#\x #\;)
(#\, #\.))
```
After transforming the above matrix of characters into a string, the function returned by
`ascii-art` produces the following output:
```scheme
((ascii-art 2 2 chars) example) => "x;\n,.\n"
```
To see the result better, you can use the function `display` as follows:
```scheme
> (display ((ascii-art 2 2 chars) example))
x;
,.
```
4 changes: 2 additions & 2 deletions homeworks.md → homeworks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ output. Consult also your local documentation in DrRacket to get more details on

## Racket

### Homework assignment 1
### 01: ASCII Art

::: danger Important
Submit your solution as a zip archive containing a single file with the name **`hw1.rkt`**.
:::

The description of the assignment can be found [here](https://drive.google.com/file/d/1cyfLDtlBvXgthCQU4mM6I3pmUi8ZnNOl/view?usp=sharing).
The description of the assignment can be found [here](hw01).

<!--
/*
Expand Down
Loading

0 comments on commit 535d522

Please sign in to comment.