We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
Looks more like a dp problem to me. Here is my long and ugly solution.
The main idea is, first find all the available spots where to put words.
Then, find their length.
Then, sort them by how many of each lengths there are.
Start with the smallest numbers. If there is only one spot of length 5. The put the apppropriate word in that spot. Move to the next smallest number of words of that length, saving the possible configurations of the crossword that you found.
Then loop over each spot/word length. For each set word/spot lengths, try all possiblities, store all possible configurations at that stage. Repeat, by the end, only one possible solution works.
I think the functions ishstart/isvstart/findend/findspots and putword are reasonably nice. The function match can probably be writtend much better, in a recursive or nicer dp way.
fromcollectionsimportdefaultdictfromcopyimportdeepcopy## Complete the 'crosswordPuzzle' function below.## The function is expected to return a STRING_ARRAY.# The function accepts following parameters:# 1. STRING_ARRAY crossword# 2. STRING words#defishstart(crossword,i,j):ifi==9orcrossword[i+1][j]=='+':returnFalseifi==0orcrossword[i-1][j]=='+':returnTruereturnFalsedefisvstart(crossword,i,j):ifj==9orcrossword[i][j+1]=='+':returnFalseifj==0orcrossword[i][j-1]=='+':returnTruereturnFalsedeffindend(crossword,i,j,wordtype):ifwordtype=='Horizontal':start=iwhilestart<10andcrossword[start][j]=='-':start+=1return(start-1,j)ifwordtype=='Vertical':start=jwhilestart<10andcrossword[i][start]=='-':start+=1return(i,start-1)deffindspots(crossword):spots=defaultdict(list)foriinrange(10):forjinrange(10):ifcrossword[i][j]=='-':ifishstart(crossword,i,j):end=findend(crossword,i,j,'Horizontal')spots[end[0]-i+1].append(((i,j),end))ifisvstart(crossword,i,j):end=findend(crossword,i,j,'Vertical')spots[end[1]-j+1].append(((i,j),end))returnspotsdefputword(cs,spot,word):xi,yi=spot[0]xf,yf=spot[1]l=0cross=deepcopy(cs)foriinrange(xi,xf+1):forjinrange(yi,yf+1):ifcs[i][j]=='-'orcs[i][j]==word[l]:cross[i][j]=word[l]l+=1else:returnFalsereturncrossdefmatch(words,spots,crossword):wlengths=defaultdict(list)forwordinwords:wlengths[len(word)].append(word)nwords=[]forwlength,wordsinwlengths.items():nwords.append([len(words),wlength])nwords.sort()dp=Nonefornwordinnwords:npossib,word_length=nwordifnpossib==1:word_toput=wlengths[word_length][0]spot_toput=spots[word_length][0]ifdp:crossword=dp[0]newcross=putword(crossword,spot_toput,word_toput)dp=[newcross]else:words_toput=wlengths[word_length]spots_toput=spots[word_length]sols=[]ifdp:forcrossindp:poss=[cross]forwdinwords_toput:newposs=[]forcrossinposs:forspinspots_toput:newcross=putword(cross,sp,wd)ifnewcross:newposs.append(newcross)poss=newpossifnotposs:breakforsolinposs:sols.append(sol)else:forwdinwords_toput:forspinspots_toput:newcross=putword(crossword,sp,wd)ifnewcross:sols.append(newcross)dp=solsreturndpdefcrosswordPuzzle(crossword,words):crossword=[list(el)forelincrossword]spots=findspots(crossword)# print(spots)words=words.split(';')'sol=match(words,spots,crossword)[-1][0]# pprint(sol)return[''.join(el)forelinsol]
Cookie support is required to access HackerRank
Seems like cookies are disabled on this browser, please enable them to open this website
Crossword Puzzle
You are viewing a single comment's thread. Return to all comments →
Looks more like a dp problem to me. Here is my long and ugly solution.
The main idea is, first find all the available spots where to put words. Then, find their length. Then, sort them by how many of each lengths there are. Start with the smallest numbers. If there is only one spot of length 5. The put the apppropriate word in that spot. Move to the next smallest number of words of that length, saving the possible configurations of the crossword that you found.
Then loop over each spot/word length. For each set word/spot lengths, try all possiblities, store all possible configurations at that stage. Repeat, by the end, only one possible solution works.
I think the functions ishstart/isvstart/findend/findspots and putword are reasonably nice. The function match can probably be writtend much better, in a recursive or nicer dp way.