Пролог - Генерация случайной строки - PullRequest
0 голосов
/ 04 октября 2018

Я очень новичок в Прологе и пытаюсь создать скрипт, в котором я могу генерировать случайную строку с Прологом.Пока что мне не очень повезло.

Я думал сделать это, чтобы сгенерировать список обязательных символов, создать случайное число на основе размера списка и попытаться вытащить персонажа изэтот список.Это прекрасно работает, но мне также нужно иметь возможность объединить переменную, которая, очевидно, будет начинаться как ничто.Сейчас я просто пытаюсь ограничить размер строки до 5 символов, но в будущем я хочу что-то более сложное (например, от 5 до 8 символов).

Вот что у меня такfar:

generate :-
    Output = '',
    generate_random_string(Output, 0),
    write(Output).

generate_random_string(Output, 5) :-
    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    append(RandomCharacter, Output, Concat),
    Output = Concat.

generate_random_string(Output, CharNum) :-
    CharNum \= 5,

    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    append(RandomCharacter, Output, Concat),
    Count is CharNum + 1,
    Output = Concat,

    generate_random_string(Output, Count).

Я полагаю, что это происходит вокруг вызова добавления, но я не совсем уверен, почему, хотя я действительно знаю, что это разрыв на первой итерации и это дает результат false.Любая помощь в этом направлении будет высоко ценится.

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Вот более простое решение:

characters(['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g']).

generate(L,N) :-  
      length(L,N),
      characters(Char_list),
      N1 is N-1,
      foreach( (between(0,N1,X), random(0, 14, RandomValue), nth0(RandomValue, Char_list, Char)) , nth0(X,L,Char) ).

Обратите внимание, что вышеприведенное решение принимает в качестве аргумента число N и создает N-значный список случайных символов:

?- generate(L,5).
L = [f, e, 'C', 'B', 'A'].

?- generate(L,8).
L = [a, 'E', c, c, 'E', f, 'B', g].

?- generate(L,N).
L = [],
N = 0 ;
L = ['B'],
N = 1 ;
L = [c, 'F'],
N = 2 ;
L = ['E', g, 'C'],
N = 3 ;
L = ['C', c, 'F', 'D'],
N = 4 ;
L = [c, 'B', 'F', 'B', 'B'],
N = 5
....and goes on
0 голосов
/ 04 октября 2018

Поскольку @PauloMoura прокомментировал в предыдущем ответе, что foreach/3 не может быть переносимым, поскольку это не предикат ISO, вот лучшее решение с использованием maplist/2:

characters(['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g']).

generate(L,N) :-  
    length(L,N),
    characters(Char_list),
    length(Char_list, N1),
    maplist( random_char_generat(Char_list, N1), L ).

random_char_generat(Char_list, N, Char):-  random(0, N, X), nth0(X, Char_list, Char ).

Решение вышелучше в терминах, перечисленных ниже:

  • Работает для любой длины сгенерированного списка случайных символов.
  • Работает для любой длины списка доступных символов.
  • Наконец, как видно из приведенных ниже примеров, он чистый и работает для очень общих запросов:

?- generate(L,5).
L = ['E', g, c, 'B', 'D'].

?- generate(L,8).
L = [g, g, f, d, 'E', a, g, b].

?- generate(L,N).
L = [],
N = 0 ;
L = [e],
N = 1 ;
L = [e, 'F'],
N = 2 ;
L = ['C', g, 'G'],
N = 3 ;
L = ['D', a, b, e],
N = 4 ;
L = ['F', 'E', 'G', f, b],
....
0 голосов
/ 04 октября 2018

Итак, как предлагается в комментариях, вы должны использовать atom_concat/3 следующим образом:

generate :-
    Output = 'abc',
    generate_random_string(Output,Result,0),
    write(Result).

generate_random_string(Output,Result,5):- !,
    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    atom_concat(RandomCharacter,Output,Result).

generate_random_string(Output,Result,CharNum) :-
    CharNum \= 5,

    Characters = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    random(0, 14, RandomValue),
    nth0(RandomValue, Characters, RandomCharacter),
    atom_concat(RandomCharacter,Output,Concat),
    Count is CharNum + 1,
    generate_random_string(Concat,Result,Count).

Запрос:

?- generate.
feFaaCabc
true

Как видите, если вы введетестроку и вы хотите добавить к ней несколько символов, программа выведет строку указанной длины (в вашем случае 5+1, потому что вы начинаете с 0) плюс длина входной строки.

Другойи модульный способ сделать это может быть следующим, используя random_member/2:

pick_random(_,0,L,L):- !.
pick_random(LC,I,SIn,SOut):-
    I > 0,
    random_member(R,LC),
    atom_concat(SIn,R,Concat),
    I1 is I-1,
    pick_random(LC,I1,Concat,SOut).


random_string(Len,SIn,SOut):-
    LC = ['A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f', 'G', 'g'],
    string_length(SIn,Ls),
    Len1 is Len - Ls,    
    pick_random(LC,Len1,SIn,SOut).

Запрос:

?- random_string(4,'gr',S).
S = grAd % note gr is in the string
?- random_string(4,'',S).
S = fdGb

С этой отправной точки довольно легко сделать также длинуслучайная строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...