Browse Source

Transfer of general solutions

main
André Palmborg 5 years ago
parent
commit
073d6abf17
  1. 12
      algorithms-and-datastructures/fenwick/Makefile
  2. 2
      algorithms-and-datastructures/fenwick/a0
  3. 2
      algorithms-and-datastructures/fenwick/a1
  4. 11
      algorithms-and-datastructures/fenwick/a2
  5. 5
      algorithms-and-datastructures/fenwick/d0
  6. 5
      algorithms-and-datastructures/fenwick/d1
  7. 13
      algorithms-and-datastructures/fenwick/d2
  8. 123
      algorithms-and-datastructures/fenwick/main.cpp
  9. 12
      algorithms-and-datastructures/fft/Makefile
  10. 5
      algorithms-and-datastructures/fft/d0
  11. 5
      algorithms-and-datastructures/fft/d1
  12. 9
      algorithms-and-datastructures/fft/d2
  13. 5
      algorithms-and-datastructures/fft/d3
  14. 5
      algorithms-and-datastructures/fft/d4
  15. 5
      algorithms-and-datastructures/fft/d5
  16. 5
      algorithms-and-datastructures/fft/d6
  17. 5
      algorithms-and-datastructures/fft/d8
  18. 196
      algorithms-and-datastructures/fft/main.cpp
  19. 12
      algorithms-and-datastructures/modular-arithmetic/Makefile
  20. 10
      algorithms-and-datastructures/modular-arithmetic/d0
  21. 11
      algorithms-and-datastructures/modular-arithmetic/d1
  22. 3
      algorithms-and-datastructures/modular-arithmetic/d10
  23. 4
      algorithms-and-datastructures/modular-arithmetic/d11
  24. 11
      algorithms-and-datastructures/modular-arithmetic/d12
  25. 1
      algorithms-and-datastructures/modular-arithmetic/d13
  26. 3
      algorithms-and-datastructures/modular-arithmetic/d14
  27. 36
      algorithms-and-datastructures/modular-arithmetic/d2
  28. 23
      algorithms-and-datastructures/modular-arithmetic/d3
  29. 3
      algorithms-and-datastructures/modular-arithmetic/d4
  30. 16
      algorithms-and-datastructures/modular-arithmetic/d5
  31. 16
      algorithms-and-datastructures/modular-arithmetic/d6
  32. 6
      algorithms-and-datastructures/modular-arithmetic/d7
  33. 14
      algorithms-and-datastructures/modular-arithmetic/d8
  34. 4
      algorithms-and-datastructures/modular-arithmetic/d9
  35. 129
      algorithms-and-datastructures/modular-arithmetic/main.cpp
  36. 12
      algorithms-and-datastructures/prime-sieve/Makefile
  37. 7
      algorithms-and-datastructures/prime-sieve/d0
  38. 28
      algorithms-and-datastructures/prime-sieve/d1
  39. 3
      algorithms-and-datastructures/prime-sieve/d2
  40. 3
      algorithms-and-datastructures/prime-sieve/d3
  41. 4
      algorithms-and-datastructures/prime-sieve/d4
  42. 4
      algorithms-and-datastructures/prime-sieve/d5
  43. 113
      algorithms-and-datastructures/prime-sieve/main.cpp
  44. 12
      algorithms-and-datastructures/unionfind/Makefile
  45. 5
      algorithms-and-datastructures/unionfind/d0
  46. 9
      algorithms-and-datastructures/unionfind/d1
  47. 5
      algorithms-and-datastructures/unionfind/d2
  48. 6
      algorithms-and-datastructures/unionfind/d3
  49. 106
      algorithms-and-datastructures/unionfind/main.cpp

12
algorithms-and-datastructures/fenwick/Makefile

@ -0,0 +1,12 @@
EXECUTABLE=a.out
CC=g++
CFLAGS=-g -lm -O2 -std=c++17 -Wall -Wextra
OBJ=main.cpp
$(EXECUTABLE): $(OBJ)
$(CC) $(CFLAGS) -o $@ -static $(OBJ)
.PHONY: clean
clean:
rm -rf $(EXECUTABLE)

2
algorithms-and-datastructures/fenwick/a0

@ -0,0 +1,2 @@
23
40

2
algorithms-and-datastructures/fenwick/a1

@ -0,0 +1,2 @@
0
-42

11
algorithms-and-datastructures/fenwick/a2

@ -0,0 +1,11 @@
0
0
0
0
0
1
1
1
1
1
1

5
algorithms-and-datastructures/fenwick/d0

@ -0,0 +1,5 @@
10 4
+ 7 23
? 8
+ 3 17
? 8

5
algorithms-and-datastructures/fenwick/d1

@ -0,0 +1,5 @@
5 4
+ 0 -43
+ 4 1
? 0
? 5

13
algorithms-and-datastructures/fenwick/d2

@ -0,0 +1,13 @@
16 12
+ 8 1
? 4
? 5
? 6
? 7
? 8
? 9
? 10
? 11
? 12
? 13
? 14

123
algorithms-and-datastructures/fenwick/main.cpp

@ -0,0 +1,123 @@
/*
* Author: André Palmborg
*
* Course: TDDD95
* Task: 1.5: Fenwick
*/
#include <stdio.h>
#include <stdlib.h>
// Fenwick Tree
//
// Stores partial cumulative sums of a value array in a binary indexed tree:
//
// 0
// |---------------8
// |-------4 |---------12
// |---2 |---6 |---10 |-----14
// |-1 |-3 |-5 |-7 |-9 |--11 |--13 |--15
//
// Position 8 stores the sum from 0 to 8.
// So to calculate the sum from 0 to 13 only the partial sums at
// position 8, 12 and 13 need to be accessed.
template<typename T>
struct Fenwick_Tree
{
T* tree;
size_t size;
Fenwick_Tree(size_t N)
{
tree = (T*) malloc(N * sizeof(T));
size = N;
for (size_t i = 0; i < size; i++)
{
tree[i] = 0;
}
};
~Fenwick_Tree()
{
delete[] tree;
};
// Add &d to hypothetical value array at index &i
void add(long int i, T d)
{
while (i <= (long int)size)
{
tree[i] += d;
if (i == 0)
i++;
else
i += ((i) & -(i)); // Add least sig. bit
}
};
// Base sum function
T _sum(long int i)
{
T sum = 0;
while (i > 0)
{
sum += tree[i];
i -= ((i) & -(i)); // Remove least sig. bit
}
return sum;
};
// Sums the range [l,r]
T sumRange(long int l, long int r)
{
return _sum(r) - _sum(l-1);
};
// Sums the range [0,r) non inclusive on right side
T sumUpTo(long int i)
{
if (i == 0)
return 0;
else if (i == 1)
return tree[0];
else
return _sum(i-1);
};
// Debug for prints
T get(size_t i)
{
return tree[i];
};
};
int main()
{
unsigned N, Q;
scanf("%u %u ", &N, &Q);
Fenwick_Tree<long int> t(N);
char op;
unsigned i;
long int d, s;
while (0 < Q--)
{
scanf("%c ", &op);
if (op == '+')
{
scanf("%u %ld ", &i, &d);
t.add(i, d);
}
else if (op == '?')
{
scanf("%u ", &i);
s = t.sumUpTo(i);
printf("%ld\n", s);
}
else
puts("Throws exception... Lazily");
}
}

12
algorithms-and-datastructures/fft/Makefile

@ -0,0 +1,12 @@
EXECUTABLE=a.out
CC=g++
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra
OBJ=main.cpp
$(EXECUTABLE): $(OBJ)
$(CC) $(CFLAGS) -o $@ -static $(OBJ)
.PHONY: clean
clean:
rm -rf $(EXECUTABLE)

5
algorithms-and-datastructures/fft/d0

@ -0,0 +1,5 @@
1
2
1 0 5
1
0 -2

5
algorithms-and-datastructures/fft/d1

@ -0,0 +1,5 @@
1
6
1 1 1 1 1 1 2
2
0 0 1

9
algorithms-and-datastructures/fft/d2

@ -0,0 +1,9 @@
2
2
1 0 5
1
0 -2
4
1 1 -1 1 1
4
9 -8 7 6 5

