Multiplying tool based on Slonimsky's theorem

In the XIX century there were interesting tools for multiplication, built on the basis of the Slonimsky theorem. This is the "Shell for Multiplication" by Slonim and Ioffe bars. It is impossible to read anything about these tools on the Internet, except for a meager description of the appearance, for any good description of the working method (in the style of “it worked like this”), borrowed from the book “History of Computer Engineering” by I.A. Apokin, L.E. Maistrov, “Science” 1990. The description does not disclose the principle of operation of devices. The literature cited by the author of the book is unacceptably difficult to obtain. I decided to open the algorithm of the device on my own, and to demonstrate - to make my own analogue.


Purpose of writing an article


This article is for those who, just like me, are interested in the history of computer technology.
Theoretically, a good description of these tools should be in the book “Devices and machines for the mechanical production of arithmetic operations: Description of the device and estimation of the score. instruments and machines ”/ V.G. von Bohl. - Moscow: Tipo. t-va I.N. Kushnerev and Co. °, 1896. - 244 p.: Ill., Damn .; 24.
But I didn’t get to the Lenin library, where it is stored, but it doesn’t matter. The main thing is that there is no information on the Internet, but I wanted it to be, because, hopefully, I was not the only one puzzled by its search.

Why Habr is selected as the placement of the article

The article is devoted, albeit ancient, but still computing technology. Therefore, is suitable for Habr on a subject.
Habr is well indexed, and I need that the information stated in article could be found. In addition, the community will help me refine the article in terms of quality of presentation.

The source data that I managed to find


On the Internet I came across a description of an interesting mathematical tool developed by Z. Ya. Slonim .

In the middle of the last century Z.Ya. Slonimsky (1810-1904) proposed a simple multiplying device based on the theorem proved by him. This device made it possible to obtain products of any number (the capacity of which did not exceed the capacity of the device) by any single digit. In other words, it was something like a mechanical multiplication table for any number by 2, 3, 4, ..., 9. Later, Slonimsky's theorem was used to create another simple multiplier device (Ioffe counting bars).

Based on his theorem, Slonimsky compiled a table consisting of 280 columns - 9 numbers each. This table is printed on the cylinders, which are the main element of the device. Cylinders can move in two directions: along the axis and around it. Two mini-cylinders are also worn on the axis on which the cylinder is located. The numbers from 0 to 9 are printed on the surface of one mini-cylinder, and the letters a, b, c, d and numbers (from 1 to 7) are applied to the surface of another.

On the lid of the device are 11 rows of reading windows, in the first (lower) row you can see the set number (multiplicable). In the second and third rows of windows, when setting a multiplier, letters and numbers appear. Their combination is the key to the operator. Thanks to him, he knows which screw and how much to turn. After that, numbers appear in the 4th to 11th rows of windows: in the 4th row - the product of the multiplicable by 2, in the 5th - by 3, in 6 - by 4, etc. Thus, the product is at our disposal multiplier for all digits of the multiplier. Now it remains the usual way (on paper) to add these results and get the desired product.


Reading this caused me, as probably yours, a reaction: nothing is clear. But the description of the bars of Joffe already leads to some thoughts:

The counting bars were proposed by Ioffe in 1881. In 1882, they received an honorary review at the All-Russian Exhibition. The principle of working with them is based on the Slonimsky theorem. The Ioffe device consisted of 70 tetrahedral bars. This allowed to place 280 columns of the Slonim table on 280 faces. Each bar and each column were marked, for which Arabic and Roman numerals and letters of the Latin alphabet were used. Latin letters and Roman numerals served to indicate the order in which the bars had to be placed in order to obtain the product of the multiplier by a single-digit factor. The resulting works (and there are as many as the number of digits in the factor) were added up (just like when using the Slonimsky multiplier) with a pencil and paper.


Those. it turns out that having 280 columns with numbers, one can add from them a table of products of any arbitrary number by a series of one-digit numbers.

From there:
Bool, in 1896, came to the following conclusion: “The Ioffe bars simplify the multiplication of numbers even more than the sticks of Napier and their modifications. After the simple witty bars of Luke and Zhanoi, this is the best of arithmetic devices for multiplication. ”

Luke and Janoia bars are also an interesting topic, about which there is even less information, but the article is not about them.

Some result was given by the search for Slonimsky's theorem.
Here is what the Bulletin of the Syktyvkar University writes . Ser. 1. Issue 13.2011. UDC 512.6, 517.987 “On the 200th Anniversary of the Birth of the Creators of Computing Machines Presented for the Demid Prize, Kh.Z. Slonimsky and G. Kummer. " V.P. Odinets

1. Suppose we have a natural number in the system J with base r written bitwise a m a m-1 ... a 2 a 1 . We multiply it sequentially by 1, 2, 3, ..., r-1, and we will sign the resulting products one under the other in compliance with the rule of categories. As a result, we get m + 1 columns (fill the empty spaces on the left with zeros), each of which contains an r-1 digit. The location of the numbers in the column is called the column representation . Multiplication of all kinds of numbers by 1, 2, ..., r-1 generates an infinite number of representations. However, the number of different representations is finite and is given by the formula


