Рубрики
sql Без рубрики

Оптимальная тактика для WORDLE

Есть такая игра WORDLE, в которой нужно угадывать слова. Ты предлагаешь игре пятибуквенное слово, а она в ответ красит буквы зелёным, если они есть в угадываемом слове и стоят на правильных местах, жёлтым если они есть в угадываемом слове, но на других местах, и серым, если этих букв в слове нет. Цель — отгадать слово не более, чем за шесть попыток.

Я в своё время написал скрипт, который перебрал тройки пятибуквенных слов и нашёл трио слов, которое открывает 15 самых частоиспользуемых букв.

Сейчас появилась версия этой игры для шести-, семи-, восьми- и даже девятибуквенных слов. Поэтому вопрос поиска оптимальных троек встал с новой силой. Предлагаю вам поупражняться в SQL и предложить подходы, которые позволят найти оптимальные слова за разумное время и при этом не положить сервер. Если решите попробовать на боевых данных, оставьте в комментариях свою почту или telegram, пришлю скрипт заполнения словаря.

Рубрики
sql Без рубрики

ASSERT

Оператор ASSERT используется для проверки определённых условий. Это оператор будет выполняться для каждой строки из набора данных.

Типичный пример, когда можно встретить этот оператор — проверка условия CHECK. Например, для столба можно ограничить список возможных значений. Тогда при вставке данных ASSERT будет проверять для каждой строки значение, переданное в столбец. К сожалению в реальной работе эти возможности SQL используют реже, чем следует. Поэтому мы рассмотрим выдуманный и сильно упрощённый пример.

DROP TABLE IF EXISTS traffic_light;
CREATE TABLE traffic_light
(
    id INT IDENTITY(1, 1),
    color CHAR(1),
    CONSTRAINT CHECK_COLOR CHECK (color IN ( 'G', 'R' ))
);
INSERT INTO dbo.traffic_light (color) VALUES ('Y');

В этой таблице мы разрешаем цвету условного светофора быть или зелёным, или красным. При вставке данных в эту таблицу SQL Server генерирует следующий план:

Если разобраться с тем, что именно проверяет ASSERT, то мы увидим, что он возвращает 0, если в столбец color передаётся значение отличное от G или R и NULL в противном случае. Ошибка будет сгенерирована, есть ASSERT вернёт значение отличное от NULL.

Помимо проверки CHECK-ограничений ASSERT используется и при проверке ограничений внешних ключей. Попробуем чуть усложнить наш пример, добавив ещё одну таблицу с потенциально возможными цветами светофора и связав две таблицы между собой.

DROP TABLE IF EXISTS possible_light;
CREATE TABLE possible_light
(
    color CHAR(1) PRIMARY KEY
);
INSERT INTO dbo.possible_light (color) VALUES ('R'),('Y'),('G');
ALTER TABLE dbo.traffic_light
ADD CONSTRAINT fk_light
    FOREIGN KEY (color)
    REFERENCES dbo.possible_light (color);

Теперь при вставке данных в первую таблицу план усложнится:

Если идти справа налево, то первый ASSERT как и раньше проверит CHECK ограничение, а второй ASSERT проверит корректность связи по ключам.

В предикате второго оператора ASSERT мы видим непонятное условие Expr1007, но всё станет на свои места, если отобразить план запроса в виде текста:

  |--Assert(WHERE:(CASE WHEN NOT [Pass1008] AND [Expr1007] IS NULL THEN (0) ELSE NULL END))
       |--Nested Loops(Left Semi Join, PASSTHRU:([lessons].[dbo].[traffic_light].[color] IS NULL), OUTER REFERENCES:([lessons].[dbo].[traffic_light].[color]), DEFINE:([Expr1007] = [PROBE VALUE]))
            |--Assert(WHERE:(CASE WHEN [lessons].[dbo].[traffic_light].[color]<>'R' AND [lessons].[dbo].[traffic_light].[color]<>'G' THEN (0) ELSE NULL END))
            |    |--Table Insert(OBJECT:([lessons].[dbo].[traffic_light]), SET:([lessons].[dbo].[traffic_light].[color] = [Expr1004],[lessons].[dbo].[traffic_light].[id] = [Expr1003]))
            |         |--Compute Scalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(char(1),[@1],0)))
            |              |--Compute Scalar(DEFINE:([Expr1003]=getidentity((1525580473),(6),NULL)))
            |                   |--Constant Scan
            |--Clustered Index Seek(OBJECT:([lessons].[dbo].[possible_light].[PK__possible__900DC6E8209DDE1B]), SEEK:([lessons].[dbo].[possible_light].[color]=[lessons].[dbo].[traffic_light].[color]) ORDERED FORWARD)