5
algorithms-and-datastructures/fft/d3

@ -0,0 +1,5 @@
1
5
0 1 0 -1 0 50
1
1 -2

5
algorithms-and-datastructures/fft/d4

@ -0,0 +1,5 @@
1
6
1 1 1 1 1 1 2
1
0 0

5
algorithms-and-datastructures/fft/d5

@ -0,0 +1,5 @@
1
2
1 0 5
1
0 -2

5
algorithms-and-datastructures/fft/d6

@ -0,0 +1,5 @@
1
4
1 1 -1 1 1
4
9 -8 7 6 5

5
algorithms-and-datastructures/fft/d8

@ -0,0 +1,5 @@
1
1
0 7
1
0 -7

196
algorithms-and-datastructures/fft/main.cpp

@ -0,0 +1,196 @@
/*
* Author: André Palmborg
*
* Course: TDDD95
* Task: 1.6: polymul2
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdexcept>
#include <complex>
typedef std::complex<long double> C;
const double PI = 3.141592653589793238460;
#include <valarray>
using std::valarray;
typedef std::valarray<C> Carray;
/* FFT_h
*
* Performs the inverse and regular Fast Fourier Transform using
* the Cooley-Tukey algorithm on a valarray of samples.
*
* Input
* Carray& samples : Valarray of complex<long double> samples.
* size_t N : The size of the $samples valarray.
* bool inv : Boolean telling FFT_h if it should compute the inverse FFT.
*
* Returns void : Transformed values are placed in the referenced $samples array
*/
void FFT_h(Carray& samples, size_t N, bool inv)
{
double f = (inv) ? 2 : -2;
if (N != 1)
{
Carray even = samples[std::slice(0, N/2, 2)];
Carray odd = samples[std::slice(1, N/2, 2)];
FFT_h(even, N/2, inv);
FFT_h(odd, N/2, inv);
for (size_t i{0}; i < N/2; i++)
{
// DEBUG
//printf("loop: (%lu) : max_i=%lu\n", i, i + N/2);
C t = even[i];
C exp = std::polar(1.0L, (long double)f * PI * i / N) * odd[i];
samples[i] = t + exp;
samples[i + N/2] = t - exp;
}
}
}
// Maps regular or inverse FFT calls to FFT_h with the correct
// coefficient; 2 for FFT and -2 for inverse FFT
void FFT(Carray& samples) {FFT_h(samples, samples.size(), false);}
void iFFT(Carray& samples) {FFT_h(samples, samples.size(), true);}
/* pMultiplication
* Pointwise multiplication of two Complex valarrays
*
* Side-effects : Will throw an exception if the given arrays are not the exact same size.
*
* Returns Carray P: New Carray with same length as A and B
* */
Carray pointMultiplication(Carray& A, Carray& B)
{
if (A.size() != B.size())
throw std::invalid_argument("Pointwise array multiplication with differing array length");
Carray P;
P.resize(A.size());
for (size_t i{0}; i < A.size(); i++) {P[i] = A[i] * B[i];}
return P;
}
/* inputArray
*
* Takes one polynomial from input and places it, in coefficient form, in
* a referenced array.
*
* Side-effect: Removes input described below incl. last newline from stdin.
* stdin : ^deg$
* ^c_0 c_1 ... c_deg$
*/
int inputArray(Carray& a)
{
size_t a_size;
scanf("%lu", &a_size);
a.resize( (a_size+1) );
int z = 1;
long int n;
for (size_t i{0}; i <= a_size; i++)
{
scanf("%lu ", &n);
if (n != 0) {z = 0;}
a[i] = (C)n;
}
return z;
}
/* takeInput
*
* Takes two polynomials from input and places them, in coefficient form, in two referenced arrays.
*
* Returns 1 if one or more of the arrays are equal to 0
* Returns 0 otherwise
*/
int takeInput(Carray& a, Carray& b)
{
if (inputArray(a) == 1 || inputArray(b) == 1)
return 1;
else
return 0;
}
/* polynomialMultiplication
*
* Polynomial multiplication using the Fast Fourier Transform.
*
* a * b = iFFT( FFT(b) .* FFT(b) )
* Where * is normal polynomial multiplication and .* is pointwise multiplication.
*
* Side-effects: Will attempt to read two polynomials from stdin.
* When computed the result will be sent to stdout.
*/
void polynomialMultiplication()
{
Carray a;
Carray b;
int z = takeInput(a, b);
// Handles cases where one or more of the arrays are equal to zero
if (z == 1) { puts("0\n0"); return; }
size_t s = (a.size() < b.size()) ? b.size() : a.size();
size_t e = 1;
while (e < s) { e<<=1; }
// Create new zero-padded arrays of length e*2 where e is the smallest
// power of 2 larger than max(a.size(), b.size()).
Carray A;
A.resize(e*2);
for (size_t i{0}; i < a.size(); i++) {A[i] = a[i];}
Carray B;
B.resize(e*2);
for (size_t i{0}; i < b.size(); i++) {B[i] = b[i];}
// Multiply polynomials
FFT(A);
FFT(B);
Carray P = pointMultiplication(A, B);
iFFT(P);
// Get the degree of the resulting polynomial.
size_t max_i{0};
for (size_t i{0}; i < P.size(); i++)
{
if ( 1e-1 < std::abs(P[i].real()) ) {max_i = i+1;}
}
printf("%lu\n", max_i-1);
// Print rounded coefficients of the resulting polynomial.
long int f, c;
long double v;
for (size_t i{0}; i < max_i; i++)
{
f = (long int)std::floor(P[i].real()/P.size());
c = f + 1;
v = P[i].real()/P.size();
if (v - (long double)f < (long double)c - v)
printf("%ld ", f);
else
printf("%ld ", c);
}
fputs("\n", stdout);
}
/* Repeats per test case to solve polymul1 and polymul2 */
int main()
{
int z;
scanf("%d ", &z);
for (int i{0}; i < z; i++) { polynomialMultiplication(); }
}

