Commit 30a5da0e authored by Taddeüs Kroes's avatar Taddeüs Kroes

Algoritmen & Complexiteit sommenserie 4

Added work done by Taddeus on this series
parent 6f811dc5
/*
* Turing machine adding two numbers in base 2.
*
* Authors: Richard Torenvliet, Taddeus Kroes, Sander van Veen, Jayke meijer
*/
#include<stdio.h>
#include<stdlib.h>
#define EOS '\0'
#define STRIP_LENGTH 70 // should ofcourse be infinity...
#define HALT_STATE 8
// Turing machine table:
// 0 1 # B z o
// q0: q0,0,R q0,1,R q0,#,R q1,B,L - -
// q1: q2,B,L q3,B,L q7,B,L - - -
// q2: q2,0,L q2,1,L q4,#,L - - -
// q3: q3,0,L q3,1,L q5,#,L - - -
// q4: q0,z,R q0,o,R - q0,z,R q4,z,L q4,o,L
// q5: q0,o,R q6,z,L - q0,o,R q5,z,L q5,o,L
// q6: q0,1,R q6,0,L - q0,1,R - -
// q7: q7,0,L q7,1,L - q8,B,R q7,0,L q7,1,L
const int state[8][6] = {
{0,0,0,1,0,0},
{2,3,7,1,1,1},
{2,2,4,2,2,2},
{3,3,5,3,3,3},
{0,0,4,0,4,4},
{0,6,5,0,5,5},
{0,6,6,0,6,6},
{7,7,7,8,7,7}
}, movement[8][6] = {
{ 1, 1, 1,-1, 1, 1},
{-1,-1,-1, 1, 1, 1},
{-1,-1,-1, 1, 1, 1},
{-1,-1,-1, 1, 1, 1},
{ 1, 1, 1, 1,-1,-1},
{ 1,-1, 1, 1,-1,-1},
{ 1,-1, 1, 1, 1, 1},
{-1,-1, 1, 1,-1,-1}
};
const char write[8][6] = {
{'0','1','#','B','z','o'},
{'B','B','B','B','z','o'},
{'0','1','#','B','z','o'},
{'0','1','#','B','z','o'},
{'z','o','#','z','z','o'},
{'o','z','#','o','z','o'},
{'1','0','#','1','z','o'},
{'0','1','#','B','0','1'}
};
int char_to_index(char c)
{
switch( c )
{
case '0': return 0; break;
case '1': return 1; break;
case '#': return 2; break;
case 'B': return 3; break;
case 'z': return 4; break;
case 'o': return 5; break;
default: printf("invalid character '%c'\n", c); exit(1);
}
}
int main(int argc, char **args)
{
int position = 1, q = 0, i;
char *c, strip[STRIP_LENGTH + 1];
strip[STRIP_LENGTH] = EOS;
for( position = 0; position < STRIP_LENGTH/2; position++ )
strip[position] = 'B';
i = position++;
for( c = args[1]; *c != EOS; c++ )
strip[i++] = *c;
for( ; i < STRIP_LENGTH; i++ )
strip[i] = 'B';
// Turing machine
while( 1 )
{
c = strip + position;
for( i = 0; i < position; i++ )
printf(" ");
printf("v\n%s q%d\n", strip, q);
if( q == HALT_STATE )
break;
i = char_to_index(*c);
*c = write[q][i];
position += movement[q][i];
q = state[q][i];
}
printf("\nAnswer: ", strip, HALT_STATE);
for( i = 0; i < STRIP_LENGTH; i++ )
{
c = strip + i;
if( *c != 'B' )
printf("%c", *c);
}
puts("\n");
return 0;
}
\section{Verdeel-en-heers algoritme voor polynoom}
We verdelen het probleem in subproblemen door koppels te vermenigvuldigen met
behulp van Fourier transformatie: $(x-x_0)(x-x_1) ... (x-x_{n-2})(x-x_{n-1})$,
dit levert $\frac{n}{2}$ polynomen op. Vervolgens voeren we FFT uit op koppels
van de verkregen polynomen, wat $\frac{n}{4}$ polynomen oplevert. Dit blijven
we doen totdat er nog maar \'e\'en polynoom over is. \\
De complexiteit van FFT is van de orde $\mathcal{O}(n\log{n})$. Het aatal keren
dat er koppels worden gevormd is van de orde $\mathcal{O}(\log{n})$ (diepte van
een binaire boom), de totale tijdscomplexiteit van het algoritme is dus van de
orde $\mathcal{O}((n\log{n})\log{n}) = \mathcal{O}(n\log^2{n})$. \\
Merk op bovenstaand algoritme werkt voor even waarden van $n$ (alle polynomen
behoren dan tot een koppel). Voor oneven waarden is de oplossing simpel: neem
\'e\'en van de eerste polynomen apart, voer vervolgens het algoritme uit op
de $n-1$ overgebleven polynomen en vermenigvuldig het resultaat hiervan met de
apart gehouden polynoom. Omdat het hierbij niet uitmaakt hoe groot $n$ is, wordt
de tijdscomplexiteit behouden.
\section{Optellen met een Turing machine}
Het programma wordt gegeven door de volgende tabel: \\
\\
\begin{tabular}{l|cccccc}
& 0 & 1 & \# & B & z & o \\
\hline
q0 & q0,0,R & q0,1,R & q0,\#,R & q1,B,L & - & - \\
q1 & q2,B,L & q3,B,L & q7,B,L & - & - & - \\
q2 & q2,0,L & q2,1,L & q4,\#,L & - & - & - \\
q3 & q3,0,L & q3,1,L & q5,\#,L & - & - & - \\
q4 & q0,z,R & q0,o,R & - & q0,z,R & q4,z,L & q4,o,L \\
q5 & q0,o,R & q6,z,L & - & q0,o,R & q5,z,L & q5,o,L \\
q6 & q0,1,R & q6,0,L & - & q0,1,R & - & - \\
q7 & q7,0,L & q7,1,L & - & q8,B,R & q7,0,L & q7,1,L \\
\end{tabular}
We hebben dit programma getest met behulp van een C-programma, dat als volgt kan
worden uitgevoerd: \\
\begin{center}
\texttt{gcc -o sum turingsum.c -std=c99 \&\& ./sum 10001001011\#101010101001110}
\end{center}
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