Commit 956f7011 authored by Autopawn's avatar Autopawn

Added vectorsum activity.

parent 79ef6d90
---
marp: true
size: 4:3
number: true
paginate: true
theme: default
style: |
img[alt~="center"]{display:block;margin: 0 auto;}
---
# :soccer: Actividad
:arrow_right: Programar el TDA `vectorsum`, consistente en un arreglo de tamaño dinámico que siempre mantenga almacenada la suma de los elementos para obtenerla rápidamente.
Debe contar con las siguientes operaciones:
* Obtener un elemento en una posición dada.
* Agregar un elemento al final.
* Modificar un elemento en una posición dada.
* Obtener la suma de los elementos, en $O(1)$.
---
:warning: **Try to do it yourself first**.
:cheese: **Hint 1**:
```c
typedef struct {
int len; // number of stored items
int size; // maximum capacity before reallocation
item *items; // pointer to an array with the items
item sum; // precomputed sum
} vectorsum;
```
:cheese: **Hint 2**: [vectorsum.h](activities/vectorsum.h)
:cheese: **Hint 3**: [vectorsum.c](activities/vectorsum.c)
---
## El problema del acceso a los miembros
:arrow_forward: Notemos que hay miembros a los que es conveniente acceder directamente para lectura, como `len` y `sum`.
:arrow_forward: Sin embargo, una **modificación** directa de los miembros puede dejar nuestra estructura en un estado **inconsistente**.
:soccer: Puede dar ejemplos de modifcaciones que resultan en estados inconsistentes:question:
---
## El problema de copiar
:arrow_forward: Notemos que copiar un `vectorsum` no es trivial, creemos uno:
```c
vectorsum *vec1 = vectorsum_init();
vectorsum_append(vec1,10);
vectorsum_append(vec1,20);
vectorsum_append(vec1,30);
```
![w:700px](figures/vectorsum_copy0.png)
---
### Copia 1:
```c
vectorsum *vec2 = vec1;
```
:arrow_forward: `vec2` será una referencia al mismo vectorsum.
![w:700px](figures/vectorsum_copy1.png)
---
### Copia 2:
```c
vectorsum *vec2 = malloc(sizeof(vectorsum));
vec2 = *vec1;
```
:arrow_forward: `vec2` compartirá el arreglo de items :skull:
![w:700px](figures/vectorsum_copy2.png)
---
### Copia 3:
```c
vectorsum *vectorsum_clone(const vectorsum *original){
assert(original);
vectorsum *vec = vectorsum_init();
for(int i=0;i<vectorsum_len(original);i++){
vectorsum_append(vec,vectorsum_get(vec,i));
}
return vec;
}
```
```c
vectorsum *vec2 = vectorsum_clone(vec1);
```
---
![w:700px](figures/vectorsum_copy3.png)
\ No newline at end of file
build
\ No newline at end of file
build:
compile:
mkdir -p build
gcc -c automata.c
gcc -c draw.c
gcc -c main.c
gcc automata.o draw.o main.o -o automata
\ No newline at end of file
gcc automata.o draw.o main.o -o automata
mv *.o automata build
\ No newline at end of file
......@@ -7,9 +7,9 @@
int main(int argc, char const *argv[]){
srand(time(NULL));
board bo = board_init();
while(1){
for(int i=0; i<100;i++){
board_print(&bo);
usleep(1000000);
usleep(400000);
board_step(&bo);
}
return 0;
......
build
\ No newline at end of file
compile:
mkdir -p build
gcc vectorsum.c test.c -o build/vectorsum
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include "vectorsum.h"
// A function to print a vectorsum
void vectorsum_print(const vectorsum *vec){
for(int i=0;i<vectorsum_len(vec);i++){
printf("%5.1f ",vectorsum_get(vec,i));
}
printf("(sum: %5.1f)\n",vectorsum_sum(vec));
}
int main(int argc, char const *argv[]){
vectorsum *vec = vectorsum_init();
// Insert random numbers
for(int k=0;k<10;k++){
float val = (rand()%20)/2.0;
vectorsum_append(vec,val);
}
vectorsum_print(vec);
// Delete some elements at random
for(int k=0;k<3;k++){
int pos = rand()%vectorsum_len(vec);
vectorsum_del(vec,pos);
}
vectorsum_print(vec);
// Change some elements at random
for(int k=0;k<3;k++){
int pos = rand()%vectorsum_len(vec);
float val = 100+vectorsum_get(vec,pos);
vectorsum_set(vec,pos,val);
}
vectorsum_print(vec);
return 0;
}
#include "vectorsum.h"
vectorsum *vectorsum_init(){
vectorsum *vec = malloc(sizeof(vectorsum));
vec->len = 0;
vec->size = INITIAL_SIZE;
vec->items = malloc(sizeof(item)*vec->size);
vec->sum = 0;
}
void vectorsum_free(vectorsum *vec){
assert(vec);
free(vec->items);
free(vec);
}
int vectorsum_len(const vectorsum *vec){
assert(vec);
return vec->len;
}
item vectorsum_get(const vectorsum *vec, int i){
assert(vec);
assert(0<=i && i<vec->len);
return vec->items[i];
}
item vectorsum_sum(const vectorsum *vec){
assert(vec);
return vec->sum;
}
void vectorsum_set(vectorsum *vec, int i, item val){
assert(vec);
assert(0<=i && i<vec->len);
// Update sum
vec->sum += val - vec->items[i];
// Replace item
vec->items[i] = val;
}
void vectorsum_append(vectorsum *vec, item val){
assert(vec);
// If there is not enough memory reserved, ask for more
if(vec->len==vec->size){
vec->size *= 2;
vec->items = realloc(vec->items, sizeof(item)*vec->size);
assert(vec->items);
}
// Add the new element
vec->items[vec->len] = val;
vec->len += 1;
vec->sum += val;
}
void vectorsum_del(vectorsum *vec, int i){
assert(vec);
assert(0<=i && i<vec->len);
// Decrease the sum
vec->sum -= vec->items[i];
// Move next items to the previous position
for(int k=i;k<vec->len-1;k++){
vec->items[k] = vec->items[k+1];
}
vec->len -= 1;
}
vectorsum *vectorsum_clone(const vectorsum *original){
assert(original);
vectorsum *vec = vectorsum_init();
for(int i=0;i<vectorsum_len(original);i++){
vectorsum_append(vec,vectorsum_get(vec,i));
}
return vec;
}
// An efficient (but less safe) alternative to the previous one:
vectorsum *vectorsum_clone_fast(const vectorsum *original){
assert(original);
vectorsum *vec = malloc(sizeof(vectorsum));
vec->len = original->len;
vec->size = original->size;
vec->sum = original->sum;
vec->items = malloc(sizeof(item)*vec->size);
for(int i=0;i<original->sum;i++){
vec->items[i] = original->items[i];
}
}
\ No newline at end of file
#ifndef VECTORSUM_H
#define VECTORSUM_H
#include <stdlib.h>
#include <assert.h>
#define INITIAL_SIZE 2
typedef float item;
typedef struct {
int len; // number of stored items (public?)
int size; // maximum capacity before reallocation
item *items;
item sum;
} vectorsum;
// Initializes an empty vectorsum, allocating memory for it
vectorsum *vectorsum_init();
// Deletes a vectorsum, liberating its memory
void vectorsum_free(vectorsum *vec);
// Gets the number of elements of the vectorsum
int vectorsum_len(const vectorsum *vec);
// Retrieves an element from the vectorsum at the given position
item vectorsum_get(const vectorsum *vec, int i);
// Gets the stored sum of the vectorsum
item vectorsum_sum(const vectorsum *vec);
// Sets an element with the given value at the given position, returns 0 on failure.
void vectorsum_set(vectorsum *vec, int i, item val);
// Adds an element at the end of the vector
void vectorsum_append(vectorsum *vec, item val);
// Deletes an element at the given position
void vectorsum_del(vectorsum *vec, int i);
// OPTIONAL Initializes a vectorsum as a copy of another
vectorsum *vectorsum_clone(const vectorsum *original);
#endif
\ No newline at end of file
<mxfile host="www.draw.io" modified="2019-10-07T06:04:38.033Z" agent="Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0" etag="7d0jzvABSQmaVNB3w-OW" version="12.0.2" type="device" pages="1"><diagram id="47TQY3FRNxbV0jGJ7nrk" name="Page-1">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</diagram></mxfile>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment