Tips for golfing in Prolog on codegolf.stackexchange.com
Handling arguments
Use feature(argv,A)
or '$argv'(A)
instead of prolog_flag(argv,A)
.
'$argv'(A)
has extra arguments at the beginning, you can filter them by index:
:-feature(argv,A),nth0(I,A,X),code(X).
:-'$argv'(A),nth0(I,A,X),I>3,code(X).
unix(argv(A))
is equivalent to '$argv'(A)
, but arguments that are syntactically valid numbers are passed as a number. You can filter them using number(X)
or atom(X)
.
Because integers are less than atoms in the standard ordering of terms, X@<''
(or maybe X@<a
if you're really lucky) works as a shorter alternative to number(X)
.
re_split
with /n
flag converts output atoms to numbers if possible:
:- S='2 3 4', re_split(' '/n,S,L), L=[2,' ',3,' ',4].
Iterating over an array
Instead of using maplist
over an array, you can use member
with careful backtracking. You can also use nth0
or nth1
to get the index of the element as well:
maplist(+,A). +A:-code.
member(V,A),code,0=1.
nth0(I,A,V),code,0=1.
nth1(I,A,V),code,0=1.
Printing
format
can accept an arithmetic expression for numeric conversions.
:-X is 1+2,write(X).
:-format('~d',1+2).
:-X is 1+2,writeln(X).
:-format('~d
',1+2).
Failing
:-member(X,[2,3]),write(X),0=1.
:-member(X,[2,3]),\+write(X).
Packing
Use backticks to get a list of character codes:
:- `0{𞉀` = [48,123,123456].
Big numbers can be written using <radix>'<number>
syntax or 0'<character>
syntax:
:- 36'PROLOG = 1558151872.
:- 0'𞉀 = 123456.
Lists of one integer or one-character atom (e.g., [97]
, `a`
, [a]
), and strings of length 1 (e.g., "a"
) in arithmetic expression are interpreted as integers:
:-X is 100.
:-X is 0'd.
:-X is"d".
Managing predicates
Predicates can be written using operators (CGSE for more details):
2+2. 1+b.
:-X+Y,write(X),\+write(Y). % prints '221b'
You can add predicates dynamically using assert
:
:-X=2,Y=3,assert(X+Y),2+3,write('success'),2+5,write('unreachable').
Generators
Some predicates generate solutions if the arguments are unbound:
nth0(X,_,_). % between(X,0,inf)
nth1(X,_,_). % between(X,1,inf)
Rational numbers
You don't need rdiv
if at least one argument is rational:
:- X is 1/2r3. % X = 3r2
A rational number literal, rdiv
result, or the value of an arithmetic expression (if it's a rational number) is converted to an integer if possible:
:- X is 4r2, Y is 1/X. % X = 2 (integer), Y = 0.5 (float)
:- X is 4 rdiv 2, Y is 1/X. % X = 2 (integer), Y = 0.5 (float)
:- X is 4r7/2r7, Y is 1/X. % X = 2 (integer), Y = 0.5 (float)
:- X = 4r7/2r7, Y is 1/X. % X = 4r7/2r7 (expression), Y = 1r2 (rational)