То, на решение чего GPT-4o потратил 2 часа, Sonnet 4.5 решает за 5 секунд.
Делиться

Мы все знаем, что возможности магистров права значительно возросли за последние несколько лет, но трудно количественно оценить, насколько хорошими они стали.
Это заставило меня вспомнить геометрическую задачу, на которую я наткнулся на одном канале YouTube в прошлом году. Это было в июне 2024 года, и я пытался решить её с помощью ведущей на тот момент модели большого языка (GPT-4o). Результат оказался не очень удачным, и поиск решения потребовал немало усилий, и мне стало интересно, как справятся с этой задачей современные магистратуры права.
Головоломка
Вот краткое напоминание о том, что я тогда просил решить магистра права. Предположим, у нас есть следующая сетка точек/узлов. В плоскостях x и y каждый узел находится на расстоянии ровно одной единицы от своего соседа. Это выглядит так:

Итак, вопрос, на который я хотел ответить, был таким:
Сколько отдельных квадратов можно нарисовать на этой диаграмме?
Быстро стало ясно, что GPT-4o не знает ответа, поэтому я немного изменил тактику и вместо этого задал ему такой вопрос.
Мне нужна программа на Python, которая бы отображала все квадраты, которые мы можем нарисовать на прилагаемой диаграмме, предполагая, что углы любого квадрата должны лежать на одной из точек на диаграмме. Предположим, что каждая соседняя точка находится на расстоянии одной единицы от другой по осям X и Y. Также выведите сводку количества квадратов одинакового размера и длины их сторон.
Короче говоря, в конце концов мне удалось добиться от GPT-4o корректного решения на Python. Тем не менее, мне потребовалось около двух часов и более 40 итераций, чтобы доработать модель и получить рабочий ответ.
Кстати, вы уже нашли ответ? Даже сейчас я не могу поверить, что на этом графике можно нарисовать 21 квадрат.
Взаимодействие с Сонетом 4.5
Это возвращает нас к сегодняшнему дню и недавнему выпуску компанией Anthropic модели программирования, которая считается лучшей на сегодняшний день, а именно Claude Sonnet 4.5. Прошло около 16 месяцев с тех пор, как я в последний раз обращался к ней. Насколько же улучшились навыки LLM за это время? Давайте посмотрим, как Sonnet 4.5 справится с этой задачей.
Чтобы использовать Sonnet 4.5, я посетил домашнюю страницу Anthropic.
https://www.anthropic.com
Вы должны увидеть такую страницу.

Нажмите большую чёрную кнопку «Попробовать Клода» в правом верхнем углу экрана. Вам будет предложено войти в систему. Если у вас ещё нет учётной записи Anthropic, пожалуйста, создайте её прямо сейчас. Это совершенно бесплатно.
После входа в систему вы попадете на экран, отображающий знакомое окно чата, позволяющее вам взаимодействовать с Sonnet 4.5 и задавать вопросы по нему.
Прежде чем попросить модель предоставить программу на Python для решения головоломки, я задал ей прямой вопрос, чтобы проверить, знает ли она уже ответ.