Где φ(n) — функция Эйлера, заданная на множестве N натуральных чисел, значение которой (для любого n ∈ N) равно количеству натуральных чисел, не превосходящих n и взаимно простых с n.

2. Пусть теперь r = 10, т.е. система счисления J десятичная. Тогда произведение любой дроби, заключённой между двумя соседними Фареевыми дробями pi/qi и pi+1/qi+1 на числа 1, 2, 3, ..., 9 порождает для целых частей полученных чисел то же представление, что и для целых частей последовательности произведений на числа 1, 2, 3,… 9 Фареевой дроби pi/qi

Full article is here .

The wording was not useful to me. I did not look for a proof of the theorem, so to speak, I took Slonimsky's word. An important moment of this theorem for my problem was that "the number of different representations is finite and is given by the formula ...". And, as follows from the theorem and from the design of the Slonimsky device, for the decimal system, there are 280 representations of the columns.

Slonimsky table


Для воссоздания прибора, действующего на основе той же математической идеи, я получил таблицу Слонимского по алгоритму, описанному в вышеуказанной статье.
Я вооружился FireBug и начал вычислять.
Далее в статье будут встречаться фрагменты JavaScript. Этот язык — основа моей профессиональной деятельности, поэтому я использовал его. Тем не менее, я полагаю, что использованные мной формулы достаточно просты, чтобы специфика языка не затрудняла их понимания, а в некоторых местах я специально использовал не принятые в JavaScript приёмы, чтобы сделать код более понятным для программистов на других языках.

Согласно статье, для построения основной таблицы Слонимского для десятичной системы счисления, была взята последовательность Фарея
F (9) = {0, 1/9, 1/8, 1/7, 1/6, 1/5, 2/9, 1/4, 2/7, 1/3, 3/8, 2 / 5, 3/7, 4/9, 1/2, 5/9, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 7/9, 4/5, 5/6, 6/7, 7/8, 8/9, 1}. 28 numbers of the sequence F (9), except 1, were each multiplied by a series of numbers from 0 to 9 and only the whole parts of the obtained products were taken. The resulting columns of numbers are numbered in increasing order of Farey numbers starting from 0.

The values ​​of the table are obtained by the formula
B[c][r] = Math.floor(F[c]*r);

Here c is the column number, r is the row number.

Slonimsky Main Table (B)
r \ c012345678910eleven12thirteen14fifteen161718192021222324252627
00000000000000000000000000000
10000000000000000000000000000
20000000000000011111111111111
30000000001111111111222222222
40000000111111122222223333333
50000011111122222233333344444
60000111112222233333444445555
70001111122223333444455555666
80011111222333344445556666677
90111112223333445555666777778

To obtain the complete Slonimsky table, an auxiliary table P was constructed, which is a multiplication table for numbers from 0 to 9 in the Pythagorean representation.
P[c][r] = c*r;
r \ c0123456789
00000000000
10123456789
2024681012141618
3036912fifteen18212427
404812162024283236
50510fifteen2025thirty354045
606121824thirty36424854
7071421283542495663
8081624324048566472
9091827364554637281


Each column of table B is vectorially combined with each column of table P. Thus, an intermediate table DU containing 280 columns is obtained.
DU[b*10+p][r] = B[b][r] + P[p][r];
DU
c012345678910eleven12thirteen14fifteen16171819
b00000000001111111111
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
3036912fifteen18212427036912fifteen18212427
40481216202428323604812162024283236
50510fifteen2025thirty3540450510fifteen2025thirty354045
606121824thirty3642485406121824thirty36424854
7071421283542495663071421283542495663
8081624324048566472081624324048566472
90918273645546372811101928374655647382
Continuation
c20212223242526272829ththirty313233343536373839
b22222222223333333333
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
3036912fifteen18212427036912fifteen18212427
40481216202428323604812162024283236
50510fifteen2025thirty3540450510fifteen2025thirty354045
606121824thirty3642485406121824thirty36424854
707142128354249566318fifteen2229th3643fifty5764
8191725334149576573191725334149576573
911019283746556473821101928374655647382
Continuation
c40414243444546474849fifty515253545556575859
b44444444445555555555
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
3036912fifteen18212427036912fifteen18212427
40481216202428323604812162024283236
50510fifteen2025thirty35404516eleven16212631364146
617thirteen1925313743495517thirteen19253137434955
718fifteen2229th3643fifty576418fifteen2229th3643fifty5764
8191725334149576573191725334149576573
911019283746556473821101928374655647382
Continuation
c6061626364656667686970717273747576777879
b66666666667777777777
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
3036912fifteen18212427036912fifteen18212427
404812162024283236159thirteen17212529th3337
516eleven1621263136414616eleven16212631364146
617thirteen1925313743495517thirteen19253137434955
718fifteen2229th3643fifty576418fifteen2229th3643fifty5764
819172533414957657321018263442fifty586674
92eleven2029th3847566574832eleven2029th384756657483
Continuation
c8081828384858687888990919293949596979899
b88888888889999999999
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
3036912fifteen1821242714710thirteen1619222528
4159thirteen17212529th3337159thirteen17212529th3337
516eleven1621263136414616eleven16212631364146
617thirteen1925313743495528142026323844fifty56
7291623thirty3744515865291623thirty3744515865
821018263442fifty58667421018263442fifty586674
92eleven2029th38475665748331221thirty394857667584
Continuation
c100101102103104105106107108109110111112113114115116117118119
b10101010101010101010eleveneleveneleveneleveneleveneleveneleveneleveneleveneleven
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
314710thirteen161922252814710thirteen1619222528
4159thirteen17212529th3337159thirteen17212529th3337
516eleven16212631364146271217222732374247
628142026323844fifty5628142026323844fifty56
7291623thirty3744515865291623thirty3744515865
83eleven19273543515967753eleven1927354351596775
931221thirty39485766758431221thirty394857667584
Continuation
c120121122123124125126127128129130131132133134135136137138139
b12121212121212121212thirteenthirteenthirteenthirteenthirteenthirteenthirteenthirteenthirteenthirteen
r \ p01234567890123456789
000000000000000000000
101234567890123456789
2024681012141618024681012141618
314710thirteen161922252814710thirteen1619222528
4159thirteen17212529th3337159thirteen17212529th3337
5271217222732374247271217222732374247
628142026323844fifty5628142026323844fifty56
731017243138455259663101724313845525966
83eleven19273543515967753eleven1927354351596775
931221thirty3948576675844thirteen2231404958677685
Continuation
c140141142143144145146147148149150151152153154155156157158159
b14141414141414141414fifteenfifteenfifteenfifteenfifteenfifteenfifteenfifteenfifteenfifteen
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
314710thirteen161922252814710thirteen1619222528
4261014182226thirty3438261014182226thirty3438
5271217222732374247271217222732374247
639fifteen2127333945515739fifteen21273339455157
731017243138455259663101724313845525966
841220283644526068764122028364452606876
94thirteen2231404958677685514233241fifty59687786
Continuation
c160161162163164165166167168169170171172173174175176177178179
b1616161616161616161617171717171717171717
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
314710thirteen161922252814710thirteen1619222528
4261014182226thirty3438261014182226thirty3438
527121722273237424738thirteen18232833384348
639fifteen2127333945515739fifteen21273339455157
74eleven18253239465360674eleven1825323946536067
841220283644526068764122028364452606876
9514233241fifty59687786514233241fifty59687786
Continuation
c180181182183184185186187188189190191192193194195196197198199
b1818181818181818181819191919191919191919
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
314710thirteen1619222528258eleven141720232629th
4261014182226thirty3438261014182226thirty3438
538thirteen1823283338434838thirteen18232833384348
639fifteen212733394551574101622283440465258
74eleven18253239465360674eleven1825323946536067
85thirteen2129th3745536169775thirteen2129th374553616977
9514233241fifty596877866fifteen2433425160697887
Continuation
c200201202203204205206207208209210211212213214215216217218219
b2020202020202020202021212121212121212121
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
3258eleven141720232629th258eleven141720232629th
4261014182226thirty343837elevenfifteen192327313539
538thirteen1823283338434838thirteen18232833384348
641016222834404652584101622283440465258
751219263340475461685121926334047546168
85thirteen2129th37455361697761422thirty384654627078
96fifteen24334251606978876fifteen2433425160697887
Continuation
c220221222223224225226227228229230231232233234235236237238239
b2222222222222222222223232323232323232323
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
3258eleven141720232629th258eleven141720232629th
437elevenfifteen19232731353937elevenfifteen192327313539
538thirteen182328333843484914192429th34394449
641016222834404652584101622283440465258
751219263340475461685121926334047546168
861422thirty38465462707861422thirty384654627078
971625344352617079887162534435261707988
Continuation
c240241242243244245246247248249250251252253254255256257258259
b2424242424242424242425252525252525252525
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
3258eleven141720232629th258eleven141720232629th
437elevenfifteen19232731353937elevenfifteen192327313539
54914192429th343944494914192429th34394449
65eleven172329th35414753595eleven172329th3541475359
751219263340475461686thirteen2027344148556269
861422thirty38465462707861422thirty384654627078
971625344352617079887162534435261707988
Continuation
c260261262263264265266267268269270271272273274275276277278279
b2626262626262626262627272727272727272727
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579eleventhirteenfifteen171913579eleventhirteenfifteen1719
3258eleven141720232629th258eleven141720232629th
437elevenfifteen19232731353937elevenfifteen192327313539
54914192429th343944494914192429th34394449
65eleven172329th35414753595eleven172329th3541475359
76thirteen20273441485562696thirteen2027344148556269
87fifteen23313947556371797fifteen2331394755637179
971625344352617079888172635445362718089


