Гугл - Плитка

Гугл - Плитка

Michael Smirnov

Мой канал о Гугл Таблицах: @pro_google_sheets

Чат канала: @pro_google_sheets_chat


Здравствуйте, товарищи!


Сегодня будем делать ремонт на кухне. Приятная медитативная часть собственно по укладке плитки будет после статьи, а тут мы порешаем головняк с рандомной раскладкой.


Наши постоянные читатели ставят лайки!


Есть квадратная плитка для кухни, для фартука. В узор не собирается (так задумано), нужен рандом. Не каждый рандом будет симпатичным, надо нагенерить побольше. Хозяйка выберет симпатичный вариант.


Наверное, есть специализированный софт для этой задачи, но мы будем делать на гугло табличке. Нам для этого не нужны никакие оправдания.


Супер коротко:

  • Берём фотки плиток, заливаем на гугл диск
  • Закидываем картинки в таблицу
  • Генерим рандомные раскладки одной небольшой формулой
  • Сохраняем понравившиеся, потом выбираем из них


Попробовать можно тут (делайте копию). Короткое видео – на канале.


Ниже чуть подробнее, что было сделано.


Фотки


Можно было бы использовать фотки с сайта, но там всего 9 разных рисунков, а в реальности у нас 13 (12 с рисунком и белая), и немного они по тону отличаются. Да и количество не как на коробке, не поровну.


Поэтому просим сделать фотки, считаем, сколько каких плиток. Идеальные квадраты не нужны – растянем потом в табличке.


Вот таких у нас 14, других может быть меньше или больше


У нас тут простой вариант: плитка квадратная, размещать нужно без смещений и без каких-либо ограничений (типа "две белые не должны быть рядом") – просто рандомно на сетке.


Единственное что, надо сделать – для каждой 4 варианта поворота. Это делаем штатными средствами операционки: делаем 4 копии каждого файла, повороачиваем их на 0 градусов (не поворачиваем), 90 по часовой, 180, 90 против часовой.


На винде есть что-то аналогичное


Возможно google apps scrips мог бы нам наделать копий (да) и повернуть картинки (не уверен), но быстрее было сделать руками.


Все файлы обзываем по одному шаблону: 1-2-(90).jpg

  • номер картинки
  • номер поворота
  • в скобках сам поворот

Тут есть некоторая избыточность, но ничего страшного.


Заливаем фотки на гугл диск. Шарим папку, чтоб можно было посмотреть по ссылке.


Теперь можем импортировать в таблицу.


Импорт фоток в таблицу


Опять же, можно было бы использовать скрипт, но быстрее было вручную: пишем @1-2- – гугл подсказывает правильный файл, его и выбираем.



Получаем чип файла.



Его URL можно достать так: =B2.url



Из URL нам нужен id, который мы достанем регуляркой: =REGEXEXTRACT(_url; "id=(.*)")



А потом подставим в ссылку https://drive.google.com/uc?export=download&id=xxxxxxxx, которую можно использовать в функции IMAGE() - получим картинку в ячейке. Второй параметр укажем - 2, чтоб картинка растянулась по всей ячейке.



А сами ячейки сделаем квадратными: строки по 100 и столбцы по 100.


Ширину колонки тоже в 100 выставил


Оформляем все эти преобразования в табличку и не забываем вписать количество каждой плитки.


Картинки вставили скопом с помощью MAP(), а вот с .url так не получилось, поэтому они отдельно достаются справа


Не обязательно было в справочнике картинки выводить, но для самопроверки, пока экспериментировали, мы это сделали.


Генерим варианты


У нас 104 плитки. Надо нам расположить их в два прямоугольника: 14 на 4 и 12 на 4 (кухня, наверное, буквой Г).


Вариантов расположения (в одну линию, а она однозначно соответствует нашим прямоугольникам):


  • в числителе – количество перестановок (n – количество вообще всех плиток)
  • в знаменателе – повторы за счёт одинаковых плиток (n_i – количество каждого вида)
  • сбоку – варианты поворотов каждой плитки (белые тоже считаем, если без них то 4^(n-26))


Это для нашего случая примерно 2,5 * 10^113. За выходные не просмотришь, поэтому мы просто сгенерим случайный, а потом другой, а потом ещё, и т.д.


Сначала берём все наши плитки столько раз, сколько у нас каждой плитки есть:

=TOCOL(MAP(ref!B2:B14; LAMBDA(_n; MAP(SEQUENCE(1; _n); LAMBDA(_i; OFFSET(_n;; -1))))); 1)
0 (это белые) - 26 штук, 1 - 5 штук, 2- 5 штук, 3 - 8 штук, ...


Варианты расположений получаем просто случайной сортировкой (по столбцу со случайными числами):

=SORT(_all; RANDARRAY(ROWS(_all); 1); 1)
_all - это то, что получили на прошлом шаге


