Savepoint

Soluções em PostgreSQL

Jogando Termo com Postgres

Esses dias, no meio do happy hour, estava comentando da última partida de Termo, que virou mania recentemente. Aí uma colega perguntou qual a palavra você utiliza para começar o jogo? Após ver que o nosso expert Guedes já pegou o dicionário para brincar no banco de dados, resolvi responder à pergunta com um pouco de SQL e brincar também!

Preparação

Vejamos como começar… o jogo Termo tem uma página onde ele diz que utiliza um dicionário com licença livre, disponível aqui. Então, basta baixar o dicionário e importar no seu banco de dados (aqui estou fazendo com PostgreSQL, mas com algumas diferenças, você pode fazer em outros bancos de dados, claro):

SQL
CREATE TABLE palavras (p text);
COPY palavras(p) FROM '/tmp/palavras.txt' ;

Ou seja, criei uma tabela chamada palavras com uma única coluna chamada p e importei os dados nela. Simples e rápido.

Depois resolvi filtrar apenas as palavras com 5 letras:
SELECT p FROM palavras WHERE length(unaccent(p)) = 5;
Notem aqui que eu utilizei a função unaccent, pois palavras acentuadas podem contar como mais de 1 byte.

Brincando

Agora como seria saber quais palavras começam com TOR e terminam com A?

SQL
SELECT p 
FROM palavras
WHERE
    length(unaccent(p)) = 5 AND
    unaccent(p) LIKE 'tor_a';

p
-----
torda
torba
torga
torma
torna
torra
torsa
torta
torva
torça
tória
(11 rows)

Já dá pra ver que é possível brincar bastante com isso.

Agora uma contribuição do nosso colega Guedes que eu tomei a liberdade de adaptar para o meu exemplo aqui. Quais são as letras mais utilizadas na primeira posição da palavra?

SQL
SELECT 
    substring(unaccent(p) FROM 1 FOR 1) letra,
    count() qt, 
    repeat('█', (count()/40)::int) "%"
FROM palavras
WHERE length(unaccent(p)) = 5
GROUP BY 1
ORDER BY 2 DESC;

l |  qt  | %
--+------+------------------------------------------------------------
a | 2255 | ████████████████████████████████████████████████████████
c | 1623 | ████████████████████████████████████████
p | 1354 | █████████████████████████████████
m | 1347 | █████████████████████████████████
b | 1156 | ████████████████████████████
t | 1151 | ████████████████████████████
s | 1127 | ████████████████████████████
r | 1007 | █████████████████████████
f | 929  | ███████████████████████
l | 869  | █████████████████████
g | 86 7 | █████████████████████
e | 746  | ██████████████████
d | 690  | █████████████████
v | 613  | ███████████████
o | 610  | ███████████████
i | 598  | ██████████████
n | 575  | ██████████████
u | 413  | ██████████
j | 361  | █████████
z | 271  | ██████
h | 259  | ██████
x | 160  | ████
q | 82   | ██
k | 11   |
w | 5    |
y | 3    |
(26 rows)

Melhor palavra para começar

E agora, para responder à pergunta da minha colega… eu quero saber primeiro quais são as 5 letras mais utilizadas no dicionário?

SQL
SELECT l, count(1) AS q
FROM
    palavras,
    (SELECT CHR(i) AS l FROM generate_series(97,122) AS l(i)) AS letra
WHERE p ~ l
GROUP BY l
ORDER BY q DESC
LIMIT 5;

l | q
---+--------
a | 942848
e | 808949
r | 720964
s | 714080
i | 703338
(5 rows)

Agora que eu já sei que são as letras A, E, R, S e I, vou procurar palavras que tenham apenas estas 5 letras:

SQL
SELECT p
FROM palavras
WHERE
    length(unaccent(p)) = 5
AND unaccent(p) LIKE '%a%'
AND unaccent(p) LIKE '%e%'
AND unaccent(p) LIKE '%i%'
AND p LIKE '%r%'
AND p LIKE '%s%'
;

p
-----
aires
areis
eiras
erais
reais
ieras
rasei
raies
sairé
sarei
áries
seira
seria
érias
(14 rows)

E aí, vamos jogar?

SQL
SELECT p
FROM palavras
WHERE
    length(unaccent(p)) = 5
and unaccent(p) LIKE 'cai_a%'
and p not like '%s%'
and p not like '%r%'
and p not like '%n%'
and p not like '%g%'
and p not like '%m%'
and p not like '%t%'
and p not like '%p%'
and p not like '%l%'
and p not like '%f%'
and p not like '%x%'
and p not like '%b%';
    p
---------
 caída
 caiuá
 caiçá
 caíva
(4 rows)

Comments

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress