diff options
Diffstat (limited to 'prolog/problems/lists/divide_3')
-rw-r--r-- | prolog/problems/lists/divide_3/en.py | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/prolog/problems/lists/divide_3/en.py b/prolog/problems/lists/divide_3/en.py index f4cfa82..f47a51b 100644 --- a/prolog/problems/lists/divide_3/en.py +++ b/prolog/problems/lists/divide_3/en.py @@ -1,5 +1,5 @@ name = 'divide/3' -slug = 'split a list into parts of roughly equal length' +slug = 'split a list into two parts of roughly equal length' description = '''\ <p><code>divide(L, L1, L2)</code>: the list <code>L1</code> contains elements at odd positions in <code>L</code>, and the list <code>L2</code> contains the elements at even positions in <code>L</code>.</p> @@ -10,4 +10,84 @@ description = '''\ X = [a,c,e], Y = [b,d,f]. </pre>''' -hint = {} +plan = ['''\ +<p><img src="[%@resource plan.svg%]" /></p> +<p>You know... first, second, first, second, ...</p> +''', '''\ +<p>Can you pick two heads from the list's beginning? The pattern is <code>[H1,H2|T]</code>.</p> +''', '''\ +<p>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.</p> +''', '''\ +<p>If we assume the recursion splits the tail <code>T</code> into lists <code>L1</code> and <code>L2</code>, +and upon returning the result we add <code>H1</code> at the start of <code>L1</code> and <code>H2</code> +at the start of <code>L2</code>, then we get the split of the initial list of the form <code>[H1,H2|T]</code> +into two approximately equal parts.</p> +'''] + +hint = { + 'eq_instead_of_equ': '''\ +<p>The operator <code>==</code> is "stricter" than operator <code>=</code> in the sense that +for the latter it is enough to be able to make the two operands equal (unification).</p> +<p>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).</p> +''', + + 'eq_instead_of_equ_markup': '''\ +<p>Perhaps the operator for unification (=) would be better?</p> +''', + + 'base_case': '''\ +<p>Did you think of a base case? What's the simplest possible case? What if the list is empty?</p> +''', + + 'base_case_arbitrary': '''\ +<p>How can the result of splitting a list be an arbitrary list(s) or an unassigned variable(s)?</p> +<p>If your base case is reminiscent of <code>divide([], _, _)</code> or <code>divide([X], [X|_], ...)</code>, +rethink it! What should be the result of splitting? The base case <em>always</em> fully specifies the result, +usually there are no unknowns (<code>_</code> or variables without assigned values) in what is being +returned as the result.</p> +''', + + 'second_base_case_missing': '''\ +<p>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.</p> +<p><code>?- divide([a,b,c], L1, L2).</code></p> +<p><code>?- divide([a,b,c,d], L1, L2).</code></p> +''', + + 'unsuccessful_conc_use': '''\ +<p>Are you using <code>conc/3</code>? This is probably not a good idea here as <code>conc/3</code> +splits the list in "blocks" and not on an element-by-element level. Rather try without it.</p> +''', + + 'forcing_result_onto_recursion': ''' +<p>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.</p> +<p>Is your recursive call of the form <code>divide(T, [H1|...], [H2|...])</code>? This forces the recursive call +to also <em>return</em> both heads that it <em>doesn't know of</em> 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 <code>H1</code> and <code>H2</code> outside the recursive call.</p> +''', + + 'recursive_case': '''\ +<p>The base cases are ok. However, what about the general recursive case?</p> +''', + + 'predicate_always_false': '''\ +<p>It seems your predicate is <emph>always</emph> "false". Did you give it the correct name, +or is it perhaps misspelled?</p> +<p>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?</p> +<p>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 <code>[]</code> is equal to a list with +exactly three elements <code>[A,B,C]</code>, or something similarly impossible).</p> +''', + + 'timeout': '''\ +<p>Is there an infinite recursion at work here? How will it ever stop?</p> +<p>Or perhaps is there a missing, faulty, or simply incompatible (with the general recursive case) base case?</p> +''', +} |