1*37da2899SCharles.Forsythimplement Powers; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsythinclude "draw.m"; 6*37da2899SCharles.Forsythinclude "arg.m"; 7*37da2899SCharles.Forsythinclude "lock.m"; 8*37da2899SCharles.Forsyth lockm: Lock; 9*37da2899SCharles.Forsyth Semaphore: import lockm; 10*37da2899SCharles.Forsyth 11*37da2899SCharles.ForsythPowers: module 12*37da2899SCharles.Forsyth{ 13*37da2899SCharles.Forsyth init: fn(nil: ref Draw->Context, nil: list of string); 14*37da2899SCharles.Forsyth}; 15*37da2899SCharles.Forsyth 16*37da2899SCharles.ForsythMAXNODES: con (1<<20)/4; 17*37da2899SCharles.Forsyth 18*37da2899SCharles.Forsythverbose: int; 19*37da2899SCharles.Forsyth 20*37da2899SCharles.Forsyth# Doing 21*37da2899SCharles.Forsyth# powers -p 3 22*37da2899SCharles.Forsyth# gives 23*37da2899SCharles.Forsyth# [2] 1729 = 1**3 + 12**3 = 9**3 + 10**3 24*37da2899SCharles.Forsyth# [2] 4104 = 2**3 + 16**3 = 9**3 + 15**3 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth# ie 1729 can be written in two ways as the sum of 2 cubes as can 4104. 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth# The options are 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth# -p the power to use - default 2 31*37da2899SCharles.Forsyth# -n the number of powers summed - default 2 32*37da2899SCharles.Forsyth# -f the minimum number of ways found before reporting it - default 2 33*37da2899SCharles.Forsyth# -l the least number to consider - default 0 34*37da2899SCharles.Forsyth# -m the greatest number to consider - default 8192 35*37da2899SCharles.Forsyth 36*37da2899SCharles.Forsyth# Thus 37*37da2899SCharles.Forsyth# pow -p 4 -n 3 -f 3 -l 0 -m 1000000 38*37da2899SCharles.Forsyth# gives 39*37da2899SCharles.Forsyth# [3] 811538 = 12**4 + 17**4 + 29**4 = 7**4 + 21**4 + 28**4 = 4**4 + 23**4 + 27**4 40*37da2899SCharles.Forsyth 41*37da2899SCharles.Forsyth# ie fourth powers, 3 in each sum, minimum of 3 representations, numbers from 0-1000000. 42*37da2899SCharles.Forsyth 43*37da2899SCharles.Forsyth# [2] 25 44*37da2899SCharles.Forsyth# [3] 325 45*37da2899SCharles.Forsyth# [4] 1105 46*37da2899SCharles.Forsyth# [5] 4225 47*37da2899SCharles.Forsyth# [6] 5525 48*37da2899SCharles.Forsyth# [7] 203125 49*37da2899SCharles.Forsyth# [8] 27625 50*37da2899SCharles.Forsyth# [9] 71825 51*37da2899SCharles.Forsyth# [10] 138125 52*37da2899SCharles.Forsyth# [11] 2640625 53*37da2899SCharles.Forsyth# [12] 160225 54*37da2899SCharles.Forsyth# [13] 17850625 55*37da2899SCharles.Forsyth# [14] 1221025 56*37da2899SCharles.Forsyth# [15] 1795625 57*37da2899SCharles.Forsyth# [16] 801125 58*37da2899SCharles.Forsyth# [18] 2082925 59*37da2899SCharles.Forsyth# [20] 4005625 60*37da2899SCharles.Forsyth# [23] 30525625 61*37da2899SCharles.Forsyth# [24] 5928325 62*37da2899SCharles.Forsyth# [32] 29641625 63*37da2899SCharles.Forsyth 64*37da2899SCharles.Forsyth# [24] 5928325 = 63**2 + 2434**2 = 94**2 + 2433**2 = 207**2 + 2426**2 = 294**2 + 2417**2 = 310**2 + 2415**2 = 465**2 + 2390**2 = 490**2 + 2385**2 = 591**2 + 2362**2 = 690**2 + 2335**2 = 742**2 + 2319**2 = 849**2 + 2282**2 = 878**2 + 2271**2 = 959**2 + 2238**2 = 1039**2 + 2202**2 = 1062**2 + 2191**2 = 1201**2 + 2118**2 = 1215**2 + 2110**2 = 1290**2 + 2065**2 = 1410**2 + 1985**2 = 1454**2 + 1953**2 = 1535**2 + 1890**2 = 1614**2 + 1823**2 = 1633**2 + 1806**2 = 1697**2 + 1746**2 65*37da2899SCharles.Forsyth 66*37da2899SCharles.Forsyth# [32] 29641625 = 67**2 + 5444**2 = 124**2 + 5443**2 = 284**2 + 5437**2 = 320**2 + 5435**2 = 515**2 + 5420**2 = 584**2 + 5413**2 = 835**2 + 5380**2 = 955**2 + 5360**2 = 1180**2 + 5315**2 = 1405**2 + 5260**2 = 1460**2 + 5245**2 = 1648**2 + 5189**2 = 1795**2 + 5140**2 = 1829**2 + 5128**2 = 1979**2 + 5072**2 = 2012**2 + 5059**2 = 2032**2 + 5051**2 = 2245**2 + 4960**2 = 2308**2 + 4931**2 = 2452**2 + 4861**2 = 2560**2 + 4805**2 = 2621**2 + 4772**2 = 2840**2 + 4645**2 = 3005**2 + 4540**2 = 3035**2 + 4520**2 = 3320**2 + 4315**2 = 3365**2 + 4280**2 = 3517**2 + 4156**2 = 3544**2 + 4133**2 = 3664**2 + 4027**2 = 3715**2 + 3980**2 = 3803**2 + 3896**2 67*37da2899SCharles.Forsyth 68*37da2899SCharles.Forsyth# [2] 1729 = 1**3 + 12**3 = 9**3 + 10**3 69*37da2899SCharles.Forsyth# [2] 4104 = 2**3 + 16**3 = 9**3 + 15**3 70*37da2899SCharles.Forsyth# [3] 87539319 = 167**3 + 436**3 = 228**3 + 423**3 = 255**3 + 414**3 71*37da2899SCharles.Forsyth 72*37da2899SCharles.Forsyth# [2] 635318657 = 59**4 + 158**4 = 133**4 + 134**4 73*37da2899SCharles.Forsyth# [2] 3262811042 = 7**4 + 239**4 = 157**4 + 227**4 74*37da2899SCharles.Forsyth# [2] 8657437697 = 193**4 + 292**4 = 256**4 + 257**4 75*37da2899SCharles.Forsyth# [2] 68899596497 = 271**4 + 502**4 = 298**4 + 497**4 76*37da2899SCharles.Forsyth# [2] 86409838577 = 103**4 + 542**4 = 359**4 + 514**4 77*37da2899SCharles.Forsyth# [2] 160961094577 = 222**4 + 631**4 = 503**4 + 558**4 78*37da2899SCharles.Forsyth# [2] 2094447251857 = 76**4 + 1203**4 = 653**4 + 1176**4 79*37da2899SCharles.Forsyth# [2] 4231525221377 = 878**4 + 1381**4 = 997**4 + 1342**4 80*37da2899SCharles.Forsyth# [2] 26033514998417 = 1324**4 + 2189**4 = 1784**4 + 1997**4 81*37da2899SCharles.Forsyth# [2] 37860330087137 = 1042**4 + 2461**4 = 2026**4 + 2141**4 82*37da2899SCharles.Forsyth# [2] 61206381799697 = 248**4 + 2797**4 = 2131**4 + 2524**4 83*37da2899SCharles.Forsyth# [2] 76773963505537 = 1034**4 + 2949**4 = 1797**4 + 2854**4 84*37da2899SCharles.Forsyth# [2] 109737827061041 = 1577**4 + 3190**4 = 2345**4 + 2986**4 85*37da2899SCharles.Forsyth# [2] 155974778565937 = 1623**4 + 3494**4 = 2338**4 + 3351**4 86*37da2899SCharles.Forsyth# [2] 156700232476402 = 661**4 + 3537**4 = 2767**4 + 3147**4 87*37da2899SCharles.Forsyth# [2] 621194785437217 = 2694**4 + 4883**4 = 3966**4 + 4397**4 88*37da2899SCharles.Forsyth# [2] 652057426144337 = 604**4 + 5053**4 = 1283**4 + 5048**4 89*37da2899SCharles.Forsyth# [2] 680914892583617 = 3364**4 + 4849**4 = 4288**4 + 4303**4 90*37da2899SCharles.Forsyth# [2] 1438141494155441 = 2027**4 + 6140**4 = 4840**4 + 5461**4 91*37da2899SCharles.Forsyth# [2] 1919423464573697 = 274**4 + 6619**4 = 5093**4 + 5942**4 92*37da2899SCharles.Forsyth# [2] 2089568089060657 = 498**4 + 6761**4 = 5222**4 + 6057**4 93*37da2899SCharles.Forsyth# [2] 2105144161376801 = 2707**4 + 6730**4 = 3070**4 + 6701**4 94*37da2899SCharles.Forsyth# [2] 3263864585622562 = 1259**4 + 7557**4 = 4661**4 + 7269**4 95*37da2899SCharles.Forsyth# [2] 4063780581008977 = 5181**4 + 7604**4 = 6336**4 + 7037**4 96*37da2899SCharles.Forsyth# [2] 6315669699408737 = 1657**4 + 8912**4 = 7432**4 + 7559**4 97*37da2899SCharles.Forsyth# [2] 6884827518602786 = 635**4 + 9109**4 = 3391**4 + 9065**4 98*37da2899SCharles.Forsyth# [2] 7191538859126257 = 4903**4 + 9018**4 = 6842**4 + 8409**4 99*37da2899SCharles.Forsyth# [2] 7331928977565937 = 1104**4 + 9253**4 = 5403**4 + 8972**4 100*37da2899SCharles.Forsyth# [2] 7362748995747617 = 5098**4 + 9043**4 = 6742**4 + 8531**4 101*37da2899SCharles.Forsyth# [2] 7446891977980337 = 1142**4 + 9289**4 = 4946**4 + 9097**4 102*37da2899SCharles.Forsyth# [2] 7532132844821777 = 173**4 + 9316**4 = 4408**4 + 9197**4 103*37da2899SCharles.Forsyth# [2] 7985644522300177 = 6262**4 + 8961**4 = 7234**4 + 8511**4 104*37da2899SCharles.Forsyth 105*37da2899SCharles.Forsyth# 5, 6, 7, 8, 9, 10, 11 none 106*37da2899SCharles.Forsyth 107*37da2899SCharles.ForsythBtree: adt{ 108*37da2899SCharles.Forsyth sum: big; 109*37da2899SCharles.Forsyth left: cyclic ref Btree; 110*37da2899SCharles.Forsyth right: cyclic ref Btree; 111*37da2899SCharles.Forsyth}; 112*37da2899SCharles.Forsyth 113*37da2899SCharles.ForsythDtree: adt{ 114*37da2899SCharles.Forsyth sum: big; 115*37da2899SCharles.Forsyth freq: int; 116*37da2899SCharles.Forsyth lst: list of array of int; 117*37da2899SCharles.Forsyth left: cyclic ref Dtree; 118*37da2899SCharles.Forsyth right: cyclic ref Dtree; 119*37da2899SCharles.Forsyth}; 120*37da2899SCharles.Forsyth 121*37da2899SCharles.ForsythnCr(n: int, r: int): int 122*37da2899SCharles.Forsyth{ 123*37da2899SCharles.Forsyth if(r > n-r) 124*37da2899SCharles.Forsyth r = n-r; 125*37da2899SCharles.Forsyth 126*37da2899SCharles.Forsyth # f := g := 1; 127*37da2899SCharles.Forsyth # for(i := 0; i < r; i++){ 128*37da2899SCharles.Forsyth # f *= n-i; 129*37da2899SCharles.Forsyth # g *= i+1; 130*37da2899SCharles.Forsyth # } 131*37da2899SCharles.Forsyth # return f/g; 132*37da2899SCharles.Forsyth 133*37da2899SCharles.Forsyth num := array[r] of int; 134*37da2899SCharles.Forsyth den := array[r] of int; 135*37da2899SCharles.Forsyth for(i := 0; i < r; i++){ 136*37da2899SCharles.Forsyth num[i] = n-i; 137*37da2899SCharles.Forsyth den[i] = i+1; 138*37da2899SCharles.Forsyth } 139*37da2899SCharles.Forsyth for(i = 0; i < r; i++){ 140*37da2899SCharles.Forsyth for(j := 0; den[i] != 1; j++){ 141*37da2899SCharles.Forsyth if(num[j] == 1) 142*37da2899SCharles.Forsyth continue; 143*37da2899SCharles.Forsyth k := hcf(num[j], den[i]); 144*37da2899SCharles.Forsyth if(k != 1){ 145*37da2899SCharles.Forsyth num[j] /= k; 146*37da2899SCharles.Forsyth den[i] /= k; 147*37da2899SCharles.Forsyth } 148*37da2899SCharles.Forsyth } 149*37da2899SCharles.Forsyth } 150*37da2899SCharles.Forsyth f := 1; 151*37da2899SCharles.Forsyth for(i = 0; i < r; i++) 152*37da2899SCharles.Forsyth f *= num[i]; 153*37da2899SCharles.Forsyth return f; 154*37da2899SCharles.Forsyth} 155*37da2899SCharles.Forsyth 156*37da2899SCharles.ForsythnHr(n: int, r: int): int 157*37da2899SCharles.Forsyth{ 158*37da2899SCharles.Forsyth if(n == 0) 159*37da2899SCharles.Forsyth return 0; 160*37da2899SCharles.Forsyth return nCr(n+r-1, r); 161*37da2899SCharles.Forsyth} 162*37da2899SCharles.Forsyth 163*37da2899SCharles.ForsythnSr(n: int, i: int, j: int): int 164*37da2899SCharles.Forsyth{ 165*37da2899SCharles.Forsyth return nHr(j, n)-nHr(i, n); 166*37da2899SCharles.Forsyth # s := 0; 167*37da2899SCharles.Forsyth # for(k := i; k < j; k++) 168*37da2899SCharles.Forsyth # s += nHr(k+1, n-1); 169*37da2899SCharles.Forsyth # return s; 170*37da2899SCharles.Forsyth} 171*37da2899SCharles.Forsyth 172*37da2899SCharles.ForsythnSrmax(n: int, i: int, m: int): int 173*37da2899SCharles.Forsyth{ 174*37da2899SCharles.Forsyth s := 0; 175*37da2899SCharles.Forsyth for(k := i; ; k++){ 176*37da2899SCharles.Forsyth s += nHr(k+1, n-1); 177*37da2899SCharles.Forsyth if(s > m) 178*37da2899SCharles.Forsyth break; 179*37da2899SCharles.Forsyth } 180*37da2899SCharles.Forsyth if(k == i) 181*37da2899SCharles.Forsyth return i+1; 182*37da2899SCharles.Forsyth return k; 183*37da2899SCharles.Forsyth} 184*37da2899SCharles.Forsyth 185*37da2899SCharles.Forsythkth(c: array of int, n: int, i: int, j: int, k: int) 186*37da2899SCharles.Forsyth{ 187*37da2899SCharles.Forsyth l, u: int; 188*37da2899SCharles.Forsyth 189*37da2899SCharles.Forsyth m := nSr(n, i, j); 190*37da2899SCharles.Forsyth if(k < 0) 191*37da2899SCharles.Forsyth k = 0; 192*37da2899SCharles.Forsyth if(k >= m) 193*37da2899SCharles.Forsyth k = m-1; 194*37da2899SCharles.Forsyth p := 0; 195*37da2899SCharles.Forsyth for(q := 0; q < n; q++){ 196*37da2899SCharles.Forsyth if(q == 0){ 197*37da2899SCharles.Forsyth l = i; 198*37da2899SCharles.Forsyth u = j-1; 199*37da2899SCharles.Forsyth } 200*37da2899SCharles.Forsyth else{ 201*37da2899SCharles.Forsyth l = 0; 202*37da2899SCharles.Forsyth u = c[q-1]; 203*37da2899SCharles.Forsyth } 204*37da2899SCharles.Forsyth for(x := l; x <= u; x++){ 205*37da2899SCharles.Forsyth m = nHr(x+1, n-q-1); 206*37da2899SCharles.Forsyth p += m; 207*37da2899SCharles.Forsyth if(p > k){ 208*37da2899SCharles.Forsyth p -= m; 209*37da2899SCharles.Forsyth break; 210*37da2899SCharles.Forsyth } 211*37da2899SCharles.Forsyth } 212*37da2899SCharles.Forsyth c[q] = x; 213*37da2899SCharles.Forsyth } 214*37da2899SCharles.Forsyth} 215*37da2899SCharles.Forsyth 216*37da2899SCharles.Forsythpos(c: array of int, n: int): int 217*37da2899SCharles.Forsyth{ 218*37da2899SCharles.Forsyth p := 0; 219*37da2899SCharles.Forsyth for(q := 0; q < n; q++) 220*37da2899SCharles.Forsyth p += nSr(n-q, 0, c[q]); 221*37da2899SCharles.Forsyth return p; 222*37da2899SCharles.Forsyth} 223*37da2899SCharles.Forsyth 224*37da2899SCharles.Forsythmin(c: array of int, n: int, p: int): big 225*37da2899SCharles.Forsyth{ 226*37da2899SCharles.Forsyth s := big(0); 227*37da2899SCharles.Forsyth for(i := 0; i < n; i++) 228*37da2899SCharles.Forsyth s += big(c[i])**p; 229*37da2899SCharles.Forsyth m := s; 230*37da2899SCharles.Forsyth for(i = n-1; i > 0; i--){ 231*37da2899SCharles.Forsyth s -= big(c[i])**p; 232*37da2899SCharles.Forsyth s -= big(c[i-1])**p; 233*37da2899SCharles.Forsyth c[i]--; 234*37da2899SCharles.Forsyth c[i-1]++; 235*37da2899SCharles.Forsyth s += big(c[i-1])**p; 236*37da2899SCharles.Forsyth if(s < m) 237*37da2899SCharles.Forsyth m = s; 238*37da2899SCharles.Forsyth } 239*37da2899SCharles.Forsyth c[0]--; 240*37da2899SCharles.Forsyth c[n-1]++; 241*37da2899SCharles.Forsyth # m--; 242*37da2899SCharles.Forsyth return m; 243*37da2899SCharles.Forsyth} 244*37da2899SCharles.Forsyth 245*37da2899SCharles.Forsythhcf(a, b: int): int 246*37da2899SCharles.Forsyth{ 247*37da2899SCharles.Forsyth if(b == 0) 248*37da2899SCharles.Forsyth return a; 249*37da2899SCharles.Forsyth for(;;){ 250*37da2899SCharles.Forsyth if(a == 0) 251*37da2899SCharles.Forsyth break; 252*37da2899SCharles.Forsyth if(a < b) 253*37da2899SCharles.Forsyth (a, b) = (b, a); 254*37da2899SCharles.Forsyth a %= b; 255*37da2899SCharles.Forsyth # a -= (a/b)*b; 256*37da2899SCharles.Forsyth } 257*37da2899SCharles.Forsyth return b; 258*37da2899SCharles.Forsyth} 259*37da2899SCharles.Forsyth 260*37da2899SCharles.Forsythgcd(l: list of array of int): int 261*37da2899SCharles.Forsyth{ 262*37da2899SCharles.Forsyth g := (hd l)[0]; 263*37da2899SCharles.Forsyth for(; l != nil; l = tl l){ 264*37da2899SCharles.Forsyth d := hd l; 265*37da2899SCharles.Forsyth n := len d; 266*37da2899SCharles.Forsyth for(i := 0; i < n; i++) 267*37da2899SCharles.Forsyth g = hcf(d[i], g); 268*37da2899SCharles.Forsyth } 269*37da2899SCharles.Forsyth return g; 270*37da2899SCharles.Forsyth} 271*37da2899SCharles.Forsyth 272*37da2899SCharles.Forsythadddup(s: big, root: ref Dtree): int 273*37da2899SCharles.Forsyth{ 274*37da2899SCharles.Forsyth n, p, lp: ref Dtree; 275*37da2899SCharles.Forsyth 276*37da2899SCharles.Forsyth p = root; 277*37da2899SCharles.Forsyth while(p != nil){ 278*37da2899SCharles.Forsyth if(s == p.sum) 279*37da2899SCharles.Forsyth return ++p.freq; 280*37da2899SCharles.Forsyth lp = p; 281*37da2899SCharles.Forsyth if(s < p.sum) 282*37da2899SCharles.Forsyth p = p.left; 283*37da2899SCharles.Forsyth else 284*37da2899SCharles.Forsyth p = p.right; 285*37da2899SCharles.Forsyth } 286*37da2899SCharles.Forsyth n = ref Dtree(s, 2, nil, nil, nil); 287*37da2899SCharles.Forsyth if(s < lp.sum) 288*37da2899SCharles.Forsyth lp.left = n; 289*37da2899SCharles.Forsyth else 290*37da2899SCharles.Forsyth lp.right = n; 291*37da2899SCharles.Forsyth return n.freq; 292*37da2899SCharles.Forsyth} 293*37da2899SCharles.Forsyth 294*37da2899SCharles.Forsythcp(c: array of int): array of int 295*37da2899SCharles.Forsyth{ 296*37da2899SCharles.Forsyth n := len c; 297*37da2899SCharles.Forsyth m := 0; 298*37da2899SCharles.Forsyth for(i := 0; i < n; i++) 299*37da2899SCharles.Forsyth if(c[i] != 0) 300*37da2899SCharles.Forsyth m++; 301*37da2899SCharles.Forsyth nc := array[m] of int; 302*37da2899SCharles.Forsyth nc[0: ] = c[0: m]; 303*37da2899SCharles.Forsyth return nc; 304*37da2899SCharles.Forsyth} 305*37da2899SCharles.Forsyth 306*37da2899SCharles.Forsythfinddup(s: big, c: array of int, root: ref Dtree, f: int) 307*37da2899SCharles.Forsyth{ 308*37da2899SCharles.Forsyth p: ref Dtree; 309*37da2899SCharles.Forsyth 310*37da2899SCharles.Forsyth p = root; 311*37da2899SCharles.Forsyth while(p != nil){ 312*37da2899SCharles.Forsyth if(s == p.sum){ 313*37da2899SCharles.Forsyth if(p.freq >= f) 314*37da2899SCharles.Forsyth p.lst = cp(c) :: p.lst; 315*37da2899SCharles.Forsyth return; 316*37da2899SCharles.Forsyth } 317*37da2899SCharles.Forsyth if(s < p.sum) 318*37da2899SCharles.Forsyth p = p.left; 319*37da2899SCharles.Forsyth else 320*37da2899SCharles.Forsyth p = p.right; 321*37da2899SCharles.Forsyth } 322*37da2899SCharles.Forsyth} 323*37da2899SCharles.Forsyth 324*37da2899SCharles.Forsythprintdup(p: ref Dtree, pow: int, ix: int) 325*37da2899SCharles.Forsyth{ 326*37da2899SCharles.Forsyth if(p == nil) 327*37da2899SCharles.Forsyth return; 328*37da2899SCharles.Forsyth printdup(p.left, pow, ix); 329*37da2899SCharles.Forsyth if((l := p.lst) != nil){ 330*37da2899SCharles.Forsyth if(gcd(l) == 1){ 331*37da2899SCharles.Forsyth min1 := min2 := 16r7fffffff; 332*37da2899SCharles.Forsyth for(; l != nil; l = tl l){ 333*37da2899SCharles.Forsyth n := len hd l; 334*37da2899SCharles.Forsyth if(n < min1){ 335*37da2899SCharles.Forsyth min2 = min1; 336*37da2899SCharles.Forsyth min1 = n; 337*37da2899SCharles.Forsyth } 338*37da2899SCharles.Forsyth else if(n < min2) 339*37da2899SCharles.Forsyth min2 = n; 340*37da2899SCharles.Forsyth } 341*37da2899SCharles.Forsyth i := min1+min2-pow; 342*37da2899SCharles.Forsyth if(i <= ix){ 343*37da2899SCharles.Forsyth sys->print("[%d, %d] %bd", i, p.freq, p.sum); 344*37da2899SCharles.Forsyth for(l = p.lst; l != nil; l = tl l){ 345*37da2899SCharles.Forsyth d := hd l; 346*37da2899SCharles.Forsyth n := len d; 347*37da2899SCharles.Forsyth sys->print(" = "); 348*37da2899SCharles.Forsyth for(j := n-1; j >= 0; j--){ 349*37da2899SCharles.Forsyth sys->print("%d**%d", d[j], pow); 350*37da2899SCharles.Forsyth if(j > 0) 351*37da2899SCharles.Forsyth sys->print(" + "); 352*37da2899SCharles.Forsyth } 353*37da2899SCharles.Forsyth } 354*37da2899SCharles.Forsyth sys->print("\n"); 355*37da2899SCharles.Forsyth if(i < 0){ 356*37da2899SCharles.Forsyth sys->print("****************\n"); 357*37da2899SCharles.Forsyth exit; 358*37da2899SCharles.Forsyth } 359*37da2899SCharles.Forsyth } 360*37da2899SCharles.Forsyth } 361*37da2899SCharles.Forsyth } 362*37da2899SCharles.Forsyth printdup(p.right, pow, ix); 363*37da2899SCharles.Forsyth} 364*37da2899SCharles.Forsyth 365*37da2899SCharles.Forsythaddsum(s: big, root: ref Btree, root1: ref Dtree): int 366*37da2899SCharles.Forsyth{ 367*37da2899SCharles.Forsyth n, p, lp: ref Btree; 368*37da2899SCharles.Forsyth 369*37da2899SCharles.Forsyth p = root; 370*37da2899SCharles.Forsyth while(p != nil){ 371*37da2899SCharles.Forsyth if(s == p.sum) 372*37da2899SCharles.Forsyth return adddup(s, root1); 373*37da2899SCharles.Forsyth lp = p; 374*37da2899SCharles.Forsyth if(s < p.sum) 375*37da2899SCharles.Forsyth p = p.left; 376*37da2899SCharles.Forsyth else 377*37da2899SCharles.Forsyth p = p.right; 378*37da2899SCharles.Forsyth } 379*37da2899SCharles.Forsyth n = ref Btree(s, nil, nil); 380*37da2899SCharles.Forsyth if(s < lp.sum) 381*37da2899SCharles.Forsyth lp.left = n; 382*37da2899SCharles.Forsyth else 383*37da2899SCharles.Forsyth lp.right = n; 384*37da2899SCharles.Forsyth return 1; 385*37da2899SCharles.Forsyth} 386*37da2899SCharles.Forsyth 387*37da2899SCharles.Forsythoiroot(x: big, p: int): int 388*37da2899SCharles.Forsyth{ 389*37da2899SCharles.Forsyth for(i := 0; ; i++){ 390*37da2899SCharles.Forsyth n := big(i)**p; 391*37da2899SCharles.Forsyth if(n > x) 392*37da2899SCharles.Forsyth break; 393*37da2899SCharles.Forsyth } 394*37da2899SCharles.Forsyth return i-1; 395*37da2899SCharles.Forsyth} 396*37da2899SCharles.Forsyth 397*37da2899SCharles.Forsythiroot(x: big, p: int): int 398*37da2899SCharles.Forsyth{ 399*37da2899SCharles.Forsyth m: big; 400*37da2899SCharles.Forsyth 401*37da2899SCharles.Forsyth if(x == big(0) || x == big(1)) 402*37da2899SCharles.Forsyth return int x; 403*37da2899SCharles.Forsyth v := x; 404*37da2899SCharles.Forsyth n := 0; 405*37da2899SCharles.Forsyth for(i := 32; i > 0; i >>= 1){ 406*37da2899SCharles.Forsyth m = ((big(1)<<i)-big(1))<<i; 407*37da2899SCharles.Forsyth if((v&m) != big(0)){ 408*37da2899SCharles.Forsyth n += i; 409*37da2899SCharles.Forsyth v >>= i; 410*37da2899SCharles.Forsyth } 411*37da2899SCharles.Forsyth } 412*37da2899SCharles.Forsyth a := big(1) << (n/p); 413*37da2899SCharles.Forsyth b := a<<1; 414*37da2899SCharles.Forsyth while(a < b){ 415*37da2899SCharles.Forsyth m = (a+b+big(1))/big(2); 416*37da2899SCharles.Forsyth y := m**p; 417*37da2899SCharles.Forsyth if(y > x) 418*37da2899SCharles.Forsyth b = m-big(1); 419*37da2899SCharles.Forsyth else if(y < x) 420*37da2899SCharles.Forsyth a = m; 421*37da2899SCharles.Forsyth else 422*37da2899SCharles.Forsyth a = b = m; 423*37da2899SCharles.Forsyth } 424*37da2899SCharles.Forsyth if(a**p <= x && (a+big(1))**p > x) 425*37da2899SCharles.Forsyth ; 426*37da2899SCharles.Forsyth else{ 427*37da2899SCharles.Forsyth sys->print("fatal: %bd %d -> %bd\n", x, p, a); 428*37da2899SCharles.Forsyth exit; 429*37da2899SCharles.Forsyth } 430*37da2899SCharles.Forsyth return int a; 431*37da2899SCharles.Forsyth} 432*37da2899SCharles.Forsyth 433*37da2899SCharles.Forsythinitval(c: array of int, n: int, p: int, v: int): big 434*37da2899SCharles.Forsyth{ 435*37da2899SCharles.Forsyth for(i := 0; i < n; i++) 436*37da2899SCharles.Forsyth c[i] = 0; 437*37da2899SCharles.Forsyth c[0] = v; 438*37da2899SCharles.Forsyth return big(v)**p; 439*37da2899SCharles.Forsyth} 440*37da2899SCharles.Forsyth 441*37da2899SCharles.Forsythnxtval(c: array of int, n: int, p: int, s: big): big 442*37da2899SCharles.Forsyth{ 443*37da2899SCharles.Forsyth for(k := n-1; k >= 0; k--){ 444*37da2899SCharles.Forsyth s -= big(c[k])**p; 445*37da2899SCharles.Forsyth c[k]++; 446*37da2899SCharles.Forsyth if(k == 0){ 447*37da2899SCharles.Forsyth s += big(c[k])**p; 448*37da2899SCharles.Forsyth break; 449*37da2899SCharles.Forsyth } 450*37da2899SCharles.Forsyth else{ 451*37da2899SCharles.Forsyth if(c[k] <= c[k-1]){ 452*37da2899SCharles.Forsyth s += big(c[k])**p; 453*37da2899SCharles.Forsyth break; 454*37da2899SCharles.Forsyth } 455*37da2899SCharles.Forsyth c[k] = 0; 456*37da2899SCharles.Forsyth } 457*37da2899SCharles.Forsyth } 458*37da2899SCharles.Forsyth return s; 459*37da2899SCharles.Forsyth} 460*37da2899SCharles.Forsyth 461*37da2899SCharles.Forsythpowers(p: int, n: int, f: int, ix: int, lim0: big, lim: big, ch: chan of int, lock: ref Semaphore) 462*37da2899SCharles.Forsyth{ 463*37da2899SCharles.Forsyth root := ref Btree(big(-1), nil, nil); 464*37da2899SCharles.Forsyth root1 := ref Dtree(big(-1), 0, nil, nil, nil); 465*37da2899SCharles.Forsyth 466*37da2899SCharles.Forsyth min := max := lim0; 467*37da2899SCharles.Forsyth 468*37da2899SCharles.Forsyth c := array[n] of int; 469*37da2899SCharles.Forsyth 470*37da2899SCharles.Forsyth for(;;){ 471*37da2899SCharles.Forsyth imin := iroot((min+big(n-1))/big(n), p); 472*37da2899SCharles.Forsyth imax := nSrmax(n, imin, MAXNODES); 473*37da2899SCharles.Forsyth max = big(imax)**p - big(1); 474*37da2899SCharles.Forsyth while(max <= min){ # could do better 475*37da2899SCharles.Forsyth imax++; 476*37da2899SCharles.Forsyth max = big(imax)**p - big(1); 477*37da2899SCharles.Forsyth } 478*37da2899SCharles.Forsyth if(max > lim){ 479*37da2899SCharles.Forsyth max = lim; 480*37da2899SCharles.Forsyth imax = iroot(max, p)+1; 481*37da2899SCharles.Forsyth } 482*37da2899SCharles.Forsyth 483*37da2899SCharles.Forsyth if(verbose) 484*37da2899SCharles.Forsyth sys->print("searching in %d-%d(%bd-%bd)\n", imin, imax, min, max); 485*37da2899SCharles.Forsyth 486*37da2899SCharles.Forsyth m := mm := 0; 487*37da2899SCharles.Forsyth maxf := 0; 488*37da2899SCharles.Forsyth s := initval(c, n, p, imin); 489*37da2899SCharles.Forsyth for(;;){ 490*37da2899SCharles.Forsyth mm++; 491*37da2899SCharles.Forsyth if(s >= min && s < max){ 492*37da2899SCharles.Forsyth fr := addsum(s, root, root1); 493*37da2899SCharles.Forsyth if(fr > maxf) 494*37da2899SCharles.Forsyth maxf = fr; 495*37da2899SCharles.Forsyth m++; 496*37da2899SCharles.Forsyth } 497*37da2899SCharles.Forsyth s = nxtval(c, n, p, s); 498*37da2899SCharles.Forsyth if(c[0] == imax) 499*37da2899SCharles.Forsyth break; 500*37da2899SCharles.Forsyth } 501*37da2899SCharles.Forsyth 502*37da2899SCharles.Forsyth root.left = root.right = nil; 503*37da2899SCharles.Forsyth 504*37da2899SCharles.Forsyth if(maxf >= f){ 505*37da2899SCharles.Forsyth if(verbose) 506*37da2899SCharles.Forsyth sys->print("finding duplicates\n"); 507*37da2899SCharles.Forsyth 508*37da2899SCharles.Forsyth s = initval(c, n, p, imin); 509*37da2899SCharles.Forsyth for(;;){ 510*37da2899SCharles.Forsyth if(s >= min && s < max) 511*37da2899SCharles.Forsyth finddup(s, c, root1, f); 512*37da2899SCharles.Forsyth s = nxtval(c, n, p, s); 513*37da2899SCharles.Forsyth if(c[0] == imax) 514*37da2899SCharles.Forsyth break; 515*37da2899SCharles.Forsyth } 516*37da2899SCharles.Forsyth 517*37da2899SCharles.Forsyth if(lock != nil) 518*37da2899SCharles.Forsyth lock.obtain(); 519*37da2899SCharles.Forsyth printdup(root1, p, ix); 520*37da2899SCharles.Forsyth if(lock != nil) 521*37da2899SCharles.Forsyth lock.release(); 522*37da2899SCharles.Forsyth 523*37da2899SCharles.Forsyth root1.left = root1.right = nil; 524*37da2899SCharles.Forsyth } 525*37da2899SCharles.Forsyth 526*37da2899SCharles.Forsyth if(verbose) 527*37da2899SCharles.Forsyth sys->print("%d(%d) nodes searched\n", m, mm); 528*37da2899SCharles.Forsyth 529*37da2899SCharles.Forsyth if(mm != nSr(n, imin, imax)){ 530*37da2899SCharles.Forsyth sys->print("**fatal**\n"); 531*37da2899SCharles.Forsyth exit; 532*37da2899SCharles.Forsyth } 533*37da2899SCharles.Forsyth 534*37da2899SCharles.Forsyth min = max; 535*37da2899SCharles.Forsyth if(min >= lim) 536*37da2899SCharles.Forsyth break; 537*37da2899SCharles.Forsyth } 538*37da2899SCharles.Forsyth if(ch != nil) 539*37da2899SCharles.Forsyth ch <-= 0; 540*37da2899SCharles.Forsyth} 541*37da2899SCharles.Forsyth 542*37da2899SCharles.Forsythusage() 543*37da2899SCharles.Forsyth{ 544*37da2899SCharles.Forsyth sys->print("usage: powers -p power -n number -f frequency -i index -l minimum -m maximum -s procs -v\n"); 545*37da2899SCharles.Forsyth exit; 546*37da2899SCharles.Forsyth} 547*37da2899SCharles.Forsyth 548*37da2899SCharles.Forsythpartition(p: int, n: int, l: big, m: big, s: int): array of big 549*37da2899SCharles.Forsyth{ 550*37da2899SCharles.Forsyth a := array[s+1] of big; 551*37da2899SCharles.Forsyth a[0] = big(iroot(l, p))**n; 552*37da2899SCharles.Forsyth a[s] = (big(iroot(m, p))+big(1))**n; 553*37da2899SCharles.Forsyth nn := a[s]-a[0]; 554*37da2899SCharles.Forsyth q := nn/big(s); 555*37da2899SCharles.Forsyth r := nn-q*big(s); 556*37da2899SCharles.Forsyth t := big(0); 557*37da2899SCharles.Forsyth lb := a[0]; 558*37da2899SCharles.Forsyth for(i := 0; i < s; i++){ 559*37da2899SCharles.Forsyth ub := lb+q; 560*37da2899SCharles.Forsyth t += r; 561*37da2899SCharles.Forsyth if(t >= big(s)){ 562*37da2899SCharles.Forsyth ub++; 563*37da2899SCharles.Forsyth t -= big(s); 564*37da2899SCharles.Forsyth } 565*37da2899SCharles.Forsyth a[i+1] = ub; 566*37da2899SCharles.Forsyth lb = ub; 567*37da2899SCharles.Forsyth } 568*37da2899SCharles.Forsyth if(a[s] != a[0]+nn){ 569*37da2899SCharles.Forsyth sys->print("fatal: a[s]\n"); 570*37da2899SCharles.Forsyth exit; 571*37da2899SCharles.Forsyth } 572*37da2899SCharles.Forsyth for(i = 0; i < s; i++){ 573*37da2899SCharles.Forsyth # sys->print("%bd %bd\n", a[i], a[i]**p); 574*37da2899SCharles.Forsyth a[i] = big(iroot(a[i], n))**p; 575*37da2899SCharles.Forsyth } 576*37da2899SCharles.Forsyth a[0] = l; 577*37da2899SCharles.Forsyth a[s] = m; 578*37da2899SCharles.Forsyth while(a[0] >= a[1]){ 579*37da2899SCharles.Forsyth a[1] = a[0]; 580*37da2899SCharles.Forsyth a = a[1: ]; 581*37da2899SCharles.Forsyth --s; 582*37da2899SCharles.Forsyth } 583*37da2899SCharles.Forsyth while(a[s] <= a[s-1]){ 584*37da2899SCharles.Forsyth a[s-1] = a[s]; 585*37da2899SCharles.Forsyth a = a[0: s]; 586*37da2899SCharles.Forsyth --s; 587*37da2899SCharles.Forsyth } 588*37da2899SCharles.Forsyth return a; 589*37da2899SCharles.Forsyth} 590*37da2899SCharles.Forsyth 591*37da2899SCharles.Forsythinit(nil: ref Draw->Context, args: list of string) 592*37da2899SCharles.Forsyth{ 593*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 594*37da2899SCharles.Forsyth arg := load Arg Arg->PATH; 595*37da2899SCharles.Forsyth lockm = load Lock Lock->PATH; 596*37da2899SCharles.Forsyth 597*37da2899SCharles.Forsyth lockm->init(); 598*37da2899SCharles.Forsyth lock := Semaphore.new(); 599*37da2899SCharles.Forsyth 600*37da2899SCharles.Forsyth p := n := f := 2; 601*37da2899SCharles.Forsyth ix := 1<<30; 602*37da2899SCharles.Forsyth l := m := big(0); 603*37da2899SCharles.Forsyth s := 1; 604*37da2899SCharles.Forsyth 605*37da2899SCharles.Forsyth arg->init(args); 606*37da2899SCharles.Forsyth while((c := arg->opt()) != 0){ 607*37da2899SCharles.Forsyth case c { 608*37da2899SCharles.Forsyth 'p' => 609*37da2899SCharles.Forsyth p = int arg->arg(); 610*37da2899SCharles.Forsyth 'n' => 611*37da2899SCharles.Forsyth n = int arg->arg(); 612*37da2899SCharles.Forsyth 'f' => 613*37da2899SCharles.Forsyth f = int arg->arg(); 614*37da2899SCharles.Forsyth 'i' => 615*37da2899SCharles.Forsyth ix = int arg->arg(); 616*37da2899SCharles.Forsyth 'l' => 617*37da2899SCharles.Forsyth l = big(arg->arg()); 618*37da2899SCharles.Forsyth 'm' => 619*37da2899SCharles.Forsyth m = big(arg->arg())+big(1); 620*37da2899SCharles.Forsyth 's' => 621*37da2899SCharles.Forsyth s = int arg->arg(); 622*37da2899SCharles.Forsyth 'v' => 623*37da2899SCharles.Forsyth verbose = 1; 624*37da2899SCharles.Forsyth * => 625*37da2899SCharles.Forsyth usage(); 626*37da2899SCharles.Forsyth } 627*37da2899SCharles.Forsyth } 628*37da2899SCharles.Forsyth if(arg->argv() != nil) 629*37da2899SCharles.Forsyth usage(); 630*37da2899SCharles.Forsyth 631*37da2899SCharles.Forsyth if(p < 2){ 632*37da2899SCharles.Forsyth p = 2; 633*37da2899SCharles.Forsyth sys->print("setting p = %d\n", p); 634*37da2899SCharles.Forsyth } 635*37da2899SCharles.Forsyth if(n < 2){ 636*37da2899SCharles.Forsyth n = 2; 637*37da2899SCharles.Forsyth sys->print("setting n = %d\n", n); 638*37da2899SCharles.Forsyth } 639*37da2899SCharles.Forsyth if(f < 2){ 640*37da2899SCharles.Forsyth f = 2; 641*37da2899SCharles.Forsyth sys->print("setting f = %d\n", f); 642*37da2899SCharles.Forsyth } 643*37da2899SCharles.Forsyth if(l < big(0)){ 644*37da2899SCharles.Forsyth l = big(0); 645*37da2899SCharles.Forsyth sys->print("setting l = %bd\n", l); 646*37da2899SCharles.Forsyth } 647*37da2899SCharles.Forsyth if(m <= big(0)){ 648*37da2899SCharles.Forsyth m = big((1<<13)+1); 649*37da2899SCharles.Forsyth sys->print("setting m = %bd\n", m-big(1)); 650*37da2899SCharles.Forsyth } 651*37da2899SCharles.Forsyth if(l >= m) 652*37da2899SCharles.Forsyth exit; 653*37da2899SCharles.Forsyth 654*37da2899SCharles.Forsyth if(s <= 1) 655*37da2899SCharles.Forsyth powers(p, n, f, ix, l, m, nil, nil); 656*37da2899SCharles.Forsyth else{ 657*37da2899SCharles.Forsyth nproc := 0; 658*37da2899SCharles.Forsyth ch := chan of int; 659*37da2899SCharles.Forsyth a := partition(p, n, l, m, s); 660*37da2899SCharles.Forsyth lb := a[0]; 661*37da2899SCharles.Forsyth for(i := 0; i < s; i++){ 662*37da2899SCharles.Forsyth ub := a[i+1]; 663*37da2899SCharles.Forsyth if(lb < ub){ 664*37da2899SCharles.Forsyth nproc++; 665*37da2899SCharles.Forsyth spawn powers(p, n, f, ix, lb, ub, ch, lock); 666*37da2899SCharles.Forsyth } 667*37da2899SCharles.Forsyth lb = ub; 668*37da2899SCharles.Forsyth } 669*37da2899SCharles.Forsyth for( ; nproc != 0; nproc--) 670*37da2899SCharles.Forsyth <- ch; 671*37da2899SCharles.Forsyth } 672*37da2899SCharles.Forsyth} 673