Based on it, two tables U and D are constructed containing, respectively, the digits of the category of units and the category of tens of received amounts.

  U[c][r] = DU[c][r] % 10;
  D[c][r] = Math.floor(DU[c][r]/10);

U
c012345678910eleven12thirteen14fifteen16171819
b00000000001111111111
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
303692581470369258147
404826048260482604826
505050505050505050505
606284062840628406284
707418529630741852963
808642086420864208642
909876543211098765432
q0058eleven14171923270158eleven1417192327
Continuation
c20212223242526272829ththirty313233343536373839
b22222222223333333333
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
303692581470369258147
404826048260482604826
505050505050505050505
606284062840628406284
707418529631852963074
819753197531975319753
910987654321098765432
q0158eleven14171923270158eleven1417202327
Continuation
c40414243444546474849fifty515253545556575859
b44444444445555555555
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
303692581470369258147
404826048260482604826
505050505051616161616
617395173951739517395
718529630741852963074
819753197531975319753
910987654321098765432
q0158eleven14172023270158eleven1417202327
Continuation
c6061626364656667686970717273747576777879
b66666666667777777777
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
303692581470369258147
404826048261593715937
516161616161616161616
617395173951739517395
718529630741852963074
819753197532086420864
921098765432109876543
q0168eleven14172023270268eleven1418202327
Continuation
c8081828384858687888990919293949596979899
b88888888889999999999
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
303692581471470369258
415937159371593715937
516161616161616161616
617395173952840628406
729630741852963074185
820864208642086420864
921098765433210987654
q02681214182023270269121418202427
Continuation
c100101102103104105106107108109110111112113114115116117118119
b10101010101010101010eleveneleveneleveneleveneleveneleveneleveneleveneleveneleven
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
314703692581470369258
415937159371593715937
516161616162727272727
628406284062840628406
729630741852963074185
831975319753197531975
932109876543210987654
q02691214182024270269121418202427
Continuation
c120121122123124125126127128129130131132133134135136137138139
b12121212121212121212thirteenthirteenthirteenthirteenthirteenthirteenthirteenthirteenthirteenthirteen
r \ p01234567890123456789
000000000000000000000
101234567890123456789
202468024680246802468
314703692581470369258
415937159371593715937
527272727272727272727
628406284062840628406
730741852963074185296
831975319753197531975
932109876544321098765
q03691214182024270369thirteen1418202427
Continuation
c140141142143144145146147148149150151152153154155156157158159
b14141414141414141414fifteenfifteenfifteenfifteenfifteenfifteenfifteenfifteenfifteenfifteen
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
314703692581470369258
426048260482604826048
527272727272727272727
639517395173951739517
730741852963074185296
842086420864208642086
943210987655432109876
q0379thirteen14182124270379thirteenfifteen18212427
Continuation
c160161162163164165166167168169170171172173174175176177178179
b1616161616161616161617171717171717171717
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
314703692581470369258
426048260482604826048
527272727273838383838
639517395173951739517
741852963074185296307
842086420864208642086
954321098765432109876
q0379thirteenfifteen182125270379thirteenfifteen18212527
Continuation
c180181182183184185186187188189190191192193194195196197198199
b1818181818181818181819191919191919191919
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
314703692582581470369
426048260482604826048
538383838383838383838
639517395174062840628
741852963074185296307
853197531975319753197
954321098766543210987
q0379thirteenfifteen182125270479thirteenfifteen19212527
Continuation
c200201202203204205206207208209210211212213214215216217218219
b2020202020202020202021212121212121212121
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
325814703692581470369
426048260483715937159
538383838383838383838
640628406284062840628
752963074185296307418
853197531976420864208
965432109876543210987
q0479thirteen161921252704710thirteen1619212627
Continuation
c220221222223224225226227228229230231232233234235236237238239
b2222222222222222222223232323232323232323
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
325814703692581470369
437159371593715937159
538383838384949494949
640628406284062840628
752963074185296307418
864208642086420864208
976543210987654321098
q04710thirteen161922262704710thirteen1619222627
Continuation
c240241242243244245246247248249250251252253254255256257258259
b2424242424242424242425252525252525252525
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
325814703692581470369
437159371593715937159
549494949494949494949
651739517395173951739
752963074186307418529
864208642086420864208
976543210987654321098
q04710thirteen161922262704810thirteen1619222627
Continuation
c260261262263264265266267268269270271272273274275276277278279
b2626262626262626262627272727272727272727
r \ p01234567890123456789
000000000000000000000
101234567890123456789
213579135791357913579
325814703692581470369
437159371593715937159
549494949494949494949
651739517395173951739
763074185296307418529
875319753197531975319
976543210988765432109
q0481013161922262704810131619222727

