Владимир, приветствую на нашем форуме!
Для несведущих: Владимир - это автор и постоянный ведущий
Математического Марафона. Надеюсь, скоро он нас порадует новыми нестандартными задачками.
А представленная задача представляет хороший шанс продемонстрировать возможности PARI/GP - в качестве приложения к моему
введению в PARI/GP - чем я не премину воспользоваться.
Прежде чем решать задачу, нужно сделать некоторые предположения. Я буду считать, что г.р. (год рождения) присутствующих доцентов и самого Васи (для простоты изложения в дальнейшем будем причислять Васю к доцентам и считать, что он самый молодой из них) лежат в отрезке
- с запасом: мне
-летние и новорождённые доценты незнакомы :) А математик на портрете, будем считать, родился в отрезке годов
. Если я ошибся в своих предположениях, то решение отыскать не удастся, и скоро мы узнаем это. Или же, если эти рамки слишком широкие, решений будет много, но бестолковых :)
Для начала отберём те года из отрезка
, что не содержат простых делителей
, - понятно, что только такие могут быть г.р. доцентов:
Код:
? g=[]; for(k=1900,2008,if(vecmax(factor(k)[,1])<=50,g=concat(g,[k])))
? g
%1 = [1900, 1904, 1911, 1914, 1920, 1922, 1924, 1925, 1927, 1932, 1935, 1936, 1938, 1944, 1950, 1953, 1955, 1960, 1968, 1972, 1974, 1976, 1978, 1980, 1984, 1989, 1995, 1998, 2000, 2001, 2002]
? n=#g
%2 = 31
Как видим, "хороших" годов оказалось всего лишь 31.
Далее запишем их в виде столбцов матрицы
размером
, где
и
равно степени
-го простого в разложении
-го "хорошего" года (
и
). Два дополнительных (
-й и
-й) столбца матрицы
зарезервированы для г.р. математика на портрете и для факториала, который Вася нашёл в таблице (их мы будем искать перебором), а дополнительная строка нужна для трюка, который будет описан ниже.
Код:
? m=primepi(50)
%3 = 15
? M=matrix(m+1,n+2,i,j,if(i<=m&&j<=n,valuation(g[j],prime(i))))
%5 =
[2 4 0 1 7 1 2 0 0 2 0 4 1 3 1 0 0 3 4 2 1 3 1 2 6 0 0 1 4 0 1 0 0]
[0 0 1 1 1 0 0 0 0 1 2 0 1 5 1 2 0 0 1 0 1 0 0 2 0 2 1 3 0 1 0 0 0]
[2 0 0 0 1 0 0 2 0 0 1 0 0 0 2 0 1 1 0 0 0 0 0 1 0 0 1 0 3 0 0 0 0]
[0 1 2 0 0 0 0 1 0 1 0 0 0 0 0 1 0 2 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0]
[0 0 0 1 0 0 0 1 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0]
[0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0]
[0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0]
[1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0]
[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
Теперь начинаем перебор по годам рождения математика на портрете и результирующему факториалу, заполняя последние два столба нашей матрицы. Для каждой заполненной таким образом матрицы найдем
-базис её решётки с помощью функции
matkerint, а в нем будем искать такие вектора, что
-я компонента равна
, и
-я компонента равны
, а все остальные равны
или
(с точностью до знака целой строки). Мы используем дополнительную строку, чтобы гарантировать противоположные знаки у
-й и
-й компонент: а именно положим
.
Понятно, что решение может быть только в случае, когда в нашем базисе присутствует вектор, у которого
-я и
-я компоненты по модулю равны
. Но мы будем даже наглее - будем надеяться, что решение возникнет непосредственно как элемент базиса. Дальнейшее показывает, что наша наглость обоснована - таких решений довольно много:
Код:
? M[m+1,n+1]=M[m+1,n+2]=1
%6 = 1
? for(h=1000,1899, if(vecmax(factor(h)[,1])>50,next); for(i=1,m,M[i,n+1]=valuation(h,prime(i))); for(r=1,50, for(i=1,m,M[i,n+2]=valuation(r!,prime(i))); K=matkerint(M); sol=0; for(j=1,matsize(K)[2], if(abs(K[n+2,j])!=1,next); t=K[,j]; if(t[n+2]==1,t=-t); t[n+2]=0; if(vecmin(t)>=0 && vecmax(t)<=1, print1([h,r]); for(k=1,n, if(t[k],print1(" ",g[k])));print(); )) ))
[1344, 28] 1920 1932 1944 1980 1989 1995 2000 2002
[1368, 28] 1920 1932 1944 1960 1980 1989 2000 2002
[1386, 28] 1920 1932 1944 1960 1976 1980 1989 2000
[1404, 28] 1920 1932 1938 1944 1960 1980 2000 2002
[1408, 28] 1911 1920 1932 1944 1980 1989 1995 2000
[1440, 28] 1900 1920 1932 1944 1960 1980 1989 2002
[1458, 28] 1904 1932 1936 1944 1950 1960 1976 2000
[1485, 28] 1904 1920 1932 1944 1950 1960 1976 1980
[1512, 28] 1904 1920 1925 1932 1944 1950 1976 1980
[1536, 28] 1900 1911 1920 1925 1932 1944 1980 1989
[1539, 28] 1904 1911 1920 1932 1936 1944 1950 2000
[1584, 28] 1900 1904 1911 1920 1932 1944 1950 1980
[1600, 13] 1944 2002
[1620, 13] 1920 2002
[1620, 28] 1900 1904 1911 1920 1932 1936 1944 1950
[1638, 13] 1920 1980
[1664, 13] 1925 1944
[1728, 21] 1938 1944 1960 2000 2002
[1760, 21] 1920 1944 1960 1989 1995
[1764, 21] 1904 1944 1976 1980 2000
[1768, 21] 1920 1944 1960 1980 1995
[1782, 21] 1904 1944 1960 1976 2000
[1785, 21] 1920 1944 1960 1976 1980
[1792, 21] 1900 1944 1960 1980 1989
[1800, 21] 1920 1938 1944 1960 2002
[1820, 21] 1920 1938 1944 1960 1980
[1824, 21] 1904 1911 1944 1980 2000
[1836, 21] 1920 1925 1944 1960 1976
[1848, 21] 1900 1920 1944 1960 1989
[1862, 21] 1904 1920 1944 1950 1980
[1872, 21] 1920 1925 1938 1944 1960
[1881, 21] 1904 1911 1920 1944 2000
[1890, 10] 1920
[1890, 21] 1904 1920 1925 1944 1976
Как видим, решений нашлось много, но в них присутствуют либо слишком старые, либо слишком молодые доценты. Это наводит на мысль, что нам следует сделать возрастные рамки более жёсткими. Оставляю это читателям в качестве упражнения.
Скажу лишь ответ:
Если зажать г.р. доцентов в отрезок
, то наша программа выдаст единственное решение:
[1792, 21] 1938 1944 1950 1960 1980
То есть:
зав.кафедрой ("старейшина") родился в 1938 году;
Вася в 1980-м;
доцентов на кафедре раз, два и обчёлся;
а с портрета смотрит Лобачевский.