12
algorithms-and-datastructures/modular-arithmetic/Makefile

@ -0,0 +1,12 @@
EXECUTABLE=a.out
CC=g++
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra -Weffc++
OBJ=main.cpp
$(EXECUTABLE): $(OBJ)
$(CC) $(CFLAGS) -o $@ -static $(OBJ)
.PHONY: clean
clean:
rm -rf $(EXECUTABLE)

10
algorithms-and-datastructures/modular-arithmetic/d0

@ -0,0 +1,10 @@
1000 3
1 / 999
1 / 998
578 * 178
13 4
7 / 9
9 * 3
0 - 9
10 + 10
0 0

11
algorithms-and-datastructures/modular-arithmetic/d1

@ -0,0 +1,11 @@
1000 4
1 / 999
1 / 998
578 / 178
578 / 177
13 4
7 / 9
9 / 3
0 / 9
10 / 10
0 0

3
algorithms-and-datastructures/modular-arithmetic/d10

@ -0,0 +1,3 @@
1000000000000000000 1
999999999999999999 / 999999999999999999
0 0

4
algorithms-and-datastructures/modular-arithmetic/d11

@ -0,0 +1,4 @@
1000000000000000000 2
999999999999999999 * 999999999999999999
999999999999999999 * 999999999999999997
0 0

11
algorithms-and-datastructures/modular-arithmetic/d12

@ -0,0 +1,11 @@
1000 4
1 / 999
1 / 998
578 / 178
578 / 177
13 4
7 / 9
9 / 3
0 / 9
10 / 10
0 0

1
algorithms-and-datastructures/modular-arithmetic/d13

@ -0,0 +1 @@

3
algorithms-and-datastructures/modular-arithmetic/d14

@ -0,0 +1,3 @@
780205311 1
0 / 27094470
0 0

36
algorithms-and-datastructures/modular-arithmetic/d2

@ -0,0 +1,36 @@
10 22
0 + 1
0 + 2
0 + 3
0 + 4
0 + 5
0 + 6
0 + 7
0 + 8
0 + 9
0 + 10
0 + 11
5 + 1
5 + 2
5 + 3
5 + 4
5 + 5
5 + 6
5 + 7
5 + 8
5 + 9
5 + 10
5 + 11
5 11
1 * 0
1 * 1
1 * 2
1 * 3
1 * 4
1 * 5
1 * 6
1 * 7
1 * 8
1 * 9
1 * 10
0 0

