Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>I've also written a function to get the minimum and the maximum (highest and lowest losses).</p> </blockquote> <p>Prolog and other declarative languages differ from procedural languages in some surprising ways, and one of them is that frequently doing one little bit of the work in anticipation of reusing it from within some kind of looping construct is not exactly the right approach. This is more obviously true in SQL where you should always be dealing in terms of sets, but it also holds in Prolog where the few explicit looping constructs we have are not heavily employed. </p> <p>The problem of matching low and high scoring teams in a procedural environment would be best solved by a process like this:</p> <pre><code>def match(teams): while we have teams: remove the lowest scoring team from teams remove the highest scoring team from teams save this pair return the list of pairs </code></pre> <p>A naive way to make this more functional would be to use recursion:</p> <pre><code>def match(teams): if teams is empty: return empty list otherwise: remove the lowest scoring team remove the highest scoring team return this pair appended to match(teams without these two items) </code></pre> <p>You could actually convert this to reasonable looking Prolog without a lot of effort:</p> <pre><code>match([], []). match(Teams, [Lowest-Highest|Pairs]) :- lowest(Teams, Lowest), highest(Teams, Highest), select(Lowest, Teams, TeamsWithoutLowest), select(Highest, TeamsWithoutLowest, RemainingTeams), match(RemainingTeams, Pairs). </code></pre> <p>This is not likely to be efficient because there is a lot of repeated list scanning and a lot of list rebuilding going on within <code>select/3</code>, but it might be more declarative.</p> <p>Another approach would be to get the list of teams sorted, and then fold it back on itself to get the lowest and highest paired. Visually:</p> <pre><code>[1, 2, 3, 4, 5, 6] [1, 2, 3], [4, 5, 6] [1, 2, 3], [6, 5, 4] [1, 2, 3] [6, 5, 4] ------------------- [1-6], [2-5], [3-4] </code></pre> <p>We can do this somewhat directly in Prolog, but first we need a way to pair off two lists:</p> <pre><code>pair_off([], _, []). pair_off([L|Ls], [R|Rs], [L-R|Rest]) :- pair_off(Ls, Rs, Rest). </code></pre> <p>Then the algorithm goes to Prolog like this:</p> <pre><code>match_lowest_highest(SortedList, Pairs) :- length(SortedList, N2), N is N2 div 2, length(TopHalf, N), append(TopHalf, BottomHalf, SortedList), reverse(BottomHalf, BottomHalfFlipped), pair_off(TopHalf, BottomHalfFlipped, Pairs). </code></pre> <p>This still isn't terribly efficient, but the <code>reverse/2</code> builtin is probably using difference lists so it shouldn't be too expensive; by using <code>append/3</code> with an already-materialized list of unknowns we save a bunch of temporary list construction which would just be thrown away. So I would not expect this to be horribly inefficient, but I'm sure there are other ways that it could be done that would be more efficient.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload