Saturday, August 02, 2025

[lugfcqhu] gendered chess piece types

define the ranged pieces queen, rook, and bishop to be female.

define the non-ranged pieces king, knight, and pawn to be male.

but I can't think of any good reason to do this, though it is elegant that the piece types divide half and half.  mnemonic: the sexist trope in fiction that only men are tough enough to do melee combat; women like Katniss and Aerith (but not Tifa) specialize in ranged attacks from afar.

orthodox chess does not have artillery which can kill from afar without moving.  fairy chess could add such truly female pieces.

pawn promotion might be a sex change.

[elgwjvis] AI to draw an endgame

apply neural network machine learning on positions of a theoretically drawn but hard to defend chess endgame such as KRBKR.  can an AI playing the weaker side learn a policy to maintain a draw?  inspired by an AI learning to drive, not falling off the road, in the game Trackmania.

with overfitting, this is of course possible, so seek a small, or the smallest, neural network.

the AI can be tested against a tablebase.

during training, should the AI be immediately punished once it "falls" from a tablebase drawn position, or should it be punished only when checkmated?  the latter might be helpful for the AI to learn the underlying structure of the game.

previously, a human doing the learning.

[bicxxhnq] primes of digits 0 1 2

little-endian radix conversion and unconversion in Pari/GP:

tobase(n,x)= my(l=List); while(x>0, my(r=x%n); listput(l,r); x-=r; x/=n); l;

tonumber(b,L)= my(x=0); my(n=1); foreach(L, d, x+=d*n; n*=b); x;

fixed-width least-significant digits (pads with zeros if necessary to achieve width):

towidthbase(width,n,x)= my(l=List); for(i=1, width, my(r=x%n); listput(l,r); x-=r; x/=n); l;

we demonstrate using these functions to search for primes containing only certain digits in base 10.  we first generate numbers in base 2 then interpret the bit string as base 10.

c=0; for(i=0, 2^10, x=tonumber(10, tobase(2,i)); if(isprime(x), print(x); c+=1)); print("count="c)

11 101 10111 101111 1011001 1100101 10010101 10011101 10100011 10101101 10110011 10111001 11000111 11100101 11110111 11111101 100100111 100111001 101001001 101001011 101100011 101101111 101111011 101111111 110010101 110101001 110111011 111000101 111001001 111010111 1000001011 1000010101 1000011011 1000110101 1001000111 1001001011 1001010011 1001110111 1010000011 1010000111 1010001101 1010010011 1010011111 1010100011 1010110001 1010111111 1011000101 1011110011 1100001101 1100010001 1100101111 1101001001 1101010111 1101110011 1110011101 1110110011 1111011101 1111100101 1111110001 (count=59 up to 10 digits)

note: the next repunit prime after 11 in base 10 is (10^19 - 1)/9 so is beyond the range of all these lists (OEIS A004023).

c=0; for(w=1, 9, for(i=0, 2^w-1, l=towidthbase(w,2,i); for(j=1, w, l[j]+=1); x=tonumber(10,l); if(isprime(x), print(x); c+=1))); print("count="c)

2 11 211 2111 2221 12211 21121 21211 21221 22111 111121 111211 112111 112121 1111211 1121221 1212121 1212221 1221221 2121121 2211211 2221111 11221211 12111221 12121121 12121211 12122111 12122221 12212111 12222121 12222211 21112121 21121211 21122111 21122221 21212111 21222211 22111121 22112221 22221211 111112121 111121121 111221221 112111211 112112111 112212211 112221211 121111121 121112111 121211221 122111111 211122211 211212121 211222111 211222211 212111111 212122121 221112121 221212111 222221221 (count=60 up to 9 digits)

c=0; for(i=0, 3^6, x=tonumber(10, tobase(3,i)); if(isprime(x), print(x); c+=1)); print("count="c)

2 11 101 211 1021 1201 2011 2111 2221 10111 10211 12011 12101 12211 20011 20021 20101 20201 21001 21011 21101 21121 21211 21221 22111 101021 101111 101221 102001 102101 102121 110221 111121 111211 112111 112121 120011 120121 121001 121021 122011 122021 122201 200201 201011 201101 201121 201211 202001 202021 202121 202201 210011 210101 220021 221021 221101 221201 222011 (count=59 up to 6 digits)

previously: composites with low digits.

update: Pari/GP has built-in digits() and fromdigits() for base conversion.

[hefympwg] fitting a polynomial through points