Случайный поворот - один из возможных 4-х, так что делаем случайное целое число от 0 до 3:

=ARRAYFORMULA(INT(RANDARRAY(ROWS(_all); 1) * 4))


Записываем рядом с номером плитки в виде строки

=ARRAYFORMULA("(" & _all_randomized & ", " & INT(RANDARRAY(ROWS(_all); 1) * 4) & ")")


Строки нам нужны, чтоб мы могли наш случайный вариант сохранить.


В итоге получилась вот такая формула (в конце мы все пары в скобках собрали в одну строку через ; с помощью JOIN()):

={
    "Случайный вариант";
    LET(
        _all;
            TOCOL(
                MAP(
                    ref!B2:B14;
                    LAMBDA(
                        _n;
                        MAP(
                            SEQUENCE(1; _n);
                            LAMBDA(_i; OFFSET(_n;; -1))
                        )
                    )
                );
                1
            );
        _all_randomized;
            SORT(
                _all;
                RANDARRAY(ROWS(_all); 1);
                1
            );
        _w_rotation;
            ARRAYFORMULA(
                "("
                & _all_randomized
                & ", "
                & INT(RANDARRAY(ROWS(_all); 1) * 4)
                & ")"
            );
        JOIN(";"; _w_rotation)
    )
}


При любом изменении в таблице, генерит новый вариант.


Теперь надо его отрисовать.


Рисуем вариант


Для начала нашу строку разделим на пары (то, что в скобках): номер плитки, номер поворота.

SPLIT(_v; ";")


Потом складываем это всё в 4 строки.

WRAPCOLS(SPLIT(_v; ";"); 4)


Разделяем немного: добавляем после 14 столбца два пустых. Просто, чтоб два куска (которые 14 на 4 и 12 на 4) не смешивались.

IFNA(HSTACK(CHOOSECOLS(_vs; SEQUENCE(14));;; CHOOSECOLS(_vs; SEQUENCE(COLUMNS(_vs) - 14; 1; 15))))


Теперь из каждой пары достанем номер плитки _i и номер поворота _j.

LET(_i; --REGEXEXTRACT(_t; "\d+"); _j; --REGEXEXTRACT(_t; "(\d+)\)"); ...


По ним достанем URL правильной картинки из нашего справочника.

VLOOKUP(_i; {ref!A:A\ ref!M:P}; 2 + _j;)


В итоге получилась вот такая формула (в ней уже есть знакомые ранее кусок про отображение картинки):

=LET(
    _v;
        B9;
    _vs;
        WRAPCOLS(SPLIT(_v; ";"); 4);
    _vs2;
        IFNA(HSTACK(
            CHOOSECOLS(
                _vs;
                SEQUENCE(14)
            );
            ;;
            CHOOSECOLS(_vs;
                SEQUENCE(COLUMNS(_vs) - 14; 1; 15)
            )
        ));
    MAP(
        _vs2;
        LAMBDA(
            _t;
            IF(
                _t = "";;
                    LET(
                        _i;
                            --REGEXEXTRACT(_t; "\d+");
                        _j;
                            --REGEXEXTRACT(_t; "(\d+)\)");
                        IMAGE(
                            "https://drive.google.com/uc?export=download&id="
                            & REGEXEXTRACT(
                                VLOOKUP(
                                    _i;
                                    {ref!A:A\ ref!M:P};
                                    2 + _j;
                                );
                                "id=(.*)"
                            );
                            2
                        )
                    )
            )
        )
    )
)


И такой результат.


Сохранение понравившихся


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


Для сохранения под текущим случайным вариантом оставили место. И у каждого варианта галочка - если её нажать, то отображаться будет не свежий сгенерённый вариант, а выбранный.


Отмеченные зелёным понравились особенно


А если несколько нажать? Отобразится последний (который нижний).


Для этого немного формула отображения доработана вот таким условием:

=LET(
    _saved;
        FILTER(B15:B; A15:A; B15:B <> "");
    _v;
        IF(
            ISNA(_saved);
                B9;
                INDEX(_saved; ROWS(_saved); 1)
        );
    ...


Покрупнее


Есть ещё один лист, который большой смысловой нагрузки не несёт. На нём квадратики крупнее, список плиток с поворотами отображается в читаемом виде, по которому легко собрать вариант.


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




Делал на скорую руку. Автоматизировал только рандомизацию, остальное быстрее было сделать вручную.


В целом – прикольная задачка на вечер.


2-3 часа лепил всё это, воспользовались один раз на 10 минут. Но с другой стороны, сильно сэкономили время на ручном переборе и плитку не побили (её ещё клеить, так что не всё потеряно).


Ну, а для вас, надеюсь, было что-то полезное среди этих шагов реализации.


На этом всё. Спасибо за внимание.



Мой канал о Гугл Таблицах: @pro_google_sheets

Чат канала: @pro_google_sheets_chat

Report Page