aboutsummaryrefslogtreecommitdiff
path: root/challenge-211/luca-ferrari/postgresql/ch-2.sql
blob: 802a8f693236ec7d899277e06cfc474bdd54241b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
--
-- Perl Weekly Challenge 211
-- Task 2
--
-- See <https://perlweeklychallenge.org/blog/perl-weekly-challenge-211/>
--

CREATE SCHEMA IF NOT EXISTS pwc211;

-- see <https://wiki.postgresql.org/wiki/Permutations>
CREATE FUNCTION pwc211.permute(anyarray)
  RETURNS SETOF anyarray
  LANGUAGE SQL IMMUTABLE
AS $f$
  SELECT (WITH RECURSIVE r(n,p,a,b)
               AS (SELECT i, $1[1:0], $1, array_upper($1,1)
                   UNION ALL
                   SELECT n / b, p || a[n % b + 1], a[1:n % b] || a[n % b + 2:b], b-1
                     FROM r
                    WHERE b > 0)
          SELECT p FROM r WHERE b=0)
  FROM generate_series(0,factorial( (array_upper($1,1)) )::integer-1) i;
$f$;




CREATE OR REPLACE FUNCTION
pwc211.task2_plpgsql( a int[] )
RETURNS SETOF int[]
AS $CODE$
DECLARE
	split_at int := 0;
	current_array int[];
	l int[];
	r int [];
	avg_l numeric;
	avg_r numeric;
BEGIN
	split_at := array_length( a, 1 ) / 2;

	FOR current_array IN SELECT * FROM pwc211.permute( a ) LOOP
	    l := current_array[ 1:split_at ];
	    r := current_array[ (split_at + 1): array_length( a, 1 ) ];


	    SELECT avg( v )
	    INTO   avg_l
	    FROM   unnest( l ) v;

	    SELECT avg( v )
	    INTO   avg_r
	    FROM   unnest( r ) v;

	    IF avg_r = avg_l THEN
	       RETURN NEXT l;
	       RETURN NEXT r;
	       RETURN;
	    END IF;
	END LOOP;

RETURN;
END
$CODE$
LANGUAGE plpgsql;