Вайб-кодинг

Привет! Сегодня у нас короткий пост про вайб-кодинг.
Итак, я уже довольно давно использую ИИ в работе и люблю в свободное время вайбкодить какие-нибудь утилиты для себя. В этой статье речь пойдет о написании программы для решения пазла-головоломки.
Если вы еще здесь то начнем 🙂
Проблема (несуществующая)
У нас в офисе есть универсальный пазл с головоломкой которую можно решать каждый день 365 дней в году. Он находится на кухне и помогает скоротать время в момент чаепития.
Часто бывает что чай уже закончился, а рабочие задачи нет а пазл так и не сложился. В один из таких моментов я задумался о том решить проблему программным способом.
Естественно без написания кода вручную и с максимально комфортным подходом.
Выглядит всё как приключение на 5 минут. Ну что, погнали! 🏃♂️➡️
Попытка решения №1
В основом для вайбкодинга я выбираю Go так как программы компилируются в бинарник поддерживаемый на всех популярных платформах. Также из плюсов хочу отметить что большинство ошибок проявляется на этапе компилирования программы, а тулинг поддерживает тесты и автоматическое форматирование из коробки.
Этот язык мне очень нравится хотя на нем я самостоятельно написал наверное менее сотни строк.
Но в этот раз я почему-то решил начать с Python.
Первым делом я сфотографировал пазл со всеми его деталями:
Открыл Cursor, выбрал в чате claude-4-sonnet, приложил туда фотографию и написал вот такой промт:
1 | I have a challenge to fill this board with "bricks" and make cells related to current date unfilled. |
Сразу скажу что промт неоптимальный и неправильный.
Тем не менее Claude честно попытался решить эту задачу и сгенерировал скрипт который он назвал Calendar Puzzle Solver.
В первой версии скрипта он накосячил с фигурками и просто заполнял поле фигурами произвольных форм.
На что резонно получил вот такой комментарий:
1 | Please fix your solution. You should use only provided limited bricks set. |
Получив следующий результат я понял что Claude неверно интерпретировал картинку и неправильно определил доступный сет фигурок.
Следующий мой промт был такой, с попыткой в ASCII-арт 😁:
1 | Here is a set of bricks: |
На этот раз я почему-то получил в качестве решения скрипт который ожидал 44 ячейки притом что их всего лишь 43,
На то он получил новый промт.
1 | Please fix program. It expectecs 44 total cells, but board has only 43 cells - 12 for months and 31 for days |
В этот раз я получил скрипт который по заверениям Claude точно должен работать. Я запустил его и не дождался окончания работы скрипта за 5 минут. Очевидно решение нерабочее.
Так так так, кажется я зашел в тупик. Самое время открыть новый чат.
Попытка решения №2
На этом моменте я удалил весь код и написал новый стартовый промт и также приложил картинку с пазлом.
1 | I have a challenge to fill this board with "bricks" and make cells related to current date unfilled. For example today it should be filled excluding 26 and "Май" |
На этот раз клод меня почти понял и после первого решения пришлось подправить только одну фигуру.
1 | Please fix Piece 6 |
Насколько я помню эта версия скрипта также работала очень долго и не смогла решить задачу.
Поэтому я решил что пора немного подебажить.
1 | Please print configuration of board on script run. I want to be sure that board has correct dimensions |
И еще немного
1 | And please also show bricks |
Также добавить статистику
1 | And please also count time that spent for finding solution |
И поддержку аргументов
1 | How to run script for another date? |
В результате я получил довольно информативный скрипт который тем не менее работал очень долго и не решал мою задачу 😁
1 | python ./main.py |
Попытка решения #3
На этом этапе я задал себе вопрос - «а зачем тут нужен Python?»
Итак, срочно переписываем все на Go. В этом случае хотя бы есть шанс дождаться заверешения работы программы 😁
Тем более с го есть возможность нагрузить все ядра CPU, а не только одно 🤣
Вставляем в промт последнюю версию полученного скрипта на Python и добавляем такой текст:
1 | Please rewrite this script in go and use parallel calculations |
Запускаем программу и видим результам уже через 11 секунд и 10 млн. попыток, а не спустя вечность как это было с питоном.
Правда решение не нашлось 💩
1 | ✗ No solution found for 6 Июнь (took 11.7612 seconds) |
Что ж, самое время разьяснить условия мсье Клоду более подробно.
1 | Unfortunately it can't found solutions. All bricks can be rotated 90 degrees and flipped |
Ура! Текущее решение работает! Просим клода пофиксить нейминг для фигур и написать README.md.
1 | Please generate a descriptive README |
1 | Please update names of piece 3, because it is not square, it is cutted rectangle |
В итоге получаем рабочую программу которая мнгновенно решает задачу и нагружает все доступные ядра CPU.
Здесь цифрами от 1 до 8 у нас помечены фигуры, а x
это пустые клетки.
Судя по скрину программа подобрала решение для сегодняшней головоломки всего лишь за 0.2 секунды и 13 тысяч попыток!
При этом было задействовано 11 ядер CPU 🚀
Ну что ж, неплохо! Дальше мы просто инициализируем git-репозиторий и выкатываем наше поделие на GitHub - https://github.com/rhamdeew/calendar_solver
Бонус вариант
CLI-утилита это конечно круто, но недостаточно удобно. Давайте же сделаем Web GUI!
Причем чтобы было еще интереснее портируем наше решение на WebAssembly!
На этом моменте я осмелел достаточно чтобы написать промт в духе:
1 | 1. Extract core logic into separate file |
Claude бодро приступил к работе, но подвис на первом пункте. Далее я пытался давать ему только первую часть задачи, но клод каждый раз зависал пытаясь сгенерировать solver.go
.
Ну что ж, тогда перестаем дружить с клодом и идем к новому приятелю - gemini-2.5-pro
!
Новый укороченный промт:
1 | Extract solver logic into `solver.go` file. I want to re-use it. |
Gemini в отличие от Claude прекрасно справился с этой задачей. Логика вынесена в solver.go, аппка прекрасно собирается и работает точно так же 💪
Теперь попробуем доделать все остальное в одном чате:
1 | Create `web` directory and implement similar solution written on Go but with web GUI using htmlx, tailwind and WebAssembly |
Тут Gemini начал прекрасно, но потом закопался в названиях файлов и не смог сделать так чтобы все корректно собиралось.
Понятно, откатываемся 💩
Важный момент - хоть в Cursor и реализована система чекпоинов к которым можно откатываться все же надежнее коммитить каждый шаг. Лишние коммиты потом можно отребейзить, а вот случайно попорченный код восстанавливать не так удобно.
Кстати, похоже что зря я гнал на Claude что он не смог вынести логику из одного файла в другой.
Такое ощущение что он просто работает сегодня с большими перебоями. Дело не в задаче в общем 🙂
Делаем шаг назад и просим Gemini чуть поменять структуру файлов
1 | I use `solver.go` as a package. Please move it into directory with name that follows Go conventions and best practices. |
Итак, гемини отработал и сказал что все прекрасно работает.
Разбираться в том как теперь собирать приложение мне лень, поэтому спросим это у нашего нового друга.
1 | How to build cli app? |
И заодно попросим написать мейкфаил
1 | Please generate Makefile with: |
Так, вроде бы все хорошо, но кажется чего-то не хватает. Может ТЕСТОВ? 🤔
1 | Write tests for cli app and add `test_cli` target |
Так, теперь у нас есть код cli-приложения с корректной структурой и даже есть тесты.
1 | make test_cli |
Приступаем в генерации web-приложения на WebAssembly.
1 | Create `web` directory and implement similar solution written on Go but with web GUI using htmlx, tailwind and WebAssembly |
Gemini спорил сам с собой то и дело переписывая код, но в итоге родил что-то что может собираться в бинарник и запускать сервер.
Также я попросил его добавить Makefile со всеми необходимыми целями для сборки и запуска обоих версий приложения.
Запускаем веб версию:
1 | make web |
Выглядит красиво!
Но работает некорректно:
Судя по одинаковому с cli-версией количеству попыток для подбора решение правильное, а вот отображение решения какое-то кривое.
Снова идем в чат и жалуемся:
1 | Please fix your solution. It displays incorrect board with incorrect block positions, but attempts count similar to cli solution. I think calculations is correct, rendering not correct. |
Gemini снова думает, но рождает почему-то такое же решение 🤔
Жалуемся еще
1 | No, your board is incorrect. |
Результат:
Мне уже практически все нравится, но думаю стоит немного поправить стили.
Также заодно похвалим Gemini (и впустую израсходуем токены).
1 | Thanks! It looks good! |
Новый результат:
Все это конечно круто, но я хочу лайв-демо прямо на гитхабе.
Идем в новый чат.
1 | I want to push this repo to GitHub and want to make index.html accessible from web as a live demo. How to do it? |
На что Gemini предлагает вручную копировать билд в docs
. Минус вайб 💩
1 | Is there a way to do it using GitHub Actions? I don't want to manually copy every build to `docs` dir |
Gemini сказал что все сделает. Плюс вайб 👍
На этом этапе почти все заработало, но нужно было еще включить GitHub Pages в настройках репозитория.
Итог
Потрачено конечно чуть больше чем 5 минут, но результат стоит того 🙂
Live demo: https://rhamdeew.github.io/calendar_solver/