name = 'divide/3' slug = 'split a list into two parts of roughly equal length' description = '''\
divide(L, L1, L2)
: the list L1
contains elements at odd positions in L
, and the list L2
contains the elements at even positions in L
.
?- divide([a,b,c,d,e,f,g], X, Y). X = [a,c,e,g], Y = [b,d,f]. ?- divide([a,b,c,d,e,f], X, Y). X = [a,c,e], Y = [b,d,f].''' plan = ['''\
You know... first, second, first, second, ...
''', '''\Can you pick two heads from the list's beginning? The pattern is [H1,H2|T]
.
You take two elements from the list's beginning, the rest is recursively split, and then you accordingly add those two elements into the recursion's result. By taking the two elements out, you reduce (simplify) the problem and thus enable the recursion.
''', '''\If we assume the recursion splits the tail T
into lists L1
and L2
,
and upon returning the result we add H1
at the start of L1
and H2
at the start of L2
, then we get the split of the initial list of the form [H1,H2|T]
into two approximately equal parts.
The operator ==
is "stricter" than operator =
in the sense that
for the latter it is enough to be able to make the two operands equal (unification).
Of course, you can also solve the exercise without explicit use of either of these two operators, just remember that unification is implicitly performed with the predicate's arguments (head of clause).
''', 'eq_instead_of_equ_markup': '''\Perhaps the operator for unification (=) would be better?
''', 'base_case': '''\Did you think of a base case? What's the simplest possible case? What if the list is empty?
''', 'base_case_arbitrary': '''\How can the result of splitting a list be an arbitrary list(s) or an unassigned variable(s)?
If your base case is reminiscent of divide([], _, _)
or divide([X], [X|_], ...)
,
rethink it! What should be the result of splitting? The base case always fully specifies the result,
usually there are no unknowns (_
or variables without assigned values) in what is being
returned as the result.
The recursion doesn't always succeed. Are there perhaps two different cases how it could end? You know, odd and even ;) Do you need an extra base case? Try the following two queries; one will succeed, and the other will fail.
?- divide([a,b,c], L1, L2).
?- divide([a,b,c,d], L1, L2).
Are you using conc/3
? This is probably not a good idea here as conc/3
splits the list in "blocks" and not on an element-by-element level. Rather try without it.
Don't force the result onto recursion, don't tell it what it should return. Just let it be and assume it will do its job. If this assumption is correct, then the rule will work for a larger case.
Is your recursive call of the form divide(T, [H1|...], [H2|...])
? This forces the recursive call
to also return both heads that it doesn't know of since you previously took them away.
Adding those heads to the result, returned by the recursive call, is your job. To put it shortly,
add elements H1
and H2
outside the recursive call.
The base cases are ok. However, what about the general recursive case?
''', 'predicate_always_false': '''\It seems your predicate is
If the name is correct, check whether something else is misspelled, perhaps there is a full stop instead of a comma or vice versa, or maybe you typed a variable name in lowercase?
It is, of course, also possible that your conditions are too restrictive, or even impossible to satisfy
(as would be, for example, the condition that an empty list []
is equal to a list with
exactly three elements [A,B,C]
, or something similarly impossible).
Is there an infinite recursion at work here? How will it ever stop?
Or perhaps is there a missing, faulty, or simply incompatible (with the general recursive case) base case?
''', }