Он вернулся с:
Глядя на эту сетку, мне нужно посчитать все возможные квадраты разных размеров, которые могут быть образованы путем соединения точек. Позвольте мне сначала определить структуру сетки. Точки образуют: 2 точки в верхнем ряду 2 точки во втором ряду 6 точек в третьем ряду 6 точек в четвертом ряду 2 точки в пятом ряду 2 точки в шестом ряду Похоже, что это сетка в форме креста или знака плюс. Теперь я посчитаю квадраты по размеру: Квадраты 1×1: они образованы любыми 4 точками, которые составляют единичный квадрат. В горизонтальной средней части (строки 3-4): 5 квадратов в строке × 1 = 5 квадратов В вертикальной средней части (столбцы, где пересекается крест): подсчет вертикальных сегментов дает нам еще 5 квадратов Итого: 10 маленьких квадратов Квадраты 2×2: для них нужны расположения точек 4×4. В горизонтальном сечении: 4 квадрата. В вертикальном сечении: 4 квадрата. Перекрытие в центре: -1 (учитывается дважды). Всего: 7 квадратов размером 2×2. Квадраты 3×3 и больше: Ширина сетки составляет всего 6 точек, но форма креста ограничивает место, где могут поместиться более крупные квадраты. Проверка геометрии: Один квадрат 3×3 может поместиться в центре, где перекрещиваются перекладины креста. Всего: 1 квадрат размером 3×3. Всего: 10 + 7 + 1 = 18 квадратов.
Итак, уверенно неверно. Заинтригованный и заинтригованный ссылкой модели на квадрат 3×3 (что невозможно в этой сетке), я попросил её показать мне этот квадрат на схеме. Она ответила вот что.
Присмотревшись к сетке внимательнее, мне нужно пересмотреть вопрос о том, существует ли квадрат 3×3 на самом деле. Для существования квадрата 3×3 мне потребуется расположение точек 4×4 (поскольку для квадрата 3×3 требуется 4 точки на каждой стороне). Давайте проверим структуру сетки: Сетка выглядит следующим образом: Строки 1-2: всего 2 точки в каждой (по центру) Строки 3-4: 6 точек в каждой (по всей ширине) Строки 5-6: всего 2 точки в каждой (по центру) Для квадрата 3×3 мне понадобится 4 последовательных строки и 4 последовательных столбца с точками на пересечениях. Однако, глядя на рисунок крест/плюс: Вверху только 2 столбца точек В середине 6 столбцов точек Внизу только 2 столбца точек Поскольку строки 1-2 и строки 5-6 имеют только 2 точки каждая (не охватывая всю ширину), на самом деле нигде в этой сетке нет блока точек 4×4. Мне нужно исправить свой ответ: В этой сетке НЕВОЗМОЖНО построить квадрат 3×3. Всего должно быть: 10 (квадраты 1×1) + 7 (квадраты 2×2) = 17 квадратов Я прошу прощения за ошибку в моем первоначальном подсчете. Рисунок в форме креста предотвращает образование любого квадрата больше, чем 2×2.
Ладно, этот ответ отчасти реабилитировал его, но, по сути, он неверно указал, что всего было 21 квадрат.
Окончательный ответ
Чтобы соблюсти справедливость при сравнении моделей за 16 месяцев, я задал Sonnet 4.5 тот же самый вопрос, который я задал GPT-4o, а именно, напомню, следующий.
Мне нужна программа на Python, которая бы отображала все квадраты, которые мы можем нарисовать на прилагаемой диаграмме, предполагая, что углы любого квадрата должны лежать на одной из точек на диаграмме. Предположим, что каждая соседняя точка находится на расстоянии одной единицы от другой по осям X и Y. Также выведите сводку количества квадратов одинакового размера и длины их сторон.
Sonnet 4.5 задумался всего на 5 секунд, прежде чем сгенерировать свой код Python.
import matplotlib.pyplot as plt import numpy as np from itertools import combins from collections import defaultdict # Определить точки сетки на основе изображения points = [ # Верхние две строки (по 2 точки, по центру) (3, 6), (4, 6), (3, 5), (4, 5), # Средние две строки (по 6 точек, по всей ширине) (1, 4), (2, 4), (3, 4), (4, 4), (5, 4), (6, 4), (1, 3), (2, 3), (3, 3), (4, 3), (5, 3), (6, 3), # Нижние две строки (по 2 точки, по центру) (3, 2), (4, 2), (3, 1), (4, 1), ] def is_square(p1, p2, p3, p4): «»»Проверка, образуют ли четыре точки квадрат и вернуть длину стороны, если true.»»» points = [p1, p2, p3, p4] # Вычислить все попарные расстояния distances = [] for i in range(len(points)): for j in range(i + 1, len(points)): dist = np.sqrt((points[i][0] — points[j][0])**2 + (points[i][1] — points[j][1])**2) distances.append(dist) distances.sort() # Для квадрата: 4 равные стороны и 2 равные диагонали # Диагонали должны быть sqrt(2) раз больше длины стороны if len(distances) == 6: sides = distances[:4] diagonals = distances[4:] # Проверяем, все ли стороны равны if np.allclose(sides, [sides[0]] * 4, atol=1e-6): # Проверяем, все ли диагонали равны if np.allclose(diagonals, [diagonals[0]] * 2, atol=1e-6): # Проверяем, диагональ ли = сторона * sqrt(2) if np.allclose(diagonals[0], sides[0] * np.sqrt(2), atol=1e-6): return True, sides[0] return False, 0 def order_square_points(p1, p2, p3, p4): «»»Упорядочить точки квадрата против часовой стрелки, начиная с левого нижнего угла.»»» points = [p1, p2, p3, p4] # Найти центроид cx = sum(p[0] for p in points) / 4 cy = sum(p[1] for p in points) / 4 # Сортировать по углу от центроида def angle(p): return np.arctan2(p[1] — cy, p[0] — cx) points.sort(key=angle) return points # Найти все квадраты squares = [] squares_by_size = defaultdict(list) for combo in combineds(points, 4): is_sq, side_length = is_square(*combo) if is_sq: order_square_points(*combo) squares.append(ordered) squares_by_size[round(side_length, 2)].append(ordered) # Вывести сводку print(«=» * 50) print(«СВОДКА НАЙДЕННЫХ КВАДРАТОВ») print(«=» * 50) total_squares = 0 for side_length in sorted(squares_by_size.keys()): count = len(squares_by_size[side_length]) total_squares += count print(f»Длина стороны {side_length}: {count} square(s)») print(f»nВсего квадратов: {total_squares}») print(«=» * 50) # Создать визуализацию fig, axes = plt.subplots(2, 2, figsize=(14, 14)) axes = axes.flatten() # Участок 1: Все точки ax = axes[0] x_coords = [p[0] для p в точках] y_coords = [p[1] для p в точках] ax.scatter(x_coords, y_coords, c='black', s=100, zorder=3) ax.set_xlim(0, 7) ax.set_ylim(0, 7) ax.set_aspect('equal') ax.grid(True, alpha=0.3) ax.set_title('Original Grid', fontsize=14, fontweight='bold') ax.set_xlabel('X') ax.set_ylabel('Y') # Участок 2: Все квадраты наложенный ax = axes[1] ax.scatter(x_coords, y_coords, c='black', s=100, zorder=3) colors = plt.cm.rainbow(np.linspace(0, 1, len(squares))) для квадрата, цвет в zip(squares, colors): square_closed = square + [square[0]] xs = [p[0] для p в square_closed] ys = [p[1] для p в square_closed] ax.plot(xs, ys, c=color, linewidth=2, alpha=0.6) ax.set_xlim(0, 7) ax.set_ylim(0, 7) ax.set_aspect('equal') ax.grid(True, alpha=0.3) ax.set_title(f'All {total_squares} Squares Overlaid', fontsize=14, fontweight='bold') ax.set_xlabel('X') ax.set_ylabel('Y') # Участок 3 и 4: Квадраты по размеру plot_idx = 2 for side_length in sorted(squares_by_size.keys()): if plot_idx >= len(axes): break ax = axes[plot_idx] ax.scatter(x_coords, y_coords, c='lightgray', s=100, zorder=2) squares_of_size = squares_by_size[side_length] colors = plt.cm.viridis(np.linspace(0, 1, len(squares_of_size))) for square, color in zip(squares_of_size, colors): square_closed = square + [square[0]] xs = [p[0] для p в square_closed] ys = [p[1] для p в square_closed] ax.plot(xs, ys, c=color, linewidth=2.5, marker='o', markersize=8) ax.set_xlim(0, 7) ax.set_ylim(0, 7) ax.set_aspect('equal') ax.grid(True, alpha=0.3) ax.set_title(f'Квадраты с длиной стороны {side_length} ({len(squares_of_size)} total)', fontsize=14, fontweight='bold') ax.set_xlabel('X') ax.set_ylabel('Y') plot_idx += 1 plt.tight_layout() plt.show()
На первый взгляд я подумал, что Sonnet не мог так быстро найти правильное решение. GPT-4o потребовалось несколько часов . Тем не менее, я установил все необходимые библиотеки, скопировал код и вставил его в ячейку Jupyter Notebook, запустил его и получил следующий вывод. Я пока опустил графики, которые тоже были выведены.
== … что я здесь не показываю #
Это меня потрясло. Ответ был абсолютно точным.
Единственная небольшая ошибка, с которой столкнулась модель, заключалась в том, что она не выводила графики для каждого набора квадратов разного размера. Она выводила только девять квадратов 1×1 и четыре квадрата √2x√2. Я решил эту проблему, попросив Sonnet включить и их.
Можно ли распечатать графики в порядке убывания сторон квадрата? Или можно ли разместить два графика рядом на каждой линии?
Вот что из этого получилось.



