algreduce 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
algreduce/algreduce.py ADDED
@@ -0,0 +1,839 @@
1
+ import math
2
+
3
+ # determine whether a radicand is a perfect square
4
+ def is_square(radicand: int) -> bool:
5
+ return round(math.sqrt(radicand)) ** 2 == radicand
6
+
7
+ # simplify squares: √r -> a√b
8
+ def square(radicand: int) -> tuple:
9
+ """
10
+ return:
11
+ tuple (a, b)
12
+
13
+ examples:
14
+ >>>square(4)
15
+ (2, 1)
16
+ >>>square(8)
17
+ (2, 2)
18
+ >>>square(5)
19
+ (1, 5)
20
+ >>>square(48)
21
+ (4, 3)
22
+ """
23
+ if is_square(radicand):
24
+ a = round(math.sqrt(radicand))
25
+ b = 1
26
+
27
+ else:
28
+ b = 2
29
+
30
+ while not is_square(radicand/b):
31
+ b += 1
32
+
33
+ a = round(math.sqrt(radicand/b))
34
+
35
+ return (a, b)
36
+
37
+ # calculate the cubic root of radicands
38
+ def cbrt(radicand: float) -> float:
39
+ if radicand >= 0:
40
+ return math.pow(radicand, 1/3)
41
+
42
+ elif radicand < 0:
43
+ return -math.pow(-radicand, 1/3)
44
+
45
+ # determine whether a radicand is a perfect cube
46
+ def is_cube(radicand: int) -> bool:
47
+ return round(cbrt(radicand)) ** 3 == radicand
48
+
49
+ # simplify cubes: ³√r -> a·³√b
50
+ def cube(radicand: int) -> tuple:
51
+ """
52
+ return:
53
+ tuple (a, b)
54
+
55
+ examples:
56
+ >>>cube(8)
57
+ (2, 1)
58
+ >>>cube(18)
59
+ (1, 18)
60
+ >>>cube(-9)
61
+ (-1, 9)
62
+ >>>cube(24)
63
+ (2, 3)
64
+ """
65
+ if is_cube(radicand):
66
+ a = round(cbrt(radicand))
67
+ b = 1
68
+
69
+ else:
70
+ b = 2
71
+
72
+ while not is_cube(radicand/b):
73
+ b += 1
74
+
75
+ a = round(cbrt(radicand/b))
76
+
77
+ return (a, b)
78
+
79
+ # simplify fractions
80
+ def fraction(numerator: int, denominator: int) -> str:
81
+ """
82
+ simplify and format mathematical expressions as strings
83
+
84
+ parameters:
85
+ numerator: the numerator of the fraction
86
+ denominator: the denominator of the fraction
87
+
88
+ return:
89
+ formatted string of the mathematical expression
90
+
91
+ examples:
92
+ >>>fraction(5, 7)
93
+ '5/7'
94
+ >>>fraction(10, 4)
95
+ '5/2'
96
+ >>>fraction(3, 9)
97
+ '1/3'
98
+ >>>fraction(8, 2)
99
+ '4'
100
+ """
101
+ # special cases for 0
102
+ if numerator == 0 and denominator != 0:
103
+ return '0'
104
+
105
+ elif numerator != 0 and denominator == 0:
106
+ return '∞'
107
+
108
+ elif numerator == 0 and denominator == 0:
109
+ return '0/0'
110
+
111
+ else:
112
+ # simplify the fraction into reduced fraction
113
+ gcd = math.gcd(numerator, denominator)
114
+ num = numerator // gcd
115
+ den = denominator // gcd
116
+
117
+ # n/1 -> n
118
+ if den == 1:
119
+ return f'{num}'
120
+
121
+ # n/-1 -> -n
122
+ elif den == -1:
123
+ return f'{-num}'
124
+
125
+ # n/d -> n/|d|
126
+ elif den > 0:
127
+ return f'{num}/{den}'
128
+
129
+ # n/d -> -n/|d|
130
+ elif den < 0:
131
+ return f'{-num}/{-den}'
132
+
133
+ # simplify fractions contain square root
134
+ def sqfrac(rational: int, radicand: int, denominator: int, is_minus: bool=False) -> str:
135
+ """
136
+ simplify and format fractions with square root
137
+
138
+ parameters:
139
+ rational: the integer in numerator of the fraction
140
+ radicand: the radicand in numerator of the fraction
141
+ denominator: the denominator of the fraction
142
+ is_minus: change the '+' between rational and radicand into '-' (default as False)
143
+
144
+ return:
145
+ formatted string of the mathematical expression
146
+
147
+ examples:
148
+ >>>sqfrac(2, 3, 1)
149
+ '2+√3'
150
+ >>>sqfrac(1, 9, 1)
151
+ '4'
152
+ >>>sqfrac(3, 8, 3, True)
153
+ '(3-2√2)/3'
154
+ >>>sqfrac(1, 0, 2)
155
+ '1/2'
156
+ >>>sqfrac(0, -4, 2, True)
157
+ '-i'
158
+ """
159
+ # format the reduced fraction
160
+ def formal(expression: str) -> str:
161
+ if cef == 1:
162
+ # 1√1/den -> 1/den
163
+ if rdc == 1:
164
+ if radicand < 0:
165
+ expression = expression.replace('1√1', '')
166
+
167
+ else:
168
+ expression = expression.replace('√1', '')
169
+
170
+ # 1√rdc/den -> √rdc/den
171
+ else:
172
+ expression = expression.replace('1√', '√')
173
+
174
+ else:
175
+ # cef√1/den -> cef/den
176
+ if rdc == 1:
177
+ expression = expression.replace('√1', '')
178
+
179
+ # cef√rdc/den
180
+ else:
181
+ pass
182
+
183
+ return expression
184
+
185
+ # ± √radicand / denominator
186
+ if rational == 0:
187
+ # fraction is a real number
188
+ if radicand > 0:
189
+ rdc = square(radicand)[1]
190
+ gcd = math.gcd(square(radicand)[0], denominator)
191
+ cef = square(radicand)[0] // gcd
192
+ den = denominator // gcd
193
+
194
+ if den == 1:
195
+ if is_minus:
196
+ return formal(f'{-cef}√{rdc}')
197
+
198
+ else:
199
+ return formal(f'{cef}√{rdc}')
200
+
201
+ elif den == -1:
202
+ if is_minus:
203
+ return formal(f'{cef}√{rdc}')
204
+
205
+ else:
206
+ return formal(f'{-cef}√{rdc}')
207
+
208
+ elif den > 0:
209
+ if is_minus:
210
+ return formal(f'{-cef}√{rdc}/{den}')
211
+
212
+ else:
213
+ return formal(f'{cef}√{rdc}/{den}')
214
+
215
+ elif den < 0:
216
+ if is_minus:
217
+ return formal(f'{cef}√{rdc}/{-den}')
218
+
219
+ else:
220
+ return formal(f'{-cef}√{rdc}/{-den}')
221
+
222
+ # fraction is a complex number
223
+ elif radicand < 0:
224
+ rdc = square(-radicand)[1]
225
+ gcd = math.gcd(square(-radicand)[0], denominator)
226
+ cef = square(-radicand)[0] // gcd
227
+ den = denominator // gcd
228
+
229
+ if den == 1:
230
+ if is_minus:
231
+ return formal(f'{-cef}√{rdc}i')
232
+
233
+ else:
234
+ return formal(f'{cef}√{rdc}i')
235
+
236
+ elif den == -1:
237
+ if is_minus:
238
+ return formal(f'{cef}√{rdc}i')
239
+
240
+ else:
241
+ return formal(f'{-cef}√{rdc}i')
242
+
243
+ elif den > 0:
244
+ if is_minus:
245
+ return formal(f'{-cef}√{rdc}i/{den}')
246
+
247
+ else:
248
+ return formal(f'{cef}√{rdc}i/{den}')
249
+
250
+ elif den < 0:
251
+ if is_minus:
252
+ return formal(f'{cef}√{rdc}i/{-den}')
253
+
254
+ else:
255
+ return formal(f'{-cef}√{rdc}i/{-den}')
256
+
257
+ # case for 0
258
+ else:
259
+ return '0'
260
+
261
+ # (rational ± √radicand) / denominator
262
+ else:
263
+ # fraction is a real number
264
+ if radicand > 0:
265
+ # num / den
266
+ if is_square(radicand):
267
+ if is_minus:
268
+ numerator = rational - square(radicand)[0]
269
+
270
+ else:
271
+ numerator = rational + square(radicand)[0]
272
+
273
+ return fraction(numerator, denominator)
274
+
275
+ # (rtn ± √rdc) / den
276
+ else:
277
+ fct = math.gcd(rational, square(radicand)[0])
278
+ gcd = math.gcd(fct, denominator)
279
+ rtn = rational // gcd
280
+ cef = square(radicand)[0] // gcd
281
+ rdc = square(radicand)[1]
282
+ den = denominator // gcd
283
+
284
+ if den == 1:
285
+ if is_minus:
286
+ return formal(f'{rtn}-{cef}√{rdc}')
287
+
288
+ else:
289
+ return formal(f'{rtn}+{cef}√{rdc}')
290
+
291
+ elif den == -1:
292
+ if is_minus:
293
+ return formal(f'{-rtn}+{cef}√{rdc}')
294
+
295
+ else:
296
+ return formal(f'{-rtn}-{cef}√{rdc}')
297
+
298
+ elif den > 0:
299
+ if is_minus:
300
+ return formal(f'({rtn}-{cef}√{rdc})/{den}')
301
+
302
+ else:
303
+ return formal(f'({rtn}+{cef}√{rdc})/{den}')
304
+
305
+ elif den < 0:
306
+ if is_minus:
307
+ return formal(f'({-rtn}+{cef}√{rdc})/{-den}')
308
+
309
+ else:
310
+ return formal(f'({-rtn}-{cef}√{rdc})/{-den}')
311
+
312
+ # fraction is a complex number
313
+ elif radicand < 0:
314
+ fct = math.gcd(rational, square(-radicand)[0])
315
+ gcd = math.gcd(fct, denominator)
316
+ rtn = rational // gcd
317
+ cef = square(-radicand)[0] // gcd
318
+ rdc = square(-radicand)[1]
319
+ den = denominator // gcd
320
+
321
+ if den == 1:
322
+ if is_minus:
323
+ return formal(f'{rtn}-{cef}√{rdc}i')
324
+
325
+ else:
326
+ return formal(f'{rtn}+{cef}√{rdc}i')
327
+
328
+ elif den == -1:
329
+ if is_minus:
330
+ return formal(f'{-rtn}+{cef}√{rdc}i')
331
+
332
+ else:
333
+ return formal(f'{-rtn}-{cef}√{rdc}i')
334
+
335
+ elif den > 0:
336
+ if is_minus:
337
+ return formal(f'({rtn}-{cef}√{rdc}i)/{den}')
338
+
339
+ else:
340
+ return formal(f'({rtn}+{cef}√{rdc}i)/{den}')
341
+
342
+ elif den < 0:
343
+ if is_minus:
344
+ return formal(f'({-rtn}+{cef}√{rdc}i)/{-den}')
345
+
346
+ else:
347
+ return formal(f'({-rtn}-{cef}√{rdc}i)/{-den}')
348
+
349
+ # rational / denominator
350
+ else:
351
+ return fraction(rational, denominator)
352
+
353
+ # simplify fractions contain cubic root which contains square root
354
+ def cbfrac(rational: int, radicand: int, denominator: int, is_minus: bool=False) -> str:
355
+ """
356
+ simplify fractions with cubic root
357
+
358
+ parameters:
359
+ rational: the integer in numerator of the fraction
360
+ radicand: the radicand in numerator of the fraction
361
+ denominator: the denominator of the fraction
362
+ is_minus: change the '+' between rational and radicand into '-' (default as False)
363
+
364
+ return:
365
+ formatted string of the mathematical expression
366
+
367
+ examples:
368
+ >>>cbfrac(3, 5, 1)
369
+ '³√(3+√5)'
370
+ >>>cbfrac(15, 1, 2)
371
+ '³√2'
372
+ >>>cbfrac(0, -3, 3)
373
+ '-⁶√3i/3'
374
+ >>>cbfrac(9, 1, 5, True)
375
+ '2/5'
376
+ >>>cbfrac(7, -4, 3, True)
377
+ '³√(7-2i)/3'
378
+ """
379
+ # format the cubic root
380
+ def sformal(expression: str) -> str:
381
+ if num == 1 or num == -1:
382
+ # 1·³√1/den -> 1/den, 1·⁶√1/den -> 1/den
383
+ if rdc == 1:
384
+ if radicand < 0:
385
+ expression = expression.replace('1·³√1', '').replace('1·⁶√1', '')
386
+
387
+ else:
388
+ expression = expression.replace('·³√1', '').replace('·⁶√1', '')
389
+
390
+ # 1·³√rdc/den -> ³√rdc/den, 1·⁶√rdc/den -> ⁶√rdc/den
391
+ else:
392
+ expression = expression.replace('1·³√', '³√').replace('1·⁶√', '⁶√')
393
+
394
+ else:
395
+ # num·³√1/den -> num/den, num·⁶√1/den -> num/den
396
+ if rdc == 1:
397
+ expression = expression.replace('·³√1', '').replace('·⁶√1', '')
398
+
399
+ # num·³√rdc/den, num·⁶√rdc/den
400
+ else:
401
+ pass
402
+
403
+ return expression
404
+
405
+ # format the cubic root and square root
406
+ def cformal(expression: str) -> str:
407
+ # 1·³√rdc/den -> ³√rdc/den, 1·⁶√rdc/den -> ⁶√rdc/den
408
+ if num == 1 or num == -1:
409
+ expression = expression.replace('1·³√', '³√')
410
+
411
+ if cef == 1:
412
+ # rtn ± 1√1 -> rtn ± 1
413
+ if rdc == 1:
414
+ if radicand < 0:
415
+ expression = expression.replace('1√1', '')
416
+
417
+ else:
418
+ expression = expression.replace('1√1', '1')
419
+
420
+ # rtn ± 1√rdc -> rtn ± √rdc
421
+ else:
422
+ expression = expression.replace('1√', '√')
423
+
424
+ else:
425
+ # rtn ± cef√1 -> rtn ± cef
426
+ if rdc == 1:
427
+ expression = expression.replace(f'{cef}√1', f'{cef}')
428
+
429
+ # rtn ± cef√rdc
430
+ else:
431
+ pass
432
+
433
+ return expression
434
+
435
+ # ± ⁶√radicand / denominator
436
+ if rational == 0:
437
+ # fraction is a real number
438
+ if radicand > 0:
439
+ if is_minus:
440
+ fct = -square(radicand)[0]
441
+
442
+ else:
443
+ fct = square(radicand)[0]
444
+
445
+ # num·³√rdc / den
446
+ if is_square(radicand):
447
+ rdc = cube(fct)[1]
448
+ gcd = math.gcd(cube(fct)[0], denominator)
449
+ num = cube(fct)[0] // gcd
450
+ den = denominator // gcd
451
+
452
+ if den == 1:
453
+ return sformal(f'{num}·³√{rdc}')
454
+
455
+ elif den == -1:
456
+ return sformal(f'{-num}·³√{rdc}')
457
+
458
+ elif den > 0:
459
+ return sformal(f'{num}·³√{rdc}/{den}')
460
+
461
+ elif den < 0:
462
+ return sformal(f'{-num}·³√{rdc}/{-den}')
463
+
464
+ # num·⁶√rdc / den
465
+ else:
466
+ rdc = square(radicand)[1] * cube(fct)[1] ** 2
467
+ gcd = math.gcd(cube(fct)[0], denominator)
468
+ num = cube(fct)[0] // gcd
469
+ den = denominator // gcd
470
+
471
+ if den == 1:
472
+ return sformal(f'{num}·⁶√{rdc}')
473
+
474
+ elif den == -1:
475
+ return sformal(f'{-num}·⁶√{rdc}')
476
+
477
+ elif den > 0:
478
+ return sformal(f'{num}·⁶√{rdc}/{den}')
479
+
480
+ elif den < 0:
481
+ return sformal(f'{-num}·⁶√{rdc}/{-den}')
482
+
483
+ # fraction is a complex number
484
+ if radicand < 0:
485
+ if is_minus:
486
+ fct = square(-radicand)[0]
487
+
488
+ else:
489
+ fct = -square(-radicand)[0]
490
+
491
+ # num·³√rdc*i / den
492
+ if is_square(-radicand):
493
+ rdc = cube(fct)[1]
494
+ gcd = math.gcd(cube(fct)[0], denominator)
495
+ num = cube(fct)[0] // gcd
496
+ den = denominator // gcd
497
+
498
+ if den == 1:
499
+ return sformal(f'{num}·³√{rdc}i')
500
+
501
+ elif den == -1:
502
+ return sformal(f'{-num}·³√{rdc}i')
503
+
504
+ elif den > 0:
505
+ return sformal(f'{num}·³√{rdc}i/{den}')
506
+
507
+ elif den < 0:
508
+ return sformal(f'{-num}·³√{rdc}i/{-den}')
509
+
510
+ # num·⁶√rdc*i / den
511
+ else:
512
+ rdc = square(-radicand)[1] * cube(fct)[1] ** 2
513
+ gcd = math.gcd(cube(fct)[0], denominator)
514
+ num = cube(fct)[0] // gcd
515
+ den = denominator // gcd
516
+
517
+ if den == 1:
518
+ return sformal(f'{num}·⁶√{rdc}i')
519
+
520
+ elif den == -1:
521
+ return sformal(f'{-num}·⁶√{rdc}i')
522
+
523
+ elif den > 0:
524
+ return sformal(f'{num}·⁶√{rdc}i/{den}')
525
+
526
+ elif den < 0:
527
+ return sformal(f'{-num}·⁶√{rdc}i/{-den}')
528
+
529
+ # case for 0
530
+ else:
531
+ return '0'
532
+
533
+ # ³√(rational ± √radicand) / denominator
534
+ else:
535
+ # fraction is a real number
536
+ if radicand > 0:
537
+ # num·³√rdc / den
538
+ if is_square(radicand):
539
+ if is_minus:
540
+ rtn = rational - square(radicand)[0]
541
+
542
+ else:
543
+ rtn = rational + square(radicand)[0]
544
+
545
+ rdc = cube(rtn)[1]
546
+ gcd = math.gcd(cube(rtn)[0], denominator)
547
+ num = cube(rtn)[0] // gcd
548
+ den = denominator // gcd
549
+
550
+ if den == 1:
551
+ return sformal(f'{num}·³√{rdc}')
552
+
553
+ elif den == -1:
554
+ return sformal(f'{-num}·³√{rdc}')
555
+
556
+ elif den > 0:
557
+ return sformal(f'{num}·³√{rdc}/{den}')
558
+
559
+ elif den < 0:
560
+ return sformal(f'{-num}·³√{rdc}/{-den}')
561
+
562
+ # ³√(rtn ± cef√rdc) / den
563
+ else:
564
+ rdc = square(radicand)[1]
565
+ fct = math.gcd(rational, square(radicand)[0])
566
+ rtn = rational * cube(fct)[1] // fct
567
+ cef = square(radicand)[0] * cube(fct)[1] // fct
568
+ gcd = math.gcd(cube(fct)[0], denominator)
569
+ num = cube(fct)[0] // gcd
570
+ den = denominator // gcd
571
+
572
+ if den == 1:
573
+ if is_minus:
574
+ return cformal(f'{num}·³√({rtn}-{cef}√{rdc})')
575
+
576
+ else:
577
+ return cformal(f'{num}·³√({rtn}+{cef}√{rdc})')
578
+
579
+ elif den == -1:
580
+ if is_minus:
581
+ return cformal(f'{-num}·³√({rtn}-{cef}√{rdc})')
582
+
583
+ else:
584
+ return cformal(f'{-num}·³√({rtn}+{cef}√{rdc})')
585
+
586
+ elif den > 0:
587
+ if is_minus:
588
+ return cformal(f'{num}·³√({rtn}-{cef}√{rdc})/{den}')
589
+
590
+ else:
591
+ return cformal(f'{num}·³√({rtn}+{cef}√{rdc})/{den}')
592
+
593
+ elif den < 0:
594
+ if is_minus:
595
+ return cformal(f'{-num}·³√({-rtn}-{cef}√{rdc})/{-den}')
596
+
597
+ else:
598
+ return cformal(f'{-num}·³√({-rtn}+{cef}√{rdc})/{-den}')
599
+
600
+ # fraction is a complex number
601
+ elif radicand < 0:
602
+ # ³√(rtn ± cef√rdc*i) / den
603
+ rdc = square(-radicand)[1]
604
+ fct = math.gcd(rational, square(-radicand)[0])
605
+ rtn = rational * cube(fct)[1] // fct
606
+ cef = square(-radicand)[0] * cube(fct)[1] // fct
607
+ gcd = math.gcd(cube(fct)[0], denominator)
608
+ num = cube(fct)[0] // gcd
609
+ den = denominator // gcd
610
+
611
+ if den == 1:
612
+ if is_minus:
613
+ return cformal(f'{num}·³√({rtn}-{cef}√{rdc}i)')
614
+
615
+ else:
616
+ return cformal(f'{num}·³√({rtn}+{cef}√{rdc}i)')
617
+
618
+ elif den == -1:
619
+ if is_minus:
620
+ return cformal(f'{-num}·³√({rtn}-{cef}√{rdc}i)')
621
+
622
+ else:
623
+ return cformal(f'{-num}·³√({rtn}+{cef}√{rdc}i)')
624
+
625
+ elif den > 0:
626
+ if is_minus:
627
+ return cformal(f'{num}·³√({rtn}-{cef}√{rdc}i)/{den}')
628
+
629
+ else:
630
+ return cformal(f'{num}·³√({rtn}+{cef}√{rdc}i)/{den}')
631
+
632
+ elif den < 0:
633
+ if is_minus:
634
+ return cformal(f'{-num}·³√({-rtn}-{cef}√{rdc}i)/{-den}')
635
+
636
+ else:
637
+ return cformal(f'{-num}·³√({-rtn}+{cef}√{rdc}i)/{-den}')
638
+
639
+ # ³√rational / denominator
640
+ else:
641
+ rdc = cube(rational)[1]
642
+ gcd = math.gcd(cube(rational)[0], denominator)
643
+ num = cube(rational)[0] // gcd
644
+ den = denominator // gcd
645
+
646
+ if den == 1:
647
+ return sformal(f'{num}·³√{rdc}')
648
+
649
+ elif den == -1:
650
+ return sformal(f'{-num}·³√{rdc}')
651
+
652
+ elif den > 0:
653
+ return sformal(f'{num}·³√{rdc}/{den}')
654
+
655
+ elif den < 0:
656
+ return sformal(f'{-num}·³√{rdc}/{-den}')
657
+
658
+ # simplify cubic roots
659
+ def cubic_root(rational: int, radicand: int=0, denominator: int=1, is_minus: bool=False) -> str:
660
+ """
661
+ automatically simplify and format cubic roots
662
+
663
+ parameters:
664
+ rational: the integer in numerator of the cubic root
665
+ radicand: the radicand in numerator of the cubic root (default as 0)
666
+ denominator: the denominator of the cubic root (default as 1)
667
+ is_minus: change the '+' between rational and radicand into '-' (default as False)
668
+
669
+ return:
670
+ formatted string of the mathematical expression
671
+
672
+ examples:
673
+ >>>cubic_root(5, 3, 8, True)
674
+ '³√(5-√3)/8'
675
+ >>>cubic_root(12)
676
+ '³√12'
677
+ >>>cubic_root(0, -5)
678
+ '-⁶√5i'
679
+ >>>cubic_root(-32, -704)
680
+ '1-√11i'
681
+ >>>cubic_root(-48, -64, 3, True)
682
+ '2·³√(-6-i)/3'
683
+ >>>cubic_root(-64800, 33139243584)
684
+ '-6+6√33·³√3'
685
+ """
686
+ # ± ⁶√radicand / denominator
687
+ if rational == 0:
688
+ if is_minus:
689
+ return cbfrac(0, radicand, denominator, True)
690
+
691
+ else:
692
+ return cbfrac(0, radicand, denominator)
693
+
694
+ # ³√(rational ± √radicand) / denominator
695
+ else:
696
+ # case for real number
697
+ if radicand > 0:
698
+ fct = math.gcd(rational, square(radicand)[0])
699
+ rtn = rational // fct
700
+ rdc = radicand // fct ** 2
701
+ R1 = (rtn ** 2 - rdc) * (rtn + math.sqrt(rdc))
702
+ R2 = (rtn ** 2 - rdc) * (rtn - math.sqrt(rdc))
703
+ x = round(rtn/4+3*(cbrt(R1)+cbrt(R2))/8)
704
+
705
+ if is_cube(x):
706
+ pass
707
+
708
+ else:
709
+ x = 0
710
+
711
+ R1 = (rational ** 2 - radicand) * (rational + math.sqrt(radicand))
712
+ R2 = (rational ** 2 - radicand) * (rational - math.sqrt(radicand))
713
+ y = round(rational/4+3*(cbrt(R1)+cbrt(R2))/8)
714
+
715
+ if is_cube(y):
716
+ pass
717
+
718
+ else:
719
+ y = 0
720
+
721
+ if x != 0 and is_cube((rtn-x)**3//(27*x)):
722
+ a = cube(fct)[0] * cube(x)[0]
723
+ b = cube(fct)[0] ** 2 * (rtn - x) // (3 * cube(x)[0])
724
+
725
+ if is_cube(fct):
726
+ if is_minus:
727
+ return sqfrac(a, b, denominator, True)
728
+
729
+ else:
730
+ return sqfrac(a, b, denominator)
731
+
732
+ else:
733
+ if is_minus:
734
+ return f'{sqfrac(a, b, denominator, True)}·{cubic_root(cube(fct)[1])}'
735
+
736
+ else:
737
+ return f'{sqfrac(a, b, denominator)}·{cubic_root(cube(fct)[1])}'
738
+
739
+ elif y != 0 and is_cube((rational-y)**3//(27*y)):
740
+ a = cube(y)[0]
741
+ b = (rational - y) // (3 * cube(y)[0])
742
+
743
+ if is_minus:
744
+ return sqfrac(a, b, denominator, True)
745
+
746
+ else:
747
+ return sqfrac(a, b, denominator)
748
+
749
+ else:
750
+ if is_minus:
751
+ return cbfrac(rational, radicand, denominator, True)
752
+
753
+ else:
754
+ return cbfrac(rational, radicand, denominator)
755
+
756
+ # case for complex number
757
+ elif radicand < 0:
758
+ fct = math.gcd(rational, square(-radicand)[0])
759
+ rtn = rational // fct
760
+ rdc = radicand // fct ** 2
761
+ theta = math.atan(math.sqrt(-rdc)/abs(rtn))
762
+ z1 = round(abs(rtn)/4+3*math.sqrt(rtn**2-rdc)*math.cos(theta/3)/4)
763
+ z2 = round(abs(rtn)/4+3*math.sqrt(rtn**2-rdc)*math.cos(theta/3+2*math.pi/3)/4)
764
+ z3 = round(abs(rtn)/4+3*math.sqrt(rtn**2-rdc)*math.cos(theta/3+4*math.pi/3)/4)
765
+
766
+ if is_cube(z1):
767
+ x = z1
768
+
769
+ elif is_cube(z2):
770
+ x = z2
771
+
772
+ elif is_cube(z3):
773
+ x = z3
774
+
775
+ else:
776
+ x = 0
777
+
778
+ theta = math.atan(math.sqrt(-radicand)/abs(rational))
779
+ z1 = round(abs(rational)/4+3*math.sqrt(rational**2-radicand)*math.cos(theta/3)/4)
780
+ z2 = round(abs(rational)/4+3*math.sqrt(rational**2-radicand)*math.cos(theta/3+2*math.pi/3)/4)
781
+ z3 = round(abs(rational)/4+3*math.sqrt(rational**2-radicand)*math.cos(theta/3+4*math.pi/3)/4)
782
+
783
+ if is_cube(z1):
784
+ y = z1
785
+
786
+ elif is_cube(z2):
787
+ y = z2
788
+
789
+ elif is_cube(z3):
790
+ y = z3
791
+
792
+ else:
793
+ y = 0
794
+
795
+ if rational < 0:
796
+ x = -x
797
+ y = -y
798
+
799
+ else:
800
+ pass
801
+
802
+ if x != 0 and is_cube((rtn-x)**3//(27*x)):
803
+ a = cube(fct)[0] * cube(x)[0]
804
+ b = cube(fct)[0] ** 2 * (rtn - x) // (3 * cube(x)[0])
805
+
806
+ if is_cube(fct):
807
+ if is_minus and 3 * a ** 2 + b > 0 or not is_minus and 3 * a ** 2 + b < 0:
808
+ return sqfrac(a, b, denominator, True)
809
+
810
+ else:
811
+ return sqfrac(a, b, denominator)
812
+
813
+ else:
814
+ if is_minus and 3 * a ** 2 + b > 0 or not is_minus and 3 * a ** 2 + b < 0:
815
+ return f'{sqfrac(a, b, denominator, True)}·{cubic_root(cube(fct)[1])}'
816
+
817
+ else:
818
+ return f'{sqfrac(a, b, denominator)}·{cubic_root(cube(fct)[1])}'
819
+
820
+ elif y != 0 and is_cube((rational-y)**3//(27*y)):
821
+ a = cube(y)[0]
822
+ b = (rational - y) // (3 * cube(y)[0])
823
+
824
+ if is_minus and 3 * a ** 2 + b > 0 or not is_minus and 3 * a ** 2 + b < 0:
825
+ return sqfrac(a, b, denominator, True)
826
+
827
+ else:
828
+ return sqfrac(a, b, denominator)
829
+
830
+ else:
831
+ if is_minus:
832
+ return cbfrac(rational, radicand, denominator, True)
833
+
834
+ else:
835
+ return cbfrac(rational, radicand, denominator)
836
+
837
+ # case for radicand = 0
838
+ else:
839
+ return cbfrac(rational, 0, denominator)