Update README.md

This commit is contained in:
Nuño Sempere 2018-04-07 21:04:13 +02:00 committed by GitHub
parent aa1938c002
commit 74f017cf01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -6,31 +6,34 @@ He was wrong.
I never make jokes :)
Anyways, to see if I could do it and to grok how Turing machines work, as described in Automata and Computability, by Dexter C. Kozen, here are:
Anyways, to see if I could do it and to grok how Turing machines, as described in Automata and Computability, by Dexter C. Kozen, work here are:
- A Turing Machine that accepts if a number n doesn't divide another number m and rejects otherwise.
- A Turing Machine that accepts if n doesn't divide m, or if n=m, and rejects otherwise.
- A Turing Machine that accepts if n is prime, and rejects otherwise.
- A Turing Machine that accepts once it has found the nth prime.
Early versions, deprecated, start with 0.
Early versions, deprecated, start with 0:
- A Turing Machine that accepts if a number n doesn't divide another number m and rejects otherwise.
- A Turing Machine that detects whether a number >=2 is prime.
Every function is my own.
Every idea here has been my own.
If you want to see the raw functions, go to, f.ex., find_nth_prime 1.1 -> states.c You can also download any folder and, in Linux/Ubuntu, compile it with the instruction
gcc -g main.c turing.c states.c turing.h states.h const.h -o main
and run it in the Linux command line with
./main
To do this, you will have to be in the appropriate folder, which you can change by using the command
To do this, you will have to be in the appropriate folder, which you can reach by using the command
cd ./Foldername/Subfoldername/Subsubfoldername
In Windows, compile it and run it with the compiler of your choice.
There is also an animation at: https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=42
There is also an animated version at: https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=42
***
Below is a transcription of my notes, which are dry but should be easy to understand. The states are gradually defined as the Turing machine moves, and then modified when it makes sense to do so.
Pero, Nuño, ¿por qué lo has escrito en inglés y no en español?
Porque mi bibliografía estaba en inglés, porque escribir código en c en español es engorroso, y porque me confunde un poco cambiar de idioma rápidamente.
(divisor 1.0) Accepts if n doesn't divide m, rejects otherwise.
Gets as an input 0111...11822..229␣␣␣␣␣...., where:
@ -40,6 +43,8 @@ Gets as an input 0111...11822..229␣␣␣␣␣...., where:
- Similarly, there are (m-2) '2's and 1 '9'. The 9 signals the end of the '2's.
- The ␣ are blanks, and the TM has an infinite number of them to the left.
The idea here is to replace the '2's y '4's in blocks of n, and check whether we have reached the end of m every time we finish a block.
state 0:
- The TM starts on this state.
- Inmediatly, it moves to the right, to state 1.
@ -60,38 +65,39 @@ state 3:
// As I write this, I realize that if I replace state 0 by state 3, nothing happens.
// Excursus: After competing this project, I searched for similar ones, and found one by a William Bernoudy. My finding the nth prime TM had 14 states and 12 symbols, while his had 14 states and only 10 symbols. But if I replace state 0 by state 3, I have one state less! Anyways, from now on no state is state 3. We modify state 2, which refers to it.
// Excursus: After competing this project, I searched for similar ones, and found one by a William Bernoudy. My TM to find the nth prime had 14 states and 12 symbols, while his had 14 states and only 10 symbols. But if I replace state 0 by state 3, I have one state less! Thus, from now on no state is state 3, because I don't want to change my code.
We modify state 0 and state 2, which refers to the now nonexistent state 3.
state 0:
- If symbol = 0, move right, change to state 1.
- If it reads a 0, move right, change to state 1.
- else: move left, keep state.
state 2:
- it looks for a 2 to replace by a 4.
- if symbol = 2, write 4, change to state 0.
- if it reads a 2, write 4, change to state 0.
- else: move right, keep state
Now, once all the 1s are turned into 3s, state 1 would go on searching, so we want to modify it to notice that it has run out of threes.
state 1:
- if symbol = 1, write 3, move right, change to state 2.
- if symbol = 8, write 8, move right, change to state 4.
- if it reads a 1, write 3, move right, change to state 2.
- if it reads a 8, write 8, move right, change to state 4.
- otherwise: move right.
If there were no 2s left to turn to 4s, then n|m (n divides m). But if there are, n can still divide m, so we keep on going.
state 4:
- if symbol = 2, write 4, move to the right, change to state 5.
- if symbol = 9, REJECT, n | m
- if it reads a 2, write 4, move to the right, change to state 5.
- if it reads a 9, REJECT, because n|m
We also notice that if state 2 finds no 2s to turn into 4s, then ¬ (n|m), so we add that option.
We also notice that if state 2 finds no 2s to turn into 4s, then ¬ (n|m), so we add that.
state 2:
- if symbol = 2, write 4, change to state 0.
- if symbol = 9, ACCEPT.
- if it reads a 2, write 4, change to state 0.
- if it reads a 9, ACCEPT.
- else: move to the right.
If state 4 does find a 2, then the situation looks, for example, like this; take n=3, m=6, then the tape cpuld have:
If state 4 does find a 2, then the situation looks, for example, like this; take n=3, m=6, then the tape could have:
0338444229
@ -106,8 +112,8 @@ End.
(divisor 1.1) Accepts if n|m or if n=m.
Now the input is: 05111...11822..229
The 5 will be cahnged to a 6 once we change the 2 that corresponds to the 8. If there is no such 2, n = m. So we modify state 4 and 5 and create a state 6.
Now the input is of the form: 05111...11822..229
The 5 will be changed to a 6 once we change the 2 that corresponds to the 8. If there is no such a 2, n = m. So we modify states 4 and 5, and create a state 6.
state 5:
- if it reads a 3, write 1, move left, keep state.
@ -120,8 +126,8 @@ state 4:
- else: move to the right, keep state.
state 6:
- if it reads a 5, accept.
- if it reads a 6, reject.
- if it reads a 5, ACCEPT.
- if it reads a 6, REJECT.
- else: move to the left.
End.
@ -130,17 +136,17 @@ End.
We start with: 0518777...77722..229
This reads: The initial n=2, after which there are enough 7s to increase n to find divisors of m.
This reads: There is an initial n=2, after which there are enough 7s to increase n to find divisors of m.
Q: But, how many 7s?
A: Well, a priori at least sqrt(n), but up to n, if you one.
A: Well, a priori at least sqrt(m), but up to m.
Q: But Nuño, if you put ceil(sqrt(n)) '7's, aren't you offloading some of the calculations to yourself instead of making the machine calculate it?
A: Yes, I am.
Anyways, right now the only state which can accept is state 2, which does so if ¬(n|m) for a given n. Instead of accepting, we want to increase n by 1. We modify state 2, and create 2 new states: state 7 and state 8.
Anyways, right now the only state which can accept is state 2, which does so if ¬(n|m) for a given n. Instead of accepting, we want to increase n by 1. We modify state 2, and create 2 new states: state 7 and state 8, which respectively initialize all '4's to '2's and increase n by one.
state 2:
- if it reads a 2: write 4, move left, change to state 0.
@ -164,13 +170,13 @@ End.
Initial input: 0AA...AA51829␣␣␣...␣␣
The TM will replace an A by a B each time it finds a prime, so if n-1 is the number of 'A's, it will find the nth prime.
The TM will replace an A by a B each time it finds a prime, so if the number of 'A's is (n-1) , it will find the nth prime.
State 9 will change an A to a B. States 10, 11 and 12 initialize n to 2.
States 12, 13 and 14 move m one step to the right and increase it to m+1. Thus, at each step n will be bounded only by m+1.
The states that can accept are state 6 and state 8, and only state 6 can reject. We modify them so:
The states that can accept are state 6 and state 8, and only state 6 can reject. We modify them to go to state 9 or 10:
state 6
- if it reads a 5, write 5, change to state 9.