Mostrando las entradas con la etiqueta programas. Mostrar todas las entradas
Mostrando las entradas con la etiqueta programas. Mostrar todas las entradas

sábado, 23 de junio de 2012

En homenaje a Alan Turing, una máquina en Python

En homenaje a Alan Turing, en el centenario de su nacimiento, una máquina universal de Turing, implementada en Python.

El ejemplo toma una cadena de A's y B's arbitrarias y sustituye todo por A's. Cambiando las reglas de las transiciones y los símbolos usados se podría cargar cualquier máquina... Al final se produce una respuesta: Accept o Crash.

Tomada de: http://code.activestate.com/recipes/252486-turing-machine-simulator/

## {{{ http://code.activestate.com/recipes/252486/ (r1)
#!/usr/bin/env python
# (C) 2003 Ryan Phillips 
# Uses Python 3 
 
import sys

pr = sys.stdout.write

class MachineTapeException(Exception):
 """ Turing Exception Exception """
 def __init__(self, value):
  Exception.__init__(self)
  self.value = value
 def __str__(self):
  return self.value

class TuringErrorException(Exception):
 """ Turing Exception Exception """
 def __str__(self):
  return "Crash"

class TuringAcceptException(Exception):
 """ Turing Accept Exception """
 def __str__(self):
  return "Accept"

class MachineTape:
 def __init__(self, initialString=[], initialPos=0, blank="_"):
  """ The Tape uses a simple list.  It could easily be changed into a string if
      need be """
  self.tape = []
  self.pos = initialPos
  self.blank = blank
  self.initialString = initialString
  if len(initialString) > 0:
      for ch in initialString:
       self.tape.append(ch)
  else:
      self.tape.append(blank)

 def reinit(self):
  self.__init__(self.initialString)

 def move(self, check_char, changeto_char, direction):
  """ Only R, L directions are supported """
  # check to see if the character under the head is what we need
  if check_char != self.tape[self.pos]:
   raise MachineTapeException ("Tape head doesn't match head character")
  
  # at this point the head is over the same character we are looking for
  #  change the head character to the new character
  self.tape[self.pos] = changeto_char
  
  if direction == "L":
   self.move_left()
  elif direction == "R":
   self.move_right()
  else: raise MachineTapeException ("Direction is invalid")
 
 def read(self):
  """ return the character over the head """
  return self.tape[self.pos]
 
 def move_left(self):
  if self.pos <= 0: 
   self.tape.insert(-1, self.blank)
   self.pos = 0
  else:
   self.pos += -1

 def move_right(self):
  self.pos += 1
  if self.pos >= len(self.tape): self.tape.append(self.blank)
 
 def show(self):
  """ print the tape """
  for ch in self.tape:
   pr(ch)
  pr("\n"); pr(" "*self.pos + "^"); pr("\n")

"""
The program structure for the TM is created with a dictionary.
    To step algorithm:
 1. Check to see if the length of the string is zero and if we
     are in a final state
 2. If the currentstate is in the final states then raise an Accept
 3. If the currentstate is not in the program then raise an Error
 4. Check the head character
 5. If the head character is not in the program and in the current state then
     raise an Error
 6. Retrieve from the dictionary the dest_state, char_out, and movement
 7. set the current state to the new state
 8. write the tape, and move the head

Program Layout:
    [state][char_in] --> [(dest_state, char_out, movement)]
"""

class TuringMachine:
 def __init__(self, initialString, finalStates=[], blank="_"):
  self.blank = blank
  self.tape = MachineTape(initialString)
  self.fstates = finalStates
  self.program = {}
  self.initState = 0
  self.state = self.initState
  self.lenStr = len(initialString)
 
 def reinit(self):
  self.state = self.initState
  self.tape.reinit()
 
 def addTransition(self, state, char_in, dest_state, char_out, movement):
  if not self.program.has_key(state):
   self.program[state] = {}

  tup = (dest_state, char_out, movement)
  self.program[state][char_in] = tup

 def step(self):
  """ Steps 1 - 3 """
  if self.lenStr == 0 and self.state in self.fstates: raise TuringAcceptException
  if self.state in self.fstates: raise TuringAcceptException 
  if self.state not in self.program.keys(): raise TuringErrorException
  
  """ Steps 4 and 5 """
  head = self.tape.read()
  if head not in self.program[self.state].keys(): raise TuringErrorException
   
  """ Steps 6 and 7 """
  # execute transition
  (dest_state, char_out, movement) = self.program[self.state][head]
  self.state = dest_state
  try:
   """ Step 8 """
   self.tape.move(head, char_out, movement)
  except MachineTapeException, s:
   print s

 def execute(self):
  """ The TM will keep stepping forever until the TM accepts or rejects.
      This does allow for looping TM's """
  try:
   while 1:
    m.tape.show()
    m.step()
  except (TuringErrorException, TuringAcceptException), s:
   print s