По строке DEFINE:([Expr1007] = [PROBE VALUE]) становится понятно, что это выражение — просто результат объединения таблиц. Этим выражением ASSERT проверяет, что вставляемое значение действительно есть в таблице possible_light.

Наконец, рассмотрим ещё один случай, где оператор ASSERT может встречаться в реальной работе. Речь идёт о подзапросах. Во многих ситуациях встречается «скалярный» подзапрос. Т.е. такой подзапрос, который возвращает строго одно значение. В качестве тестового запроса рассмотрим следующий код:

SELECT * FROM dbo.traffic_light tl
WHERE (tl.color>
(SELECT pl.color FROM dbo.possible_light pl WHERE (1=1)and(pl.color>'A'))
)

Практического смысла он не несёт, но позволяет продемонстрировать ситуацию, когда мы сравниваем скалярное значение с результатом подзапроса. План получился не очень сложный:

Самый интересный блок тут это часть где данные из possible_light агрегируются, чтобы подсчитать количество строк, а потом полученное значение передаётся в ASSERT. Думаю, вы уже сами догадались, что Expr1004 это результат агрегации

Stream Aggregate(DEFINE:([Expr1004]=Count(*)...

Вот такой большой пост у меня получился о простейшем, но очень важном операторе.

Рубрики
wosb_freshwater Без рубрики

Caridina golden dragon

Торговое название этой креветки «золотой дракон». Почему «золотой» понятно, но вот про «дракона» я не понял. Если у вас есть версия, пишите в комментариях. Относится к селекционным видам. В остальном ничего особенного. Обычная креветка-каридина.

Рубрики
photoblog Без рубрики

2022-10-17

В горы ходить вообще не круто.

Рубрики
photoblog Без рубрики

2022-10-16

Рубрики
wosb_freshwater Без рубрики

Thorichthys ellioti

Цихлазома Элиота — американская цихлида, живущая в медленных реках Мексики. Эти рыбы чаще всего живут стаями недалеко от берега. Их удивительная красота и необычный внешний вид сделали этих рыб любимцами аквариумистов. К сожалению, содержать этих рыб в аквариуме с растениями довольно тяжело, так как цихлазомы ищут корм, просеивая грунт. Если вы хотите попробовать разводить рыб, то цихлазомы Элиота — отличный выбор. Они легко нерестятся и долго ухаживают за мальком, защищая его от других рыб.

Рубрики
wosb_freshwater Без рубрики

Caridina sp. (Galaxy fishbone)

Помимо морских аквариумов, я содержу ещё и пресноводных креветок. На фото относительно редкая креветка из рода Caridina. Коллекционеры называют эту расцветку Galaxy (потому что есть точки, похожие на звёзды) Fishbone (рисунок на спине напоминает скелет рыбы). Недавно у меня впервые появились мальки этих креветок.

Рубрики
photoblog Без рубрики

2022-10-05

Рубрики
blogpost Без рубрики

Список моих питомцев

Иногда меня спрашивают, сколько всего у меня кораллов, рыбок, креветок и других животных. По правде говоря, я и сам этого точно не знаю, поэтому я решил как-то систематизировать всех, кого я содержал ранее, или содержу сейчас. Получилась интерактивная схема, которая позволяет не только приблизительно ответить на вопрос из начала статьи, но и оценить как далеко мои питомцы находятся друг от друга на филогенетическом дереве. Буду рад любым комментариям или предложениям по улучшению — https://agorkov.ru/biota/

Рубрики
wosb_freshwater Без рубрики

Бактериальная слизь под микроскопом

В течение нескольких недель на канале моих друзей из BioBox проходил интересный марафон. В кубиках Aquael Shrimp Set создавали различные биотопы: флорариум, палюдариум и аквариум. Буквально вчера я посещал их студию и видел получившийся аквариум. Видео о нём вы можете посмотреть ниже:

Как и в большинстве аквариумов коряга там покрылась белым слоем бактериальной слизи. Выглядит это примерно так:

Опыт говорит, что вреда от слизи нет, но любопытство берёт своё. Я сделал соскобы и поехал домой, изучать их под микроскопом. Сам не знаю почему, но я ожидал увидеть там много диатомовых водорослей. Они, конечно, присутствовали, но гораздо больше там было инфузорий. Может, кто-то даже возьмётся определить конкретный вид: