Happy New Year: a stereogram in SQL
I'm spending this New Year holiday in sunny Florida.
One of its most beautiful places is the Everglades: the endless sea of grass, extending to the horizon, as far as the eye can see and beyond, and teeming with life.
There are all kinds of animals there. Herons, egrets, anhingas; fish, turtles, snakes; otters, skunks, small rodents; and of course, the king of Florida's wetlands, the American alligator.
The alligator is a well-oiled killing machine. It's motionless and extremely energy efficient when resting, but deadly fast when hunting. When the alligator is hunting, its eyes instantly track the faintest motion — and a fierce jump in any direction will follow immediately.
I was on a guided tour, and the tour guide mentioned that the alligators have binocular vision. The fields of view of their two eyes overlap, giving the predator the ability to estimate the direction and the distance to its prey more accurately.
We humans also have binocular vision. It allows us to see the world in three dimensions. When we are looking at an object with our two eyes, each eye sees it at a slightly different angle. The closer the thing is to us, the more the difference. This effect is called binocular parallax, and our brain can use it to estimate the distance to the object.
There are ways to trick the brain into believing something is 3D while it's not. To do this, we need a way to project a different image into each eye. There are lots of ways to do that: think holograms, polarized glasses, tilt cards, and many more.
Most of those methods require special equipment and materials, either to see or to produce the image. Maybe even both.
However, there is a way to see a three-dimensional image even on a simple piece of paper (or a plain LCD monitor without any 3D capabilities). It is technically called an autostereogram but most people know them as Magic Eye pictures.
A picture like this looks like repeating patterns of random dots or characters. The frequency of the patterns encodes the three-dimensional image: the close is the part of the image to the observer, the more frequent are the patterns.
It takes some effort to see the depth in what at first seems to be a random dot pattern. Not everyone can do that on the first try. There are lots of resources online which teach how to do that. The good thing is it's like riding a bicycle: once you got it right for the first time, there's no going back, it's always there with you.
Ever since I was a kid, I have been fascinated by the stereograms. So the moment I heard the words "binocular vision" from the tour guide, I instantly knew what would this New Year post be about.
Let's make a stereogram in PostgreSQL!
Stereogram theory
ASCII characters are almost as good as the color dots for the stereograms. All you have to do is combine them into repeating patterns. It does not matter if it's color dots or symbols. Ideally, they should be random and have different shapes within the pattern, but it's not necessary.
The go-to resource on ASCII stereograms is Gary Beene's page. There is a detailed description of the principles behind them, some examples, and even a code snippet in PowerBASIC to generate them. The only thing we need is translating it from PowerBASIC to SQL.
To create a stereogram, we first need an image to encode. Let's generate a simple depth mask: two overlapping rectangles. A larger number means closer to us.
WITH parameters AS ( SELECT * FROM ( VALUES (112, 50) ) v (width, height) ), mask AS ( SELECT x, y, CASE WHEN x BETWEEN 40 AND 90 AND y BETWEEN 15 AND 35 THEN 4 WHEN x BETWEEN 15 AND 65 AND y BETWEEN 10 AND 30 THEN 2 ELSE 0 END AS depth FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL GENERATE_SERIES(0, width - 1) x ) SELECT STRING_AGG(COALESCE(depth::TEXT, ' '), '' ORDER BY x) FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL GENERATE_SERIES(0, width - 1) x JOIN mask USING (x, y) GROUP BY y ORDER BY y;
string_agg |
---|
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000002222222222222222222222222222222222222222222222222220000000000000000000000000000000000000000000000 |
0000000000000002222222222222222222222222222222222222222222222222220000000000000000000000000000000000000000000000 |
0000000000000002222222222222222222222222222222222222222222222222220000000000000000000000000000000000000000000000 |
0000000000000002222222222222222222222222222222222222222222222222220000000000000000000000000000000000000000000000 |
0000000000000002222222222222222222222222222222222222222222222222220000000000000000000000000000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000002222222222222222222222222444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000000000000000000000000000000444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000000000000000000000000000000444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000000000000000000000000000000444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000000000000000000000000000000444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000000000000000000000000000000444444444444444444444444444444444444444444444444444000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
The depth map here is quite simple, and it's easy to see what's going on here: zero means the background level, two is closer to us, four is yet closer.
Random patterns
Now, let's generate a character map of random patterns. Every pattern will be 16 characters wide, and there will be 7 of them.
We will be seeding our random number generator with a constant value so that the random patterns will be the same between query invocations. In a short while, this will allow us to see what's happening with the 3D pictures. For now, we'll generate a plain background.
To do this, we will first generate our "lines" with a GENERATE_SERIES
function and then, for each line, call another GENERATE_SERIES
to generate a random pattern for each line.
Note that we are using 0 * y
instead of just 0 as a first parameter to GENERATE_SERIES
. It is because PostgreSQL optimizer is trying to be smart and will only invoke the lateral query once if it sees that it does not depend on the outermost query.
Usually, it's a good thing, but in this case, we do need the engine to invoke that RANDOM
for each separate value of y
, and that's how we introduce that external dependency (which does not do that much as it's a multiplication by zero).
Here's what our background looks like:
SELECT SETSEED(0.20191231); WITH RECURSIVE parameters AS ( SELECT * FROM ( VALUES (16, 7, 50) ) v (pattern_length, pattern_count, height) CROSS JOIN LATERAL ( SELECT pattern_length * pattern_count AS width ) q ), patterns AS ( SELECT y, pattern FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL ( SELECT STRING_AGG(CHR(FLOOR(RANDOM() * 94)::INT + 33), '') FROM GENERATE_SERIES(0 * y, pattern_length - 1) x ) q (pattern) ) SELECT REPEAT(pattern, pattern_count) AS line FROM patterns CROSS JOIN parameters ORDER BY y;
line |
---|
lV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.E |
}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN |
Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K= |
2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s |
c1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RU |
.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p |
Fe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\Fhj |
f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11 |
Pkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!v |
Pr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#U |
!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW" |
mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:< |
{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q |
/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^ |
"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf |
2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M! |
B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X:: |
z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6; |
O%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSz |
!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G |
00`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB2 |
mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp) |
hQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(C |
4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC* |
=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA! |
^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4 |
(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc) |
p!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1w |
24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f, |
=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5 |
m[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0w |
!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh |
[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x |
*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=] |
Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,# |
ZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vy |
&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj |
!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2 |
^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe |
P"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doq |
|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u? |
@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^( |
4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd` |
7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws |
ivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"z |
\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w |
:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6 |
*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb |
xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*" |
vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O. |
At first glance, it looks completely random, but if you look close enough, you see that the patterns are repeating horizontally every 16 characters.
Adding depth
Now, the fun part. On the background plane, our patterns are 16 characters long. We need them to have a shorter period where the depth map value is larger than 0. It means that they have to be 14 characters long on the background rectangle (which has the depth of 2) and 12 characters long on the foreground rectangle (which has the depth of 4).
The algorithm on Gary's page describes how to do that.
We will have to convert our query to a recursive one so that we can keep track of the pattern string for each line as we build it.
On each step, we will calculate the period of our pattern (according to the value of the depth map at this point), then we will take N'th character from the end of the string we've built so far (where N is the current value of the period) and append it to the end of the line.
The pattern will stay periodic as long as the depth remains the same.
When the depth increases, the pattern will lose some of its symbols (just in the right place).
When the depth decreases, the pattern will take the extra symbols from its beginning.
It will not be the original pattern anymore, of course, but it was random in the first place, so it does not matter much, as long as it's still periodic.
To have a better look at this algorithm, let's replace our random characters with hexadecimal digits and see what's going on here:
SELECT SETSEED(0.20191231); WITH RECURSIVE parameters AS ( SELECT * FROM ( VALUES (16, 7, 50) ) v (pattern_length, pattern_count, height) CROSS JOIN LATERAL ( SELECT pattern_length * pattern_count AS width ) q ), patterns AS ( SELECT y, pattern FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL ( SELECT STRING_AGG(CHR(CASE WHEN x < 10 THEN x + 48 ELSE x + 55 END), '') FROM GENERATE_SERIES(0 * y, pattern_length - 1) x ) q (pattern) ), mask AS ( SELECT x, y, CASE WHEN x BETWEEN 40 AND 90 AND y BETWEEN 15 AND 35 THEN 4 WHEN x BETWEEN 15 AND 65 AND y BETWEEN 10 AND 30 THEN 2 ELSE 0 END AS depth FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL GENERATE_SERIES(0, width - 1) x ), lines AS ( SELECT 0 AS x, y, pattern AS line FROM patterns CROSS JOIN parameters UNION ALL SELECT x + 1, y, line || LEFT(RIGHT(line, pattern_length - depth), 1) FROM lines JOIN mask USING (x, y) CROSS JOIN parameters WHERE x < width ) SELECT SUBSTR(line, pattern_length + 1, width) AS line FROM lines CROSS JOIN parameters WHERE x = width ORDER BY y;
line |
---|
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDE123456789ABCDE123456789ABCDE123456789ABCDE12345678989ABCDE12345678989ABCDE12345678989ABCDE1234567 |
0123456789ABCDE123456789ABCDE123456789ABCDE123456789ABCDE12345678989ABCDE12345678989ABCDE12345678989ABCDE1234567 |
0123456789ABCDE123456789ABCDE123456789ABCDE123456789ABCDE12345678989ABCDE12345678989ABCDE12345678989ABCDE1234567 |
0123456789ABCDE123456789ABCDE123456789ABCDE123456789ABCDE12345678989ABCDE12345678989ABCDE12345678989ABCDE1234567 |
0123456789ABCDE123456789ABCDE123456789ABCDE123456789ABCDE12345678989ABCDE12345678989ABCDE12345678989ABCDE1234567 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDE123456789ABCDE123456789ABE123456789ABE123456789ABE123456789ABE123456789ABE12BE123456789ABE12BE123 |
0123456789ABCDEF0123456789ABCDEF01234567CDEF01234567CDEF01234567CDEF01234567CDEF01234567CDE7CDEF01234567CDE7CDEF |
0123456789ABCDEF0123456789ABCDEF01234567CDEF01234567CDEF01234567CDEF01234567CDEF01234567CDE7CDEF01234567CDE7CDEF |
0123456789ABCDEF0123456789ABCDEF01234567CDEF01234567CDEF01234567CDEF01234567CDEF01234567CDE7CDEF01234567CDE7CDEF |
0123456789ABCDEF0123456789ABCDEF01234567CDEF01234567CDEF01234567CDEF01234567CDEF01234567CDE7CDEF01234567CDE7CDEF |
0123456789ABCDEF0123456789ABCDEF01234567CDEF01234567CDEF01234567CDEF01234567CDEF01234567CDE7CDEF01234567CDE7CDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF |
The first ten lines are perfectly periodic from 0 to F.
On line 11 and below, however, something weird is happening: starting from the very first period, the F and the 0 vanish from the pattern.
It goes on for some time from 1 to E (with a period of 14), and then it makes recovery of sorts and gets its original length of 16 back.
However, it's not that beautiful series of consecutive digits anymore. The 0 and the F are gone forever, and 8 and 9 are inserted back into the pattern instead. It is the artifact of the algorithm. However, if we go back to the random sequences of characters, it does not matter much.
You have probably noticed that the shapes of the rectangles are discernible in the picture above. It is because it already is a complete, functioning stereogram!
But the fact that the patterns are repeating vertically, as well as horizontally, confuses the brain. The picture works much better with a random pattern of dots for every line.
Final result
Let's combine the last two queries and see the result:
SELECT SETSEED(0.20191231); WITH RECURSIVE parameters AS ( SELECT * FROM ( VALUES (16, 7, 50) ) v (pattern_length, pattern_count, height) CROSS JOIN LATERAL ( SELECT pattern_length * pattern_count AS width ) q ), patterns AS ( SELECT y, pattern FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL ( SELECT STRING_AGG(CHR(FLOOR(RANDOM() * 94)::INT + 33), '') FROM GENERATE_SERIES(0 * y, pattern_length - 1) x ) q (pattern) ), mask AS ( SELECT x, y, CASE WHEN x BETWEEN 40 AND 90 AND y BETWEEN 15 AND 35 THEN 4 WHEN x BETWEEN 15 AND 65 AND y BETWEEN 10 AND 30 THEN 2 ELSE 0 END AS depth FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL GENERATE_SERIES(0, width - 1) x ), lines AS ( SELECT 0 AS x, y, pattern AS line FROM patterns CROSS JOIN parameters UNION ALL SELECT x + 1, y, line || LEFT(RIGHT(line, pattern_length - depth), 1) FROM lines JOIN mask USING (x, y) CROSS JOIN parameters WHERE x < width ) SELECT SUBSTR(line, pattern_length + 1, width) AS line FROM lines CROSS JOIN parameters WHERE x = width ORDER BY y;
line |
---|
lV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.E |
}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN |
Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K= |
2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s |
c1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RU |
.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p |
Fe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\Fhj |
f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11 |
Pkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!v |
Pr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#U |
!qmM-cidO9y_PzWqmM-cidO9y_PzWqmM-cidO9y_PzWqmM-cidO9y_PzWqmM-cidO9O9y_PzWqmM-cidO9O9y_PzWqmM-cidO9O9y_PzWqmM-cid |
mZZ@.C%5^('c<*:ZZ@.C%5^('c<*:ZZ@.C%5^('c<*:ZZ@.C%5^('c<*:ZZ@.C%5^(^('c<*:ZZ@.C%5^(^('c<*:ZZ@.C%5^(^('c<*:ZZ@.C%5 |
{(i)kSm;kgz<bS>(i)kSm;kgz<bS>(i)kSm;kgz<bS>(i)kSm;kgz<bS>(i)kSm;kgkgz<bS>(i)kSm;kgkgz<bS>(i)kSm;kgkgz<bS>(i)kSm; |
/wp<<tQy|X^9bxUwp<<tQy|X^9bxUwp<<tQy|X^9bxUwp<<tQy|X^9bxUwp<<tQy|X|X^9bxUwp<<tQy|X|X^9bxUwp<<tQy|X|X^9bxUwp<<tQy |
"?flqT)^=%z!W9Q?flqT)^=%z!W9Q?flqT)^=%z!W9Q?flqT)^=%z!W9Q?flqT)^=%=%z!W9Q?flqT)^=%=%z!W9Q?flqT)^=%=%z!W9Q?flqT)^ |
2B#M8TG5-'Mn~#MB#M8TG5-'Mn~#MB#M8TG5-'MnMB#M8TG5-'MnMB#M8TG5-'MnMB#M8TG5-'MnMB#M8TG5-'MnMB#nMB#M8TG5-'MnMB#nMB#M |
B5m5ivr'zn'S(X:5m5ivr'zn'S(X:5m5ivr'zn'S:5m5ivr'zn'S:5m5ivr'zn'S:5m5ivr'zn'S:5m5ivr'zn'S:5mS:5m5ivr'zn'S:5mS:5m5 |
z=f3p/H|6ul5x;6=f3p/H|6ul5x;6=f3p/H|6ul56=f3p/H|6ul56=f3p/H|6ul56=f3p/H|6ul56=f3p/H|6ul56=f56=f3p/H|6ul56=f56=f3 |
O%O9zC@v2GJ:~cS%O9zC@v2GJ:~cS%O9zC@v2GJ:S%O9zC@v2GJ:S%O9zC@v2GJ:S%O9zC@v2GJ:S%O9zC@v2GJ:S%O:S%O9zC@v2GJ:S%O:S%O9 |
!;/qJVo_L\tEw,_;/qJVo_L\tEw,_;/qJVo_L\tE_;/qJVo_L\tE_;/qJVo_L\tE_;/qJVo_L\tE_;/qJVo_L\tE_;/E_;/qJVo_L\tE_;/E_;/q |
00`,S!#dGM~G1SB0`,S!#dGM~G1SB0`,S!#dGM~GB0`,S!#dGM~GB0`,S!#dGM~GB0`,S!#dGM~GB0`,S!#dGM~GB0`GB0`,S!#dGM~GB0`GB0`, |
mP%9(swSQlxIwXpP%9(swSQlxIwXpP%9(swSQlxIpP%9(swSQlxIpP%9(swSQlxIpP%9(swSQlxIpP%9(swSQlxIpP%IpP%9(swSQlxIpP%IpP%9 |
hQ5<R8"xd"AuTb(Q5<R8"xd"AuTb(Q5<R8"xd"Au(Q5<R8"xd"Au(Q5<R8"xd"Au(Q5<R8"xd"Au(Q5<R8"xd"Au(Q5u(Q5<R8"xd"Au(Q5u(Q5< |
4,[;!SnQAgy:AjC,[;!SnQAgy:AjC,[;!SnQAgy:C,[;!SnQAgy:C,[;!SnQAgy:C,[;!SnQAgy:C,[;!SnQAgy:C,[:C,[;!SnQAgy:C,[:C,[; |
=WFnoHhTI*J}lRAWFnoHhTI*J}lRAWFnoHhTI*J}AWFnoHhTI*J}AWFnoHhTI*J}AWFnoHhTI*J}AWFnoHhTI*J}AWF}AWFnoHhTI*J}AWF}AWFn |
^{<^P+1qq,-3vO={<^P+1qq,-3vO={<^P+1qq,-3={<^P+1qq,-3={<^P+1qq,-3={<^P+1qq,-3={<^P+1qq,-3={<3={<^P+1qq,-3={<3={<^ |
(c$v,kLUuvSbJscc$v,kLUuvSbJscc$v,kLUuvSbcc$v,kLUuvSbcc$v,kLUuvSbcc$v,kLUuvSbcc$v,kLUuvSbcc$bcc$v,kLUuvSbcc$bcc$v |
p!gB+x4|%A1{oM1!gB+x4|%A1{oM1!gB+x4|%A1{1!gB+x4|%A1{1!gB+x4|%A1{1!gB+x4|%A1{1!gB+x4|%A1{1!g{1!gB+x4|%A1{1!g{1!gB |
24o=!<qu4EX]:=f4o=!<qu4EX]:=f4o=!<qu4EX]f4o=!<qu4EX]f4o=!<qu4EX]f4o=!<qu4EX]f4o=!<qu4EX]f4o]f4o=!<qu4EX]f4o]f4o= |
=OMHHaEM#VJr$ZjOMHHaEM#VJr$ZjOMHHaEM#VJrjOMHHaEM#VJrjOMHHaEM#VJrjOMHHaEM#VJrjOMHHaEM#VJrjOMrjOMHHaEM#VJrjOMrjOMH |
m[RmvEd,j>h%ZP0[RmvEd,j>h%ZP0[RmvEd,j>h%0[RmvEd,j>h%0[RmvEd,j>h%0[RmvEd,j>h%0[RmvEd,j>h%0[R%0[RmvEd,j>h%0[R%0[Rm |
!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euBy!Uh!]@H?euBy!Uh!]@H?euBy!Uh!]@H?euBy!Uh!]@H?euBy!UBy!Uh!]@H?euBy!UBy!Uh |
[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7xL-x[(WSL<^7xL-x[(WSL<^7xL-x[(WSL<^7xL-x[(WSL<^7xL-7xL-x[(WSL<^7xL-7xL-x |
*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kN"D=]*MBI39kN"D=]*MBI39kN"D=]*MBI39kN"D=]*MBI39kN"D=N"D=]*MBI39kN"D=N"D=] |
Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0jw.,#Kt2w1p0jw.,#Kt2w1p0jw.,#Kt2w1p0jw.,#Kt2w1p0jw.,jw.,#Kt2w1p0jw.,jw.,# |
ZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@N1vyZNKlf7<@N1vyZNKlf7<@N1vyZNKlf7<@N1vyZNKlf7<@N1v@N1vyZNKlf7<@N1v@N1vy |
&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj |
!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2 |
^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe |
P"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doq |
|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u? |
@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^( |
4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd` |
7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws |
ivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"z |
\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w |
:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6 |
*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb |
xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*" |
vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O. |
line |
---|
lV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.E |
}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN |
Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K= |
2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s |
c1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RU |
.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p.@P(DnkD(S&C-57p |
Fe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\FhjFe[]g`K^n>s3\Fhj |
f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11f9r+(^O03TR?ii11 |
Pkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8M:u<XjO518!v |
Pr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#U |
!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmM-cidO9y_PzW" |
mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:< |
{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q{(i)kSm;kgz<bS>Q |
/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^/wp<<tQy|X^9bxU^ |
"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf"?flqT)^=%z!W9Qf |
2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M!2B#M8TG5-'Mn~#M! |
B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X::B5m5ivr'zn'S(X:: |
z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6;z=f3p/H|6ul5x;6; |
O%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSzO%O9zC@v2GJ:~cSz |
!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G!;/qJVo_L\tEw,_G |
00`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB200`,S!#dGM~G1SB2 |
mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp)mP%9(swSQlxIwXp) |
hQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(ChQ5<R8"xd"AuTb(C |
4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC*4,[;!SnQAgy:AjC* |
=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA! |
^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4 |
(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc) |
p!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1w |
24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f,24o=!<qu4EX]:=f, |
=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5=OMHHaEM#VJr$Zj5 |
m[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0wm[RmvEd,j>h%ZP0w |
!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh!]@H?euB<@6@y!Uh |
[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x |
*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBI39kNX"mS"D=] |
Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,# |
ZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vy |
&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj&*q7y##4N#FG0RIj |
!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2!tWg,r(D|z]K-UF2 |
^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe^8IX;LkiO32_eZJe |
P"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doqP"N[tU!rQ]>]3doq |
|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u?|:K8e8#5J4s0n>u? |
@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^(@Dz5yz(KXF*k+y^( |
4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd`4*@xAB/kV#zFAqd` |
7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws7`u1[}\5Df"O`_Ws |
ivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"zivm+:{vp~q7Ad{"z |
\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w\w,9uhM;ONj0/B%w |
:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6:q$TnyEnl\0RY2M6 |
*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb*YN!B{;qK'#YH'Rb |
xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*" |
vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O. |
If you're still having problems seeing the 3D image, move the mouse cursor over the picture and back to highlight the differences between the original background and the stereogram.
Hidden message
I've made one more stereogram, with a hidden message. Can you see what it is?
SELECT SETSEED(0.20191231); WITH RECURSIVE parameters AS ( SELECT * FROM ( VALUES (16, 7, 50) ) v (pattern_length, pattern_count, height) CROSS JOIN LATERAL ( SELECT pattern_length * pattern_count AS width ) q ), patterns AS ( SELECT y, pattern FROM parameters CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL ( SELECT STRING_AGG(CHR(FLOOR(RANDOM() * 94)::INT + 33), '') FROM GENERATE_SERIES(0 * y, pattern_length - 1) x ) q (pattern) ), mask AS ( SELECT x, y, CASE WHEN y > 4 AND SUBSTRING(SPLIT_PART(banner, E'\n', FLOOR(y / 4)::INT), FLOOR(x / 12)::INT, 1) = '*' THEN 2 ELSE 0 END depth FROM parameters CROSS JOIN ( SELECT CONVERT_FROM(DECODE(' KioqICoqKgogICogKiAqCioqKiAqICoK KiAgICogKgoqKiogKioqCgoqKiogKioqCiAgKiAqICoK KioqICogKgoqICAgKiAqCioqKiAqKioK', 'BASE64'), 'UTF8') AS banner ) q CROSS JOIN LATERAL GENERATE_SERIES(0, height - 1) y CROSS JOIN LATERAL GENERATE_SERIES(0, width - 1) x ), lines AS ( SELECT 0 AS x, y, pattern AS line FROM patterns CROSS JOIN parameters UNION ALL SELECT x + 1, y, line || LEFT(RIGHT(line, pattern_length - depth), 1) FROM lines JOIN mask USING (x, y) CROSS JOIN parameters WHERE x < width ) SELECT SUBSTR(line, pattern_length + 1, width) AS line FROM lines CROSS JOIN parameters WHERE x = width ORDER BY y;
line |
---|
lV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.ElV:R"z&u4OCmPI.E |
}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN}zEPh*7Dizy%a#pN |
Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K=Y+"Z''Q;Ut)&?7K= |
2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s2olyx%?c~9g`;X0s |
c1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RUc1Oj8"&lv.r6D>RU |
.@P(DnkD(S&C7p.@P(DnkD(S&C7p.@P(DnkD(S&C7p.@P(DnDnkD(S&C7p.@DnDnkD(S&C7p.@DnDnkD(S&C7p.@DnDnkD(S(S&C7p.@DnDnkD(S |
Fe[]g`K^n>s3hjFe[]g`K^n>s3hjFe[]g`K^n>s3hjFe[]g`g`K^n>s3hjFeg`g`K^n>s3hjFeg`g`K^n>s3hjFeg`g`K^n>n>s3hjFeg`g`K^n> |
f9r+(^O03TR?11f9r+(^O03TR?11f9r+(^O03TR?11f9r+(^(^O03TR?11f9(^(^O03TR?11f9(^(^O03TR?11f9(^(^O03T3TR?11f9(^(^O03T |
Pkn8M:u<XjO518!vPkn8M:u<XjO518!vPkn8u<XjO518!vPkPkn8u<XjO518PkPkn8u<XjO5O518PkPkn8u<O5O518PkPkn8n8u<O5O518PkPkn8 |
Pr#XQRhc(<$q&4#UPr#XQRhc(<$q&4#UPr#Xhc(<$q&4#UPrPr#Xhc(<$q&4PrPr#Xhc(<$q$q&4PrPr#Xhc$q$q&4PrPr#X#Xhc$q$q&4PrPr#X |
!qmM-cidO9y_PzW"!qmM-cidO9y_PzW"!qmMidO9y_PzW"!q!qmMidO9y_Pz!q!qmMidO9y_y_Pz!q!qmMidy_y_Pz!q!qmMmMidy_y_Pz!q!qmM |
mZZ@.C%5^('c<*:<mZZ@.C%5^('c<*:<mZZ@%5^('c<*:<mZmZZ@%5^('c<*mZmZZ@%5^('c'c<*mZmZZ@%5'c'c<*mZmZZ@Z@%5'c'c<*mZmZZ@ |
{(i)kSm;kgz<>Q{(i)kSm;kgz<>Q{(i)kSm;kgz<>Q{(i)kSkSm;kgz<>Q{(kSkSm;kgz<>Q>Q{(kSkSm;kg>Q>Q{(kSkSm;m;kg>Q>Q{(kSkSm; |
/wp<<tQy|X^9U^/wp<<tQy|X^9U^/wp<<tQy|X^9U^/wp<<t<tQy|X^9U^/w<t<tQy|X^9U^U^/w<t<tQy|XU^U^/w<t<tQyQy|XU^U^/w<t<tQy |
"?flqT)^=%z!Qf"?flqT)^=%z!Qf"?flqT)^=%z!Qf"?flqTqT)^=%z!Qf"?qTqT)^=%z!QfQf"?qTqT)^=%QfQf"?qTqT)^)^=%QfQf"?qTqT)^ |
2B#M8TG5-'MnM!2B#M8TG5-'MnM!2B#M8TG5-'MnM!2B#M8T8TG5-'MnM!2B8T8TG5-'MnM!M!2B8T8TG5-'M!M!2B8T8TG5G5-'M!M!2B8T8TG5 |
B5m5ivr'zn'S::B5m5ivr'znzn'S::B5m5ivr'znzn'S::B5m5ivr'znzn'SB5m5ivr'znznzn'SB5m5ivr'znzn'SB5m5ivivr'znzn'SB5m5iv |
z=f3p/H|6ul56;z=f3p/H|6u6ul56;z=f3p/H|6u6ul56;z=f3p/H|6u6ul5z=f3p/H|6u6u6ul5z=f3p/H|6u6ul5z=f3p/p/H|6u6ul5z=f3p/ |
O%O9zC@v2GJ:SzO%O9zC@v2G2GJ:SzO%O9zC@v2G2GJ:SzO%O9zC@v2G2GJ:O%O9zC@v2G2G2GJ:O%O9zC@v2G2GJ:O%O9zCzC@v2G2GJ:O%O9zC |
!;/qJVo_L\tE_G!;/qJVo_L\L\tE_G!;/qJVo_L\L\tE_G!;/qJVo_L\L\tE!;/qJVo_L\L\L\tE!;/qJVo_L\L\tE!;/qJVJVo_L\L\tE!;/qJV |
00`,S!#dGM~GB200`,S!#dGM~GB200`,S!#dGM~GB200`,S!S!#dGM~GB200S!S!#dGM~GB200S!S!#dGM~GB200S!S!#dGMGM~GB200S!S!#dGM |
mP%9(swSQlxIp)mP%9(swSQlxIp)mP%9(swSQlxIp)mP%9(s(swSQlxIp)mP(s(swSQlxIp)mP(s(swSQlxIp)mP(s(swSQlQlxIp)mP(s(swSQl |
hQ5<R8"xd"Au(ChQ5<R8"xd"Au(ChQ5<R8"xd"Au(ChQ5<R8R8"xd"Au(ChQR8R8"xd"Au(ChQR8R8"xd"Au(ChQR8R8"xd"d"Au(ChQR8R8"xd" |
4,[;!SnQAgy:C*4,[;!SnQAgy:C*4,[;!SnQAgy:C*4,[;!S!SnQAgy:C*4,!S!SnQAgy:C*4,!S!SnQAgy:C*4,!S!SnQAgAgy:C*4,!S!SnQAg |
=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA!=WFnoHhTI*J}lRA! |
^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4^{<^P+1qq,-3vO=4 |
(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc)(c$v,kLUuvSbJsc) |
p!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1wp!gB+x4|%A1{oM1w |
24o=!<qu4EX]f,24o=!<qu4EX]f,24o=!<qu4EX]f,24o=!<!<qu4EX]f,24!<!<qu4EX]f,24!<!<qu4EX]f,24!<!<qu4E4EX]f,24!<!<qu4E |
=OMHHaEM#VJrj5=OMHHaEM#VJrj5=OMHHaEM#VJrj5=OMHHaHaEM#VJrj5=OHaHaEM#VJrj5=OHaHaEM#VJrj5=OHaHaEM#V#VJrj5=OHaHaEM#V |
m[RmvEd,j>h%0wm[RmvEd,j>h%0wm[RmvEd,j>h%0wm[RmvEvEd,j>h%0wm[vEvEd,j>h%0wm[vEvEd,j>h%0wm[vEvEd,j>j>h%0wm[vEvEd,j> |
!]@H?euB<@6@Uh!]@H?euB<@6@Uh!]@H?euB<@6@Uh!]@H?e?euB<@6@Uh!]?e?euB<@6@Uh!]?e?euB<@6@Uh!]?e?euB<@<@6@Uh!]?e?euB<@ |
[(WSL<^7YH<5xL-x[(WSL<^7YH<5xL-x[(WS^7YH<5xL-x[([(WS^7YH<5xL[([(WS^7YH<5<5xL[([(WS^7<5<5xL[([(WSWS^7<5<5xL[([(WS |
*MBI39kNX"mS"D=]*MBI39kNX"mS"D=]*MBIkNX"mS"D=]*M*MBIkNX"mS"D*M*MBIkNX"mSmS"D*M*MBIkNmSmS"D*M*MBIBIkNmSmS"D*M*MBI |
Kt2w1p0j9L!3w.,#Kt2w1p0j9L!3w.,#Kt2w0j9L!3w.,#KtKt2w0j9L!3w.KtKt2w0j9L!3!3w.KtKt2w0j!3!3w.KtKt2w2w0j!3!3w.KtKt2w |
ZNKlf7<@8+s:N1vyZNKlf7<@8+s:N1vyZNKl<@8+s:N1vyZNZNKl<@8+s:N1ZNZNKl<@8+s:s:N1ZNZNKl<@s:s:N1ZNZNKlKl<@s:s:N1ZNZNKl |
&*q7y##4N#FGIj&*q7y##4N#FGIj&*q7y##4N#FGIj&*q7y#y##4N#FGIj&*y#y##4N#FGIjIj&*y#y##4N#IjIj&*y#y##4#4N#IjIj&*y#y##4 |
!tWg,r(D|z]KF2!tWg,r(D|z]KF2!tWg,r(D|z]KF2!tWg,r,r(D|z]KF2!t,r,r(D|z]KF2F2!t,r,r(D|zF2F2!t,r,r(D(D|zF2F2!t,r,r(D |
^8IX;LkiO32_Je^8IX;LkiO32_Je^8IX;LkiO32_Je^8IX;L;LkiO32_Je^8;L;LkiO32_JeJe^8;L;LkiO3JeJe^8;L;LkikiO3JeJe^8;L;Lki |
P"N[tU!rQ]>]oqP"N[tU!rQ]>]oqP"N[tU!rQ]>]oqP"N[tUtU!rQ]>]oqP"tUtU!rQ]>]oqoqP"tUtU!rQ]oqoqP"tUtU!r!rQ]oqoqP"tUtU!r |
|:K8e8#5J4s0u?|:K8e8#5J4J4s0u?|:K8e8#5J4J4s0u?|:K8e8#5J4J4s0|:K8e8#5J4J4J4s0|:K8e8#5J4J4s0|:K8e8e8#5J4J4s0|:K8e8 |
@Dz5yz(KXF*k^(@Dz5yz(KXFXF*k^(@Dz5yz(KXFXF*k^(@Dz5yz(KXFXF*k@Dz5yz(KXFXFXF*k@Dz5yz(KXFXF*k@Dz5yzyz(KXFXF*k@Dz5yz |
4*@xAB/kV#zFd`4*@xAB/kV#V#zFd`4*@xAB/kV#V#zFd`4*@xAB/kV#V#zF4*@xAB/kV#V#V#zF4*@xAB/kV#V#zF4*@xABAB/kV#V#zF4*@xAB |
7`u1[}\5Df"OWs7`u1[}\5DfDf"OWs7`u1[}\5DfDf"OWs7`u1[}\5DfDf"O7`u1[}\5DfDfDf"O7`u1[}\5DfDf"O7`u1[}[}\5DfDf"O7`u1[} |
ivm+:{vp~q7A"zivm+:{vp~q7A"zivm+:{vp~q7A"zivm+:{:{vp~q7A"ziv:{:{vp~q7A"ziv:{:{vp~q7A"ziv:{:{vp~q~q7A"ziv:{:{vp~q |
\w,9uhM;ONj0%w\w,9uhM;ONj0%w\w,9uhM;ONj0%w\w,9uhuhM;ONj0%w\wuhuhM;ONj0%w\wuhuhM;ONj0%w\wuhuhM;ONONj0%w\wuhuhM;ON |
:q$TnyEnl\0RM6:q$TnyEnl\0RM6:q$TnyEnl\0RM6:q$TnynyEnl\0RM6:qnynyEnl\0RM6:qnynyEnl\0RM6:qnynyEnl\l\0RM6:qnynyEnl\ |
*YN!B{;qK'#YRb*YN!B{;qK'#YRb*YN!B{;qK'#YRb*YN!B{B{;qK'#YRb*YB{B{;qK'#YRb*YB{B{;qK'#YRb*YB{B{;qK'K'#YRb*YB{B{;qK' |
xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*"xV7gQ\V?:fprw>*" |
vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O.vX#:T=,~D.Yl5-O. |
You can view the queries here: https://github.com/quassnoi/explain-extended-2020
Let your life in this New Year be full and solid!
Previous New Year posts:
Christmas, new year, explain-extended!
Nicely done as sualy good sir, Happy New Year!
Vincent
1 Jan 20 at 21:49