State Diagram for Turing Machine to compute next string in lexicographical order - theory

What would the state diagram look like for a Turing Machine that computes the next string in lexicographical order over alphabet Σ = {1, 2, 3}?
String size is 4, i.e ---1, ---2, ---3, --11, --12, etc...
Already tried figuring it out from Michael Sipser's Introduction to Theory of Computation with no luck.
Also tried to look it up online, again with no luck.
Thanks in advance!

If I have understood correctly, you want a TM to take as input a string over {1, 2, 3} of length up to four, and to overwrite this number with the string over the same alphabet which comes next in lexicographic order. Here is a strategy for this problem.
move right three times so we're looking at the fourth symbol on the tape.
if this is blank, our input is malformed and we die. otherwise, if the symbol is 1, write 2 and halt-accept; if 1, write 2 and halt-accept; if 3, write 1 and move left in state "carry2"
if this is blank, 1 or 2, write 1, 2 or 3, respectively, and halt-accept. if 3, write 1 and move left in state "carry3"
if this is blank, 1 or 2, write 1, 2 or 3, respectively, and halt-accept. if 3, write 1 and move left in state "carry4"
if this is blank, 1 or 2, write 1, 2 or 3, respectively, and halt-accept. if 3, the input was the number 3333 and there is no lexicographically larger 4-digit string over {1, 2, 3}… so either crash or wrap and write ---1 to the tape.
Note that this does not verify the tape contents are sane... since we are using blanks to encode "missing" high-order digits we can just reasonably assume there's nothing after position 4 on the tape (defining what our TM does carefully to avoid implying we did anything after there). Furthermore, we are not sanitizing the front, so mixing symbols and blanks improperly could be an issue... so we could either run some steps first to validate the input or just require the input be well-formed when we get it.

Related

How can I take a string and differentiate it in different strings each one with 2 characters?

I was trying to do a program that analyzes poker hands, however I am extremely confused and I don't know where to start. The suits are represented by the letters C(clubs), D(diamonds), H(hearts) and S(spades).
The value of the cards is represented by the numbers and the letters A(ace), 2, 3, 4, 5, 6, 7, 8, 9, T(ten), J(jack), Q(queen) and K(king).
The program is supposed to receive input like AS KC QC JH 9D.
But the difficult part is that it should be able to receive 5, 7, 9 or 10 cards (strings with 2 chars).
Note: each card is made of two chars (example: 2C).
Thank you in advance :)
I will offer incremental suggestions in this answer:
To determine how many cards are in the hand/set: you can call strlen(string) to count the number of characters in the string.
Once you know how many cards are there, you can use a switch statement: switch(number_of_cards) { ... } to branch the processing logic into distinct cases.

Searching for shortest slice in an array with all unique values, how to do this in optimal way?

I have an array that contains N elements, which values are in 0 <= value < N range and can be discontinuous. For this array I need to find a slice which will contain all unique values and at the same time it will be the shortest slice that will meet the above criterion.
An example, for array {1, 2, 1, 2, 1, 4, 3, 4, 8, 1, 8} with 5 unique values {1, 2, 3, 4, 8} we are talking about slice {2, 1, 4, 3, 4, 8} with length 6.
Is there an optimal way to do this? As for now I've naive implementation that has far too high complexity (nested loops). I've tried to come up with an idea for an algorithm to do this in an optimal way but sadly to no avail. As for now I've tried to come up with something that will make use of occurrences for each unique value when looping through array, but still my mind is not clear enough. Any ideas are welcome, this problem is troubling me for a long time. :) Thank you in advance.
Best regards
The first run collects possible values and creates a map with pairs (value; counter = 0). Let Nis map size
For the second run prepare two indexes - left and right, and ActiveCnt.
Move right, updating map counters. When you update zero counter, increment ActiveCnt. When ActiveCnt becomes equal to N, stop.
Now move left, decrementing map counters. When some counter becomes zero, get difference between right and left, compare it with current MinLength, then decrement ActiveCnt. Continue with right index and so on.

Finding all combinations of numbers that equal a specific number

