OraQA

Oracle Question and Answer

  • Do you have a solution to a problem? Do you have an unanswered question? Login and share it with the Oracle community. More...

Oracle News


Entries RSS feed

Comments RSS feed

How to solve the Optimal Ghost Puzzle in SQL

January 13th, 2010 By Frank Zhou

The following is an interesting puzzle posted by Itasofware on the web.

In the game of Ghost , two players take turns building up an English word from left to right.

Each player adds one letter per turn. The goal is to not complete the spelling of a word: if you add a letter that completes a word (of 4+ letters), or if you add a letter that produces a string that cannot be extended into a word, you lose.

Write a program that allows a user to play Ghost against the computer. The computer should play optimally given the following dictionary: WORD.LST.

Allow the human to play first. If the computer thinks it will win, it should play randomly among all its winning moves; if the computer thinks it will lose, it should play so as to extend the game as long as possible (choosing randomly among choices that force the maximal game length).

—————————————————————————————————————————————————-
Here is the strategy for solving this problem: Try to add a letter to the current input string, so that there is only “one word” left in the whole dictionary for your opponent. Once your opponent adds the next letter to the input string, that will complete the spelling of the word.

Solution:
Copy the word.lst from the web to a word.txt file on the database server ( \tmp directory).

create or replace directory tmp as 'C:\oracle\tmp';

CREATE  TABLE words (str VARCHAR2(38))
     ORGANIZATION EXTERNAL
     (
       TYPE ORACLE_LOADER
       DEFAULT DIRECTORY tmp
       ACCESS PARAMETERS
       (
         records delimited by newline
         fields terminated by whitespace
         missing field values are null
         ( str
         )
       )
       LOCATION ('word.txt')
     )
     REJECT LIMIT UNLIMITED;

COLUMN input FORMAT A18
COLUMN destination FORMAT A28
COLUMN next_char   FORMAT A12

variable input varchar2(38)
SQL> exec :input :='tar'

PL/SQL procedure successfully completed.

------------------------------SQL Solution----------------- 

WITH data AS
(SELECT str, length(str) as len, :input as input, length(:input) as in_len,
        case when str like :input||'_'
             then  str
             end as flag_str
 FROM words
 WHERE str LIKE :input||'%' and length(str) >=4
),
flag_data as
(
SELECT flag_str FROM data WHERE flag_str is not null
),
Filter_data as
(
SELECT distinct a.str FROM data a , flag_data b
WHERE substr(a.str, 1, length(b.flag_str)) = b.flag_str
),
Base_data as
(SELECT str, len , in_len, input FROM data
 WHERE str not in ( SELECT str FROM Filter_data)
)
SELECT input, destination, next_char
FROM
(SELECT input, str as destination, substr(str, in_len+1, 1) as next_char
  FROM
 (SELECT a.str, a.len, input, a.in_len,
         case when mod(a.len, 2) = 0 then 1
              else case when  REGEXP_LIKE (a.str, '^'||input||'[[:alpha:]]{2}$')
                        then case when
                                 (SELECT count(*) FROM data
                                  WHERE REGEXP_LIKE (str, '^'||substr(a.str,0,length(a.input)+1)||'[[:alpha:]]{2,}$')
                                  and  not REGEXP_LIKE (str, '^'||a.str||'[[:alpha:]]+$')
                                  ) = 0
                                  then 4
                                  else 3
                             end
                        else  2
                    end
         end as flag
  FROM Base_data a
 ) ORDER BY flag desc , case when flag = 1 then len else 0 end desc
)
WHERE ROWNUM = 1;

INPUT              DESTINATION                  NEXT_CHAR
------------------ ---------------------------- ------------
tar                targe                        g

SQL> exec :input := 'bot'

SQL> /

INPUT              DESTINATION                  NEXT_CHAR
------------------ ---------------------------- ------------
bot                botch                        c

SQL> exec :input := 'aba'

SQL> /

INPUT              DESTINATION                  NEXT_CHAR
------------------ ---------------------------- ------------
aba                abamp                        m

Leave a Reply

You must be logged in to post a comment.

RSS feed for comments on this question