D
c012345678910111213141516171819
b00000000001111111111
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300001112220000111222
400011222330001122233
500112233440011223344
600112334450011233445
700122344560012234456
800123445670012344567
900123456780112345678
q00581114171923270158111417192327
Продолжение
c2021222324252627282930313233343536373839
b22222222223333333333
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300001112220000111222
400011222330001122233
500112233440011223344
600112334450011233445
700122344560012234556
800123445670012344567
901123456780112345678
q01581114171923270158111417202327
Продолжение
c4041424344454647484950515253545556575859
b44444444445555555555
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300001112220000111222
400011222330001122233
500112233440011223344
600112334450011233445
700122345560012234556
800123445670012344567
901123456780112345678
q01581114172023270158111417202327
Продолжение
c6061626364656667686970717273747576777879
b66666666667777777777
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300001112220000111222
400011222330001122233
500112233440011223344
600112334450011233445
700122345560012234556
800123445670112345567
901223456780122345678
q01681114172023270268111418202327
Продолжение
c8081828384858687888990919293949596979899
b88888888889999999999
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300001112220001111222
400011222330001122233
500112233440011223344
600112334450012233455
700123345560012334556
801123455670112345567
901223456780123345678
q02681214182023270269121418202427
Продолжение
c100101102103104105106107108109110111112113114115116117118119
b1010101010101010101011111111111111111111
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011112220001111222
400011222330001122233
500112233440011223344
600122334550012233455
700123345560012334556
801123455670112345567
901233456780123345678
q02691214182024270269121418202427
Продолжение
c120121122123124125126127128129130131132133134135136137138139
b1212121212121212121213131313131313131313
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011112220001111222
400011222330001122233
500112233440011223344
600122334550012233455
701123345560112334556
801123455670112345567
901233456780123445678
q03691214182024270369131418202427
Продолжение
c140141142143144145146147148149150151152153154155156157158159
b1414141414141414141415151515151515151515
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011112220001111222
400111223330011122333
500112233440011223344
600122334550012233455
701123345560112334556
801223456670122345667
901234456780123455678
q03791314182124270379131518212427
Продолжение
c160161162163164165166167168169170171172173174175176177178179
b1616161616161616161617171717171717171717
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011112220001111222
400111223330011122333
500112233440011223344
600122334550012233455
701123345660112334566
801223456670122345667
901234556780123455678
q03791315182125270379131518212527
Продолжение
c180181182183184185186187188189190191192193194195196197198199
b1818181818181818181819191919191919191919
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011112220001112222
400111223330011122333
500112233440011223344
600122334550112234455
701123345660112334566
801223456670122345667
901234556780123456678
q03791315182125270479131519212527
Продолжение
c200201202203204205206207208209210211212213214215216217218219
b2020202020202020202021212121212121212121
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011122220001112222
400111223330011122333
500112233440011223344
601122344550112234455
701123445660112344566
801223456670123345677
901234566780123456678
q047913161921252704710131619212627
Продолжение
c220221222223224225226227228229230231232233234235236237238239
b2222222222222222222223232323232323232323
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011122220001112222
400111223330011122333
500112233440011223344
601122344550112234455
701123445660112344566
801233456770123345677
901234567780123456778
q0471013161922262704710131619222627
Продолжение
c240241242243244245246247248249250251252253254255256257258259
b2424242424242424242425252525252525252525
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011122220001112222
400111223330011122333
500112233440011223344
601122344550112234455
701123445660122344566
801233456770123345677
901234567780123456778
q0471013161922262704810131619222627
Продолжение
c260261262263264265266267268269270271272273274275276277278279
b2626262626262626262627272727272727272727
r \ p01234567890123456789
000000000000000000000
100000000000000000000
200000111110000011111
300011122220001112222
400111223330011122333
500112233440011223344
601122344550112234455
701223445660122344566
801233456770123345677
901234567780123456788
q0481013161922262704810131619222727


Обнаружено, что таблица разряда единиц (U) содержит не повторяющиеся столбцы, тогда как все столбцы таблицы разряда десятков (D) встречаются и в таблице U, и в таблице B.

Таким образом таблица U исчерпывает все порождённые столбцы. Следовательно, она и является полной таблицей Слонимского.