I've found a few articles on something similar but I'm still so new to coding that I feel I'm getting more confused. I picked this project to work on so if anyone can help or point me in a direction you think can best explain it for me that would be helpful or be able to dissect the code in smaller pieces.
The goal
User picks a number between 1-150
The code shows all combinations of numbers that sum up to equal that number but only using numbers between 1-50 and only using 5 digits. Also number can only be used once.
Example input is 15
Output:
1, 2, 3, 4, 5
This equals 15
If it was a higher number there would be more output combinations.
So general rules
Array of 5 numbers (can only use numbers between 1-50
Can only use each number once
Has to equal the input
Also no duplicate arrays would be nice like 1,2,3,4,5 vs 5,1,4,2,3
I'm trying to write this using Kotlin or Java but anything should help, thanks!
Interesting challenge :)
I believe following link might be useful:
All you need to do is replace array with yours and the value '10' ( ... sum(seq) == 10]) at the end of the equation is gonna be replaced by your chosen number, like so:
import itertools
numbers = [1, 2, 3, 7, 7, 9, 10, 11, 12, 13, 14, 15, 16]
chosen_number = 15
result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == chosen_number]
print result

Why does Python remove numbers randomly from array?

I am trying to solve a complex problem on HackerRank.com that involves creating a solution that accepts both small and large arrays of data ranging from 10 integers to 99,000 integers in length.
Find the problem here -> https://www.hackerrank.com/challenges/array-and-simple-queries
The Problem
How to put this simple is that I have take a array, copy a range of numbers from that array that the user specifies, then append it to a new array.
i = 2
j = 4
a = [1, 2, 3, 4, 5, 6, 7, 8]
for numbers in range(i, j + 1):
b.append(a[numbers - 1])
The range of numbers is appended to the b[] array. This should be 2, 3, 4 in the above example. Now I want to remove() the 2, 3, 4 from the a[] array. This is where I run into problems.
for numbers in range(i, j + 1):
a.remove(a[i-1])
This should remove numbers 2, 3, 4 and leave the a[] array as 1, 5, 6, 7, 8. This works in most cases as specified.
However, in larger arrays such as 500 in length. I see that a.remove() randomly removes numbers not in the range of i, j + 1.
Example
i = 239
j = 422
It removes a[47] and places it in another position as well removes i through j. I have NO IDEA why a[47] is being removed with the code specified above. Is remove() buggy?
What I Need Help On
I'm not trying to have the problem solved for me. I'm trying to understand why remove() is not working correctly. Logic says that it should not be removing anything from i through j, yet it is. Any help is greatly appreciated.
The .remove method on arrays doesn't remove elements by their index, but their value. If you want to delete part of the list, use the del operator (e.g. del a[5] to delete the sixth element, and del a[1:4] to delete the second, third, and fourth elements).
(As for solving this problem efficiently: if you look at the operations in reverse order, I think you don't have to actually manipulate an array.)

Algorithm to find "most common elements" in different arrays

I have for example 5 arrays with some inserted elements (numbers):
1,4,8,10
1,2,3,4,11,15
2,4,20,21
2,30
I need to find most common elements in those arrays and every element should go all the way till the end (see example below). In this example that would be the bold combination (or the same one but with "30" on the end, it's the "same") because it contains the smallest number of different elements (only two, 4 and 2/30).
This combination (see below) isn't good because if I have for ex. "4" it must "go" till it ends (next array mustn't contain "4" at all). So combination must go all the way till the end.
1,4,8,10
1,2,3,4,11,15
2,4,20,21
2,30
EDIT2: OR
1,4,8,10
1,2,3,4,11,15
2,4,20,21
2,30
OR anything else is NOT good.
Is there some algorithm to speed this thing up (if I have thousands of arrays with hundreds of elements in each one)?
To make it clear - solution must contain lowest number of different elements and the groups (of the same numbers) must be grouped from first - larger ones to the last - smallest ones. So in upper example 4,4,4,2 is better then 4,2,2,2 because in first example group of 4's is larger than group of 2's.
EDIT: To be more specific. Solution must contain the smallest number of different elements and those elements must be grouped from first to last. So if I have three arrrays like
1,2,3
1,4,5
4,5,6
Solution is 1,1,4 or 1,1,5 or 1,1,6 NOT 2,5,5 because 1's have larger group (two of them) than 2's (only one).
Thanks.
EDIT3: I can't be more specific :(
EDIT4: #spintheblack 1,1,1,2,4 is the correct solution because number used first time (let's say at position 1) can't be used later (except it's in the SAME group of 1's). I would say that grouping has the "priority"? Also, I didn't mention it (sorry about that) but the numbers in arrays are NOT sorted in any way, I typed it that way in this post because it was easier for me to follow.
Here is the approach you want to take, if arrays is an array that contains each individual array.
Starting at i = 0
current = arrays[i]
Loop i from i+1 to len(arrays)-1
new = current & arrays[i] (set intersection, finds common elements)
If there are any elements in new, do step 6, otherwise skip to 7
current = new, return to step 3 (continue loop)
print or yield an element from current, current = arrays[i], return to step 3 (continue loop)
Here is a Python implementation:
def mce(arrays):
count = 1
current = set(arrays[0])
for i in range(1, len(arrays)):
new = current & set(arrays[i])
if new:
count += 1
current = new
else:
print " ".join([str(current.pop())] * count),
count = 1
current = set(arrays[i])
print " ".join([str(current.pop())] * count)
>>> mce([[1, 4, 8, 10], [1, 2, 3, 4, 11, 15], [2, 4, 20, 21], [2, 30]])
4 4 4 2
If all are number lists, and are all sorted, then,
Convert to array of bitmaps.
Keep 'AND'ing the bitmaps till you hit zero. The position of the 1 in the previous value indicates the first element.
Restart step 2 from the next element
This has now turned into a graphing problem with a twist.
The problem is a directed acyclic graph of connections between stops, and the goal is to minimize the number of lines switches when riding on a train/tram.
ie. this list of sets:
1,4,8,10 <-- stop A
1,2,3,4,11,15 <-- stop B
2,4,20,21 <-- stop C
2,30 <-- stop D, destination
He needs to pick lines that are available at his exit stop, and his arrival stop, so for instance, he can't pick 10 from stop A, because 10 does not go to stop B.
So, this is the set of available lines and the stops they stop on:
A B C D
line 1 -----X-----X-----------------
line 2 -----------X-----X-----X-----
line 3 -----------X-----------------
line 4 -----X-----X-----X-----------
line 8 -----X-----------------------
line 10 -----X-----------------------
line 11 -----------X-----------------
line 15 -----------X-----------------
line 20 -----------------X-----------
line 21 -----------------X-----------
line 30 -----------------------X-----
If we consider that a line under consideration must go between at least 2 consecutive stops, let me highlight the possible choices of lines with equal signs:
A B C D
line 1 -----X=====X-----------------
line 2 -----------X=====X=====X-----
line 3 -----------X-----------------
line 4 -----X=====X=====X-----------
line 8 -----X-----------------------
line 10 -----X-----------------------
line 11 -----------X-----------------
line 15 -----------X-----------------
line 20 -----------------X-----------
line 21 -----------------X-----------
line 30 -----------------------X-----
He then needs to pick a way that transports him from A to D, with the minimal number of line switches.
Since he explained that he wants the longest rides first, the following sequence seems the best solution:
take line 4 from stop A to stop C, then switch to line 2 from C to D
Code example:
stops = [
[1, 4, 8, 10],
[1,2,3,4,11,15],
[2,4,20,21],
[2,30],
]
def calculate_possible_exit_lines(stops):
"""
only return lines that are available at both exit
and arrival stops, discard the rest.
"""
result = []
for index in range(0, len(stops) - 1):
lines = []
for value in stops[index]:
if value in stops[index + 1]:
lines.append(value)
result.append(lines)
return result
def all_combinations(lines):
"""
produce all combinations which travel from one end
of the journey to the other, across available lines.
"""
if not lines:
yield []
else:
for line in lines[0]:
for rest_combination in all_combinations(lines[1:]):
yield [line] + rest_combination
def reduce(combination):
"""
reduce a combination by returning the number of
times each value appear consecutively, ie.
[1,1,4,4,3] would return [2,2,1] since
the 1's appear twice, the 4's appear twice, and
the 3 only appear once.
"""
result = []
while combination:
count = 1
value = combination[0]
combination = combination[1:]
while combination and combination[0] == value:
combination = combination[1:]
count += 1
result.append(count)
return tuple(result)
def calculate_best_choice(lines):
"""
find the best choice by reducing each available
combination down to the number of stops you can
sit on a single line before having to switch,
and then picking the one that has the most stops
first, and then so on.
"""
available = []
for combination in all_combinations(lines):
count_stops = reduce(combination)
available.append((count_stops, combination))
available = [k for k in reversed(sorted(available))]
return available[0][1]
possible_lines = calculate_possible_exit_lines(stops)
print("possible lines: %s" % (str(possible_lines), ))
best_choice = calculate_best_choice(possible_lines)
print("best choice: %s" % (str(best_choice), ))
This code prints:
possible lines: [[1, 4], [2, 4], [2]]
best choice: [4, 4, 2]
Since, as I said, I list lines between stops, and the above solution can either count as lines you have to exit from each stop or lines you have to arrive on into the next stop.
So the route is:
Hop onto line 4 at stop A and ride on that to stop B, then to stop C
Hop onto line 2 at stop C and ride on that to stop D
There are probably edge-cases here that the above code doesn't work for.
However, I'm not bothering more with this question. The OP has demonstrated a complete incapability in communicating his question in a clear and concise manner, and I fear that any corrections to the above text and/or code to accommodate the latest comments will only provoke more comments, which leads to yet another version of the question, and so on ad infinitum. The OP has gone to extraordinary lengths to avoid answering direct questions or to explain the problem.
I am assuming that "distinct elements" do not have to actually be distinct, they can repeat in the final solution. That is if presented with [1], [2], [1] that the obvious answer [1, 2, 1] is allowed. But we'd count this as having 3 distinct elements.
If so, then here is a Python solution:
def find_best_run (first_array, *argv):
# initialize data structures.
this_array_best_run = {}
for x in first_array:
this_array_best_run[x] = (1, (1,), (x,))
for this_array in argv:
# find the best runs ending at each value in this_array
last_array_best_run = this_array_best_run
this_array_best_run = {}
for x in this_array:
for (y, pattern) in last_array_best_run.iteritems():
(distinct_count, lengths, elements) = pattern
if x == y:
lengths = tuple(lengths[:-1] + (lengths[-1] + 1,))
else :
distinct_count += 1
lengths = tuple(lengths + (1,))
elements = tuple(elements + (x,))
if x not in this_array_best_run:
this_array_best_run[x] = (distinct_count, lengths, elements)
else:
(prev_count, prev_lengths, prev_elements) = this_array_best_run[x]
if distinct_count < prev_count or prev_lengths < lengths:
this_array_best_run[x] = (distinct_count, lengths, elements)
# find the best overall run
best_count = len(argv) + 10 # Needs to be bigger than any possible answer.
for (distinct_count, lengths, elements) in this_array_best_run.itervalues():
if distinct_count < best_count:
best_count = distinct_count
best_lengths = lengths
best_elements = elements
elif distinct_count == best_count and best_lengths < lengths:
best_count = distinct_count
best_lengths = lengths
best_elements = elements
# convert it into a more normal representation.
answer = []
for (length, element) in zip(best_lengths, elements):
answer.extend([element] * length)
return answer
# example
print find_best_run(
[1,4,8,10],
[1,2,3,4,11,15],
[2,4,20,21],
[2,30]) # prints [4, 4, 4, 30]
Here is an explanation. The ...this_run dictionaries have keys which are elements in the current array, and they have values which are tuples (distinct_count, lengths, elements). We are trying to minimize distinct_count, then maximize lengths (lengths is a tuple, so this will prefer the element with the largest value in the first spot) and are tracking elements for the end. At each step I construct all possible runs which are a combination of a run up to the previous array with this element next in sequence, and find which ones are best to the current. When I get to the end I pick the best possible overall run, then turn it into a conventional representation and return it.
If you have N arrays of length M, this should take O(N*M*M) time to run.
I'm going to take a crack here based on the comments, please feel free to comment further to clarify.
We have N arrays and we are trying to find the 'most common' value over all arrays when one value is picked from each array. There are several constraints 1) We want the smallest number of distinct values 2) The most common is the maximal grouping of similar letters (changing from above for clarity). Thus, 4 t's and 1 p beats 3 x's 2 y's
I don't think either problem can be solved greedily - here's a counterexample [[1,4],[1,2],[1,2],[2],[3,4]] - a greedy algorithm would pick [1,1,1,2,4] (3 distinct numbers) [4,2,2,2,4] (two distinct numbers)
This looks like a bipartite matching problem, but I'm still coming up with the formulation..
EDIT : ignore; This is a different problem, but if anyone can figure it out, I'd be really interested
EDIT 2 : For anyone that's interested, the problem that I misinterpreted can be formulated as an instance of the Hitting Set problem, see http://en.wikipedia.org/wiki/Vertex_cover#Hitting_set_and_set_cover. Basically the left hand side of the bipartite graph would be the arrays and the right hand side would be the numbers, edges would be drawn between arrays that contain each number. Unfortunately, this is NP complete, but the greedy solutions described above are essentially the best approximation.

Resources