23
algorithms-and-datastructures/modular-arithmetic/d3

@ -0,0 +1,23 @@
5 21
1 / 0
1 / 1
1 / 2
1 / 3
1 / 4
1 / 5
1 / 6
3 / 0
3 / 1
3 / 2
3 / 3
3 / 4
3 / 5
3 / 6
5 / 0
5 / 1
5 / 2
5 / 3
5 / 4
5 / 5
5 / 6
0 0

3
algorithms-and-datastructures/modular-arithmetic/d4

@ -0,0 +1,3 @@
5 1
3 / 2
0 0

16
algorithms-and-datastructures/modular-arithmetic/d5

@ -0,0 +1,16 @@
7 14
0 / 5
1 / 5
2 / 5
3 / 5
4 / 5
5 / 5
6 / 5
7 / 5
8 / 5
9 / 5
10 / 5
11 / 5
12 / 5
13 / 5
0 0

16
algorithms-and-datastructures/modular-arithmetic/d6

@ -0,0 +1,16 @@
7 14
0 / 5
1 / 5
2 / 5
3 / 5
4 / 5
5 / 5
6 / 5
7 / 5
-6 / 5
-5 / 5
-4 / 5
-3 / 5
-2 / 5
-1 / 5
0 0

6
algorithms-and-datastructures/modular-arithmetic/d7

@ -0,0 +1,6 @@
1 4
1 / 1
0 / 1
1 / 0
3 * 3
0 0

14
algorithms-and-datastructures/modular-arithmetic/d8

@ -0,0 +1,14 @@
2 4
1 / 1
0 / 1
1 / 0
3 * 3
2 2
2 / 1
2 / 2
7 4
1 / 14
0 / 14
0 / 0
0 * 6
0 0

4
algorithms-and-datastructures/modular-arithmetic/d9

@ -0,0 +1,4 @@
1000000000000000000 2
1 / 999999999999999998
999999999999999999 / 999999999999999999
0 0

129
algorithms-and-datastructures/modular-arithmetic/main.cpp

@ -0,0 +1,129 @@
#include <stdexcept>
#include <stdio.h>
#define ll long long int
inline void add(ll lhs, ll rhs, ll n)
{
ll out = lhs+rhs;
if( out < 0 )
out += n;
printf("%lld\n", (lhs+rhs)%n);
}
inline void sub(ll lhs, ll rhs, ll n)
{
ll out = lhs-rhs;
while( out < 0 )
out += n;
printf("%lld\n", out%n);
}
inline void mul(ll lhs, ll rhs, ll n)
{
//if (lhs < 0 || rhs < 0) throw std::invalid_argument("BAD");
ll out = lhs*rhs;
while( out < 0 )
out += n;
printf("%lld\n", out%n);
}
bool extEuclid(ll m, ll n, ll &a, ll &b)
{
ll a1 = 1;
ll b1 = 0;
a = 0;
b = 1;
ll c = m;
ll d = n;
ll q;
ll r;
if (d == 0) return false;
ll t;
while (true)
{
q = c/d;
r = c%d;
//printf("a'(%lld) a(%lld) b'(%lld) b(%lld) c(%lld) d(%lld) q(%lld) r(%lld)\n", a1, a, b1, b, c, d, q, r);
if (r == 0) break;
c = d;
d = r;
t = a1;
a1 = a;
a = t - q*a;
t = b1;
b1 = b;
b = t - q*b;
}
return true;
}
inline void div(ll lhs, ll rhs, ll n)
{
//printf("lhs(%lld) rhs(%lld)\n", lhs, rhs);
if( rhs == 0 ) { puts("-1"); return; }
//else if( lhs == 0 ) { puts("0"); return; }
ll a, inv;
if( extEuclid(n, rhs, a, inv) && n*a + rhs*inv == 1 )
{
//printf("lhs(%lld) inv(%lld)\n", lhs, inv);
//printf("sum: %d\n", n*a + rhs*inv);
while( inv < 0 )
inv += n;
inv %= n;
mul( lhs, inv, n );
}
else
{
puts("-1");
return;
}
}
int main()
{
ll n;
int nOps;
char op;
ll lhs, rhs;
scanf("%lld %d ", &n, &nOps);
while( !(n == 0 && nOps == 0) )
{
//printf("n(%lld) nOps(%d)\n", n, nOps);
while(nOps--)
{
scanf("%lld %c %lld ", &lhs, &op, &rhs);
lhs %= n;
rhs %= n;
//printf("lhs(%lld) op(%c) rhs(%lld)\n", lhs, op, rhs);
switch( op )
{
case '+': add(lhs, rhs, n);
break;
case '-': sub(lhs, rhs, n);
break;
case '*': mul(lhs, rhs, n);
break;
case '/': div(lhs, rhs, n);
break;
default: throw std::invalid_argument("BAD OP");
}
}
scanf("%lld %d ", &n, &nOps);
}
return 0;
}