Для удобства дальнейшей работы, я пометил, с каким столбцом таблицы B совпадает каждый столбец таблицы D, и теми же номерами пометил столбцы того же номера таблицы U (строка q обеих таблиц), а для ещё большего удобства ввёл массив Q, содержащий указанные значения, под номерами, соответствующими номерам столбцов в таблицах D и U.
Q
Q = [0, 0, 5, 8, 11, 14, 17, 19, 23, 27, 0, 1, 5, 8, 11, 14, 17, 19, 23, 27, 0, 1, 5, 8, 11, 14, 17, 19, 23, 27, 0, 1, 5, 8, 11, 14, 17, 20, 23, 27, 0, 1, 5, 8, 11, 14, 17, 20, 23, 27, 0, 1, 5, 8, 11, 14, 17, 20, 23, 27, 0, 1, 6, 8, 11, 14, 17, 20, 23, 27, 0, 2, 6, 8, 11, 14, 18, 20, 23, 27, 0, 2, 6, 8, 12, 14, 18, 20, 23, 27, 0, 2, 6, 9, 12, 14, 18, 20, 24, 27, 0, 2, 6, 9, 12, 14, 18, 20, 24, 27, 0, 2, 6, 9, 12, 14, 18, 20, 24, 27, 0, 3, 6, 9, 12, 14, 18, 20, 24, 27, 0, 3, 6, 9, 13, 14, 18, 20, 24, 27, 0, 3, 7, 9, 13, 14, 18, 21, 24, 27, 0, 3, 7, 9, 13, 15, 18, 21, 24, 27, 0, 3, 7, 9, 13, 15, 18, 21, 25, 27, 0, 3, 7, 9, 13, 15, 18, 21, 25, 27, 0, 3, 7, 9, 13, 15, 18, 21, 25, 27, 0, 4, 7, 9, 13, 15, 19, 21, 25, 27, 0, 4, 7, 9, 13, 16, 19, 21, 25, 27, 0, 4, 7, 10, 13, 16, 19, 21, 26, 27, 0, 4, 7, 10, 13, 16, 19, 22, 26, 27, 0, 4, 7, 10, 13, 16, 19, 22, 26, 27, 0, 4, 7, 10, 13, 16, 19, 22, 26, 27, 0, 4, 8, 10, 13, 16, 19, 22, 26, 27, 0, 4, 8, 10, 13, 16, 19, 22, 26, 27, 0, 4, 8, 10, 13, 16, 19, 22, 27, 27];


Вскрытие алгоритма



Сперва я обратил внимание на то, что группа столбцов с b=0 таблицы DU — совпадает с таблицей Пифагора.
c0123456789
b0000000000
r \ p0123456789
00000000000
10123456789
2024681012141618
30369121518212427
404812162024283236
5051015202530354045
6061218243036424854
7071421283542495663
8081624324048566472
9091827364554637281

Второе наблюдение: если выбрать из таблицы U столбцы с p=0, составленная из них таблица совпадает с таблицей B.
c0102030405060708090100110120130
b012345678910111213
r \ p00000000000000
000000000000000
100000000000000
200000000000000
300000000011111
400000001111111
500000111111222
600001111122222
700011111222233
800111112223333
901111122233334
q00000000000000
Продолжение
c140150160170180190200210220230240250260270
b1415161718192021222324252627
r \ p00000000000000
000000000000000
100000000000000
211111111111111
311111222222222
422222223333333
522233333344444
633333444445555
733444455555666
844445556666677
945555666777778
q00000000000000

Значит каждый столбец D[i] таблицы D входит в таблицу U как столбец у которого b=Q[i], p=0.

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

Тогда я предположил, что q — это номер группы, из которой я должен взять столбец для следующего разряда. Начинать решил с группы 0.
Провёл вычислительный эксперимент с помощью FireBug — вроде как получается.

Возьмём для примера случайное четырёхразрядное (чтобы эксперимент был не слишком простым) число. При подготовке статьи, я сделал это так:
value = (100 + Math.floor(Math.random()*(999-100)))*10 + 1 + Math.floor(Math.random()*(9-1));

Такая формула гарантирует, что будет получено число не меньше 1000 и что в разряде единиц не будет нуля.
При крайней сборке статьи, рандом выдал мне value = 3212.
Возьмём из группы 0 таблицы U столбец 2:
c2
b0
r \ p2
00
12
24
36
48
50
62
74
86
98
q5

Видим, что для него q = 5. Теперь для следующего разряда возьмём из группы 5 столбец 1:
c512
b50
r \ p12
000
112
224
336
448
560
672
784
896
908
q15

Для этого столбца q = 1. Продолжим таблицу аналогичным образом, и получим:
c5312512
b5150
r \ p3212
00000
13212
26424
39636
42848
56060
69272
72484
85696
98908
q8515

Цифры у нас кончились, очередное q = 8. Очевидно, нужно из группы 8 взять нулевой столбец. Получаем:
c805312512
b85150
r \ p03212
000000
103212
206424
309636
412848
516060
619272
722484
825696
928908
q08515

Легко видеть, что в строках этой таблицы находятся произведения нашего числа 3212 на 0, 1, 2,… 9.

Разбор эксперимента

Труднее было разобраться, почему это работает.
Итак, у нас есть 28 групп (от 0 по 27) по 10 столбцов. Группам присвоены те же номера, что и столбцам таблицы B.
В таблицах DU, U и D в строке b содержится номер группы, в строке p — номер столбца в группе.

Введём функции:
Функция умножения числа на вектор {0; 1; 2; 3; 4; 5; 6; 7; 8; 9} (вектор представлен массивом)
function mul(n){
  var result = new Array(10);
  for(var i=0; i<10; ++i){
    result[i]=n*i;
  }
  return result;
}