the following Perl script feeding GP uses Lagrange polynomials to interpolate a polynomial between given points.  input is stdin (or a file or files specified on the command line after the script), one point per line, X and Y coordinates separated by whitespace.  Pari/GP does the heavy lifting of (automatically) multiplying out and simplifying the polynomial.  if inputs are integers or rational numbers, Pari/GP automatically does arbitrary precision arithmetic.  (if the inputs are floating point, be careful, as this method is not numerically stable.  you may wish to increase Pari/GP's floating point precision.)

perl -nlwae 'push @x,$F[0]; push @y,$F[1]; END{ for $i(0..$#x){ $l=1; for $j(0..$#x){ next if $i==$j; $l.="*((x-($x[$j]))/($x[$i]-($x[$j])))";} $_.="+" if defined$_; $_.="($y[$i])*($l)";} print;}' | gp -q

Because perl is only manipulating strings (no BigInt needed), the inputs may be any expressions that Pari/GP can evaluate.  all the extra parentheses in the script support this.  (the parentheses were originally needed to support negative inputs.)  here we demonstrate the script recovering a general quadratic when given input of algebraic expressions.

$ echo -e 'x1 a*x1^2+b*x1+c\nx2 a*x2^2+b*x2+c\nx3 a*x3^2+b*x3+c' | perl lagrangepolynomial.pl | gp -q
a*x^2 + b*x + c

this was inspired by a "guess the next word" puzzle, so input expressions such as 27*(27*(27*(27*(8)+5)+12)+12)+15 (the word "hello" encoded in big-endian base 27) also work.  it is always possible to guess a next value (or word) of a sequence by interpolating a polynomial to the previous values.  (the answer might not be what the puzzle poser is looking for.  unclear what to do with a negative predicted next value when values are encoded words.)  it is also possible to justify any next value by adding it to the interpolation.

runtimes with exact arithmetic:

( echo "allocatemem(10^9)" ; for i in `seq 1 100` ; do echo $i $RANDOM ; done | perl lagrangepolynomial.pl ) | nice time gp -q > /dev/null

100 points: 1.4 seconds
150 points: 7 s
200 points: 22 s
250 points: 56 s
300 points: 120 s
400 points: 400 s
450 points: 655 s
500 points: 1016 s

can runtime be improved?

[mzebapic] to the fairest

Eris tosses a golden apple among Hera, Athena, and Aphrodite, and they immediately start fighting over it, causing the typical amounts of destruction that happens when gods fight each other.

why do they want the golden apple?  golden apples are rare and extremely difficult to obtain.  also, a golden apple might contain golden apple seeds from which more golden apple trees could be grown.  (Demeter enthusiastically dispenses god-level gardening advice about growing such an interesting plant.)

several googol destroyed universes later, Paris points out that the apple is inscribed "to The Fairest", which the goddesses had not noticed.  oops.  (but, they reason, along with the golden apple, Eris probably threw Idiot Balls at all of us, as she normally does, so stupidity was to be expected.  fortunately, nothing of value had been lost in the war.)

they stop fighting and deliver the golden apple to the nymph literally named "The Fairest" -- Callisto -- then tease Eris for having a crush on a nymph.  and maybe something about bear-fucking.

Monday, July 28, 2025

[evzistck] if I had a million dollars

"...I'd buy you various expensive goods."

that's sweet.

"...I'd buy your love."

well, that turned dark.  or maybe it was always dark, 1 always as a means to 2.

(a seemingly lighthearted song by Barenaked Ladies)

create a cover or remix highlighting this darkness.

[foofbzwe] revenge of the Jedi

team A rises to power and nearly genocides ("humanitarian crisises") team B.  team B survivors regroup, play the plucky underdogs for a while, then overthrow team A.  team B, now in power and fully aware that the reason they succeeded was because team A only "nearly" humanitarian crisised team B earlier, avoids making the same mistake and completely humanitarian crisises team A.  then they live happily ever after.

what sections of this narrative make the best fiction stories?  of course, "happily ever after" because fantasy utopia is pleasant.  though discovering one's dark past might not be.  team B overthrowing evil team A, because we love rooting for the underdog.  we also love tragedies: team B, the good guys, logically descending to evil, more evil than even the evil team A that they overthrew.

[clyaebic] worst chess evar

we set up some common chess openings, direct one side to play the worst moves according to MultiPV of the Stockfish chess engine and the other side to play the best moves according to Stockfish, and watch hilarity ensue.

Stockfish 16-1 (Debian sid; NB: this is Stockfish 16 not 16.1; the -1 is Debian versioning), hash 4096M, depth 24, no multithreading, 5 piece syzygy endgame tablebase. multipv set to 400 to find the worst move; multipv disabled when finding the best move. engine restarted (Hash cleared) between each move.  there are (probably) instances of multiple possible moves with the same (terrible) evaluation score; we choose whichever Stockfish MultiPV chooses to sort as last.

in each game below, the side which gets checkmated is unsurprisingly the side playing worst moves, and the other side is playing best moves.  even though these are all quick checkmates, they are not helpmates: the side playing good moves does not know the other side will be playing bad moves so plays best moves preparing the the best response.

(future work: helpmates after common openings.)

many variations of Fool's Mate, Botez Gambit, and Bongcloud happen.  the computer knows the memes.

no opening moves, white playing worst moves:

1.g4 d5 2.f4 Bxg4 3.e3 Bxd1 4.Bc4 dxc4 5.a3 Qd5 6.Ne2 Qxh1+ 7.Ng1 Qxg1#

the next opening is hilariously classified by Scid as ECO code B00b [Reversed Grob (Borg/Basman Defence)].  no opening moves, white playing best moves, black playing worst moves:

1.e4 g5 2.d4 f5 3.Qh5#

1.e4 {end of scripted opening} e5 2.Ba6 Nxa6 3.g4 d5 4.f4 Qh4+ 5.Ke2 Bxg4+ 6.Ke3 exf4+ 7.Kd4 Qf2+ 8.Kxd5 Qc5#

1.e4 e5 {end of opening} 2.Nf3 Qg5 3.Nxg5 Kd8 4.Nxf7+ Ke8 5.Nxh8 h5 6.Qxh5+ Ke7 7.Qxe5+ Kd8 8.Nf7#

1.e4 e5 2.Nf3 {end of opening} Nc6 3.Nd4 exd4 4.Ba6 bxa6 5.Ke2 Rb8 6.Kd3 Qh4 7.Kc4 d5+ 8.Kd3 Qxe4#

1.e4 e5 2.Nf3 Nc6 {end of opening} 3.Bb5 Qg5 4.Nxg5 Kd8 5.Nxf7+ Ke8 6.Nxh8 h5 7.Qxh5+ g6 8.Qxg6+ Kd8 9.Qxg8 Rb8 10.Qxf8#

1.e4 c5 {end of opening} 2.Ba6 Nxa6 3.g4 d5 4.Ke2 dxe4 5.f4 Bxg4+ 6.Ke3 Qd4#

1.e4 c5 {end of opening} 2.Nf3 c4 3.Bxc4 h6 4.Bxf7+ Kxf7 5.Ne5+ Ke8 6.Qh5+ g6 7.Qxg6#

1.e4 e6 {end of opening} 2.Ba6 Nxa6 3.b4 Nxb4 4.Qg4 Nxc2+ 5.Ke2 Nxa1 6.Qg5 Qxg5 7.Kd3 Qb5+ 8.Kd4 Bc5+ 9.Ke5 Be3#

1.e4 e6 {end of opening} 2.d4 Qg5 3.Bxg5 Ba3 4.Nxa3 c5 5.Nb5 g6 6.Nd6+ Kf8 7.Qf3 Kg7 8.Qxf7#

1.e4 e6 2.d4 {end of opening} d5 3.Bh6 Nxh6 4.Qg4 Nxg4 5.Kd1 Nxf2+ 6.Ke1 Nxh1 7.h4 Qxh4+ 8.Ke2 Qf2+ 9.Kd3 Qe1 10.b4 Nf2#

1.e4 c6 {end of opening} 2.Ba6 Nxa6 3.Qg4 d5 4.c4 Bxg4 5.f4 Nb4 6.h3 Nd3+ 7.Kf1 Qb6 8.g3 Qf2#

1.e4 c6 {end of opening} 2.d4 g5 3.Bxg5 f5 4.Qh5#

1.e4 c6 2.d4 {end of opening} d5 3.Qg4 Bxg4 4.Bh6 Nxh6 5.Kd2 dxe4 6.c4 Qxd4+ 7.Ke1 Qd1#

1.e4 d6 {end of opening} 2.Qg4 Bxg4 3.Ba6 Nxa6 4.c4 Nb4 5.e5 dxe5 6.Kf1 Qd3+ 7.Ke1 Nc2#

1.e4 d6 {end of opening} 2.d4 Bh3 3.Nxh3 f5 4.exf5 Kf7 5.Qh5+ Kf6 6.Bg5+ Kxf5 7.Qf7+ Kg4 8.f3#

1.e4 d6 2.d4 {end of opening} Nf6 3.Qg4 Bxg4 4.Ba6 Nxa6 5.Bh6 gxh6 6.b4 Nxb4 7.Kd2 Nxe4+ 8.Ke1 Nxc2+ 9.Kf1 Qd7 10.Nd2 Nxd2#

1.e4 d6 2.d4 Nf6 {end of opening} 3.Nc3 Bh3 4.Nxh3 Nd5 5.Nxd5 f5 6.exf5 Nd7 7.Qh5+ g6 8.fxg6 Rc8 9.gxh7#

1.e4 g6 {end of opening} 2.Qh5 gxh5 3.Ba6 Nxa6 4.c3 Nc5 5.a3 Nd3+ 6.Kd1 d5 7.exd5 Qxd5 8.Ne2 Qb3#

1.e4 g6 {end of opening} 2.d4 g5 3.Bxg5 f5 4.Qh5#

1.e4 g6 2.d4 {end of opening} Bg7 3.Qh5 gxh5 4.Bh6 Nxh6 5.d5 Bxb2 6.Nc3 Bxc3+ 7.Ke2 Bxa1 8.Kd3 c6 9.Kc4 Qa5 10.c3 Qxc3#

1.d4 {end of opening} g5 2.Bxg5 e6 3.Bxd8 Nf6 4.Bxf6 Ba3 5.Nxa3 O-O 6.e3 e5 7.Qg4#

Trompowsky but worse:

1.d4 {end of opening} Nf6 2.Bh6 gxh6 3.Kd2 c5 4.Kc3 Ne4+ 5.Kb3 Qb6+ 6.Ka3 Qb4#

1.d4 Nf6 {end of opening} 2.c4 Nd5 3.cxd5 Nc6 4.dxc6 f5 5.Nf3 Kf7 6.cxd7 Kg8 7.Qb3+ e6 8.Qxe6#

1.d4 d5 {end of opening} 2.Bh6 Nxh6 3.Kd2 c5 4.Kc3 Qa5+ 5.Kb3 c4#

1.d4 d5 {end of opening} 2.c4 Bh3 3.Nxh3 Kd7 4.cxd5 Nc6 5.dxc6+ Ke6 6.Ng5+ Kf5 7.Qd3+ Kg4 8.Qh3#

1.Nf3 {end of opening} g5 2.Nxg5 f6 3.e4 f5 4.Qh5#

1.c4 {end of opening} g5 2.d4 f5 3.Bxg5 e6 4.Bxd8 Bc5 5.dxc5 a6 6.Qd4 Nh6 7.Qxh8+ Ng8 8.Qxg8#

challenge: start from a reasonable position and maximize the number of consecutive worst moves before checkmate.

Sunday, July 20, 2025

[iqtsgzqr] 16-minute mile

running one lap around the track in 4 minutes is just like running a 4-minute mile, except you only have to go around the track once.

[ycastlnl] cardinality of integrability

derivatives are easy; integrals are hard: "most" functions can be differentiated in closed form, but "most" functions do not have closed form integrals.  how can this statement be made mathematically precise?  (what is "most"?)  how small is the set of functions with closed form indefinite integral?

possibly relevant is the Risch algorithm, though we do not care how the antiderivative is obtained.

[piqwhqfy] 102 and 221 for mental arithmetic

102 = 17*6 and 221 = 13*17 have low digit weight, so it is easy to add or subtract those multiples of 17 and 13 without many carries.

17*17 = (4*17) + (13*17) = 68 + 221 = 289, if you already knew 4*17 = 68.

possibly useful for memorizing composites.

can the technique be generalized to decrease combinational depth of ripple carry adders?

Tuesday, June 24, 2025

[sggdczyg] private moon

order the objects in the solar system by decreasing mass.  what is the mass of object number N, where N is human population (currently 8.2 billion)?

at what N do things become messy, for example, the precise definition of the extent of an object affects its place in line (e.g., atmospheres, aggregates of rocks and ice so loosely gravitationally bound that there might be gaps between them)?

sort similarly the objects in the Milky Way galaxy.  currently, everyone gets a star, provocatively presuming that we are space-faring and the only ones space-faring.

inspired by Gaila's Moon.

previously, your patch of the sky.

[knajvmcz] numbers easy to multiply by a single digit

the numbers output by the following Perl script are easy to mentally multiply by any 1-digit number 0 1 2 3 4 5 6 7 8 9:

perl -lwe '$c=0; for(0..1999){ next unless/^[0-9]([0-1]|0+[1-9])*$/; print; ++$c; END{ print"(count=$c)"}}'

0 1 2 3 4 5 6 7 8 9 10 11 20 21 30 31 40 41 50 51 60 61 70 71 80 81 90 91 100 101 102 103 104 105 106 107 108 109 110 111 200 201 202 203 204 205 206 207 208 209 210 211 300 301 302 303 304 305 306 307 308 309 310 311 400 401 402 403 404 405 406 407 408 409 410 411 500 501 502 503 504 505 506 507 508 509 510 511 600 601 602 603 604 605 606 607 608 609 610 611 700 701 702 703 704 705 706 707 708 709 710 711 800 801 802 803 804 805 806 807 808 809 810 811 900 901 902 903 904 905 906 907 908 909 910 911 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1020 1021 1030 1031 1040 1041 1050 1051 1060 1061 1070 1071 1080 1081 1090 1091 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 (count=176)

although some of the multiplications induce carries, they carry into a zero, so it is easy.

modify the subexpression [0-1] in the regular expression to [0-2] to get the larger set of numbers for which it is easy to multiply by 0 1 2 3 4:

perl -lwe '$c=0; for(0..1999){ next unless/^[0-9]([0-2]|0+[1-9])*$/; print; ++$c; END{ print"(count=$c)"}}'

0 1 2 3 4 5 6 7 8 9 10 11 12 20 21 22 30 31 32 40 41 42 50 51 52 60 61 62 70 71 72 80 81 82 90 91 92 100 101 102 103 104 105 106 107 108 109 110 111 112 120 121 122 200 201 202 203 204 205 206 207 208 209 210 211 212 220 221 222 300 301 302 303 304 305 306 307 308 309 310 311 312 320 321 322 400 401 402 403 404 405 406 407 408 409 410 411 412 420 421 422 500 501 502 503 504 505 506 507 508 509 510 511 512 520 521 522 600 601 602 603 604 605 606 607 608 609 610 611 612 620 621 622 700 701 702 703 704 705 706 707 708 709 710 711 712 720 721 722 800 801 802 803 804 805 806 807 808 809 810 811 812 820 821 822 900 901 902 903 904 905 906 907 908 909 910 911 912 920 921 922 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1020 1021 1022 1030 1031 1032 1040 1041 1042 1050 1051 1052 1060 1061 1062 1070 1071 1072 1080 1081 1082 1090 1091 1092 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1120 1121 1122 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1220 1221 1222 (count=250)

modify to [0-3] to get numbers easy to multiply by 0 1 2 3: (count=356) up to 1999

modify to [0-4] to get numbers easy to multiply 0 1 2: (count=500) up to 1999

open problems: generate these lists in order directly, not using filtering.  create a regex that that does not require backtracking.

what is the asymptotic density?  probably something involving sqrt.

investigate numbers on a list divisible by other numbers on the list.  numbers form connections to other numbers, a directed graph.  it also feels a little like the word problem in computer science.

products yielding numbers with small digits might be useful for further connections in the graph:

102 = 2 * 3 * 17
110 = 2 * 5 * 11
111 = 3 * 37
112 = 2^4 * 7
120 = 2^3 * 3 * 5
121 = 11^2
122 = 2 * 61
200 = 2^3 * 5^2
201 = 3 * 67
202 = 2 * 101
210 = 2 * 3 * 5 * 7
212 = 2^2 * 53
220 = 2^2 * 5 * 11
221 = 13 * 17
222 = 2 * 3 * 37

future post piqwhqfy on 221 and 102.

"easy" assumes you have the 10x10 multiplication table memorized.  what if you had more?

[qaxpbods] Hilbert curve integer coordinates

an order N+1 Hilbert curve concatenates 4 copies of order N.  therefore, one can draw an order N curve, then seamlessly continue the curve into an order N+1 with the same step size, and so forth.  in this way, the curve can be continued indefinitely.  (previously, a roller coaster.)

assume a step size of 1 and that the curve starts at the origin.  given as input an index, i.e., a positive integer length from the start of this infinite Hilbert curve, compute the integer coordinates of that index.  note that N, the order of the curve, is not given as input.  it is not just a simple matter of internally computing N from the index then computing coordinates of an order N curve because we want order N to always coincide with the first quarter of N+1.  the standard method of drawing Hilbert curves does not do this.  easiest solution might be to compute the smallest even N containing the index, because the first 1/16 of an order N+2 curve is congruent to and in the same orientation as an order N.

compute the inverse: from non-negative integer coordinates to index.

also consider higher dimensional Hilbert curves.  according to this page, there are many possible definitions of a Hilbert curve of dimension 3 or higher.

the link above also seems to suggest that there are many opportunities for optimization in computing this mapping and its inverse.  the computation does a lot of bit manipulation, so consider implementing it in hardware, e.g., Bluespec.  at what point, if ever, would hardware performance exceed software?

given that all nonnegative integers therefore can be mapped nicely to 2D lattice points in a quarter plane, consider the primes.  a quick internet search finds others have plotted primes along a Hilbert curve.  unlike in the Ulam spiral, there are disappointingly no obvious patterns.  density is high near the origin, and points get sparser further away, thinning out at the rate given by the prime number theorem.

are there integer sequences which look surprisingly nice when plotted on a Hilbert curve?

Wednesday, June 18, 2025

[mjhowdnw] 3D maze of thin rods

fly anywhere, unimpeded by the rods.  you can see quite far because the rods are thin.  slide a cursor that rides on the rods to the exit.

2D mazes are usually overhead view, providing lots of visibility; thin rods with unlimited camera movement approximates that for 3D.

it might be difficult to tell which of a pair of visually intersecting rods is closer.  add artificial visual cues.

Tuesday, June 17, 2025

[ihehqrko] supergun space fountain

at first glance, a giant gun seems not a very practical method for space launch, because very few payloads, certainly not humans, can survive that kind of acceleration.

in contrast, a space elevator, if we could build one, would be a very practical method of getting humans and other fragile cargo to outer space.  (a space elevator is not so great for putting satellites into low earth orbit because it only provides vertical height not horizontal speed.)  one of the most promising designs for a space elevator, promising because it does not require materials with currently unachievable amounts of strength, is a space fountain.  and one of the ways to build a space fountain is a giant gun launching pellets up a tall evacuated tube to space.  the tube does not need to be made of an impossibly strong material because it is actively held up by skimming momentum (somehow) from the pellets shooting upward inside it.  humans then leisurely climb up the outside of the tube to space and beyond.

(at the top of the space fountain, the pellets fall back down to earth.  for energy efficiency, their falling energy at the bottom should be recovered or reflected to launch pellets up again.)

space elevators seem the only realistic way to migrate all humans off the planet before the gradually warming sun boils all water on earth.  alternatively, maybe we can get nuclear pulse propulsion to work, but rockets with radioactive exhaust will be extremely messy near the earth's surface.

(maybe we can increase albedo or play cosmic pinball to survive the warming then red giant sun, but we would still need to get off planet to survive white dwarf sun.)

therefore, the executions of both the world's leading scientist on giant guns and his patron, with the chilling effect those assassinations have on anyone considering continuing such work in the future, may have tremendous consequences on the long-term outcome of our species and survival of intelligent life in the universe.  perhaps that was precisely the moment when humanity went extinct: "Israel, you fool!  you've doomed us all!"

Wednesday, June 04, 2025

[wgiquvdb] mpv watch_later invertible hash

if you quit with Q instead of q (which is possible to do by accident, e.g., CAPS LOCK accidentally on), mpv stores its resume or "watch later" information in ~/.config/mpv/watch_later/ .  by default for privacy (see the manpage documentation of the flag --write-filename-in-watch-later-config), the filename of the media being watched is not written; instead, the resume file filename is the MD5 hash of the full path (or just the filename if --ignore-path-in-watch-later-config).  this hash is computed in mp_get_playback_resume_config_filename in player/configfiles.c .

although MD5 cannot generally be inverted, it can be if the attacker need only check a small universe of possibilities, so this feature is a privacy risk.  check every filename on the filesystem, every file suspected of having been on the filesystem, or every filename of illegal content.

one can disable "watch later" entirely with --no-config, but this disables all configuration.  best would be a way to generally disable it, only enabling it if explicitly invoked for a certain video in the command line or UI.  (capital Q is arguably an implementation of exactly this: improve it with an "are you sure?" dialog.)

another idea is to use a much smaller hash, say, 16 bits (configurable), which permits plausible deniability.  of course, each collision, now more frequent, will lose information about one of the colliding files.

or, create a wrapper around mpv which always copies the file to a random name, then calls mpv on it.

[sdmzsnne] unobvious composites

a multiplication table between pairs of small prime numbers:

* 13 17 19 23 29 31 37 41 43
13 169 221 247 299 377 403 481 533 559
17 221 289 323 391 493 527 629 697 731
19 247 323 361 437 551 589 703 779 817
23 299 391 437 529 667 713 851 943 989
29 377 493 551 667 841 899 1073 1189 1247
31 403 527 589 713 899 961 1147 1271 1333
37 481 629 703 851 1073 1147 1369 1517 1591
41 533 697 779 943 1189 1271 1517 1681 1763
43 559 731 817 989 1247 1333 1591 1763 1849

divisibility by 2, 3, 5, 11 can be checked by well known rules, and 7 can be checked by short division (requiring effort similar to checks of 3 and 11), so the table starts at 13.  it stops at the last prime (43) whose square is less than the cube of the smallest: (13^3 = 2197) < (47^2 = 2209).

45 table entries, after commutativity.

there are many non-obvious composites (without easy divisibility check) of similar size as entries in the table but not in the table above.  the smallest is 13*47 = 611, so the table contains all non-obvious composites only up to 610.

with that in mind, better is a list rather than a table.  below are the 43 non-obvious composites less than 1000:

169 = 13 * 13
221 = 13 * 17
247 = 13 * 19
289 = 17 * 17
299 = 13 * 23
323 = 17 * 19
361 = 19 * 19
377 = 13 * 29
391 = 17 * 23
403 = 13 * 31
437 = 19 * 23
481 = 13 * 37
493 = 17 * 29
527 = 17 * 31
529 = 23 * 23
533 = 13 * 41
551 = 19 * 29
559 = 13 * 43
589 = 19 * 31
611 = 13 * 47
629 = 17 * 37
667 = 23 * 29
689 = 13 * 53
697 = 17 * 41
703 = 19 * 37
713 = 23 * 31
731 = 17 * 43
767 = 13 * 59
779 = 19 * 41
793 = 13 * 61
799 = 17 * 47
817 = 19 * 43
841 = 29 * 29
851 = 23 * 37
871 = 13 * 67
893 = 19 * 47
899 = 29 * 31
901 = 17 * 53
923 = 13 * 71
943 = 23 * 41
949 = 13 * 73
961 = 31 * 31
989 = 23 * 43

the next entry would be 1003 = 17 * 59.

for divisibility and prime factorization, you only need to know one of the factors, probably the smaller one.

previously, on memorizing the primes less than 1000.  memorizing the composites this way seems competitive and also gets you useful prime factorization.

Friday, May 30, 2025

[dlghlxon] two moving rows of dots

consider a horizontal row of dots equally spaced 1 unit apart.  put another such row above it, also with horizontal spacings of 1 unit.  let the vertical spacing between rows be A = sqrt(15)/4 ~= 0.968 .

let the upper row slide horizontally at a constant velocity.  at some snapshot in time, consider a dot in the upper row, and the dot in the lower row that it is closest to.  if the upper dot is directly above the lower dot, that is, their relative horizontal offset is zero, then the distance between them is A.  if their relative horizontal offset is 0.25, then the distance between them is 1 by Pythagoras.  if their relative horizontal offset is 0.5, then the distance between them is sqrt(19)/4 ~= 1.090 .  this is the maximum possible separation: if the offset is greater, then it gets closer to the next dot in the row.  thus, half the time (0 to 0.25) the vertical distance is less than the horizontal distance between dots (namely 1), and the other half of the time (0.25 to 0.5), the vertical distance is greater.

motivation is dots in motion but staying well separated.  rows can be stacked.

previously: dots arranged in rings instead of rows.

if we want the average distance to the nearest dot in the other row to equal 1, then I don't think there is a closed form solution for the vertical space h between rows.  Mathematica:

N[Solve[ 2*Integrate[ Sqrt[h^2+x^2], {x, 0, 1/2}, Assumptions -> Element[h, Reals] && h > 0]==1, {h}, Reals], 50]

yields h ~= 0.95813624081219179188949156285292561053238539746725

(Inverse Symbolic Calculator finds nothing.)

if the rows of dots are not moving, then both the square lattice and equilateral triangular lattice achieve equal separation vertically and horizontally.

[hiexjgic] well separated dots in circles

consider the vertices of a regular n-gon with side length 1, centered on the origin and an additional "inner" point at Cartesian coordinates (inner, 0).  the distance from the inner point to the nearest polygon vertex depends on the rotation of the polygon.

the smallest possible distance is when a polygon vertex is on the X axis, at coordinates (1/(2*sin(Pi/n)), 0).  the distance is abs(inner - 1/(2*sin(Pi/n))).  (if n=1, then let the vertex be at (0,0)).

the largest possible distance is when there are two vertices symmetrically above and below the X axis, at coordinates (1/(2*tan(Pi/n)), +-1/2).  the distance is sqrt((inner - 1/(2*tan(Pi/n)))^2 + 1/4).  (if n=2, let the vertices be at (0, +-1/2)).

let the inner point itself be a vertex of a regular polygon with side length 1, centered on the origin and having one vertex (the inner point) lying on the positive X axis.  let this inner polygon have m sides, so inner = 1/(2*sin(Pi/m)).  in order for inner to actually be inside, m < n.

incidentally, all the coordinates of all the vertices of these regular polygons can be expressed in radicals.

we seek pairs of nested regular polygons such that the gap between them is about 1, or more precisely, that the smallest possible distance as defined above is strictly less than 1 and largest possible distance is strictly greater than 1.  this happens for a 2-gon nested inside a 9-gon, and for all (m, m+6) for m >= 7.  there are no solutions for m = {1, 3, 4, 5, 6}.

for m=1 and n=6, the distance is always exactly 1, not a solution by our definition with "strictly", but maybe it should be.

for m=6 and n=12, the largest possible distance is exactly 1.  this is geometrically surprising: attaching equilateral triangle ears to the vertices of a regular hexagon (and squares to the edges) yields a regular dodecagon (12-gon).  trigonometrically, 1/(2*tan(Pi/12))-1 = sqrt(3)/4.

it is a little surprising that solutions (m, m+6) seem to exist for all m >= 7.  the offset 6 is probably round(2*Pi): in the limit when polygons are nearly circular, adding 1 to the radius adds 2*Pi to the circumference.  future post on the limiting case of two lines of dots.

next, consider fudging to create solutions for m = {3, 4, 5, 6}:

the outer n-gon must still have side length 1, but let the inner m-gon have side length s, different from 1.  among all possible relative orientations (rotations), half the time the distance to the nearest vertex should be less than s; half the time greater.  this probability distribution is from the point of view of a given vertex of the inner polygon.  surprisingly, there are closed form solutions for s, via Mathematica.  we start with the following auxiliary functions:

inner[n_,s_]= s/(2*Sin[Pi/n])
l[n_]= inner[n,1]
x[n_]= l[n]*Cos[Pi/(2*n)]
y[n_]= l[n]*Sin[Pi/(2*n)]
py[n_,inx_]= (x[n]-inx)^2+y[n]^2

let us first consider a regular 9-gon of side length 1 with a concentric equilateral triangle of side length s.

s /. First[Solve[py[9,inner[3,s]] == s^2 && s>0, s]] //Simplify //InputForm

(Sqrt[3]*(-2*Cos[Pi/18] + Sqrt[2*(5 + Cos[Pi/9])])*Csc[Pi/18]*Sec[Pi/18])/16

N[%]

0.9349946

that is, a regular nonagon with side length 1 with a concentric equilateral triangle with side length (Sqrt[3] * (-2*Cos[Pi/18] + Sqrt[2*(5 + Cos[Pi/9])]) * Csc[Pi/18]*Sec[Pi/18])/16 ~= 0.9349946 inside it satisfies our requirements on s.

10-gon with inside it a regular triangle of the following side length:
(Sqrt[3]*(Sqrt[(3 + Sqrt[5])*(20 + Sqrt[2*(5 + Sqrt[5])])] - 2*(1 + Sqrt[5])*Cos[Pi/20]))/8
1.03312

10-gon with inside it a square of the following side length:
(Sqrt[(3 + Sqrt[5])*(12 + Sqrt[2*(5 + Sqrt[5])])] - 2*(1 + Sqrt[5])*Cos[Pi/20])/(2*Sqrt[2])
0.9561354

11-gon with square inside it:
((-2*Cos[Pi/22] + Sqrt[2*(3 + Cos[Pi/11])])*Csc[Pi/11])/(2*Sqrt[2])
1.04714

11-gon with pentagon inside it:
-((((-5 + Sqrt[5])*Cos[Pi/22] + Sqrt[85 - 35*Sqrt[5] - 5*(-3 + Sqrt[5])*Cos[Pi/11]])*Csc[Pi/11])/(Sqrt[10 - 2*Sqrt[5]]*(-3 + Sqrt[5])))
0.967348

12-gon with pentagon inside it:
(-Sqrt[(5*(136 + 15*Sqrt[2] + 68*Sqrt[3] - 56*Sqrt[5] + 9*Sqrt[6] - 5*Sqrt[10] - 28*Sqrt[15] - 3*Sqrt[30]))/2] - (1 + Sqrt[3])*(-5 + Sqrt[5])*Cos[Pi/24])/(Sqrt[5 - Sqrt[5]]*(-3 + Sqrt[5]))
1.05153

12-gon with hexagon inside it:
((2 + Sqrt[3])*Sec[Pi/24])/(Sqrt[2] + Sqrt[6])
0.974261

13-gon with hexagon inside it:
(Csc[Pi/13]*Sec[Pi/26])/4
1.05232

no regular polygon that satisfies our constraints fits in a heptagon or octagon.  future work: relax constraints further.

motivation is a collection of moving dots filling the plane which remain roughly equally spaced, dots staying below some maximum velocity, and whose configuration never repeats.  this can be achieved by having rings of dots rotate independently at speeds none of which are rational multiples of another.  future post: points on lines.

previously vaguely similar: concentric regular polygons that touch, not maintaining any gap.