Can someone explain Rule 110 in the simplest way possible? - programming-languages

I can't wrap my head around what the Wikipedia article or the answer here say.
Can someone explain Rule 110 in simple terms? How does it guarantee Turing completeness?

My attempt at a succinct, layman's terms explanation:
Rule 110 is an elementary cellular automaton: a rule for transforming a finite pattern of 1's and 0's into another pattern of 1's and 0's.
When Rule 110 is iteratively applied on certain input bit sequences, patterns emerge depending on sub-sequences found in the input bits. Given enough iterations, the following can happen:
The original sub-sequence appears in the same location as in the original input.
The original sub-sequence is preserved but 'moves' to a different location in the bitfield.
Two sub-sequences moving toward each other interact and 'pass through' each other.
Two sub-sequences combine to create a new sub-sequence.
Different sub-sequences can be given symbolic meaning like '1', '0', 'clock pulse', or 'production rule' that correspond to the elements of a cyclic tag system.
With many iterations of Rule 110 on a carefully constructed input bitfield, the interaction of the sub-sequences simulates the behavior of a cyclic tag system.
A cyclic tag system can be used to simulate a universal Turing machine. Thus a cyclic tag system is Turing-complete.
Since Rule 110 can simulate a cyclic tag system, it too is Turing-complete.

