aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-11-14 23:57:00 +0000
committerGitHub <noreply@github.com>2021-11-14 23:57:00 +0000
commitab6264c731bd86ab90b28c82d43af85d482756c4 (patch)
treec7b6a68e2da36d261a5becd31fa5518588298cdc
parent420648a04bcbbe13dfdb7b3e6ff095ca33607b23 (diff)
parent82aacb0fa599e5b4214553f91f223c0871d15826 (diff)
downloadperlweeklychallenge-club-ab6264c731bd86ab90b28c82d43af85d482756c4.tar.gz
perlweeklychallenge-club-ab6264c731bd86ab90b28c82d43af85d482756c4.tar.bz2
perlweeklychallenge-club-ab6264c731bd86ab90b28c82d43af85d482756c4.zip
Merge pull request #5218 from Util/branch-for-challenge-138
Add Raku, Perl, and C solutions for #138 by Bruce Gray
-rw-r--r--challenge-138/bruce-gray/blog.txt1
-rw-r--r--challenge-138/bruce-gray/c/ch-2.c474
-rw-r--r--challenge-138/bruce-gray/perl/ch-1.pl32
-rw-r--r--challenge-138/bruce-gray/perl/ch-2.pl78
-rw-r--r--challenge-138/bruce-gray/raku/ch-1.raku24
-rw-r--r--challenge-138/bruce-gray/raku/ch-2.raku48
6 files changed, 657 insertions, 0 deletions
diff --git a/challenge-138/bruce-gray/blog.txt b/challenge-138/bruce-gray/blog.txt
new file mode 100644
index 0000000000..57f75a1ee3
--- /dev/null
+++ b/challenge-138/bruce-gray/blog.txt
@@ -0,0 +1 @@
+http://blogs.perl.org/users/bruce_gray/2021/11/twc-138-partition-free-weekends.html
diff --git a/challenge-138/bruce-gray/c/ch-2.c b/challenge-138/bruce-gray/c/ch-2.c
new file mode 100644
index 0000000000..083807a365
--- /dev/null
+++ b/challenge-138/bruce-gray/c/ch-2.c
@@ -0,0 +1,474 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+gcc -Wall -O3 c/ch-2.c
+
+Running with numeric command-line params:
+./a.out 36 1028956744 1028956743 1028956745
+ 36 : 1
+ 1028956744 : 1
+ 1028956743 : 0
+ 1028956745 : 0
+
+Run with no parameters to auto-test (runs in < 1 second):
+./a.out
+ All 3200 tests (through 1028956744) of known-good numbers returned True as expected
+ All 6223 tests (through 1028956744) of known-good numbers ±1 returned False as expected
+
+Run with a dash parameters to generate the all perfect-square numbers that can_partition_to_square
+from 0 to 1 million, which is a perfect match for https://oeis.org/A104113/b104113.txt :
+./a.out -
+ 1 0
+ 2 1
+ 3 81
+ ...
+ 406 999982000081
+ 407 999998000001
+ 408 1000000000000
+
+Note that this program does not even try to embrace the "you give me a perfect square,
+and I will try to partition to its root" input that is specified in the Task.
+This is C! We are only here for performance!
+Instead, every number tested and printed (except via '-' above) will *be* the root,
+and we will use the digits of that root's square to sum back to the specified root.
+
+*/
+
+
+unsigned long powers_of_10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000 };
+
+int can_partition_to_target ( unsigned long n, unsigned long target ) {
+ if (n == target) return 1;
+ if (n < target) return 0;
+
+ unsigned long right = 0;
+ unsigned long left = n;
+ unsigned long digit;
+ for ( unsigned long *p = &powers_of_10[0] ; n >= *p ; ++p ) {
+ digit = left % 10;
+ left -= digit;
+ left /= 10;
+ right += (digit * *p);
+
+ if (target < right) {
+ break; // guard against the unsigned subtraction below.
+ }
+
+ if (can_partition_to_target(left, target - right))
+ return 1;
+ }
+
+ return 0;
+}
+
+int can_partition_to_square ( unsigned int n ) {
+ unsigned long n2 = n;
+ n2 *= n2;
+ return can_partition_to_target(n2, n);
+}
+
+void print_all_that_can_partition ( ) {
+ const unsigned int limit = 1000000 + 1; // 1M = 5s O0, 0.8s O3
+ printf("Calculating for 0 .. %u\n", limit-1);
+ unsigned int count = 1;
+ for ( unsigned int i = 0 ; i < limit; i++ ) {
+ if ( can_partition_to_square(i) ) {
+ unsigned long square = i;
+ square *= square;
+ printf("%u %lu\n", count++, square);
+ }
+ }
+}
+
+void test_known_good_and_bad ( ) {
+ // From https://oeis.org/A038206/b038206.txt (the b-file for https://oeis.org/A038206/ )
+ // raku -e 'say .fmt("%8d,", "") for lines.map(*.words[1]).batch(10)' b038206.txt
+ const unsigned int b_data[] = {
+ 0, 1, 9, 10, 36, 45, 55, 82, 91, 99,
+ 100, 235, 297, 369, 370, 379, 414, 657, 675, 703,
+ 756, 792, 909, 918, 945, 964, 990, 991, 999, 1000,
+ 1296, 1702, 1782, 2223, 2728, 3366, 3646, 3682, 4132, 4879,
+ 4906, 4950, 5050, 5149, 5292, 6832, 7191, 7272, 7389, 7533,
+ 7543, 7587, 7777, 7956, 8416, 8443, 8767, 8856, 8910, 8938,
+ 9208, 9315, 9325, 9586, 9621, 9640, 9765, 9901, 9909, 9918,
+ 9945, 9955, 9964, 9990, 9991, 9999, 10000, 10512, 12222, 12727,
+ 17271, 17344, 22222, 22231, 25354, 27414, 33669, 34327, 35442, 36558,
+ 36855, 38962, 39420, 41149, 41814, 42643, 45657, 46279, 48790, 48835,
+ 49492, 49563, 49906, 50050, 51454, 52920, 52965, 53415, 57393, 57547,
+ 59284, 62146, 64341, 65242, 67132, 68428, 69058, 69157, 69669, 72612,
+ 74647, 75331, 76851, 77121, 77716, 77778, 77896, 79516, 81118, 82045,
+ 82620, 82656, 85212, 85941, 87571, 88768, 88812, 88813, 89632, 90819,
+ 91756, 93402, 93574, 94141, 94581, 95121, 97137, 99055, 99226, 99244,
+ 99343, 99559, 99630, 99631, 99703, 99765, 99900, 99901, 99909, 99918,
+ 99945, 99955, 99964, 99990, 99991, 99999, 100000, 104878, 105112, 105382,
+ 117343, 122221, 130050, 131959, 140050, 142857, 143532, 148149, 163567, 167832,
+ 172827, 181819, 187110, 203274, 208495, 215829, 249832, 275725, 283924, 304930,
+ 310339, 316728, 318682, 319176, 320050, 329967, 333666, 336699, 336700, 336799,
+ 338760, 339453, 344143, 349785, 351352, 352693, 354393, 356329, 356643, 357796,
+ 364420, 364932, 369261, 369792, 370017, 370134, 370153, 383581, 389620, 389665,
+ 390313, 410050, 417330, 417340, 419860, 428419, 434331, 440874, 441217, 452133,
+ 452241, 461539, 463284, 466830, 471537, 473967, 474067, 482608, 490050, 499321,
+ 499500, 499906, 500050, 500500, 501499, 512811, 514926, 524638, 529200, 529650,
+ 532917, 533170, 534150, 536284, 538461, 549459, 551025, 552745, 561781, 571464,
+ 584308, 584452, 596619, 600633, 609687, 627372, 627615, 639739, 642078, 643357,
+ 643672, 647029, 648648, 649782, 656244, 668332, 670033, 670050, 673651, 675037,
+ 681318, 684099, 689778, 695071, 697834, 713241, 719280, 736687, 739863, 751249,
+ 754821, 758475, 758863, 760050, 770050, 780697, 784297, 789589, 790372, 791505,
+ 791757, 792684, 795484, 798741, 804241, 805014, 810819, 811305, 812890, 818181,
+ 825886, 826074, 831672, 831718, 834166, 836127, 836172, 847629, 849520, 850546,
+ 851851, 852165, 852517, 853542, 853867, 857143, 857151, 860050, 865242, 872146,
+ 877501, 880749, 887824, 888363, 889642, 890046, 906427, 906796, 907740, 908235,
+ 910719, 919180, 920494, 921528, 921969, 929566, 935785, 940050, 945649, 945819,
+ 948411, 949231, 951049, 951210, 952335, 955351, 961038, 961039, 968256, 968760,
+ 969669, 977769, 987391, 989901, 990099, 991144, 991233, 991584, 992467, 992611,
+ 993168, 994482, 994708, 994851, 994950, 996634, 998218, 998298, 998704, 999001,
+ 999009, 999010, 999036, 999055, 999082, 999091, 999208, 999244, 999297, 999325,
+ 999343, 999586, 999621, 999630, 999631, 999703, 999765, 999900, 999901, 999909,
+ 999918, 999945, 999955, 999964, 999990, 999991, 999999, 1000000, 1005291, 1020304,
+ 1038961, 1050957, 1051219, 1051246, 1074277, 1091197, 1100412, 1142856, 1148148, 1181818,
+ 1187109, 1208494, 1226341, 1269918, 1300050, 1308385, 1318681, 1327150, 1329966, 1351351,
+ 1356642, 1356966, 1390312, 1400050, 1461556, 1465093, 1635670, 1637694, 1643356, 1648647,
+ 1670032, 1673820, 1681317, 1743966, 1782756, 1839601, 1865286, 1885869, 1907740, 1939572,
+ 1952335, 2020446, 2026458, 2050624, 2078650, 2137338, 2307178, 2310894, 2371437, 2499832,
+ 2579391, 2604583, 2671615, 2853469, 2866581, 3002454, 3022650, 3089872, 3100050, 3113829,
+ 3161196, 3200050, 3212668, 3217347, 3245374, 3274641, 3336669, 3385530, 3441430, 3463786,
+ 3469105, 3505617, 3558340, 3563335, 3582712, 3688597, 3696300, 3701197, 3701439, 3701493,
+ 3701511, 3701529, 3701538, 3701556, 3704572, 3706354, 3718026, 3733273, 3848823, 3951549,
+ 3980251, 3996541, 4042872, 4042945, 4100050, 4119966, 4126186, 4129218, 4158487, 4173408,
+ 4187152, 4188303, 4221874, 4235842, 4238092, 4241512, 4292892, 4327867, 4395952, 4444444,
+ 4454721, 4501611, 4522222, 4531275, 4647403, 4748131, 4776651, 4803624, 4811248, 4857786,
+ 4894741, 4900050, 4927941, 4933045, 4983471, 4994298, 4999321, 4999906, 5000050, 5000500,
+ 5002236, 5020921, 5050207, 5053222, 5072059, 5086756, 5088763, 5136570, 5160286, 5236911,
+ 5246299, 5246388, 5253841, 5325228, 5364109, 5375736, 5401342, 5403277, 5413599, 5413644,
+ 5467509, 5479453, 5527414, 5555556, 5642469, 5725882, 5881159, 5900050, 5913171, 5960503,
+ 5973543, 6038983, 6045957, 6089778, 6104179, 6110766, 6188590, 6193701, 6209829, 6276150,
+ 6276195, 6296382, 6308848, 6310809, 6313726, 6337458, 6364341, 6449409, 6472999, 6480945,
+ 6530931, 6538644, 6557176, 6582241, 6595596, 6597019, 6607629, 6643242, 6651253, 6671332,
+ 6682087, 6700050, 6721363, 6727312, 6728805, 6742954, 6780618, 6784767, 6790248, 6832513,
+ 6844213, 6844221, 6844240, 6844285, 6848127, 6851323, 6905836, 6911361, 6938254, 6942744,
+ 6946722, 6978376, 7006708, 7032546, 7050178, 7053868, 7080048, 7117381, 7198741, 7205950,
+ 7223247, 7235830, 7333030, 7373593, 7395418, 7398639, 7412472, 7428151, 7449661, 7474941,
+ 7505244, 7513156, 7533478, 7556041, 7558939, 7588017, 7588639, 7588675, 7588683, 7588720,
+ 7600050, 7601985, 7657929, 7700050, 7757416, 7812540, 7834429, 7854165, 7869421, 7895935,
+ 7915834, 7987374, 7987411, 7997292, 7997374, 8007372, 8040403, 8047666, 8049780, 8085843,
+ 8092261, 8112412, 8161912, 8187265, 8199280, 8210592, 8235505, 8239077, 8263314, 8285985,
+ 8286633, 8356771, 8365158, 8416269, 8416746, 8454852, 8492635, 8499294, 8514567, 8526069,
+ 8537293, 8566129, 8600050, 8605143, 8647111, 8659207, 8709850, 8710398, 8757144, 8770797,
+ 8773371, 8835490, 8878248, 8880309, 8881516, 8881524, 8903242, 8967736, 8971606, 8994411,
+ 9050922, 9064486, 9078031, 9083169, 9122499, 9127863, 9142849, 9149464, 9186903, 9189181,
+ 9360261, 9367155, 9372385, 9400050, 9417582, 9428554, 9432891, 9450541, 9453807, 9454869,
+ 9455464, 9455581, 9457704, 9457974, 9458227, 9458235, 9472536, 9495828, 9565336, 9610380,
+ 9625537, 9634843, 9639450, 9666999, 9674541, 9677808, 9685485, 9685540, 9688618, 9693766,
+ 9726112, 9745488, 9785781, 9835263, 9869077, 9873955, 9878679, 9879210, 9898956, 9898983,
+ 9898984, 9912429, 9922879, 9923149, 9942453, 9944820, 9947080, 9949617, 9951165, 9969669,
+ 9990360, 9990685, 9991062, 9991090, 9991557, 9992044, 9992413, 9992457, 9992611, 9992809,
+ 9995094, 9995868, 9996318, 9996354, 9997272, 9997777, 9998218, 9998298, 9998704, 9999000,
+ 9999001, 9999009, 9999010, 9999036, 9999055, 9999082, 9999091, 9999208, 9999244, 9999297,
+ 9999325, 9999343, 9999586, 9999621, 9999630, 9999631, 9999703, 9999765, 9999900, 9999901,
+ 9999909, 9999918, 9999945, 9999955, 9999964, 9999990, 9999991, 9999999,10000000,10122634,
+ 10273807,10300050,10379196,10400050,10512487,10627614,10656712,11004535,11111112,11200050,
+ 11300050,11336284,11451861,11786094,11881909,12100050,12200050,12966481,13000050,13100050,
+ 13165273,13165794,13641364,13798963,13809060,13809105,13900050,14000050,14649417,14650677,
+ 14650966,14776651,14800050,14882481,14900050,15700050,15800050,15940143,16486858,16590564,
+ 16600050,16678332,17600050,17645401,17645446,17793918,17827722,17938611,18181909,18400050,
+ 18453142,19273023,19300050,19400050,19440729,19773073,20300050,20644767,20658195,21091591,
+ 21200050,22056795,22100050,22385763,22633227,22692780,22866256,23102074,23358582,23493052,
+ 23502132,23714370,23800050,23900050,24459039,24700050,24752475,24800050,24944437,24999832,
+ 25027435,25252525,25389235,25545132,25600050,25700050,25947244,26126856,26436672,26600050,
+ 26670888,26695872,27099685,27342910,27400050,27500050,27684423,27798912,27843822,28137870,
+ 28141398,28300050,28400050,28487160,28788688,28970497,29200050,29330757,29375794,30200050,
+ 30600775,30884184,31000050,31033891,31100050,31591638,31603032,31900050,31958091,32000050,
+ 32000500,32126724,32126725,32192442,32461758,32800050,32900050,33216444,33336666,33366699,
+ 33366700,33524587,33602365,33605595,33650208,33664473,33700050,33800050,33813910,34192972,
+ 34600050,34700050,34910290,35144227,35144613,35144622,35144623,35500050,35546508,35600050,
+ 35602578,35851897,35941833,36175969,36212733,36240849,36271765,36363636,36400050,36487873,
+ 36496351,36500050,36792379,36942346,36943426,37015344,37015497,37015507,37015534,37015551,
+ 37015588,37015605,37015606,37206577,37300050,37466470,37605060,37630963,37651212,37918674,
+ 37919908,38097144,38178298,38200050,38267586,38440180,38883889,39100050,39142549,39200050,
+ 39451735,39527146,39565081,39802510,39825604,40057966,40100050,40140784,40229371,40427766,
+ 40458258,40503123,40503124,40546944,40900050,40913937,41000050,41159628,41186799,41228317,
+ 41608764,41734081,41800050,41884534,41900050,42229090,42476436,42584338,42616774,42700050,
+ 42783499,42800050,42894478,43033887,43046487,43064406,43091712,43365232,43497451,43600050,
+ 43795621,43855894,43923007,44091856,44345512,44363341,44365158,44434710,44500050,44525548,
+ 44659440,44685064,44859943,44871426,45027217,45224146,45224154,45268822,45400050,45403237,
+ 45436267,45501039,45512037,45534897,45559791,45776170,46179405,46300050,46400050,46886859,
+ 47200050,47300050,47406816,47406817,47428623,47494576,47514915,47943649,48100050,48419874,
+ 48435058,48461166,48502422,48516508,48949453,49000050,49000500,49100050,49106935,49315159,
+ 49995000,49999321,49999906,50000050,50000500,50005000,50014999,50502483,50537169,50589036,
+ 50672124,50728222,50729868,50765491,50787433,50800050,50900050,50955382,51120946,51333525,
+ 51456177,51492646,51800050,52131772,52299423,52315822,52463925,52463926,52824204,53252280,
+ 53500050,53863462,54500050,54794530,54794575,54870346,54922159,55012041,55274022,55274185,
+ 55300050,55314523,55400050,55474452,55499059,55636659,56076525,56200050,56478870,56502550,
+ 57200050,57321306,57347542,57347587,57424509,57511521,57669462,57754459,57768138,57789081,
+ 57860676,58100050,58236894,58569229,58811490,58811661,58811662,58900050,59000050,59066866,
+ 59334588,59509377,59715756,59775913,59800050,59889366,59900050,59973543,59977809,60421735,
+ 60469866,60548275,60632632,60885352,60913854,61116111,61758936,61785324,61884262,62017713,
+ 62146161,62165341,62174124,62326746,62388477,62500050,62526996,62584632,62606917,62647128,
+ 62838568,62850321,62951967,62951977,63013699,63099865,63184932,63305505,63400050,63411642,
+ 63554319,63636364,64284246,64300050,64354249,64400050,64934532,64968273,65088469,65200050,
+ 65300050,65522566,65606140,65816911,66062592,66076291,66100050,66200050,66224727,66307338,
+ 66683332,67000050,67309489,67568283,67639401,67690972,67900050,68000500,68195908,68325130,
+ 68422834,68427631,68427676,68442211,68442588,68442768,68442814,68442858,68442867,68442876,
+ 68442885,68460543,68707944,68800050,68900050,69042771,69058368,69058369,69115816,69200632,
+ 69399226,69431220,69589647,69783832,69800050,69903720,70192728,70207389,70224121,70275214,
+ 70406254,70501717,70578991,70653384,71025120,71157934,71408521,71408943,71500050,71534224,
+ 71600050,72230347,72400050,72448839,72500050,72697780,72900316,72902188,72973828,73052929,
+ 73084635,73194517,73258471,73670661,73692603,73875223,73889172,74002527,74060271,74200050,
+ 74261313,74300050,74747475,75012499,75200050,75247525,75297762,75517399,75655954,75695158,
+ 75725343,75748582,75868291,75870334,75887164,75887190,75887208,75887227,75919851,76000050,
+ 76050954,76072834,76094064,76100050,76168810,76294152,76550779,76900050,77000050,77014107,
+ 77098077,77151285,77607846,77800050,77813748,77900050,77961277,78092892,78126768,78340716,
+ 78541695,78604047,78800050,78941610,79226209,79241625,79600050,79611264,79652035,79700050,
+ 79719039,79785837,80137882,80226927,80500050,80501562,80546310,80548462,80628877,80692507,
+ 80726977,80854776,80888059,80982028,80987536,81004122,81015067,81354664,81413397,81500050,
+ 81528003,81530569,81570924,81619120,81619165,81872695,82110159,82207755,82269234,82512127,
+ 82620307,82620864,82620865,82875132,82993122,83200050,83287206,83341666,83409436,83417760,
+ 83476629,83567683,83665791,83773017,84100050,84167496,84229317,84367314,84766059,84894516,
+ 84916719,85045329,85127464,85196943,85223350,85338667,85354281,85431511,85617459,85661290,
+ 85694554,85797639,85807098,85824289,85898718,85918257,85925449,85941495,86000050,86332455,
+ 86358636,86501871,86763285,86800050,86900050,86977351,87072337,87103935,87369831,87452127,
+ 87457104,87657724,87685623,87738121,87757551,87785767,87914044,88047666,88251067,88418430,
+ 88668765,88693228,88760071,88814826,88815223,88881354,88888888,88975242,89044956,89353278,
+ 89362576,89500050,89600050,89877366,89944074,90148762,90161056,90197965,90230761,90233802,
+ 90271054,90311382,90356329,90400050,90500050,90773937,90872137,90909091,91051948,91096758,
+ 91229203,91311507,91312174,91556352,91838088,91865044,92200050,92224179,92244349,92491785,
+ 92713815,92776338,93135636,93215233,93385143,93430953,93527001,93546028,93723850,93858328,
+ 93961017,93969702,94000050,94124449,94231539,94368340,94444444,94463191,94520547,94581910,
+ 94582332,94582341,94649608,94840740,94979079,95010499,95136570,95475600,95660632,95757894,
+ 96209829,96285511,96303421,96417928,96434659,96449409,96460344,96590160,96641937,96683968,
+ 96800050,96937803,97006708,97045335,97106229,97289515,97370685,97628482,97689546,97790797,
+ 97909407,98029602,98053722,98101891,98157942,98182576,98409466,98500050,98535628,98637067,
+ 98637112,98640073,98989425,98990100,99031240,99048951,99093204,99109954,99127854,99150480,
+ 99470800,99496098,99500050,99510049,99526033,99583129,99610335,99661240,99663201,99725824,
+ 99789768,99868041,99900441,99900774,99904950,99906426,99908244,99910368,99914059,99918882,
+ 99920484,99927388,99930331,99934758,99935659,99946585,99947035,99948546,99949950,99950508,
+ 99953721,99954343,99958851,99964558,99965673,99966331,99972586,99974646,99982729,99987273,
+ 99987778,99989488,99990001,99990009,99990010,99990036,99990045,99990055,99990082,99990091,
+ 99990099,99990235,99990360,99990379,99990414,99990675,99990685,99990792,99991062,99991090,
+ 99991144,99991233,99991557,99991584,99992044,99992223,99992413,99992457,99992467,99992611,
+ 99992728,99992809,99993168,99994708,99994851,99994950,99995050,99995094,99995121,99995868,
+ 99996318,99996354,99996634,99997272,99997777,99998218,99998298,99998704,99999000,99999001,
+ 99999009,99999010,99999036,99999055,99999082,99999091,99999208,99999244,99999297,99999325,
+ 99999343,99999586,99999621,99999630,99999631,99999703,99999765,99999900,99999901,99999909,
+ 99999918,99999945,99999955,99999964,99999990,99999991,99999999,100000000,100490049,100698067,
+ 103000050,104000050,104306860,105124887,105124914,105124915,105382053,105479452,107149762,107667549,
+ 108161911,108289477,108401157,108402417,111111111,111111120,112000050,113000050,113641363,114518637,
+ 116590563,118776808,119273022,119773072,121000050,122000050,123456799,124018597,124752474,125252524,
+ 125941492,126935785,129306339,129559528,130000050,130884183,131000050,133271650,134664642,136363635,
+ 138341394,138883888,139000050,140000050,142406928,144705187,146509614,146509651,146509686,146509713,
+ 148000050,149000050,150382972,152091918,152158330,152597908,152728686,154478287,155504196,155835234,
+ 157000050,157303017,157881114,158000050,160030332,160466869,160474797,160863346,163636363,165655234,
+ 166000050,166738320,169115815,170178354,170857593,174118959,176000050,178277220,178277229,179726436,
+ 180356364,181152693,181305855,181709028,182806408,184000050,185881303,187015753,189519318,190306611,
+ 193000050,193180807,194000050,195407767,197653599,198967834,200500624,200606635,201296124,202022776,
+ 202230567,203000050,203000500,205060141,205062489,205062490,206581995,207101188,207514036,207642772,
+ 207950013,210262348,211000050,212000050,212632623,215456598,216570871,217619433,220567950,220617783,
+ 221000050,221172381,221882706,228324951,228535633,228662631,229000050,229000500,230917933,232068357,
+ 234567901,235021320,237143719,238000050,238868316,238982140,239000050,239303655,239379184,240569496,
+ 241302429,241470361,241986988,242267877,243902440,244929061,245406888,246126484,246601837,247000050,
+ 248000050,248469814,249999832,250593796,252314334,252544357,254532223,254842525,256000050,256188528,
+ 257000050,259344063,260987391,261308106,262436067,264787930,266000050,267718924,269622369,270789732,
+ 271234071,272362933,272878597,274000050,275000050,275912289,277538743,280315405,281652561,283000050,
+ 283638807,284000050,286856856,290305729,291939256,292000050,292815900,294402690,294696954,295369182,
+ 297147555,299712951,301000050,301579227,302000050,302928759,303114340,305041654,305041663,305959086,
+ 306807237,307094599,307622871,308104695,308844055,309106504,310000050,311000050,311658733,312030640,
+ 313189660,314987959,315816724,316112868,317697607,318231487,319000050,319645423,320000050,320000500,
+ 320454225,322830270,322990696,324537345,326058777,326183734,327921930,328000050,328730320,328903912,
+ 329000050,329000500,329086989,330724422,331410834,332999667,333366669,333666999,333667000,333667999,
+ 333906183,334065762,335012688,335164384,335457901,335691676,335742993,336254868,336655098,337000050,
+ 338000050,338000500,338668029,338915791,340570864,340680799,340776235,341370774,344976426,346000050,
+ 347000050,348531094,351403372,351446238,351902233,352208511,352623528,353332044,354225402,354309795,
+ 354687957,354789154,355000050,355997691,355999438,356000050,356025780,356870943,356870944,357616881,
+ 358429518,358658425,359102025,359647174,360154800,361157796,361372456,362408490,363175389,363195441,
+ 364000050,364604526,365000050,365191992,365253841,365326776,365589793,365900265,366656059,367117921,
+ 367332733,368687359,369102844,370120428,370154385,370154979,370155430,370155474,370155834,370155844,
+ 370155916,370155960,370155970,370155978,370156068,370156078,370156104,370156122,370156123,370156158,
+ 370156159,370156167,370156168,370156176,370156185,370156186,370156194,370156195,370156203,370156204,
+ 370320175,370894779,373000050,373327371,373327372,373435047,373656079,375334669,376544916,378428643,
+ 378713331,379188441,379199133,379199142,379568844,379973647,380201707,381253509,381898089,382000050,
+ 383081634,383906115,383906116,386505505,387272322,387348337,387878058,388610479,390434428,391000050,
+ 391032604,391347306,391457719,391914523,392000050,392330223,392330602,393242068,393800436,394131213,
+ 394200711,395025787,395655832,397213282,398677798,399248352,399248353,399513384,400451221,400705975,
+ 401000050,401157325,401748364,402442299,402442344,405031014,405031203,405031239,405031240,405031248,
+ 405410706,405468540,405780697,406135846,406866915,407218509,408367584,408899169,409000050,409000500,
+ 409806028,410000050,413018317,414182827,414244782,414317854,417003606,417078135,417340810,417340873,
+ 417662263,418000050,418000500,419000050,419426956,419692707,419945472,420023836,421127551,422042337,
+ 423061984,423739693,424539756,424582812,425138229,425635866,425940930,426078171,427000050,427000500,
+ 427114873,427133133,427394530,428000050,428110299,428534181,429293521,429293529,429293530,429933708,
+ 430464915,432432432,436000050,440918407,440918568,440918569,441946198,442017018,442088326,443882241,
+ 444532501,444572218,445000050,445021911,445021912,445380786,445472190,448830513,450082764,450922888,
+ 452241531,453748887,454000050,455372983,455472801,458757504,459054963,459341478,461244105,461395125,
+ 461706535,463000050,463281832,464000050,464000500,464564277,466275934,469730745,472000050,472172868,
+ 472784806,472889764,473000050,473000500,473194278,474068116,474068214,474068223,474068224,474336108,
+ 475427016,475444684,476636166,477993717,479509624,479841624,480421486,481000050,481191319,481241709,
+ 481329909,484449841,485278119,485326332,487311489,487594864,488355066,489576241,489743784,490000050,
+ 490000500,490398202,491000050,491000500,491936428,492275251,492909778,493155648,494923455,495463707,
+ 496336816,496994256,497078785,497723869,498756015,499000050,499000500,499549752,499859955,499991094,
+ 499994298,499999321,499999906,500000050,500000500,500005000,500532966,502010100,502835049,502921216,
+ 503215903,503300656,503491302,504331669,504483732,505024966,505949661,506121039,507591711,508000050,
+ 508074454,508085434,508325733,508436488,508437054,509000050,509554899,509720607,510402196,511086366,
+ 511524648,512215894,514926154,514926378,514926424,515004516,515025730,515863854,516109257,516328542,
+ 518000050,518156721,518282875,518795758,519087573,519152275,519794721,520776819,521076843,521445313,
+ 521608428,521724565,522036432,522994258,524094687,524549764,524610775,524904661,525239424,525609414,
+ 528586183,528610357,534173878,534211057,534647403,535000050,535026637,535740139,536224042,536322466,
+ 538164973,539615971,539944390,540540549,543539664,543539691,544211856,544559049,544559050,544953709,
+ 545000050,545210955,545477293,547309153,547498630,550045494,551675223,552745378,553000050,553341771,
+ 554000050,556280721,557892172,558233245,558265123,558876061,558905013,558968734,560231002,560256598,
+ 560661030,561748213,561798882,561883050,562000050,562179114,562211145,562366639,562660516,563253202,
+ 563267224,563432643,563527747,564321727,565301071,567567568,568282338,568617346,569259981,569522727,
+ 571000050,571464315,571472839,571472884,571852792,572000050,573616225,574315110,575286138,577376137,
+ 579463102,579477961,579478014,580394727,580712662,581000050,581427676,581448070,584581770,585990261,
+ 586053415,587015263,588037041,588971628,589000050,589140226,589177044,590000050,590479885,590811949,
+ 591460831,593864155,595093770,595446013,595623888,596629099,596791152,597080142,598000050,599000050,
+ 599104324,600238288,600500206,601613506,602785584,604934748,605479545,607345380,608388103,608502240,
+ 611389522,611875791,611991513,613296801,613296802,615728476,616941603,617088798,617970564,618596685,
+ 618847308,619398108,619518861,619555213,621237538,621461664,621635715,622331281,623028231,623867473,
+ 623884815,624291040,625000050,626599233,627404428,627425487,627547311,628765452,628990452,629519814,
+ 629519815,630229294,630999865,632859094,633967399,634000050,634281777,637010704,637475239,637475292,
+ 637894161,638330607,638482293,639248967,642022894,642951343,643000050,643891636,644000050,644138290,
+ 645263145,645480549,646109793,648194787,648787132,649079848,650884689,652000050,652279347,652431718,
+ 652756896,653000050,653055381,653093352,653755717,653788692,653808367,654241672,657731448,657895914,
+ 658520811,658888614,660711520,660762855,660762856,661000050,661297051,661773025,662000050,663997339,
+ 664053670,664909516,665022249,665188470,666053046,666713332,667000333,667813014,668343798,668343799,
+ 668348911,670000050,671000050,671000500,671096089,671269690,671316372,672273964,672886242,672913035,
+ 673094890,674391375,675173710,675792973,675839026,675845829,675979120,676515097,677102437,677773611,
+ 679000050,679469985,680000500,680229783,680931783,681821703,683463952,683991082,684276760,684421560,
+ 684428374,684428544,684428617,684428806,684428833,684428850,684428851,684428859,684428868,684428869,
+ 685067041,685071099,686794546,687045924,687509091,687516318,688000050,688381317,688917186,689000050,
+ 689642586,690204915,691102792,691155946,691859224,692598439,693965917,694371132,694382419,695857284,
+ 696201264,697838347,697838364,698000050,699157801,699185025,699549823,701285185,701548398,701762193,
+ 702173071,702304930,703323873,704809252,705017817,705017836,705017854,705435849,708035148,709019757,
+ 709370757,710027019,710708581,711133696,711527338,712124452,712791189,713797687,715000050,716000050,
+ 716023917,716768559,717389137,717904701,718082668,719150742,719526754,722901924,723531088,723687562,
+ 723731364,724000050,724039173,725000050,726127489,726127587,726127588,727108642,729003160,729003205,
+ 730460845,730666180,730957815,731884779,732281077,732956446,733003317,733028158,733775274,733890753,
+ 734069979,734812407,737295031,739519759,739636632,739863928,740188314,741626371,742000050,742895794,
+ 743000050,746504839,747455644,747978553,748715481,748760292,748831644,748897390,749148678,751000050,
+ 751224834,751260060,751515237,752000050,752616604,752866209,752911210,753139567,753176817,753342940,
+ 754157854,754157889,754259679,754661637,755329348,756449460,756851418,757253430,758529640,758624913,
+ 758829222,758871216,758871649,758872116,758872234,758872242,758872270,758872278,758872279,758872324,
+ 758872332,758872333,760000050,760765977,761000050,762313437,764365158,764445187,764699085,765432099,
+ 766926784,767631726,768188628,769000050,769265406,770000050,770159719,770244777,770665797,773130699,
+ 773130843,775096830,775653220,778000050,779000050,779472865,779612581,779612805,779612806,779934484,
+ 781250140,782803819,782804448,783443323,784869138,786040965,786923622,788000050,788319658,788598685,
+ 789046444,790579774,791658334,792416637,792648198,794027331,794877220,794911995,795597687,796000050,
+ 796237263,796901517,797000050,797000500,797107087,798151438,798427423,798741090,799227343,801217539,
+ 801590535,802578915,802919854,803248200,804069747,805000050,805015621,805386897,806817214,807345865,
+ 809127982,810150715,810438364,811074277,811241262,811241272,811725823,812453842,813115171,813469779,
+ 813546640,815000050,816444514,817011091,817247638,817487253,817666299,817672806,818424208,819894834,
+ 820692928,821465829,823506787,823641274,824486193,825261921,826154821,826203160,826208343,826208443,
+ 826208541,826208676,826208686,826208694,826208721,826208722,826208731,826561386,827026173,827084125,
+ 827319934,827957673,827957718,828029485,829204938,829421010,829930941,830600641,831508155,832000050,
+ 832872060,833300056,835203618,835677387,835677433,836562348,837074476,838951101,841000050,841674960,
+ 841674961,842781501,843048684,843497451,844675524,845339094,846490806,846669042,847398808,847629811,
+ 847630638,848605671,848680732,849095901,850757608,851000050,851000500,851140324,853542649,853542864,
+ 853660854,853767262,853923528,855102034,855904842,857371411,858577573,859144104,859147245,859357818,
+ 859415004,860000050,861360696,861536926,862163271,863643366,866272995,866766889,867060424,867208672,
+ 867679479,868000050,868831831,869000050,871039819,871039836,873913780,873954225,875142927,876432699,
+ 876463146,876793888,876794085,877482585,878631822,881661241,883819432,883890199,885396340,886502395,
+ 886926834,886926879,887066551,887738068,887816917,888114178,888148342,888152131,888152202,888152256,
+ 888152419,888152454,888152517,888152634,888152670,888152679,888152680,888152715,888152724,888152725,
+ 888190228,888394239,888888880,888888889,890345377,890631847,891394867,891701704,892594521,893833380,
+ 895000050,895153032,895932532,896000050,896114719,896375835,896602807,898619095,898831926,899821648,
+ 900782442,902338020,902502739,902684493,904000050,904735702,905000050,905013874,905833818,906549111,
+ 907055164,907133239,909090909,910411111,910552275,910994508,913935240,914337351,915349779,915563520,
+ 915673518,916280479,916520139,916607422,916946938,918380880,918984934,919102275,919901817,920282715,
+ 921382614,922000050,923563116,924588874,924591394,924766174,925888834,926023707,926482608,926783029,
+ 926854318,927099685,928704942,929061189,929472715,931652775,931851883,933588289,933995682,934020019,
+ 934192972,934516449,935146134,935624691,936052138,937669608,937762560,938219814,938267586,939307933,
+ 940000050,940808295,942613084,942885621,943065676,943096213,943170156,943386760,944176681,944295732,
+ 944458183,944725870,945205470,945510156,945773182,945786141,945823195,945823222,945823402,945823491,
+ 945823582,945823600,945823609,945823627,945823635,945823636,946544526,948411279,948411360,949000050,
+ 949463578,949928392,951594426,951666228,952340454,952452540,953108236,953693740,953696107,953884368,
+ 953901460,954001044,955337896,956175966,956204379,956315619,956665018,957770911,958000500,958173166,
+ 958952296,958952304,959993676,960258312,960689493,960850224,961951492,964179334,964346590,966303522,
+ 966503836,967454109,968000050,969378031,970224121,970497280,970854004,970977393,971448976,971618356,
+ 972917460,972973828,973139112,974153043,974548827,974548863,974972665,976562838,977056687,977868037,
+ 979692228,979692246,979692255,981273727,982783792,983732679,983733993,983894815,984224782,985000050,
+ 985385907,986371120,986907735,986980177,987246648,988204069,989898471,990037368,990208054,990504172,
+ 990527464,990554923,990556696,990632845,992002708,992675521,992794050,992944081,993723805,994083588,
+ 995000050,995873814,996182695,996242752,996886171,998134714,998256034,998498116,998513730,998538444,
+ 998773659,999000999,999031501,999038961,999149454,999165834,999173926,999195759,999204516,999210411,
+ 999280720,999286759,999310222,999331668,999352971,999357922,999372628,999428536,999498501,999499500,
+ 999580140,999635068,999666334,999716076,999724275,999784171,999827173,999832168,999856468,999859950,
+ 999869950,999900774,999902863,999905419,999905859,999906598,999909181,999911187,999911188,999911232,
+ 999914059,999914788,999917380,999917955,999922104,999922284,999924669,999925353,999930843,999930942,
+ 999931572,999932868,999937854,999940716,999942607,999950094,999950437,999957357,999958186,999960580,
+ 999963145,999963442,999964396,999965673,999966331,999972586,999974646,999977769,999977778,999982656,
+ 999982729,999987273,999987778,999989488,999990000,999990001,999990009,999990010,999990036,999990045,
+ 999990055,999990082,999990091,999990099,999990235,999990360,999990379,999990414,999990675,999990685,
+ 999990792,999991062,999991090,999991144,999991233,999991557,999991584,999992044,999992223,999992413,
+ 999992457,999992467,999992611,999992728,999992809,999993168,999994708,999994851,999994950,999995050,
+ 999995094,999995121,999995868,999996318,999996354,999996634,999997272,999997777,999998218,999998298,
+ 999998704,999999000,999999001,999999009,999999010,999999036,999999055,999999082,999999091,999999208,
+ 999999244,999999297,999999325,999999343,999999586,999999621,999999630,999999631,999999703,999999765,
+ 999999900,999999901,999999909,999999918,999999945,999999955,999999964,999999990,999999991,999999999,
+ 1000000000,1003000050,1004000050,1005012487,1012000050,1013000050,1020658195,1021000050,1022000050,1028956744,
+ };
+ const unsigned int b_data_last_index = sizeof(b_data) / sizeof(unsigned int) - 1;
+ const unsigned int last_number = b_data[b_data_last_index];
+
+ // Check every b038206 number to make sure it can partition.
+ int all_good_tests_OK = 1;
+ for ( const unsigned int *b = &b_data[0] ; b <= &b_data[b_data_last_index] ; ++b ) {
+ unsigned int known_good = *b;
+ if (can_partition_to_square(known_good) != 1) {
+ printf("Bad known_good: %d\n", known_good);
+ all_good_tests_OK = 0;
+ }
+ }
+ if (all_good_tests_OK) {
+ printf("All %d tests (through %u) of known-good numbers returned True as expected\n",
+ b_data_last_index+1, last_number);
+ }
+
+ // Check a number on either side of every b038206 number (except when that neighbor is also in b038206) to make sure it cannot partition.
+ int all_bad_tests_OK = 1;
+ int bad_test_count = 0;
+ for ( const unsigned int *b = &b_data[1] ; b < &b_data[b_data_last_index] ; ++b ) {
+ unsigned int this = *b;
+ unsigned int last = *(b-1);
+ unsigned int next = *(b+1);
+ unsigned int this_minus_one = this - 1;
+ unsigned int this_plus_one = this + 1;
+
+ if ( this_minus_one != last ) {
+ bad_test_count++;
+ if ( can_partition_to_square(this_minus_one) != 0) {
+ printf("Good known_bad: %d\n", this_minus_one);
+ all_bad_tests_OK = 0;
+ }
+ }
+ if (this_plus_one != next) {
+ bad_test_count++;
+ if ( can_partition_to_square(this_plus_one) != 0) {
+ printf("Good known_bad: %d\n", this_plus_one);
+ all_bad_tests_OK = 0;
+ }
+ }
+ }
+ if (all_bad_tests_OK) {
+ printf("All %d tests (through %u) of known-good numbers ±1 returned False as expected\n",
+ bad_test_count, last_number);
+ }
+
+}
+
+int main ( int argc, char *argv[] ) {
+ unsigned int arg_count = argc - 1;
+
+ if (arg_count == 0) {
+ test_known_good_and_bad();
+ }
+ else if (arg_count == 1 && argv[1][0] == '-') {
+ print_all_that_can_partition();
+ }
+ else {
+ for ( int arg_n = 1 ; arg_n < argc ; ++arg_n ) {
+ unsigned int arg = atol(argv[arg_n]);
+ printf("%d : %d\n", arg, can_partition_to_square(arg));
+ }
+ }
+ return 0;
+}
diff --git a/challenge-138/bruce-gray/perl/ch-1.pl b/challenge-138/bruce-gray/perl/ch-1.pl
new file mode 100644
index 0000000000..8a40cfb3f7
--- /dev/null
+++ b/challenge-138/bruce-gray/perl/ch-1.pl
@@ -0,0 +1,32 @@
+use Modern::Perl;
+use 5.026;
+use experimental qw<signatures>;
+use DateTime;
+
+sub is_working_day ($date) {
+ my $day = $date->day_of_week;
+ return !($day == 6 or $day == 7);
+}
+sub working_days_in_year ($year) {
+ my $d = DateTime->new(year => $year);
+
+ my $working_days_count = 0;
+ for (1 .. $d->year_length) {
+ $working_days_count++ if is_working_day($d);
+ $d->add(days => 1);
+ }
+ return $working_days_count;
+}
+
+use Test::More;
+my @tests = (
+ [ 2021, 261 ],
+ [ 2020, 262 ],
+);
+plan tests => 0+@tests;
+
+for (@tests) {
+ my ($input_year, $expected) = @{$_};
+ is working_days_in_year($input_year), $expected,
+ "working_days_in_year($input_year) == $expected";
+}
diff --git a/challenge-138/bruce-gray/perl/ch-2.pl b/challenge-138/bruce-gray/perl/ch-2.pl
new file mode 100644
index 0000000000..ff16eb3237
--- /dev/null
+++ b/challenge-138/bruce-gray/perl/ch-2.pl
@@ -0,0 +1,78 @@
+use strict;
+use warnings;
+use 5.026;
+
+use experimental qw<signatures>;
+use ntheory qw<forcomp>;
+use List::Util qw<sum>;
+use Test::More;
+
+use Memoize;
+memoize('templates_for_size');
+
+# templates_for_size(3) returns ['a1 a1 a1', 'a1 a2', 'a2 a1', 'a3']
+sub templates_for_size ( $size ) {
+ my @r;
+
+ forcomp { push @r, join ' ', map "a$_", @_ } $size;
+
+ return \@r;
+}
+
+# partition_sums(789) returns (24, 96, 87, 789) because '7'+'8'+'9'=24, '7'+'89'=96, '78'+'9'=87, and '789'=789
+sub partition_sums ( $n ) {
+ my $unpack_templates_aref = templates_for_size(length $n);
+
+ return map { sum unpack $_, $n } @{$unpack_templates_aref};
+}
+
+sub can_partition_to_sqrt ( $n ) {
+ my $r = int sqrt $n;
+ die "$n is not a perfect square" if $r ** 2 != $n;
+
+ return 0 + !! grep { $_ == $r } partition_sums($n);
+}
+
+
+my @tests = (
+ # From examples in task description:
+ [ 81, 1 ],
+ [ 9801, 1 ],
+ [ 36, 0 ],
+
+ # Regression tests
+ [ 72 ** 2, 0 ],
+
+ [ 36 ** 2, 1 ], # 36² == 1296, 1+29+6 == 36. Finds single-sided insufficient algorithms.
+ [ 165607 ** 2, 0 ],
+
+ # From the far edge of https://oeis.org/A038206/b038206.txt :
+ [ 1028956743 ** 2, 0 ],
+ [ 1028956744 ** 2, 1 ],
+ [ 1028956745 ** 2, 0 ],
+
+);
+
+
+use constant USE_LONG_TESTS => 1;
+plan tests => @tests + (USE_LONG_TESTS ? 2 : 0);
+
+for (@tests) {
+ my ( $input, $expected ) = @{$_};
+ is can_partition_to_sqrt($input), $expected,
+ "can_partition_to_sqrt($input) == $expected";
+}
+
+if (USE_LONG_TESTS) {
+ # The squares for which can-partition-to-sqrt returns True are an OEIS sequence.
+ # The square-roots of those squares are also an OEIS sequence.
+ # Test all the elements given on the OEIS web pages. (49 elements, and 35 elements).
+ use constant