Красивый.
Краткое содержание
Чтобы продемонстрировать, насколько значительно продвинулись вперед студенты магистратуры права всего за год, я решил вернуться к сложной геометрической головоломке, которую впервые попытался решить с помощью GPT-4o еще в июне 2024 года. Задача заключалась в написании программы на Python, которая находит и отображает все возможные квадраты на определенной крестообразной сетке точек.
Мой опыт чуть более года назад был трудным: мне потребовалось около двух часов и более 40 подсказок, чтобы привести GPT-4o к правильному решению на Python.
Перенесёмся в сегодняшний день: я протестировал новую версию Claude Sonnet 4.5. Когда я впервые задал модели вопрос напрямую, она не смогла вычислить правильное количество квадратов. Начало было не очень удачным, однако настоящим испытанием стала та же подсказка, которую я использовал в GPT-4o.
К моему удивлению, он одним махом выдал полное и правильное решение на Python. Сгенерированный код не только нашёл все 21 квадрат, но и правильно классифицировал их по уникальным длинам сторон, а также построил подробные графики для их визуализации. Хотя мне потребовалась одна быстрая подсказка, чтобы улучшить графики, основная задача была решена мгновенно.
Может быть, сам факт моей попытки решить эту головоломку в прошлом году и публикация результатов привели к её появлению в веб-сфере, а значит, Anthropic просто скопировала её и включила в свою базу знаний? Да, возможно, так и есть, но тогда почему модель не смогла правильно ответить на первый прямой вопрос, который я ей задал, об общем количестве квадратов?
Для меня этот эксперимент наглядно иллюстрирует невероятный скачок в развитии возможностей магистратуры права. То, что 16 месяцев назад представляло собой двухчасовую итеративную борьбу с ведущей моделью своего времени, сегодня превращается в пятисекундный, одноразовый успех с ведущей моделью.
Источник: towardsdatascience.com



























