How to build special turing machine - algorithm

Good day. I have a question. Many people are familiar with the Turing machine. The following task arose, which I can’t solve for a long time: there is an alphabet consisting of the letters "X", "Y" "Z", if the number of letters "Z" in the word is exactly 2 more than the letters "X", replace the second letter "Z" with "X". Otherwise, leave the word unchanged. Considering that I cannot change the original word and the tape is infinite (that is, I cannot write an infinite number of states for the machine), I do not understand how to do this.

Just to make it more clear, if the input is for example:
XXXYZZZZZ
then the output you need is:
XXXYZXZZZZ
And if the input is:
XXYZZ
Then everything needs to stay the same, since (number of Z's) - (number of X's) != 2
XXYZZ
If I understood the problem correctly, in the way I defined above, then here comes the solution with Morphett's TM Simulator, with $ sign as left-end marker:
1 $ $ r 1
1 X A r 2
1 Y Y r 4
2 X X r 2
2 B B r 2
2 Y Y r 2
2 Z B R 3
3 Y Y l 3
3 B B l 3
3 X X l 3
3 A A r 1
3 Z Z l 3
4 Y Y r 4
4 B B r 4
4 Z B r 5
4 _ _ l 7
5 Z B r 6
5 _ _ l 7
6 Z Z l 7
6 _ _ l 8
7 B Z l 7
7 Y Y l 7
7 A X l 7
7 $ $ r 12
8 B Z l 8
8 Y Y l 8
8 A X l 8
8 $ $ r 9
9 X X r 9
9 Y Y r 9
9 Z Z r 10
10 Z X r 11
11 Z Z r 11
11 _ _ l halt
12 X X r 12
12 Y Y r 12
12 Z Z r 12
12 _ _ l halt
Copy this code and then paste it to http://morphett.info/turing/turing.html
From advanced options, set initial state to 1 from 0.
Do not forget to add a "$" to beginning of every input.

Related

Find the smallest sub square matrix that contains all the vowels

You are provided with 2-D Matrix, A, such that
1. A (MxN), is 2-Dimensional Matrix
2. A[i][j] E [A-Z]
you have to find the smallest sub square matrix, such that
it contains all the vowels i.e. {A E, I, O, U}.
Input: A[][] ->
A E I O B 1 2 3 4 5
C D U Z O 6 7 8 9 10
P O A E K 11 12 13 14 15
B R E A K 16 17 18 19 20
Possible Outputs:
A E I 1 2 3
C D U 5 6 7
P O A 9 10 11
I O B 3 4 5
U Z O 8 9 10
A E K 13 14 15
so, size here will be 3x3 square matrix, so it is 3.
Please help me to find out the logic behind this problem.

Split a subset with a constraint

Today, while practicing some Algorithm questions I found an interesting question.
The question is
You have to divide 1 to n (with one missing value x ) into two equal
halfs such that sum of the two halfs are equal.
Example:
If n = 7 and x = 4
The solution will be {7, 5} and {1, 2, 3, 6}
I can answer it with brute force method but i want an efficient solution
Can any one help me out?
If the sum of the elements 1→N without x is odd then there is no solution.
Otherwise you can find your solution in O(N) with balanced selection.
4 in a row
First let us consider that any sequence of four contiguous numbers can be split in two sets with equal sum given that:
[x, x+1, x+2, x+3] → [x+3, x];[x+2, x+1]
Thus selecting them and placing them in sets A B B A balances sets A and B.
4 across
Moreover, when we have two couples across an omitted value, it can hold a similar property:
[x-2, x-1, x+1, x+2] → [x+2, x-2]; [x+1, x-1]
so still A B B A
At this point we can fix the following cases:
we have a quadruplet: we split it as in case 1
we have 2 numbers, x and other 2 numbers: we split as in case 2
Alright, but it can happen we have 3 numbers, x and other 3 numbers, or other conditions. How can we select in balanced manner anyway?
+2 Gap
If we look again at the gap across x:
[x-1, x+1]
we can notice that somehow if we split the two neighbors in two separate sets we must balance a +2 on the set with bigger sum.
Balancing Tail
We can do this by using the last four numbers of the sequence:
[4 3 2 1] → [4, 2] ; [3, 1] → 6 ; 4
Finally we have to consider that we might not have one of them, so let's build the other case:
[3 2 1] → [2] ; [3, 1] → 2 ; 4
and let us also realize we can do the very same at the other end of the sequence with an A B A B (or B A B A) pattern - if our +2 stands on B (or A);
4 across +
It is amazing that 4 across still holds if we jump h (odd!) numbers:
[x+3, x+2, x-2, x-3] → [x+3, x-3]; [x+2, x-2]
So, exploring the array we can draw the solution step by step
An example:
11 10 9 8 7 6 5 4 3 2 1
the sum it's even, so x can be only an even number:
x = 10
11 - 9 | 8 7 6 5 | 4 3 2 1 → (+2 gap - on A) (4 in a row) (balancing tail)
A B A B B A B A B A
x = 8
11 10 | 9 - 7 | 6 5 | 4 3 2 1 → (4 across +) (+2 gap - on A) (balancing tail)
a b A B | b a | B A B A
x = 6
11 10 9 8 | 7 - 5 | 4 3 2 1 → (4 in a row) (+2 gap - on A) (balancing tail)
A B B A A B A B B B
x = 4 we have no balancing tail - we have to do that with head
11 10 9 8 | 7 6 | 5 - 3 | 2 1 → (balancing head) (4 across +) (+2 gap)
A B A B A B | b a | B A
x = 2
11 10 9 8 | 7 6 5 4 | 3 - 1 → (balancing head) (4 in a row) (+2 gap)
A B A B A B B A B A
It is interesting to notice the symmetry of the solutions. Another example.
10 9 8 7 6 5 4 3 2 1
the sum it's odd, so x can be only an odd number, and the number of elements now is odd.
x = 9
10 - 8 | 7 6 5 4 | 3 2 1 → (+2 gap - on A) (4 in a row) (balancing tail)
A B A B B A B A B
x = 7
10 9 | 8 - 6 | 5 4 | 3 2 1 → (4 across +) (+2 gap - on A) (balancing tail)
a b | A B | b a B A B
x = 5
10 9 8 7 | 6 - 4 | 3 2 1 → (4 in a row) (+2 gap - on A) (balancing tail)
A B B A A B B A B
x = 3
10 9 8 7 | 6 5 | 4 - 2 | 1 → (balancing head) (4 across + virtual 0) (+2 gap)
A B A B B A | a b | A
x = 1
10 9 8 7 | 6 5 4 3 | 2 → (balancing head) (4 in a row) (+2 gap virtual 0)
A B A B A B B A B
Finally it is worth to notice we can switch from A to B whenever we have a full balanced segment (i.e. 4 in a row or 4 across)
Funny said - but the property requesting the sum([1 ... N]-x) to be even makes the cases quite redundant if you try yourself.
I am pretty sure this algorithm can be generalized - I'll probably provide a revised version soon.
This problem can be solved by wrapping the standard subset sum problem of dynamic programming with preprocessing steps. These steps are of O(1) com
Algorithm (n, x):
sum = n * (n+1) / 2
neededSum = sum - x
If (neededSum % 2 != 0): return 0
create array [1..n] and remove x from it
call standard subsetsum(arr, 0, neededSum/2, [])
Working python implementation of subsetsum algorithm - printing all subsets is given below.
def subsetsum(arr, i, sum, ss):
if i >= len(arr):
if sum == 0:
print ss
return 1
else:
return 0
ss1 = ss[:]
count = subsetsum(arr, i + 1, sum, ss1)
ss1.append(arr[i])
count += subsetsum(arr, i + 1, sum - arr[i], ss1)
return count
arr = [1, 2, 3, 10, 5, 7]
sum = 14
a = []
print subsetsum(arr, 0, sum, a)
Hope it helps!

Did I understand the following quicksort algorithm correctly?

