Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect all k-length words of string in prolog

Words are any symbol characters that are separated by white-spaces or by start/end points of string. For ex. [w,o,r,d,1,' ',w,o,r,d,2].

I need to find all k-length words of given string and append them into the result string (separated with white-spaces). This is what I'm expecting for example in the case of k = 5:

?- kthWords([w,o,r,d,1,'',w,r,d,'',w,o,r,d,2], 5, X).
X = [w,o,r,d,1,'',w,o,r,d,2].
like image 534
Narek Atayan Avatar asked Oct 23 '16 17:10

Narek Atayan


2 Answers

You could write:

final_kthWords(L,K,Outlist):-
         kthWords(L,K,L1),
         reverse(L1,[_|T]),
         reverse(T,Outlist).

kthWords([],_,[]):-!.
kthWords(L,K,L1):-
     find_word(L,Word,L2),
     length(Word,N),
     (N=:=K-> append(Word,[' '|T],L1),kthWords(L2,K,T);
     kthWords(L2,K,L1)).

find_word([],[],[]).
find_word([H|T],[H|T1],L):-dif(H,' '),find_word(T,T1,L).
find_word([H|T],[],T):- H = ' '.

Where kthWords/3 calls find_word/2 which finds the words and finally kthWords returns the output list but it adds an ' ' in the end. The only thing that final_kthWords(L,K,Outlist)/3 does is removing the extra ' ' in the end of the list and returns the right list:

?- final_kthWords([w,o,r,d,1,' ',w,r,d,' ',w,o,r,d,2], 5, X).
X = [w, o, r, d, 1, ' ', w, o, r, d, 2] ;
false.
like image 166
coder Avatar answered Oct 21 '22 09:10

coder


Hoping that someone else can propose a simpler solution... the following seems to work

kthWordsH([], 0, _, R0, R0).

kthWordsH([], N, _, _, []) :-
  N \= 0.

kthWordsH([' ' | Tl], 0, Len, W, Revult) :-
  kthWordsH(Tl, Len, Len, [], Res0),
  append(Res0, [' ' | W], Revult).

kthWordsH([' ' | Tl], N, Len, _, Revult) :-
  N \= 0,
  kthWordsH(Tl, Len, Len, [], Revult).

kthWordsH([H | Tl], 0, Len, _, Revult) :-
  H \= ' ',
  kthWordsH(Tl, Len, Len, [], Revult).

kthWordsH([H | Tl], N, Len, Tw, Revult) :-
  H \= ' ',
  N \= 0,
  Nm1 is N-1,
  kthWordsH(Tl, Nm1, Len, [H | Tw], Revult).

kthWords(List, Len, Result) :-
  kthWordsH(List, Len, Len, [], Revult),
  reverse(Revult, Result).
like image 28
max66 Avatar answered Oct 21 '22 09:10

max66