Функция векторного сложения двух массивов
function sum(a, b){
  var result = new Array(10);
  for(var i=0; i<10; ++i){
    result[i]=a[i]+b[i];
  }
  return result;
}

Функция получения массива, содержащего значения разряда единиц значений исходного массива
function unit(a){
  var result = new Array(10);
  for(var i=0; i<10; ++i){
    result[i]=a[i] % 10;
  }
  return result;
}

Функция получения массива, содержащего значения разряда десятков значений исходного массива
function deca(a){
  var result = new Array(10);
  for(var i=0; i<10; ++i){
    result[i]=Math.floor(a[i] / 10);
  }
  return result;
}

Нетрудно сравнить формулы и заметить, что каждый столбец таблицы P, это ни что иное, результат функции mul для номера столбца;
столбцы таблиц D и U получены из столбцов таблицы DU с помощью функций unit и deca соответственно;
каждый столбец таблицы DU получен суммированием одного столбца таблицы B и одного столбца таблицы P, что соответствует использованию функции sum.

Вспомним алгоритм умножения в столбик многоразрядного числа на одноразрядное:
Пусть
anan-1...a1a0 — множимое, записанное поразрядно;
b — одноразрядный множитель;
сn+1cn...c1c0 — результат, записанный поразрядно(полагаем, что результат на один разряд длиннее множимого, в большинстве случаев так и будет, в остальных — от ведущего нуля ещё никто не умирал);
m0, m1,… mn — значения, переносимые в старший разряд (при вычислении на бумаге записываются «наверх»);
floor — функция округления вниз;
% — операция получения остатка от деления.
Переменная x будет использоваться как локальная и перевычисляться для каждого разряда.

1. Берём из таблицы умножения (она у каждого из нас в памяти) произведение нулевого разряда множимого на множитель:
x = a0*b;
разряд единиц числа x без изменений записываем в результат: c0 = x % 10;
разряд десятков числа х записываем «наверх»: m0 = floor(x/10).

2. Берём из таблицы умножения произведение первого разряда множимого на множитель и прибавляем к нему значение «сверху»:
x = a1*b + m0
разряд единиц — записываем в результат: c1 = x % 10;
разряд десятков — записываем «наверх»: m1 = floor(x/10).

3. Аналогично поступаем для разрядов со 2 по n:
x = ai*b + mi-1
ci = x % 10;
mi = floor(x/10).

4. Полученное при вычислении разряда n значение mn даст нам последний разряд результата:
cn+1 = mn.


Полагаю, все согласны? В описании ошибок нет? Тогда размышляем дальше:

Таблица Слонимского служит для получения произведений произвольного числа на ряд чисел от 0 до 9.
Если бы мы решили умножать в столбик, то умножали бы множимое число десять раз и получили по набору сn+1cn...c1c0 и m0, m1,… mn для каждого из десяти множителей.
Поскольку мы хотим вскрыть алгоритм Слонимского, введём ещё массив j0… jn+1, в котором будем хранить номера столбцов таблицы U, соответствующих столбцам результата умножения.

Для упрощения формы записи, воспользуемся введёнными нами функциями, и пройдёмся по тем же пунктам вышеупомянутого алгоритма:
1. Вычислим
x = mul(a0);
Очевидно, что x совпадает со столбцом № a0 таблицы Пифагора (P) и, что интересно, со столбцом p=a0, b=0 таблицы DU. В таблицах DU, U и D номер столбца вычисляется как b*10+p, следовательно
x = DU[a0]
Теперь нам нужны единицы, чтобы записать в результат, и десятки, чтобы записать «наверх»:
c0 = unit(x);
m0 = deca(x);
в данном случае c0 и m0 — массивы.
Обратим внимание, что c0 получен точно так же, как столбец p=a0, b=0 таблицы U, а m0 — как соответствующий столбец таблицы D.
Запишем:
j0 = a0;
c0 = U[j0];
m0 = D[j0].

2. Возьмёмся теперь за следующий разряд. Нам нужно вычислить произведения a1 на вектор, а затем векторно прибавить к полученному массиву массив m0:
x = sum(mul(a1), m0);
Разбираем эту формулу:
mul(a1) совпадает со столбцом P[a1].

В шаге 1 было вычислено:
m0 = D[j0].
Вспомним теперь, что для каждого столбца таблицы D найден номер q, под которым этот столбец входит в таблицу B. Этот номер мы для удобства записали в строку q таблиц U и D и в массив Q.
Теперь запишем:
m0 = D[j0] = B[Q[j0]];
Да простят мне программисты и математики такое смешение стилей.

Оба слагаемых разобраны. Теперь вспомним о сумме. Одно из слагаемых является членом таблицы P, а другое — таблицы B. Все суммы на этот случай у нас посчитаны и входят в таблицу DU.
Следовательно, искомый массив должен совпадать со столбцом таблицы DU, для которого p=a1, b=Q[j0]:
x = DU[Q[j0]*10 + a1].
Теперь нам снова нужны единицы и десятки от членов x:
c1 = unit(x);
m1 = deca(x);
и нам в этом снова помогут таблицы U и D.