I'm trying to understand the given algorithm and here are my thoughts:
A is the given array... x stands for the number which is on the left side of the pivot element, y stands for the number which is on the right side of the pivot element. (Let's say the pivot element is the element on the very right side of the array.) And A[y] stands for the pivot element?
If I understood correctly, the algorithm first searches from x towards y until first number is greater or equal A[y], then search from y towards x until first number is smaller or equal A[y].
After, swap both numbers and repeat if i hasn't reached j. In the end the numbers left from i are smaller than A[y] and the numbers right from j are larger than A[y]... Also move A[y] to the middle.
What do you think about this? Am I right?
Maybe you could give an example with a random array? I cannot do this yet I believe.
Algorithm Quicksort
1 func int div (A array; x, y integer) {
2 num = A[y];
3 i = x;
4 j = y-1;
5 repeat
6 while (A[i] <= num and i < y)
7 i = i+1;
8 end while;
9 while (A[j] >= num and j > x)
10 j = j-1;
11 end while;
12 if i < j then
13 swap (A[i], A[j]);
14 end if;
15 until i >= j;
16 swap (A[i], A[y]);
17 return i;
18 }
From the algorithm it looks like x and y mark the left and right bounds of the sorting algorithm within an array (to sort the complete array, you'd use x = 0 and y = A.length). The pivot element is the rightmost one (at index y).
Then, i starts at x (the left bound) and compares each element with the pivot A[y]. It increases up to an index, at which the element is larger than A[y].
j starts at y (the right bound) and does the complementary: it decreases until it reaches an index, at which an element smaller than A[y] is found.
If i is still smaller than j, these two elements (at index i and j) are then swapped, meaning all elements from x to i are smaller than A[y], all elements from j to y are larger than A[y]. In this case, there are still elements between the indices i and j, that have not been 'seen' by the algorithm.
This procedure is repeated until eventually, the complete array is partitioned into the lower 'half' (all smaller than A[y]) and the upper 'half' (all larger than A[y]). One element larger than A[y] is then swapped with A[y] and the index between the two partitions is then returned.
In conclusion, your algorithm only partitions the array into elements smaller than A[y] and elements larger than A[y]. Repeating this recursively on both partitions will eventually sort them completely.
Example:
A = [ 4 7 9 2 5 1 3 8 6 ]
--> called with x = 0, y = 8 (thus, partitioning the complete array)
e.g. div([ 4 7 9 2 5 1 3 8 6 ], 0, 8)
xi j y
[ 4 7 9 2 5 1 3 8 | 6 ] x=0, y=8, A[y]=6, i=0, j=7
x i j y
[ 4 7 9 2 5 1 3 8 | 6 ] x=0, y=8, A[y]=6, i=1, j=7
A[i]=7 >= A[y]=6 -> first while loop ends
x i j y
[ 4 7 9 2 5 1 3 8 | 6 ] x=0, y=8, A[y]=6, i=1, j=6
A[j]=3 <= A[y]=6 -> second while loop ends
x i j y
[ 4 3 9 2 5 1 7 8 | 6 ] x=0, y=8, A[y]=6, i=1, j=6
swapped A[i] and A[j] (i and j stay the same!) -> repeat until i<j
x i j y
[ 4 3 9 2 5 1 7 8 | 6 ] x=0, y=8, A[y]=6, i=2, j=6
x i j y
[ 4 3 9 2 5 1 7 8 | 6 ] x=0, y=8, A[y]=6, i=2, j=5
x i j y
[ 4 3 1 2 5 9 7 8 | 6 ] x=0, y=8, A[y]=6, i=2, j=5
swapped -> repeat (i<j)
x i j y
[ 4 3 1 2 5 9 7 8 | 6 ] x=0, y=8, A[y]=6, i=3, j=5
x i j y
[ 4 3 1 2 5 9 7 8 | 6 ] x=0, y=8, A[y]=6, i=4, j=5
x ij y
[ 4 3 1 2 5 9 7 8 | 6 ] x=0, y=8, A[y]=6, i=5, j=5
first while ends again
x j i y
[ 4 3 1 2 5 9 7 8 | 6 ] x=0, y=8, A[y]=6, i=5, j=4
second while ends again
j>i -> don't swap
j>i -> don't repeat
swap A[i] and A[y]
x j i y
[ 4 3 1 2 5 6 7 8 | 9 ] x=0, y=8, A[y]=6, i=5, j=4
return i=5
Now, all elements between x and i are smaller than your ORIGINAL A[y] (which is now different!) and all elements between i+1 and y are smaller than the ORIGINAL A[y].
Next, you'd call div([ 4 3 1 2 5 6 7 8 9 ], 0, 5) and div([ 4 3 1 2 5 6 7 8 9 ], 6, 8) or more abstract: div(A, x, i) and div(A, i+1, y).

Pandas pivot table Nested Sorting Part 3

Episode 3:
In part 2, we retained the hierarchical nature of the indices while sorting within right-most level. In part 1, we applied a custom sort to the left-most index level while sorting the values within the right-most index.
Now, I'd like to combine both methods.
Given the following data frame and resultant pivot table:
import pandas as pd
df=pd.DataFrame({'A':['a','a','a','a','a','b','b','b','b'],
'B':['x','y','z','x','y','z','x','y','z'],
'C':['a','b','a','b','a','b','a','b','a'],
'D':[7,5,3,4,1,6,5,3,1]})
df
A B C D
0 a x a 7
1 a y b 5
2 a z a 3
3 a x b 4
4 a y a 1
5 b z b 6
6 b x a 5
7 b y b 3
8 b z a 1
table = pd.pivot_table(df, index=['A', 'B','C'],aggfunc='sum')
table
D
A B C
a x a 7
b 4
y a 1
b 5
z a 3
b x a 5
y b 3
z a 1
b 6
I would like to specify a custom order of 'B'.
This seems to work:
df['B']=df['B'].astype('category')
df['B'].cat.set_categories(['z','x','y'],inplace=True)
Next, I'd like for the pivot table to keep the order for 'B' specified above while sorting the values 'D' descendingly within each category of 'B'.
Like this:
D
A B C
z a 3
x a 7
a b 4
y b 5
a 1
z b 6
b a 1
x a 5
y b 3
Thanks in advance!
UPDATE: using pivot_table()
In [79]: df.pivot_table(index=['A','B','C'], aggfunc='sum').reset_index().sort_values(['A','B','D'], ascending=[1,1,0]).set_index(['A','B','C'])
Out[79]:
D
A B C
a x a 7
b 4
y b 5
a 1
z a 3
b x a 5
y b 3
z b 6
a 1
is that what you want?
In [64]: df.sort_values(['A','B','D'], ascending=[1,1,0]).set_index(['A','B','C'])
Out[64]:
D
A B C
a z a 3
x a 7
b 4
y b 5
a 1
b z b 6
a 1
x a 5
y b 3

Unification algorithm example in WAM (Warren's Abstract Machine)

Exercise 2.2 in Warren's Abstract Machine: A Tutorial Reconstruction
asks for representations for the terms f(X, g(X, a)) and f(b, Y) and then to perform unification on the address of these terms (denoted a1 and a2 respectively).
I've constructed the heap representations for the terms, and they are as follows:
f(X, g(X, a)):
0 STR 1
1 a/0
2 STR 3
3 g/2
4 REF 4
5 STR 1
6 STR 7
7 f/2
8 REF 4
9 STR 3
f(b, Y):
10 STR 11
11 b/0
12 STR 7
13 STR 11
14 REF 14
and I am now asked to trace unify(a1, a2), but following the algorithm on page 20 in 1 I get:
d1 = deref(a1) = deref(10) = 10
d2 = deref(a2) = deref(0) = 0
0 != 10 so we continue
<t1, v1> = STORE(d1) = STORE(10) = <STR, 11>
<t2, v2> = STORE(d2) = STORE(0) = <STR, 1>
t1 != REF and t2 != REF so we continue
f1 / n1 = STORE(v1) = STORE(11) = b / 0
f2 / n2 = STORE(v2) = STORE(1) = a / 0
and now b != a so the algorithm terminated with fail = true,
and thus unification failed, but obviously there exists
a solution with X = b and Y = g(b, a).
Where is my mistake?
I found the solution myself. Here's my corrections:
Each term should have their own definitions of the functors (ie. the f-functor in the second term should not just link to the first f-functor in the first term, but should have its own) and pointers to the terms (a1 and a2) should point to the outermost term functor.
This means that a1 = 6 and a2 = 12 in the following layout
f(X, g(X, a)):
0 STR 1
1 a/0
2 STR 3
3 g/2
4 REF 4
5 STR 1
6 STR 7
7 f/2
8 REF 4
9 STR 3
f(b, Y):
10 STR 11
11 b/0
12 STR 13
13 f/2
14 REF 11
15 REF 15

Resources