12
algorithms-and-datastructures/prime-sieve/Makefile

@ -0,0 +1,12 @@
EXECUTABLE=a.out
CC=g++
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra -Weffc++
OBJ=main.cpp
$(EXECUTABLE): $(OBJ)
$(CC) $(CFLAGS) -o $@ -static $(OBJ)
.PHONY: clean
clean:
rm -rf $(EXECUTABLE)

7
algorithms-and-datastructures/prime-sieve/d0

@ -0,0 +1,7 @@
9973 6
1
2
3
4
9972
9973

28
algorithms-and-datastructures/prime-sieve/d1

@ -0,0 +1,28 @@
100 27
2
3
5
10
7
11
13
17
4
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97

3
algorithms-and-datastructures/prime-sieve/d2

@ -0,0 +1,3 @@
10 2
5
6

3
algorithms-and-datastructures/prime-sieve/d3

@ -0,0 +1,3 @@
100000000 2
5
1000000

4
algorithms-and-datastructures/prime-sieve/d4

@ -0,0 +1,4 @@
1001 3
1
2
1001

4
algorithms-and-datastructures/prime-sieve/d5

@ -0,0 +1,4 @@
9973 3
2
3
5

113
algorithms-and-datastructures/prime-sieve/main.cpp

@ -0,0 +1,113 @@
/*
* Author: André Palmborg
* LiU ID: andpa149
*
* Course: TDDD95
* Task: 3.8: primesieve
*/
#include <stdio.h>
#include <math.h>
#include <vector>
using std::vector;
/* Sieve of Eratosthenes
*
* Generates primes within a fixed span by successively marking of composite
* numbers divisible by primes. Starting marking from smallest prime leaves
* the next smallest prime unmarked in the vector.
*
* O( exp(N) ) time complexity
* O( N ) memory
*/
void eratosthenes_sieve(vector<bool>& primes, int N)
{
int i=2;
int j;
while( true )
{
if( primes[i] == true && i*2 <= N )
{
j = 2;
while( i*j <= N )
{
primes[ i*j ] = false;
j++;
}
}
if( ++i == N ) break;
}
primes[0] = false;
primes[1] = false;
}
/* is_prime
*
* Returns wheter a given int n is prime.
* Utilizes wheel factorization with wheel size=6.
*
* O( n ) time complexity
* O( 1 ) memory
*/
bool is_prime(int n)
{
if( n == 2 || n == 3 )
return true;
else if( n%2 == 0 || n%3 == 0)
return false;
long unsigned i=5, o=0, m=3;
while( n != 1 && 0 < n && i < n/m)
{
if( n%i == 0 )
return false;
m = i;
if( i%6 == 5 )
{
o++;
i += 2;
}
else
{ i += 4; }
}
return true;
}
/*
*
*/
int main()
{
int N, q;
scanf("%d ", &N);
N += 1;
vector<bool> primes(N, true);
eratosthenes_sieve(primes, N);
// Count primes
int nPrimes = 0;
int i=0;
while( true )
{
if( primes[i] == true ) nPrimes++;
if( ++i == N ) break;
}
printf("%d\n", nPrimes);
// Handle queries
scanf("%d ", &q);
int query;
while( 0 < q-- )
{
scanf("%d ", &query);
if (primes[query] == false )
puts("0"); // Not a prime
else
puts("1"); // Is a prime
}
}

