summaryrefslogtreecommitdiff
path: root/prolog/problems/lists/conc_3/sl.py
diff options
context:
space:
mode:
Diffstat (limited to 'prolog/problems/lists/conc_3/sl.py')
-rw-r--r--prolog/problems/lists/conc_3/sl.py61
1 files changed, 60 insertions, 1 deletions
diff --git a/prolog/problems/lists/conc_3/sl.py b/prolog/problems/lists/conc_3/sl.py
index 0d5af8f..779b3ed 100644
--- a/prolog/problems/lists/conc_3/sl.py
+++ b/prolog/problems/lists/conc_3/sl.py
@@ -12,4 +12,63 @@ description = '''\
X = [1,2,3].
</pre>'''
-hint = {}
+plan = ['''\
+<p>Začnimo z enostavnim vprašanjem: kaj bi bil rezultat, če konkateniram prazen seznam in seznam <code>L2</code>?</p>
+''', '''\
+<p>Sedaj recimo, da ima prvi seznam točno en element. Začasno ga vzemimo stran, ostali smo s praznim prvim seznamom.
+Kaj ni ta situacija podobna oni od prej? Seveda, problem smo zmanjšali za en element in ga tako prevedli na manjši
+problem! Uporabimo rekurzijo za rešitev tega manjšega problema. A na koncu ne pozabimo rezultat rekurzije ustrezno
+dopolniti s prej odvzetim prvim elementom...</p>
+''', '''\
+<p>Deklarativno/logično razmišljanje: Recimo, da ima prvi seznam <code>L1</code> glavo <code>H</code> in rep
+<code>T</code>. Če je (rekurzivni) rezultat konkatenacije <code>T</code> in <code>L2</code> nek seznam
+<code>L3</code> in če seznamu <code>L3</code> na začetek dodam element <code>H</code>, kaj s tem dobim?
+Konkatenacijo seznamov <code>L1</code> in <code>L2</code>!</p>
+''']
+
+hint = {
+ 'eq_instead_of_equ': '''\
+<p>Operator <code>==</code> je strožji od operatorja <code>=</code> v smislu, da je za slednjega dovolj,
+da elementa lahko naredi enaka (unifikacija). Morda z uporabo <code>=</code> narediš predikat
+<code>conc/3</code> delujoč tudi v kakšni drugi smeri.</p>
+<p>Seveda pa lahko nalogo rešiš brez obeh omenjenih operatorjev, spomni se, da lahko unifikacijo narediš
+implicitno že kar v argumentih predikata (glavi stavka).</p>
+''',
+
+ 'eq_instead_of_equ_markup': '''\
+<p>Morda bi bil bolj primeren operator za unifikacijo (=)?</p>
+''',
+
+ 'base_case': '''\
+<p>Si pomislil na robni pogoj? Kaj je najbolj enostaven primer?
+Kaj bi bil, recimo, rezultat, če je prvi seznam kar prazen?</p>
+''',
+
+ 'predicate_always_false': '''\
+<p>Vse kaže, da tvoj predikat vedno vrne "false". Si mu dal pravilno ime, si se morda pri imenu zatipkal?</p>
+<p>Če je ime pravilno, se morda splača preveriti tudi, če se nisi zatipkal kje drugje,
+je morda kakšna pika namesto vejice ali obratno, morda kakšna spremenljivka z malo začetnico?</p>
+<p>Možno je seveda tudi, da so tvoji pogoji prestrogi ali celo nemogoči (kot bi bila npr. zahteva,
+da je <code>X</code> hkrati starš in sestra od <code>Y</code> ali kaj podobno zlobnega).</p>
+''',
+
+ 'timeout': '''\
+<p>Je morda na delu potencialno neskončna rekurzija? Kako se bo ustavila?</p>
+<p>Morda pa je kriv tudi manjkajoč, neustrezen ali preprosto nekompatibilen (s splošnim primerom) robni pogoj?
+Morda npr. v rekurziji zmanjšuješ prvi seznam, ustaviš pa se pri praznem drugem seznamu (ali obratno)?</p>
+''',
+
+ 'final_hint': '''\
+<p>Predikat <code>conc/3</code> bomo večinoma uporabljali za vse drugo kot samo za konkatenacijo dveh seznamov.
+Med drugim je uporaben "v obratni smeri" za delitev seznama na dva dela, poskusi naslednja vprašanja:</p>
+<p><code>?- conc(L1, L2, [a,b,c,d]).</code></p>
+<p><code>?- conc([X,Y], L2, [a,b,c,d,e,f]).</code></p>
+<p>Si opazil, da je drugo vprašanje v bistvu vrnilo prva dva elementa iz seznama <code>[a,b,c,d,e,f]</code>?</p>
+<p>Nadalje je <code>conc/3</code> uporaben za iskanje vzorcev v seznamu, npr. takole:</p>
+<p><code>?- conc(_, [X,X|_], [a,b,c,c,d,e,f,f,g,h,h]).</code></p>
+<p>Tako je, to vprašanje najde vse možnosti, kjer se dva elementa ponovita drug za drugim v seznamu (vzorec X,X).
+V bistvu smo rekli "nekaj poljubnih elementov (lahko tudi nič) je spredaj, potem sta dva enaka, potem pa spet nekaj
+poljubnih elementov (lahko nič) zadaj."
+Še veliko drugih koristi bo od <code>conc/3</code>, jih boš že še sproti spoznal.</p>
+''',
+}