summaryrefslogtreecommitdiff
path: root/prolog/problems/lists/divide_3
diff options
context:
space:
mode:
authorMartin Možina <martin.mozina@fri.uni-lj.si>2016-09-27 15:19:07 +0200
committerMartin Možina <martin.mozina@fri.uni-lj.si>2016-09-27 15:19:07 +0200
commit01eb98c7a5e86325e1243f0d0f4e111a18d1e535 (patch)
tree7871a2a0d30fd7761b6ac0f40846fbd004e10b25 /prolog/problems/lists/divide_3
parent5a00cf460426af73cb1fef953acf01f460887f77 (diff)
parent3bfcb3e651980f1675807b8f82826dcb3e4e1013 (diff)
Merge branch 'master' of 192.168.15.97:codeq-problems
Diffstat (limited to 'prolog/problems/lists/divide_3')
-rw-r--r--prolog/problems/lists/divide_3/en.py84
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>
+''',
+}