Подведём итог второго шага:
j1 = Q[j0]*10 + a1;
c1 = U[j1];
m1 = D[j1].

3. Уже можно подметить закономерность:
x = sum(mul(ai), mi-1);
а так как:
mul(ai) = P[ai],
mi-1 = D[ji-1] = B[Q[ji-1]];
то:
x = DU[Q[ji-1]*10 + ai].
Следовательно:
ji = Q[ji-1]*10 + ai;
ci = U[ji];
mi = D[ji].

4. Теперь посмотрим, что нам делать с mn.
Последний перенос разряда это старший разряд результата. Но нам надо выбрать столбец таблицы U.
Проанализируем:
mn = D[jn].
D[jn] входит в таблицу U как столбец b=Q[jn], p=0, т.е.
D[jn] = U[Q[jn]*10].
Следовательно:
jn+1 = Q[jn]*10;
cn+1 = U[jn+1].
Поскольку никакое произведение одноразрядных чисел не может дать более чем двухразрядное число, массив mn+1 будет содержать только нули. Вычисление закончено.

Теперь соберём в кучу найденные уравнения для ji:
j0 = a0;
ji = Q[ji-1]*10 + ai;
jn+1 = Q[jn]*10.
Они сводятся к одному уравнению
ji = Q[ji-1]*10 + ai,
если принять, что
an+1 = 0 (что равносильно приписыванию ведущего нуля к множимому числу),
Q[j-1] = 0.

Это означает, что чтобы сложить из столбцов таблицы U таблицу произведений числа anan-1...a1a0 на одноразрядные числа, нужно каждый раз из группы b=Q[ji-1] брать столбец p=ai, причём строка q того же столбца таблицы подскажет нам, какая группа столбцов будет следующей, а начать работу нужно с группы столбцов 0.

Продемонстрированный в эксперименте алгоритм выведен аналитически.

Резюмирую:

Найденный алгоритм можно описать как автоматный, где входной строкой является умножаемое число, читаемое справа налево (от младших разрядов к старшим), а состояниями являются номера групп столбцов. На каждом этапе работы мы берём из группы под номером состояния столбец под номером очередной цифры и переходим в состояние под номером из строки q этого столбца.
Для корректного завершения работы алгоритма, к множимому числу нужно дописать ведущий ноль.

Материальная реализация

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

Ни «снаряд» Слонимского, ни бруски Иоффе не были мной восстановлены. Для воссоздания аутентичных копий нужно больше информации о самих изделиях.

Свой вариант инструмента я создавал с целью его эксплуатации на РИ живого действия по эпохам, для которых изделие не являлось бы анахронизмом, а так же натурной демонстрации алгоритма работы.
Аутентичность какому-либо историческому образцу не предполагалась. Во главу угла ставилось удобство эксплуатации.

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

Должен заметить, что удобно разместить столбцы на четырёхгранных брусках, как у Иоффе, мне не удалось. Подозреваю, что бруски Иоффе были не такими уж удобными.

28 групп по 10 столбцов удобно размещать на двухсторонних рейках. При этом каждая группа столбцов наносилась на собственные пять реек.

Для уменьшения объёма наносимой на рейки информации, на рейки не наносилась нулевая строка таблицы, т.к. она содержит во всех столбцах цифру 0. Номер столбца отдельно не наносился, т.к. он совпадает с цифрой в первой строке таблицы. Номер группы, к которой принадлежит рейка, был нанесён римскими цифрами на боковые грани рейки. Он нужен только для сортировки реек в случае их случайного перемешивания (чего в ходе эксплуатации нужно избегать).

Значение q столбца нанесено на каждой рейке ниже разделительной горизонтальной линии.

Рейки изготовлены из алюминиевой полосы 50х2 мм, которая для этого была напилена электролобзиком примерно по 4-6 мм (слишком узкие браковались, слишком широкие либо подтачивались точильным диском, либо также браковались).
Цифры нанесены гравировальной фрезой.
Для хранения реек был высверлен из соснового бруса 50х40 мм деревянный органайзер. Да, знаю, что можно продумать лучше, но до игры оставалось 2 дня, а силы после гравировки 2800 циферок были на исходе.
Номера групп и столбцов нанесены на органайзер гелевой ручкой.

Из-за загадочных глюков с исчезновением картинок, фотографии добавлены с помощью комментария habrahabr.ru/post/232255/#comment_7940351

Источники


1. Вестник Сыктывкарского университета. Сер.1. Вып.13.2011. УДК 512.6, 517.987 «К 200-летию со дня рождения создателей вычислительных машин, представленных к демидовской премии, Х.З. Слонимского и Г. Куммера». В.П. Одинец;
2. Теорема Слонимского и простые вычислительные устройства на ее основе.

P.S. Да благословит Дух Машины ваш сервер, ибо он пережил отправку почти 200кб кода, а с учётом эскапирования — все 500.

Also popular now: