A NFA accepting ;anguages whose final digit didn't appear before - nfa

Give a non-deterministic finite automata(NFA) which accepts the following language:
The set of strings over the alphabet {0,1,...,9} such that the final digit has not appeared before.
I have encountered this problem on introduction to automata theory languages and computation page 67 Exercise 2.3.4

When the alphabet is {0,1}, which is the simplest non-trivial situation, we can get a simplest NFA like this:
The simplest non-trivial situation
So further you can get an NFA like this:
enter image description here

An easy way to get an NFA for this is to consider each of the 10 cases separately. Consider the case of all strings in the language whose last digit is 0. Such strings contain no other 0s; a regular expression for them is (1+2+3+4+5+6+7+8+9)*0. An NFA for them looks sort of like
1,2,3,4,5,6,8,9
/--\
| /
V /
o----->A0--0-->[B0]
We can imagine 9 others with states Ax, Bx, where Bx is accepting for each x, and Ax loops to itself on every symbol besides x, and to Bx on symbol x.
We can then glue all of these together by introducing a new initial state S which has an empty/lambda transition to the Ax states. The final NFA would have:
one initial state S
empty/lambda/epsilon transitions from S to states A0, A1, A2, A3, A4, A5, A6, A7, A8 and A9
transitions from A0 to B0 on 0, A1 to B1 on 1, A2 to B2 on 2, and so on
all missing transitions from states A0, A1, A2, and so on, back to those same states
In fact, why not copy/paste the above and just write the whole thing down?
1,2,3,4,5,6,7,8,9
/--\
| /
V /
/----->A0--0-->[B0]
/
| 0,2,3,4,5,6,7,8,9
| /--\
| | /
| V /
| /----->A1--1-->[B1]
|/
| 0,1,3,4,5,6,7,8,9
| /--\
| | /
| V /
| /----->A2--2-->[B2]
|/
| 0,1,2,4,5,6,7,8,9
| /--\
| | /
| V /
| /----->A3--3-->[B3]
|/
| 0,1,2,3,5,6,7,8,9
| /--\
| | /
| V /
| /----->A4--4-->[B4]
|/
/ 0,1,2,3,4,6,7,8,9
S-< /--\
\ | /
|\ V /
| \----->A5--5-->[B5]
|
| 0,1,2,3,4,5,7,8,9
| /--\
| | /
|\ V /
| \----->A6--6-->[B6]
|
| 0,1,2,3,4,5,6,8,9
| /--\
| | /
|\ V /
| \----->A7--7-->[B7]
|
| 0,1,2,3,4,5,6,7,9
| /--\
| | /
|\ V /
| \----->A8--8-->[B8]
|
| 0,1,2,3,4,5,6,7,8
| /--\
| | /
\ V /
\----->A9--9-->[B9]
Is this the simplest NFA or DFA for this language? Almost surely not. But it should work.

Related

Detect early tie in Connect 4

I am looking for an algorithm to detect an early tie in a Connect 4 game. As of now, I already check if the board is full and no wins have been detected but I would like to know as soon as the game can be deduced a tie.
For example, consider this game, where player B just played at position Row-5, Column-0:
|
v
5 | B | | | | | | |
4 | A | B | A | B | A | B | A |
3 | A | B | A | B | A | B | A |
2 | B | A | B | A | B | A | B |
1 | B | A | B | A | B | A | B |
0 | A | B | A | B | A | B | A |
0 1 2 3 4 5 6
Then, the game is not considered a tie, because there is still a way for player B to win. Though if player A plays at Row-5, Column-1:
|
v
5 | B | A | | | | | |
4 | A | B | A | B | A | B | A |
3 | A | B | A | B | A | B | A |
2 | B | A | B | A | B | A | B |
1 | B | A | B | A | B | A | B |
0 | A | B | A | B | A | B | A |
0 1 2 3 4 5 6
At this point, either player has no way to win: it going to be a tie. I would like the algorithm to notify the user of this right away.
Check all possible runs of 4-in-a-row on the board, horizontal, vertical and diagonal. If all of them contain at least one A and at least one B then it's going to be a tie. If there is even one that is made up of a combination of empty and A or empty and B (assuming there are no rows of 4-in-a-row A or 4-in-a-row B, in which case you already have a win), then a win by A or B is still possible.
You probably already have code to check for a win, so just adapt it to check for 4-in-a-row of A or empty, or 4-in-a-row of B or empty instead of 4-in-a-row of A, or 4-in-a-row of B. If it fails to detect a possible win then a tie is inevitable.
One wrinkle is when there are a small number of empty spaces on the board. In this case you need to work out how many remaining moves A and B have and only allow them that many number of empties in the calculation, e.g. check for 4-in-a-row of A and a maximum of 2 empties. For example if there are 5 empty spaces left and it's B's turn then A has 2 moves left and B has 3.
One case it won't handle is if there is a single empty column left - there might be enough space for one player to stack 4 in a row but they can't because the players have to alternate.