12
algorithms-and-datastructures/unionfind/Makefile

@ -0,0 +1,12 @@
EXECUTABLE=a.out
CC=g++
CFLAGS=-g -lm -O2 -std=gnu++17 -Wall -Wextra
OBJ=main.cpp
$(EXECUTABLE): $(OBJ)
$(CC) $(CFLAGS) -o $@ -static $(OBJ)
.PHONY: clean
clean:
rm -rf $(EXECUTABLE)

5
algorithms-and-datastructures/unionfind/d0

@ -0,0 +1,5 @@
10 4
? 1 3
= 1 8
= 3 8
? 1 3

9
algorithms-and-datastructures/unionfind/d1

@ -0,0 +1,9 @@
4 8
? 0 0
= 0 1
= 1 2
= 0 2
? 0 3
? 0 1
? 0 2
? 1 2

5
algorithms-and-datastructures/unionfind/d2

@ -0,0 +1,5 @@
10 4
= 1 2
= 2 3
= 2 4
? 1 3

6
algorithms-and-datastructures/unionfind/d3

@ -0,0 +1,6 @@
4 5
? 0 0
= 0 1
= 1 2
= 0 2
? 0 3

106
algorithms-and-datastructures/unionfind/main.cpp

@ -0,0 +1,106 @@
/*
* Author: André Palmborg
*
* Course: TDDD95
* Task: 1.4: Unionfind
*/
#include <stdio.h> /* scanf, printf, puts */
#include <stdlib.h> /* malloc, free */
/* DisjunctSets
*
* unsigned N : Total number of elements.
* unsigned* nodes : Array keeping track of an elements parent in its set.
* The root elements parent is: (unsigned)(-1).
*
* Datastructure that keeps track of a set number of elements and the set they
* belong to.
* An element can only belong to one set at a time.
* Joining two elements together joins the two sets they belong to into one set.
*
*/
struct DisjunctSets
{
unsigned N;
unsigned* nodes;
// Constructor initializes all elements so that they belong to the set
// containing only themselves.
DisjunctSets(unsigned _N) : N(_N)
{
nodes = (unsigned*) malloc(N * sizeof(unsigned));
for (unsigned i = 0; i < N; i++)
{
nodes[i] = (unsigned)(-1);
}
}
~DisjunctSets() { free(nodes); }
// Returns the root element of a set.
// Side effects: Compresses the route to the root element by setting the
// parent of all elements accessed while seeking the root
// element to the root.
unsigned get_root(unsigned n)
{
// If checking the root element -> return root
if (nodes[n] == (unsigned)(-1))
return n;
else
{
unsigned it = get_root(nodes[n]);
nodes[n] = it;
return it;
}
}
// Returns true iff two elements are in the same set.
bool query_same(unsigned a, unsigned b)
{
if (a == b)
return true;
else
return (get_root(a) == get_root(b));
}
// Places two elements and the elements in their respective sets in the same set.
void join_sets(unsigned a, unsigned b)
{
unsigned a_root = get_root(a);
unsigned b_root = get_root(b);
if (a_root != b_root)
nodes[b_root] = a_root;
}
};
int main()
{
unsigned N, Q;
scanf("%d ", &N); // Get number of elements.
scanf("%d ", &Q); // Get number of operations to be executed on the sets.
DisjunctSets set(N);
char op;
unsigned a, b;
bool same;
for (unsigned i = 0; i < Q; i++)
{
scanf("%c %d %d ", &op, &a, &b); // Get operation type and arguments
//scanf("%d ", &a); // Get arguments
//scanf("%d ", &b); // -||-
switch (op)
{
case '?': same = set.query_same(a, b);
(same) ? puts("yes") : puts("no");
break;
case '=': set.join_sets(a, b);
break;
default: throw "Bad argument";
}
}
return 0;
}
Loading…
Cancel
Save