Flipping bits game

From Rosetta Code
Revision as of 10:39, 10 July 2013 by rosettacode>Paddy3118 (New draft task and Python solution.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Flipping bits game is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
The game

Given an N by N sqare array of zeroes or ones in an initial configuration, and a target configuration of zeroes and ones The task is to transform one to the other in as few moves as possible by inverting whole numbered rows or whole lettered columns at once, as one move.

In an inversion any 1 becomes 0, and any 0 becomes 1 for that whole row or column.

The Task

The task is to create a program to score for the Flipping bits game.

  1. The game should create an original random target configuration and a starting configuration.
  2. The starting position should not ever be the target position.
  3. The target position should be guaranteed to be reachable from the starting position.
  4. The number of moves taken so far should be shown.
  5. Show an example of a short game here, on this page, for a 3 by 3 array of bits.

Python

<lang python>""" Given a %i by %i sqare array of zeroes or ones in an initial configuration, and a target configuration of zeroes and ones The task is to transform one to the other in as few moves as possible by inverting whole numbered rows or whole lettered columns at once. In an inversion any 1 becomes 0 and any 0 becomes 1 for that whole row or column.

"""

from random import randrange from copy import deepcopy from string import ascii_lowercase


try: # 2to3 fix

   input = raw_input

except:

   pass

N = 3 # N x N Square arrray

board = [[0]* N for i in range(N)]

def setbits(board, count=1):

   for i in range(count):
       board[randrange(N)][randrange(N)] ^= 1

def shuffle(board, count=1):

   for i in range(count):
       if randrange(0, 2):
           fliprow(randrange(N))
       else:
           flipcol(randrange(N))


def pr(board, comment=):

   print(str(comment))
   print('     ' + ' '.join(ascii_lowercase[i] for i in range(N)))
   print('  ' + '\n  '.join(' '.join(['%2s' % j] + [str(i) for i in line])
                            for j, line in enumerate(board, 1)))

def init(board):

   setbits(board, count=randrange(N)+1)
   target = deepcopy(board)
   while board == target:
       shuffle(board, count=2 * N)
   prompt = '  X, T, or 1-%i / %s-%s to flip: ' % (N, ascii_lowercase[0], 
                                                   ascii_lowercase[N-1])
   return target, prompt

def fliprow(i):

   board[i-1][:] = [x ^ 1 for x in board[i-1] ]
   

def flipcol(i):

   for row in board:
       row[i] ^= 1

if __name__ == '__main__':

   print(__doc__ % (N, N))
   target, prompt = init(board)
   pr(target, 'Target configuration is:')
   print()
   turns = 0
   while board != target:
       turns += 1
       pr(board, '%i:' % turns)
       ans = input(prompt).strip()
       if (len(ans) == 1 
           and ans in ascii_lowercase and ascii_lowercase.index(ans) < N):
           flipcol(ascii_lowercase.index(ans))
       elif ans and all(ch in '0123456789' for ch in ans) and 1 <= int(ans) <= N:
           fliprow(int(ans))
       elif ans == 'T':
           pr(target, 'Target configuration is:')
           turns -= 1
       elif ans == 'X':
           break
       else:
           print("  I don't understand %r... Try again. "
                 "(X to exit or T to show target)\n" % ans[:9])
           turns -= 1
   else:
       print('\nWell done!\nBye.')</lang>
Output:
Given a 3 by 3 sqare array of zeroes or ones in an initial
configuration, and a target configuration of zeroes and ones
The task is to transform one to the other in as few moves as 
possible by inverting whole numbered rows or whole lettered 
columns at once.
In an inversion any 1 becomes 0 and any 0 becomes 1 for that
whole row or column.


Target configuration is:
     a b c
   1 0 1 0
   2 0 0 0
   3 0 0 0
()
1:
     a b c
   1 1 0 0
   2 0 0 1
   3 0 0 1
  X, T, or 1-3 / a-c to flip: 1
2:
     a b c
   1 0 1 1
   2 0 0 1
   3 0 0 1
  X, T, or 1-3 / a-c to flip: c

Well done!
Bye.
Showing bad/other inputs
Target configuration is:
     a b c
   1 0 0 0
   2 0 0 0
   3 0 0 1
()
1:
     a b c
   1 1 0 1
   2 0 1 0
   3 0 1 1
  X, T, or 1-3 / a-c to flip: 3
2:
     a b c
   1 1 0 1
   2 0 1 0
   3 1 0 0
  X, T, or 1-3 / a-c to flip: 4
  I don't understand '4'... Try again. (X to exit or T to show target)

2:
     a b c
   1 1 0 1
   2 0 1 0
   3 1 0 0
  X, T, or 1-3 / a-c to flip: c
3:
     a b c
   1 1 0 0
   2 0 1 1
   3 1 0 1
  X, T, or 1-3 / a-c to flip: d
  I don't understand 'd'... Try again. (X to exit or T to show target)

3:
     a b c
   1 1 0 0
   2 0 1 1
   3 1 0 1
  X, T, or 1-3 / a-c to flip: T
Target configuration is:
     a b c
   1 0 0 0
   2 0 0 0
   3 0 0 1
3:
     a b c
   1 1 0 0
   2 0 1 1
   3 1 0 1
  X, T, or 1-3 / a-c to flip: X