if __name__ == "__main__":
    # machine to convert a string of A's and B's to
    # all A's and accept
    m = TuringMachine("ABBABB", [1])

    m.addTransition(0,'A',0,'A','R')
    m.addTransition(0,'B',0,'A','R')
    m.addTransition(0,'_',1,'_','L')

    # run the TM
    m.execute()
## end of http://code.activestate.com/recipes/252486/ }}}

martes, 13 de septiembre de 2011

Programmers Day program: A glider!

En honor al día del programador , hice este pequeño programa...
un Glider del juego de la vida, a 10 iteraciones sobre una rejilla de 6x6 con frontera abierta...

Felicidades programadores!



glider = [[0, 0, 1, 0, 0, 0],
          [1, 0, 1, 0, 0, 0],
          [0, 1, 1, 0, 0, 0],
          [0, 0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0],
          [0, 0, 0, 0, 0, 0]
         ]

def printg(grid):
    """                                                                                                                             
    Imprime un arreglo bidimensional.                                                                                               
                                                                                                                                    
    Cambia los 0's por puntos '.' para mayor claridad.                                                                              
    """
    for i in range(len(grid)):
        row = ""
        for j in range(len(grid[i])):
            row += str(grid[i][j]) if grid[i][j] == 1 else '.'
        print row

def vecindad ((y,x), grid):
    """                                                                                                                             
    Vecindad de VonNeumann de una celda dada en la rejilla.                                                                         
                                                                                                                                    
    Se asume un automata celular de frontera 'fria' (o abierta, es                                                                  
    decir rodeada de 0's).                                                                                                          
    """
    try:
        val = grid[y][x]
        vec = [[0 for j in range(0,3)] for i in range(0,3)]
        for i in range(-1,2):
            for j in range(-1,2):
                # si la casilla vecina esta dentro de la rejilla, la                                                                
                # toma. Si no, asume un 0                                                                                           
                vec[i+1][j+1] = grid[y+i][x+j] if (y+i,x+j) >= (0,0) and y+i < len(grid) and x+j < len(grid[y+i]) else 0
    except Exception as e:
        return None
    return vec

def lifegame(grid):
    """                                                                                                                             
    Juego de la vida.                                                                                                               
                                                                                                                                    
    Toma por cada casilla su vecindad de VonNeumann y evalua la                                                                     
    cantidad de vecinos vivos de ella.                                                                                              
                                                                                                                                    
    -Si esta viva y tiene 2 o 3 vecinos vivos, queda viva                                                                           
    -De lo contrario muere                                                                                                          
    -Si esta muerta y tiene exactamente 3 vecinos vivos, vive                                                                       
    """
    # arreglo de 0's sobre el que se calculara siguiente iteracion                                                                  
    temp = [[0 for j in range(len(glider[i]))] for i in range(len(glider))]

    # recorre cada casilla de la rejilla y toma su vecindad, aplicando                                                              
    # despues reglas del juego                                                                                                      
    for i in range(len(glider)):
        for j in range(len(glider[i])):
            centro = glider[i][j]
            vec = vecindad((i,j), glider)
            if vec == None:
                return None

            # cuenta cantidad de vecinos vivos de la casilla                                                                        
            vecinos_vivos = 0
            for vi in range(len(vec)):
                for vj in range(len(vec)):
                    if (vi,vj) != (1,1) and vec[vi][vj] == 1:
                        vecinos_vivos += 1

            # aplica reglas del juego de la vida                                                                                    
            if centro == 1:
                if vecinos_vivos == 2 or vecinos_vivos == 3:
                    temp[i][j] = 1
                else:
                    temp[i][j] = 0
            else:
                if vecinos_vivos == 3:
                    temp[i][j] = 1
    return temp

#### MAIN ####                                                                                                                      
printg(glider)
for c in range(10):
    glider = lifegame(glider)
    if glider == None:
        print "Error!!!"
        break
    print ""
    printg(glider)





--- Eru kaluva tielyanna (Dios iluminará tu camino) "Ama y haz lo que quieras. Si callas, callarás con amor; si gritas, gritarás con amor; si corriges, corregirás con amor; si perdonas, perdonarás con amor. Si tienes el amor arraigado en ti, ninguna otra cosa sino amor serán tus frutos." (San Agustín) Solamente asegúrate que en realidad sea AMOR...