summaryrefslogtreecommitdiff
path: root/prolog/problems/lists
diff options
context:
space:
mode:
Diffstat (limited to 'prolog/problems/lists')
-rw-r--r--prolog/problems/lists/dup_2/en.py75
-rw-r--r--prolog/problems/lists/dup_2/sl.py2
2 files changed, 75 insertions, 2 deletions
diff --git a/prolog/problems/lists/dup_2/en.py b/prolog/problems/lists/dup_2/en.py
index 3639683..e944f74 100644
--- a/prolog/problems/lists/dup_2/en.py
+++ b/prolog/problems/lists/dup_2/en.py
@@ -10,4 +10,77 @@ description = '''\
X = [1,1,2,2,3,3].
</pre>'''
-hint = {}
+plan = ['''
+<p><img src="[%@resource plan.svg%]" /></p>
+<p>This is an exercise in classic recursion. Let's be brave and assume that we already have
+a duplicated tail of the list. Then all we need to do is to duplicate the head (H becomes H, H) and
+add this at the start of the duplicated tail.</p>
+''', '''\
+<p>A base case must be elementary, right? What if the list doesn't contain any elements at all,
+what is the result in this case?</p>
+''', '''\
+<p>If we have a duplicated tail <code>DT</code> and put two heads <code>[H, H]</code> in front of it,
+then that is exactly the duplicated list.</p>
+<p>And how do we get the duplicated tail? Since the tail is smaller than the whole list,
+we can use recursion on it!</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). Perhaps by using <code>=</code>
+you can make the predicate <code>dup/2</code> more general (e.g. able to work with output arguments becoming inputs).</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_missing_[]': '''\
+<p>Your base case makes perfect sense, but it doesn't work for a very specific case: an empty list.
+Tweak it a little bit. However, don't write two base cases, because that will result in a new problem:
+the (albeit correct) solutions will all be repeated twice.</p>
+''',
+
+ 'base_case_arbitrary': '''\
+<p>How can the result of duplicating an empty list be an arbitrary list or an unassigned variable?
+As the mathematicians would say: "Two times zero is zero and not just anything!"</p>
+<p>If your base case is <code>dup([], _).</code>, rethink it! What is the result of
+duplicating the elements of an empty list?</p>
+''',
+
+ 'base_case': '''\
+<p>Did you think of a base case? Which list is the easiest to "duplicate"?</p>
+''',
+
+ 'recursive_case': '''\
+<p>The base case is 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>
+''',
+
+ 'forcing_result_onto_recursion': '''
+<p>Don't force the result onto recursion, don't tell it what it should return. Just 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>dup(T, [H,H|...])</code>? This forces the recursive call to
+<em>return</em> the duplicated head at the start of the list. But it doesn't know of this head, because you just
+took it away! Adding the duplicated head to the result, returned by the recursive call, is your job.
+To put it shortly, add the duplicated <code>H</code> outside of the recursive call.</p>
+''',
+}
diff --git a/prolog/problems/lists/dup_2/sl.py b/prolog/problems/lists/dup_2/sl.py
index 0358726..b1492c5 100644
--- a/prolog/problems/lists/dup_2/sl.py
+++ b/prolog/problems/lists/dup_2/sl.py
@@ -71,7 +71,7 @@ da je <code>X</code> hkrati starš in sestra od <code>Y</code> ali kaj podobno z
<p>Ne vsiljuj rekurziji kaj naj vrne, prepusti se ji. To je tisti del, ko narediš predpostavko,
če je ta izpolnjena, potem bo tvoje pravilo delovalo za večji primer.</p>
<p>Je tvoj rekurzivni klic oblike <code>dup(T, [H,H|...])</code>? S tem vsiljuješ rekurziji
-da mora <emph>vrniti</emph> tudi podvojeno glavo. To moraš narediti ti z (obdelanim) rezultatom, ki ga rezurzija vrne.
+da mora <em>vrniti</em> tudi podvojeno glavo. To moraš narediti ti z (obdelanim) rezultatom, ki ga rezurzija vrne.
Skratka, [H,H] dodaj izven rekurzivnega klica.</p>
''',
}