I'll have a go at elaborating: I don't think you are looking for more details of the proof which is already quite complex in the article, although it clearly omits many details.
To quote from the article you cite: "In an elementary cellular automaton, a one-dimensional pattern of 0's and 1's evolves according to a simple set of rules. Whether a point in the pattern will be 0 or 1 depends in the new generation on its current value, as well of that of its two neighbors. The Rule 110 automaton has the following set of rules..." (see the wikipedia table that follows)
The starting point, which you can view as the data, but which can be taken as a representation of code (representing code as data is necessary for any proof of Turing-completeness; this goes back to Turing's original results), is a sequence of 0's and 1's, often, but not necessarily, surrounded on both sides by cells containing just 0. Rule 110 shows how that sequence evolves. For instance, if there is a pattern of 3 1's in one row, the middle 1 will "die" (turn into a 0) in the next row. What happens to its two neighbours depends on how the pattern extends beyond them. The triangular diagrams you see are a graphical representation of the evolution of the automaton from the original state, coding 1 as black and 0 as white and representing evolution from above to below. The initial state is often very short in length to show how very complex patterns can evolve from simple initial states.
Two unusual features of the proof of Turing completeness are that, firstly, it looks highly unlikely that such a very simple rule could do everything your favourite programming language could do, and secondly, which makes the first fact rather less amazing, is that the proof requires an infinitely long repeating background on which to work its magic. I cannot see anything fundamentally dishonest about this though; no more so than assuming a potentially infinite or semi-infinite blank tape, as Turing originally did.
To understand the proof properly you would need to get to grips with how data (and later, code) is encoded in the starting pattern, and it also looks as if familiarity with cyclic tag systems would help enormously. I'm not the person to explain those.
Although it may seem harder to understand the situation with a 2-D cellular automaton, such as Conway's "Game of Life", I found it instructive to play with that game, studying "gliders", "glider guns" and "puffer trains" and other amusing constructions. (A puffer train constructs glider guns and a glider gun fires gliders). These can be used to establish Turing-completeness for this automaton as well.
You may also find the talk page informative (you are not alone in not grasping the point, see the entry beginning "the pictures don't make any sense to me..").

In 1970 John Conway has invented Game of Life.
Ever since, I think almost every programmer tried to write its implementation - I certainly did long time ago, and it was a lot of fun.
This game is actually cellular automaton, which sets simple rules between generations of cells in infinite 2-dimensional plane. For example, if in current generation cell has less than 2 neighbors alive (bit value 1), then it should die in next generation of loneliness. If it has more than 3 neighbors alive, it should die of overcrowding. If empty (bit value 0, or dead) cell has exactly 3 neighbors, it will cause it to be born (become 1).
Since then, it was found that Game of Life is surprisingly complex - it can generate a lot of very complex patterns that continue to evolve. Also, it was shown that it is Turing-complete, that is, you can encode arbitrarily complex algorithms using starting cell combination as a program, and final combination as a result. However, it took few years to find how to actually generate complicated forms, like gliders or guns.
Now back to what rule 110 is. Simply put, rule 110 is one-dimensional variation of Game of Life.
110 is just a decimal number representation of binary string 01101110 which is short form of rule system of how current generation of cells (bits) will be translated into next one, similar to Game of Life's rule system of cells dying of loneliness or overcrowding and being born of having exactly three neighbors.
Much like Game of Life, it has been proven that rule 110 is Turing-complete. You can encode arbitrarily complex algorithm using starting cells (bits) combination as your program, and final bits combination as a result.

An implementation in python:
(Be adviced: actual python programmers would kill you for this)
import time
seed = raw_input("Feed me a string! (At least 3 characters long please)\n>")
lastline = '>'
iterator = 0
while (iterator<len(seed)):
temp = (ord(seed[iterator]))%2
if (temp == 1):
lastline += '#'
else:
lastline += ' '
iterator += 1
stop = 0
while (stop != 1): #Keep printing as long as CTRL-C isn't pressed
#dummy = raw_input(lastline)
print lastline
iterator = 0
nextline = '>'
while (iterator<len(seed)): #Convert entire string
if (len(seed) < 3): # if wrong
print "You had ONE JOB!"
stop = 1
elif (iterator == 0): # if at start
if (lastline[1] == ' '):
nextline += ' '
else:
nextline += '#'
elif (iterator+1 == len(seed)): # if at end
if (lastline[iterator+1] == ' '):
nextline += ' '
else:
nextline += '#'
else: #if in middle
if (lastline[iterator] == '#' and lastline[iterator+1] == '#' and lastline[iterator+2] == '#'): #111
nextline += ' '
elif (lastline[iterator] == '#' and lastline[iterator+1] == '#' and lastline[iterator+2] == ' '): #110
nextline += '#'
elif (lastline[iterator] == '#' and lastline[iterator+1] == ' ' and lastline[iterator+2] == '#'): #101
nextline += '#'
elif (lastline[iterator] == '#' and lastline[iterator+1] == ' ' and lastline[iterator+2] == ' '): #100
nextline += ' '
elif (lastline[iterator] == ' ' and lastline[iterator+1] == '#' and lastline[iterator+2] == '#'): #011
nextline += '#'
elif (lastline[iterator] == ' ' and lastline[iterator+1] == '#' and lastline[iterator+2] == ' '): #010
nextline += '#'
elif (lastline[iterator] == ' ' and lastline[iterator+1] == ' ' and lastline[iterator+2] == '#'): #001
nextline += '#'
else: # (lastline[iterator-1] == ' ' and lastline[iterator] == ' ' and lastline[iterator+1] == ' '): #000
nextline += ' '
iterator += 1
lastline = nextline
time.sleep(0.02)

Related

problem in character creation for mud game in python

hello i m new to python and i m making a mud game so i m stuck at a certain point where i have to create a character and following is my code. as i need to give 2 option to the player with the description and then player will select one of the given choices. help me with the code in python.
def selectcharacter():
character = ""
while character != "Red pirate" and character != "dreed prince":
character = input("which character you want to choose? (Red pirate or Dreed prince ):")
return character
def checkcharacter(chosencharacter):
if (chosencharacter == Red pirate):
print("the ability of the character is to fight close range battles and has 125 health and 50 armor!"),
if (chosencharacter == Dreed prince):
print("the ability of the character is to fight long range battles and has 100 health and 25 armor!")
else:
print("no character selected.please select the character!")
checkcharacter()
selectcharacter()
You have some syntax errors and you need to pass a string as a function argument.
From what I can tell you want to first select a character and then change the output based on your selection.
Your code is almost working you just need to fix the syntax errors and save the selection in a variable, to be able to pass it to the next function.
def selectcharacter():
character = ""
while character != "Red pirate" and character != "Dreed prince":
character = input("which character you want to choose? (Red pirate or Dreed prince ):")
return character
def checkcharacter(chosencharacter):
if (chosencharacter == "Red pirate"): # should be string
print("the ability of the character is to fight close range battles and has 125 health and 50 armor!"),
elif (chosencharacter == "Dreed prince"): # should be string
print("the ability of the character is to fight long range battles and has 100 health and 25 armor!")
else:
print("no character selected.please select the character!")
selected_character = selectcharacter()
checkcharacter(selected_character)
The characters should be converted to strings, so you can check if they are equal to the passed argument chosencharacter. You also should use an elif instead of a second if because, otherwise the second if would get evaluated (to False) even if the first one is True.

How do I achieve this following function only using while loop?

I'm currently working on this problem that ask me to generate an arrow pattern using loops function that looks something like this:
"How many columns? 3"
*
*
*
*
*
I know I can do this with for loop(probably more efficient too), but that is not what I aimed for. I wanted to achieve this only using while loop.
I have some ideas:
1. I set up a control variable and an accumulator to control the loop
2. I then write 2 separate loops to generate the upper and lower part of the pattern. I was thinking about inserting the space before the asterisks using method like this:
(accumulator - (accumulator - integer)) * spaces.
#Ask the user how many column and direction of column
#they want to generate
Keep_going = True
Go = 0
while keep_going:
Column_num = int(input("How many columns? "))
if Column_num <= 0:
print("Invalid entry, try again!")
else:
print()
Go = 1
#Upper part
while Keep_going == True and Go == 1:
print("*")
print(""*(Column_num - (Column_num - 1) + "*")
...but I soon realized it wouldn't work because I don't know the user input and thus cannot manually calculate how many spaces to insert before asterisks. Now everything on the internet tells me to use for loop and range function, I could do that, but I think that is not helpful for me to learn python since I couldn't utilize loops very well yet and brute force it with some other method just not going to improve my skills.
I assume this is achievable only using while loop.
#Take your input in MyNumber
MyNumber = 5
i = 1
MyText = '\t*'
while i <=MyNumber:
print(MyText.expandtabs(i-1))
i = i+1
i = i-1
while i >=1:
print(MyText.expandtabs(i-1))
i = i-1
Python - While Loop
Well first you have to understand that a while loop loops until a requirement is met.
And looking at your situation, to determine the number of spaces before the * you should have an ongoing counter, a variable that counts how many spaces are needed before you continue. For example:
###Getting the number of columns###
while True:
number=int(input('Enter number of rows: '))
if number<=0:
print('Invalid')
else:
###Ending the loop###
break
#This will determine the number of spaces before a '*'
counter=0
#Loops until counter equals number
while counter!=number:
print(" "*counter + "*")
#Each time it loops the counter variable increases by 1
counter=counter+1
counter=counter-1
#Getting the second half of the arrow done
while counter!=0:
counter=counter-1
print(" "*counter + "*")
Please reply if this did not help you so that i can give a more detailed response

How can I remove POS Tags in pythons and print the tree preserving subtree orders

I am pretty new to python and need help on the following.
I have a string of the format:
(S Silver/RB (Chunk 42/CD inch/NN) LED/NNP HD/NNP Nakamichi/NNP Smart/NNP Flat/NNP (Chunk 3D/CD TV/NN))
The output I want:
Silver , 42 inch, LED , Nakamichi, Smart, Flat , 3D TV
Basically I want to preserve the subtree as a single string while printing it.
Please help
Firstly, you should only post to SO with some code you tried yourself, so we can see you made any effort to solve your own problem. Getting help in state you shown is just a good will of people, but probably your post is gonna just be downvoted.
Anyways, the pattern you've shown here doesn't seem to obey any rule, as, for example, 'Silver' part has the '/RB' string stripped from it and '42 inch' element from output has not only to strip other strings, that are '/CD' and '/NN', but should also be connected as one string. Unless you just messed up your commas and you want a single string (not a list, as it seems with what you have posted), then:
text = '(S Silver/RB (Chunk 42/CD inch/NN) LED/NNP HD/NNP Nakamichi/NNP Smart/NNP Flat/NNP (Chunk 3D/CD TV/NN))'
split_text = text.split(' ')
new_text = ''
for item in split_text:
if item[0].isnumeric():
new_text += item[:item.find('/')] + ' '
elif item[0] == '(':
pass
else:
new_text += item[:item.find('/')] + ' , '
new_text = new_text[:-3]
new_text
Output:
'Silver , 42 inch , LED , HD , Nakamichi , Smart , Flat , 3D TV'
Still there is little point to do that as the string is short and there are no regular patterns in it (unless, as I said, you messed up with showing what you really want).

Implement a while loop in my hangman type/puzzle game

I'm new to python programming. I would like to display a win message after every correct letter input and no message if an incorrect letter is input.
I've written my code such that it will only accept one letter at a time and reduce an attempt by 1, regardless of if it is wrong or right.
How would I be able to implement a while loop into this so that I don't keep getting this error:
builtins.TypeError: 'str' object does not support item assignment
word="banana"
word_list=list(word)
length=len(word_list)
word_list= set(word_list)
word_list=list(word_list)
answer=["_"]*length
answer=list(answer)
guess=[]
count = 4
win=False # boolean so we do not use an identifier in our if statements
user_guess=window.input_string("Guess a letter: ", x, y)
y = y + font_height
guess.append(user_guess)
while count > 0:
# Removes guesses if they are not in the word so that the blanks do not fill in with incorrect letters
for letter in guess:
if letter not in word_list:
guess.remove(letter)
else:
win=True
# Replaces blanks in empty list with the letter guess
for place,letter in enumerate(list(word)):
for i in range(len(guess)):
if letter == guess[i]:
answer[place]=guess[i]
answer=" ".join(answer)
update_message = 'The answer so far is: '
window.draw_string(update_message + answer,x,y)
y = y + font_height
#End Game
win_message = 'Good job! You got the word.'
lose_message = 'Not quite, the correct word was: '+word +' Better luck next time'
if win:
window.draw_string(win_message,x,y)
y = y + font_height
count -=1
else:
window.draw_string(lose_message,x,y)
y = y + font_height
count -=1
Please notice this assignment: answer=" ".join(answer). Before the assignment, answer is a list of string. After the assignment, answer becomes a string.
So, in the next iteration of the while loop, answer[place]=guess[i] turns invalid, because python does not allow modifying a string by assigning a "character" to some place of the string.
It really takes some time to find the fault. You'd better provide the information, like, "which line in the program targeted the error message", when asking questions in future.

Combining words in a dictionary to match a single word

I'm working on a problem where I need to check how many words in a dictionary can be combined to match a single word.
For example:
Given the string "hellogoodsir", and the dictionary: {hello, good, sir, go, od, e, l}, the goal is to find all the possible combinations to form the string.
In this case, the result would be hello + good + sir, and hello + go + od + sir, resulting in 3 + 4 = 7 words used, or 1 + 1 = 2 combinations.
What I've come up with is simply to put all the words starting with the first character ("h" in this instance) in one hashmap (startH), and the rest in another hashmap (endH). I then go through every single word in the startH hashmap, and check if "hellogoodsir" contains the new word (start + end), where end is every word in the endH hashmap. If it does, I check if it equals the word to match, and then increments the counter with the value of the number for each word used. If it contains it, but doesn't equal it, I call the same method (recursion) using the new word (i.e. start + end), and proceed to try to append any word in the end hashmap to the new word to get a match.
This is obviously very slow for large number of words (and a long string to match). Is there a more efficient way to solve this problem?
As far as I know, this is an O(n^2) algorithm, but I'm sure this can be done faster.
Let's start with your solution. It is no linear nor quadric time, it's actually exponential time. A counter example that shows that is:
word = "aaa...a"
dictionary = {"a", "aa", "aaa", ..., "aa...a"}
Since your solution is going through each possible matching, and there is exponential number of such in this example - the solution is exponential time.
However, that can be done more efficiently (quadric time worst case), with Dynamic Programming, by following the recursive formula:
D[0] = 1 #
D[i] = sum { D[j] | word.Substring(i,j) is in the dictionary | 0 <= j < i }
Calculating each D[i] (given the previous ones are already known) is done in O(i)
This sums to total O(n^2) time, with O(n) extra space.
Quick note: By iterating the dictionary instead of all (i,j) pairs for each D[i], you can achieve O(k) time for each D[i], which ends up as O(n*k), where k is the dictionary size. This can be optimized for some cases by traversing only potentially valid strings - but for the same counter example as above, it will result in O(n*k).
Example:
dictionary = {hello, good, sir, go, od, e, l}
string = "hellogoodsir"
D[0] = 1
D[1] = 0 (no substring h)
D[2] = 0 (no substring he, d[1] = 0 for e)
...
D[5] = 1 (hello is the only valid string in dictionary)
D[6] = 0 (no dictionary string ending with g)
D[7] = D[5], because string.substring(5,7)="go" is in dictionary
D[8] = 0, no substring ending with "oo"
D[9] = 2: D[7] for "od", and D[5] for "good"
D[10] = D[11] = 0 (no strings in dictionary ending with "si" or "s")
D[12] = D[7] = 2 for substring "sir"
My suggestion would be to use a prefix tree. The nodes beneath the root would be h, g, s, o, e, and l. You will need nodes for terminating characters as well, to differentiate between go and good.
To find all matches, use a Breadth-first-search approach. The state you will want to keep track of is a composition of: the current index in the search-string, the current node in the tree, and the list of words used so far.
The initial state should be 0, root, []
While the list of states is not empty, dequeue the next state, and see if the index matches any of the keys of the children of the node. If so, modify a copy of the state and enqueue it. Also, if any of the children are the terminating character, do the same, adding the word to the list in the state.
I'm not sure on the O(n) time on this algorithm, but it should be much faster.

Resources