Skip to content

Instantly share code, notes, and snippets.

@Komzpa
Last active June 2, 2019 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Komzpa/82cd532e983d54bf29431ae14a03edcd to your computer and use it in GitHub Desktop.
Save Komzpa/82cd532e983d54bf29431ae14a03edcd to your computer and use it in GitHub Desktop.
create or replace function is_done(g int[])
returns boolean
as
$$
select exists(
select
from (
select array [g[1], g[3], g[5], g[7], g[9]]::int[] as moves
union all
select array [g[2], g[4], g[6], g[8]]::int[] as moves
) z
where (moves @> array [1,2,3])
or (moves @> array [4,5,6])
or (moves @> array [7,8,9])
or (moves @> array [1,4,7])
or (moves @> array [2,5,8])
or (moves @> array [3,6,9])
or (moves @> array [1,5,9])
or (moves @> array [3,5,7])
);
$$ language sql;
create or replace function shorten_game(g int[])
returns int[] as
$$
declare
short int[];
begin
if (not is_done(g))
then
return g;
end if;
short = g[0:array_length(g, 1) - 1];
if (is_done(short))
then
return shorten_game(short);
end if;
return g;
end;
$$
language plpgsql;
with gamefield as (
select generate_series(1, 9) as id,
pow(2, generate_series(0, 8)) as mask
),
games as (
select distinct shorten_game(
array [g1.id, g2.id, g3.id, g4.id, g5.id, g6.id, g7.id, g8.id, g9.id]::int[]) as moves
from gamefield g9,
gamefield g8,
gamefield g7,
gamefield g6,
gamefield g5,
gamefield g4,
gamefield g3,
gamefield g2,
gamefield g1
where g1.mask + g2.mask + g3.mask + g4.mask + g5.mask + g6.mask + g7.mask + g8.mask + g9.mask = 511
)
select count(*)
from games;
@dkorolev
Copy link

dkorolev commented Jun 2, 2019

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment