LINUX.ORG.RU

Покритикуйте код, кому не лень.

 


0

1

Иногда пытаюсь освежить знания старого, доброго prolog-а:

http://rosettacode.org/wiki/Poker_hand_analyser#Prolog

А версии haskell-а почему-то там нет, странно что никто не запостил, вроде такая задача была и на euler-project.



Последнее исправление: tipun (всего исправлений: 1)

Ответ на: комментарий от anonymous_sapiens

вспомнил немного как писали на прологе в универе, давно это было

Да...почти 15 лет назад...

zolden ★★★★★
()

вроде такая задача была и на euler-project.

54-я задача.

sf ★★★
()

Внешне выглядит ничего, вникать сейчас лень. Отдельный плюс за гну-пролог :)

buddhist ★★★★★
()

Выглядит неплохо, могу лишь подсказать пару полезных предикатов из Swi-Prolog, которые, возможно, есть и в GNU Prolog (лень самому проверять):

  • findall(_, run_tests, _) я бы заменил на forall(run_tests, true), но тут вопрос исключительно в личном предпочтении
  • choose_one(Xs,X,Ys) можно заменить на select/3
  • next_face можно упростить используя nextto/3
  • four_of_a_kind и ему подобные можно реализовать с помощью permutation([c(X, _), c(X, _), _], [c(2, ♥), c(2, ♦), c(3, ♣)]).
  • flush я бы реализовал с помощью maplist(X+\c(_, X)^true, [c(2, ♥), c(4, ♥), c(3, ♥)]); тут нужно подключить библиотеку lambda
runtime ★★★★
()
Ответ на: комментарий от runtime

forall, select

Точно, select был (как и maplist), спасибо. (А вот forall не видел.)

с помощью permutation

Ну да, наивный подход. Но по хорошему-то suit плохо хардкодить => тогда уж maplist bagof(..suit..) и создавать functor. Но ведь многословно.

nextto/3

Надо посмотреть аналог, но именно такую вроде не видел.

Спасибо за небольшой ликбез.

anonymous
()
Ответ на: комментарий от anonymous

suit плохо хардкодить

Немного не понял, что ты тут подразумеваешь. Там хардкодится только количество, т.е. мы говорим, что данные пять карт являются перестановкой любых четырёх карт указанной значимости плюс ещё какая угодно одна карта.

four_of_a_kind(Cards,F) :-
     permutation([
		c(F, _),
		c(F, _),
		c(F, _),
		c(F, _),
		_
	], Cards).
Но вообще решение лучше я уже кинул выше.

runtime ★★★★
()
Последнее исправление: runtime (всего исправлений: 2)
Ответ на: комментарий от runtime

F+\c(_, F)^true

Хм.. а почему не тогда findall / bagof / etc? Эти вроде iso-шные.

В целом отдает более «функциональным» подходом, в духе хаскеля. А на практике обычно какое соотношение «goal-like» / фп / императивного?

anonymous
()
Ответ на: комментарий от runtime

Да, понял, просто в том примере рубашка была указана.

anonymous
()
Ответ на: комментарий от anonymous

Хм.. а почему не тогда findall / bagof / etc? Эти вроде iso-шные.

По моему, громоздко будет (по крайней мере, то решение, что у меня вырисовывается в голове). Да и в любом случае, в прологе без лямбд - как без воздуха, рано или поздно всё равно напишешь аналог сам (что я и делал, до того как открыл pack_install(lambda)).

В целом отдает более «функциональным» подходом, в духе хаскеля. А на практике обычно какое соотношение «goal-like» / фп / императивного?

Скажу честно, я себя постоянно ловлю на мысле при кодинге на прологе, что пытаюсь всунуть туда много функциональщины. Особенно забавно то, что я никогда на функциональных языках толком ничего не писал. По поводу соотношения сложно сказать, просто стараюсь для конкретной задачи использовать более уместное решение.

runtime ★★★★
()
Последнее исправление: runtime (всего исправлений: 1)
Ответ на: комментарий от runtime

Пока «вылизывал» код, подумалось, что:

flush([c(_,S)|Cards],S) :-
    \+ (member(C,Cards), C \= c(_,S)).[/prolog]

должно быть эффективно.

anonymous
()
Ответ на: комментарий от anonymous

Это «практически» то же самое, что предложенный мною вариант:

flush(Cards, S) :-
     maplist(S+\c(_, S)^true, Cards).
Только мой вариант короче, и, возможно, быстрее :)

runtime ★★★★
()
Последнее исправление: runtime (всего исправлений: 1)
Ответ на: комментарий от runtime

Ну для gprolog-а не нашлось такого. И еще чуть смущает maplist в контексте без выходного списка, all или reduce было бы немного понятней.

возможно, быстрее :)

Дык, реализации будут разные,а gprolog-то не быстрый, зато пакет небольшой, даже обновляется иногда ).

anonymous
()
Ответ на: комментарий от anonymous

И еще чуть смущает maplist в контексте без выходного списка, all или reduce было бы немного понятней.

Это нормально - всмысле, использовать maplist как для all, так и для map:

maplist(integer, [1, 2, 3]) % check if all elements are integers
maplist(plus(1), [1, 2, 3], Out) % map \x.x+1 to list

Аналогом reduce же в Swi-Prolog являются foldl, scanl.

runtime ★★★★
()

Я бы ещё немного поменял DCG'шки:

parse_line([])      --> [].
parse_line([C|Cs])  --> parse_card(C), parse_line(Cs).
parse_line(Cards)   --> " ", parse_line(Cards).
parse_card(c(F, S)) --> parse_face(F), parse_suit(S).
parse_suit(Suit)    --> { suit(Suit), atom_codes(Suit, S) }, S.
parse_face(Face)    --> { face(Face), face_codes(Face, F) }, F.
runtime ★★★★
()
Ответ на: комментарий от runtime

Ещё - parse_line(Cards, Line, []) можно поменять на phrase(parse_line, Cards)

runtime ★★★★
()
Ответ на: комментарий от runtime

Согласен, в parse_card функтор смотрится лучше, поменял (правда оставил порядок предикатов по вкусу :).

parse_suit(Suit) --> { suit(Suit), atom_codes(Suit, S) }, S.

Сначала пробовал так, почему-то не заводится, не нравится gprolog-у инстанцированный список, а [Var] - работал.

phrase поменял, спасибо.

anonymous
()
Ответ на: комментарий от runtime

Впрочем, если эстетическое чувство требует - можно поменять, это ж типа википедии, все могут добавлять.

Лишь бы читаемо и работало. Аналогий не провожу, просто вспомнилось: http://rosettacode.org/mw/index.php?title=MD5/Implementation&diff=166456&... , видимо не понравилось, что рассветка залила код, вот «поправили», а я обратно откатывать не стал :).

anonymous
()

код говно. очень плохой код.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.