ABC problem

From Rosetta Code
Revision as of 20:40, 8 January 2014 by rosettacode>Paddy3118 (NOT a set as there are two (F S) blocks)
ABC problem 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.

You are given a collection of ABC blocks. Just like the ones you had when you were a kid. There are twenty blocks with two letters on each block. You are guaranteed to have a complete alphabet amongst all sides of the blocks. The sample blocks are:

((B O)
(X K)
(D Q)
(C P)
(N A)
(G T)
(R E)
(T G)
(Q D)
(F S)
(J W)
(H U)
(V I)
(A N)
(O B)
(E R)
(F S)
(L Y)
(P C)
(Z M))

The goal of this task is to write a function that takes a string and can determine whether you can spell the word with the given set of blocks. The rules are simple:

  1. Once a letter on a block is used that block cannot be used again
  2. The function should be case-insensitive
  3. Show your output on this page for the following words:
Example

<lang python>

   >>> can_make_word("")
   False
   >>> can_make_word("A")
   True
   >>> can_make_word("BARK")
   True
   >>> can_make_word("BOOK")
   False
   >>> can_make_word("TREAT")
   True
   >>> can_make_word("COMMON")
   False
   >>> can_make_word("SQUAD")
   True

</lang>

J

Solution: <lang j>can_make_word=: #/.~@] *./@:<: #/.~@[ {~ i.&(tolower@~.)</lang>

Examples <lang j>Blocks=: , ];._2 noun define BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM )

ExampleWords=: a: , ;:'A BARK BOOK TREAT COMMON SQUAD'

  Blocks&can_make_word &> ExampleWords

1 1 1 1 1 0 1</lang>

Python

<lang python>BLOCKS = ['BO', 'XK', 'DQ', 'CP', 'NA', 'GT', 'RE', 'TG', 'QD', 'FS',

         'JW', 'HU', 'VI', 'AN', 'OB', 'ER', 'FS', 'LY', 'PC', 'ZM',]

def _abc(word, blocks):

   for i, ch in enumerate(word):
       for blk in (b for b in blocks if ch in b):
           whatsleft = word[i + 1:]
           blksleft = blocks[:]
           blksleft.remove(blk)
           if not whatsleft: 
               return True, blksleft
           if not blksleft: 
               return False, blksleft
           ans, blksleft = _abc(whatsleft, blksleft)
           if ans:
               return ans, blksleft
       else:
           break
   return False, blocks

def abc(word, blocks=BLOCKS):

   return _abc(word.upper(), blocks)[0]

if __name__ == '__main__':

   for word in [] + 'A BARK BoOK TrEAT COmMoN SQUAD'.split():
       print('Can we spell %8r? %r' % (word, abc(word)))</lang>
Output:
Can we spell       ''? False
Can we spell      'A'? True
Can we spell   'BARK'? True
Can we spell   'BoOK'? False
Can we spell  'TrEAT'? True
Can we spell 'COmMoN'? False
Can we spell  'SQUAD'? True