Container with most water algorithm issue

Given n non-negative integers a1, a2, ..., an, where each represents
a point at coordinate (i, ai). n vertical lines are drawn such that
the two endpoints of line i is at (i, ai) and (i, 0). Find two lines,
which together with x-axis forms a container, such that the container
contains the most water
What I do not understand about this question is how am I supposed to know the y-coordinate value(height) of the n vertical lines.
If the values you are given are {1,2,3,4,4,1,3}, the vertical lines would be:
4| | |
3| | | | |
2| | | | | |
1| | | | | | | |
0| -------------------
1 2 3 4 5 6 7
ai is the height of the ith line, and it's x coordinate is i.

Enumerating Cartesian product while minimizing repetition

Given two sets, e.g.:
{A B C}, {1 2 3 4 5 6}
I want to generate the Cartesian product in an order that puts as much space as possible between equal elements. For example, [A1, A2, A3, A4, A5, A6, B1…] is no good because all the As are next to each other. An acceptable solution would be going "down the diagonals" and then every time it wraps offsetting by one, e.g.:
[A1, B2, C3, A4, B5, C6, A2, B3, C4, A5, B6, C1, A3…]
Expressed visually:
| | A | B | C | A | B | C | A | B | C | A | B | C | A | B | C | A | B | C |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | | | | | | | | | | | | | | | | | |
| 2 | | 2 | | | | | | | | | | | | | | | | |
| 3 | | | 3 | | | | | | | | | | | | | | | |
| 4 | | | | 4 | | | | | | | | | | | | | | |
| 5 | | | | | 5 | | | | | | | | | | | | | |
| 6 | | | | | | 6 | | | | | | | | | | | | |
| 1 | | | | | | | | | | | | | | | | | | |
| 2 | | | | | | | 7 | | | | | | | | | | | |
| 3 | | | | | | | | 8 | | | | | | | | | | |
| 4 | | | | | | | | | 9 | | | | | | | | | |
| 5 | | | | | | | | | | 10| | | | | | | | |
| 6 | | | | | | | | | | | 11| | | | | | | |
| 1 | | | | | | | | | | | | 12| | | | | | |
| 2 | | | | | | | | | | | | | | | | | | |
| 3 | | | | | | | | | | | | | 13| | | | | |
| 4 | | | | | | | | | | | | | | 14| | | | |
| 5 | | | | | | | | | | | | | | | 15| | | |
| 6 | | | | | | | | | | | | | | | | 16| | |
| 1 | | | | | | | | | | | | | | | | | 17| |
| 2 | | | | | | | | | | | | | | | | | | 18|
or, equivalently but without repeating the rows/columns:
| | A | B | C |
|---|----|----|----|
| 1 | 1 | 17 | 15 |
| 2 | 4 | 2 | 18 |
| 3 | 7 | 5 | 3 |
| 4 | 10 | 8 | 6 |
| 5 | 13 | 11 | 9 |
| 6 | 16 | 14 | 12 |
I imagine there are other solutions too, but that's the one I found easiest to think about. But I've been banging my head against the wall trying to figure out how to express it generically—it's a convenient thing that the cardinality of the two sets are multiples of each other, but I want the algorithm to do The Right Thing for sets of, say, size 5 and 7. Or size 12 and 69 (that's a real example!).
Are there any established algorithms for this? I keep getting distracted thinking of how rational numbers are mapped onto the set of natural numbers (to prove that they're countable), but the path it takes through ℕ×ℕ doesn't work for this case.
It so happens the application is being written in Ruby, but I don't care about the language. Pseudocode, Ruby, Python, Java, Clojure, Javascript, CL, a paragraph in English—choose your favorite.
Proof-of-concept solution in Python (soon to be ported to Ruby and hooked up with Rails):
import sys
letters = sys.argv[1]
MAX_NUM = 6
letter_pos = 0
for i in xrange(MAX_NUM):
for j in xrange(len(letters)):
num = ((i + j) % MAX_NUM) + 1
symbol = letters[letter_pos % len(letters)]
print "[%s %s]"%(symbol, num)
letter_pos += 1
String letters = "ABC";
int MAX_NUM = 6;
int letterPos = 0;
for (int i=0; i < MAX_NUM; ++i) {
for (int j=0; j < MAX_NUM; ++j) {
int num = ((i + j) % MAX_NUM) + 1;
char symbol = letters.charAt(letterPos % letters.length);
String output = symbol + "" + num;
++letterPos;
}
}
What about using something fractal/recursive? This implementation divides a rectangular range into four quadrants then yields points from each quadrant. This means that neighboring points in the sequence differ at least by quadrant.
#python3
import sys
import itertools
def interleave(*iters):
for elements in itertools.zip_longest(*iters):
for element in elements:
if element != None:
yield element
def scramblerange(begin, end):
width = end - begin
if width == 1:
yield begin
else:
first = scramblerange(begin, int(begin + width/2))
second = scramblerange(int(begin + width/2), end)
yield from interleave(first, second)
def scramblerectrange(top=0, left=0, bottom=1, right=1, width=None, height=None):
if width != None and height != None:
yield from scramblerectrange(bottom=height, right=width)
raise StopIteration
if right - left == 1:
if bottom - top == 1:
yield (left, top)
else:
for y in scramblerange(top, bottom):
yield (left, y)
else:
if bottom - top == 1:
for x in scramblerange(left, right):
yield (x, top)
else:
halfx = int(left + (right - left)/2)
halfy = int(top + (bottom - top)/2)
quadrants = [
scramblerectrange(top=top, left=left, bottom=halfy, right=halfx),
reversed(list(scramblerectrange(top=top, left=halfx, bottom=halfy, right=right))),
scramblerectrange(top=halfy, left=left, bottom=bottom, right=halfx),
reversed(list(scramblerectrange(top=halfy, left=halfx, bottom=bottom, right=right)))
]
yield from interleave(*quadrants)
if __name__ == '__main__':
letters = 'abcdefghijklmnopqrstuvwxyz'
output = []
indices = dict()
for i, pt in enumerate(scramblerectrange(width=11, height=5)):
indices[pt] = i
x, y = pt
output.append(letters[x] + str(y))
table = [[indices[x,y] for x in range(11)] for y in range(5)]
print(', '.join(output))
print()
pad = lambda i: ' ' * (2 - len(str(i))) + str(i)
header = ' |' + ' '.join(map(pad, letters[:11]))
print(header)
print('-' * len(header))
for y, row in enumerate(table):
print(pad(y)+'|', ' '.join(map(pad, row)))
Outputs:
a0, i1, a2, i3, e0, h1, e2, g4, a1, i0, a3, k3, e1,
h0, d4, g3, b0, j1, b2, i4, d0, g1, d2, h4, b1, j0,
b3, k4, d1, g0, d3, f4, c0, k1, c2, i2, c1, f1, a4,
h2, k0, e4, j3, f0, b4, h3, c4, j2, e3, g2, c3, j4,
f3, k2, f2
| a b c d e f g h i j k
-----------------------------------
0| 0 16 32 20 4 43 29 13 9 25 40
1| 8 24 36 28 12 37 21 5 1 17 33
2| 2 18 34 22 6 54 49 39 35 47 53
3| 10 26 50 30 48 52 15 45 3 42 11
4| 38 44 46 14 41 31 7 23 19 51 27
If your sets X and Y are sizes m and n, and Xi is the index of the element from X that's in the ith pair in your Cartesian product (and similar for Y), then
Xi = i mod n;
Yi = (i mod n + i div n) mod m;
You could get your diagonals a little more spread out by filling out your matrix like this:
for (int i = 0; i < m*n; i++) {
int xi = i % n;
int yi = i % m;
while (matrix[yi][xi] != 0) {
yi = (yi+1) % m;
}
matrix[yi][xi] = i+1;
}

Fitch-Style Proof

Hi I'm having trouble solving a Fitch Style Proof and I was hoping someone would be able to help me.
Premises:
A ^ (B v C)
B => D
C => E
Goal:
~E => D
(1) A /\ (B \/ C) premise
(2) B -> D premise
(3) C -> E premise
.--------------------------------------------.
(4) | ~E assumption |
(5) | B \/ C /\ elimination of 1 |
| .--------------------------------------. |
(6) | | B assumption | |
(7) | | D -> elimination 2 | |
| '--------------------------------------' |
| .--------------------------------------. |
(8) | | C assumption | |
(9) | | E -> elimination 3 | |
(10) | | cont contradiction | |
(11) | | D ! elimination 10 | |
| '--------------------------------------' |
(12) | D \/ elimination 5, 6-7, 8-11 |
'--------------------------------------------'
(13) ~E -> D -> introduction 4-12

Creating a linkages map

I have an interesting programming problem that I need to solve for a iPhone app that I am currently building. The problem is actually a logic problem that does not need to be specific to any particular programming language.
The app needs to produce a linkages map (apologies if this isn't the right terminology but it makes sense to me). You have the following data:
A=C
B=A
C=O
D=F
E=F
F=G
G=D
H=J
I=L
J=N
K=A
L=O
M=C
N=H
O=E
The letters A through to O can be linked to any other letter. The app needs to follow the links to create a map, so starting with A, A link to C, C link to O, O links to E, E links to F etc
When complete this map would look like the attached photo.
http://i.stack.imgur.com/TEfAs.jpg
The problem I have is that I need to write code that will output any map using any combination of links. So for example another link list might look like
A=B
B=A
C=A
D=A
E=A
F=A
G=A
H=A
I=A
J=A
K=A
L=A
M=A
N=A
O=A
I can't get my head around the pseudocode / logic for drawing the app. There are always 15 letters A-O and a letter can never be linked to itself so A can never = A.
Can anyone help to come up with the logic for drawing the map?
What you want is to draw a graph. There is no canonical graphical representation of a graph. So if you have no constrains how the graph should be drawn, you can simply make a row of the Letters and than draw arches between the letters according to your map,
Little like this (ASCII-ART):
Example
+-----------------------------------------+
+--------------------------------------+ |
+-----------------------------------+ | |
+--------------------------------+ | | |
+-----------------------------+ | | | |
+--------------------------+ | | | | |
+-----------------------+ | | | | | |
+--------------------+ | | | | | | |
+-----------------+ | | | | | | | |
+--------------+ | | | | | | | | |
+-----------+ | | | | | | | | | |
+--------+ | | | | | | | | | | |
+-----+ | | | | | | | | | | | |
| | | | | | | | | | | | | |
A B C D E F G H I J K L M N O
| |
+--+
Example
+-----------------------------+
+-----------------------------+ |
+--+ +-----------------------------------+
| | | | +--------+ | |
A B C D E F G H I J K L M N O
| | | | | | | | | | | |
+-----+ | +--+ | +-----+ | +--------+
| +-----+ | | +-----------+
| | +--+ +-----------------+
| +--------+ |
+-----------------------------+
Look a bit confusing, but you cannot always avoid crossings. [In this example you could, but I did not try to avoid crossing, because they cannot be avoided in the general case.]

Resources