Frakcje egipskie

20

Przegląd:

Z Wikipedii : Ułamek egipski to suma różnych ułamków jednostkowych. Oznacza to, że każda frakcja w wyrażeniu ma licznik równy 1 i mianownik, który jest dodatnią liczbą całkowitą, a wszystkie mianowniki różnią się od siebie. Wartością wyrażenia tego typu jest dodatnia liczba wymierna a / b. Każda dodatnia liczba wymierna może być reprezentowana przez ułamek egipski.

Wyzwanie:

Napisz najkrótszą funkcję, która zwróci wartości wszystkich mianowników dla najmniejszego zestawu ułamków jednostkowych, które składają się na dany ułamek.

Zasady / Ograniczenia:

  • Dane wejściowe będą dwie dodatnie wartości całkowite.
    • Może to być na STDIN, argvoddzielone przecinkami, rozdzielane spacjami lub dowolna inna metoda.
  • Pierwszą wartością wejściową jest licznik, a drugą wartością wejściową mianownik.
  • Pierwsza wartość wejściowa musi być mniejsza niż druga.
  • Dane wyjściowe mogą zawierać wartości przekraczające ograniczenia pamięci systemu / języka (RAM, MAX_INT lub jakiekolwiek inne ograniczenia kodu / systemu). Jeśli tak się stanie, po prostu skróć wynik do najwyższej możliwej wartości i zauważ, że jakoś (tj ....).
  • Wyjście powinno być w stanie obsłużyć wartość mianownika do co najmniej 2 147 483 647 (2 31 -1, 32-bitowe ze znakiem int).
    • Wyższa wartość ( longitp.) Jest całkowicie do przyjęcia.
  • Dane wyjściowe powinny zawierać listę wszystkich wartości mianowników najmniejszego zestawu znalezionych ułamków jednostkowych (lub samych ułamków, tj 1/2.).
  • Wyjście należy uporządkować rosnąco według wartości mianownika (malejącej o wartość ułamka).
  • Dane wyjściowe można rozdzielić w dowolny sposób, ale między nimi musi być jakiś znak, aby odróżnić jedną wartość od drugiej.
  • To jest golf golfowy, więc wygrywa najkrótsze rozwiązanie.

Przykłady:

  • Wejście 1:

    43, 48

  • Wyjście 1:

    2, 3, 16

  • Wejście 2:

    8/11

  • Wyjście 2:

    1/2 1/6 1/22 1/66

  • Wejście 3:

    5 121

  • Wyjście 3:

    33 121 363

Gaffi
źródło
Wejście / wyjście 2 powinno być 8, 11i 2, 6, 22, 66prawda?
mellamokb
2
Możliwą sugestią, aby usunąć tę niejednoznaczność, byłoby wymaganie najmniejszego zestawu ułamków jednostkowych o najmniejszym ostatecznym mianowniku. Na przykład, 1/2 1/6 1/22 1/66byłoby preferowane 1/2 1/5 1/37 1/4070dla danych wejściowych 8/11.
primo
2
Sugeruję dodanie 5/121 = 1/33+1/121+1/363do przypadków testowych. Wszystkie chciwe programy (w tym moje) dają za to 5 frakcji. Przykład pochodzi z Wikipedii .
ugoren
1
@primo Myślę, że jeśli istnieje wiele minimów, cokolwiek można znaleźć, byłoby dopuszczalne. Jeśli w rezultacie można napisać jeden algorytm z mniejszą liczbą znaków, nie chciałbym przeszkadzać temu rozwiązaniu.
Gaffi
1
Dałem +1, odkąd nauczyłem się o frakcjach egipskich na kursie historii matematyki (i musiałem z nimi robić matematykę, a także znaleźć sumy ułamkowe takie jak ten problem). Ładne i twórcze wyzwanie.
mbomb007

Odpowiedzi:

6

Common Lisp, 137 znaków

(defun z(n)(labels((i(n s r)(cond((= n 0)r)((< n(/ 1 s))(i n(ceiling(/ 1 n))r))(t(i(- n(/ 1 s))(1+ s)(cons s r))))))(reverse(i n 2'()))))

(z 43/48) -> (2 3 16)

(z 8/11) -> (2 5 37 4070)

(z 5/121) -> (25 757 763309 873960180913 1527612795642093418846225)

Nie musisz się martwić o ogromne liczby lub obsługę notacji ułamkowej!

Paul Richter
źródło
(defun z (n) (etykiety ((i (nsr)) (cond ((= n 0) r) ((<n (/ 1 s)) (in (pułap (/ 1 n)) r)) (t ( i (- n (/ 1 s)) (1+ s) (cons sr)))))) (reverse (in 2 '())))) (z 43/48) Pokaż brak wyniku w t ... Czego muszę użyć do wydrukowania wyniku?
RosLuP,
1
(print (z 103/333)) zwraca jedną listę 5 liczb, ale istniałaby jedna lista 4 liczb jako: 1 / 4,1 / 18,1 / 333,1 / 1332. Tak więc powyższa funkcja nie zwróci minimum.
RosLuP
8

Python 2, 169 167 znaków

x,y=input()
def R(n,a,b):
 if n<2:return[b/a][b%a:]
 for m in range((b+a-1)/a,b*n/a):
  L=R(n-1,a*m-b,m*b)
  if L:return[m]+L
n=L=0
while not L:n+=1;L=R(n,x,y)
print L

Pobiera rozdzielone przecinkami argumenty na standardowym wyjściu i drukuje listę python na standardowym wyjściu.

$ echo 8,11 | ./egypt.py 
[2, 5, 37, 4070]
Keith Randall
źródło
2
1. Myślę, że możesz zapisać dwa znaki, używając tabulatora na drugim poziomie wcięcia. 2. Skrypt nie wskazuje obcięcia z powodu przekroczenia ograniczeń pamięci systemowej.
breadbox
W Tio Twój kod zabraknie pamięci dla 103/45533
RosLuP
Zamiast tego w Ideone kod przechodzi w błąd czasu wykonania dla tego samego wejścia 103, 45533: Błąd czasu wykonania #stdin #stdout #stderr 0,89s 99264 KB
RosLuP
4

PHP 82 bajty

<?for(fscanf(STDIN,"%d%d",$a,$b);$a;)++$i<$b/$a||printf("$i ",$a=$a*$i-$b,$b*=$i);

Można to skrócić, ale bieżący licznik i mianownik należy zachować jako liczby całkowite, aby uniknąć błędu zaokrąglania zmiennoprzecinkowego (zamiast utrzymywania bieżącego ułamka).

Przykładowe użycie:

$ echo 43 48 | php egyptian-fraction.php
2 3 16
$ echo 8 11 | php egyptian-fraction.php
2 5 37 4070
primo
źródło
Operator przecinka emulowany jako bezużyteczne argumenty dla printf? Powinienem gdzieś zapisać tę sztuczkę.
Konrad Borowski
1
Jestem prawie pewien, że jest to Chciwy Algorytm , więc nie zawsze da najmniejszy zestaw ułamków. Jeśli uruchomisz go z danymi wejściowymi takimi jak 5 121lub 31 311, da złą odpowiedź (po bardzo długim czasie).
grc
@grc 31/311 -> {a [1] -> 11, a [2] -> 115, a [3] -> 13570, a [4] -> 46422970}
Dr. belisarius
4

C, 163 177 znaków

6/6 : W końcu program poprawnie obsługuje teraz obcinanie we wszystkich przypadkach. Zajęło mi to o wiele więcej znaków, niż się spodziewałem, ale było warto. Program powinien teraz w 100% spełniać wymagania dotyczące problemu.

d[99],c,z;
r(p,q,n,i){for(c=n+q%p<2,i=q/p;c?d[c++]=i,0:++i<n*q/p;)q>~0U/2/i?c=2:r(i*p-q,i*q,n-1);}
main(a,b){for(scanf("%d%d",&a,&b);!c;r(a,b,++z));while(--c)printf("%d\n",d[c]);}

Program pobiera licznik i mianownik na standardowe wejście. Mianowniki są drukowane na standardowe wyjście, po jednym w wierszu. Skrócone wyjście jest wskazywane przez wydrukowanie zerowego mianownika na końcu listy:

$ ./a.out
2020 2064
2
3
7
402
242004

$ ./a.out
6745 7604
2
3
19
937
1007747
0

Mianowniki w drugim przykładzie sumują się do 95485142815/107645519046, który różni się od 6745/7604 o około 1e-14.

chlebak
źródło
Ponownie myślę, że jest to chciwy algorytm.
grc
Najbardziej zewnętrzna pętla bada wszystkie możliwe odpowiedzi N mianowników, zanim zacznie testować odpowiedzi N + 1 mianowników. Przypuszczam, że można to nazwać chciwym, ale wierzę, że spełnia zadany problem.
breadbox
Przepraszam, cofam to. Nie podąża za chciwym rozwiązaniem, ale odkryłem, że nie jest całkowicie dokładny w przypadku niektórych danych wejściowych ( 31 311na przykład).
grc
31 311przepełnia się, ale program nie może go oflagować.
breadbox
3

Python, 61 znaków

Dane wejściowe ze STDIN, oddzielone przecinkami.
Wyjście do STDOUT, separacja nowego wiersza.
Nie zawsze zwraca najkrótszą reprezentację (np. 5/121).

a,b=input()
while a:
    i=(b+a-1)/a
    print"1/%d"%i
    a,b=a*i-b,i*b

Znaki zliczane bez zbędnych nowych linii (tj. Łączące wszystkie linie w whileużyciu ;).
Frakcja jest a/b.
ijest b/azaokrąglony, więc wiem 1/i <= a/b.
Po wydrukowaniu 1/i, zamieniam a/bsię a/b - 1/i, co jest (a*i-b)/(i*b).

ugoren
źródło
Chcę to zagłosować, ponieważ jest tak mały, ale brakuje mu tylko jednego kawałka!
Gaffi
2
Chcę naprawić ten jeden kawałek, ale nie będzie tak mały ... Mam wrażenie, że wymyślę na nowo rozwiązanie Keitha Randalla.
ugoren
2

C, 94 bajty

n,d,i;main(){scanf("%i%i",&n,&d);for(i=1;n>0&++i>0;){if(n*i>=d)printf("%i ",i),n=n*i-d,d*=i;}}

Wypróbuj online

edycja: krótsza wersja kodu została opublikowana w komentarzach, więc ją zastąpiłem. Dzięki!

う ち わ 密 か
źródło
2
Witam i witam na stronie! To zawody w golfa , więc celem jest jak najkrótszy kod . Wygląda na to, że istnieje wiele rzeczy, które możesz zrobić, aby skrócić swój kod. Na przykład możesz usunąć wszystkie niepotrzebne białe znaki z odpowiedzi.
DJMcMayhem
@DJMcMayhem Dziękuję panu, zrozumiał i zrobił.
う ち わ 密 か
Cześć, witamy w PPCG! Czy mógłbyś dodać link TryItOnline z kodem testowym dla przypadków testowych w wyzwaniu? Również niektóre rzeczy, na które można grać w golfa: for(i=2;n>0&&i>0;i++)mogą być for(i=1;n>0&++i>0;); wsporniki pętli for można usunąć (ponieważ ma ona tylko ifwnętrze); d=d*i;może być d*=i;; i nie jestem do końca pewien, ale myślę, że #include <stdio.h>może być bez spacji: #include<stdio.h>. Och, i może być interesujące przeczytać Porady dotyczące gry w golfa w C i Porady dotyczące gry w golfa w <wszystkich językach>
Kevin Cruijssen
@KevinCruijssen Dzięki za wskazówki.
う ち わ 密 か
94 bajty .
Jonathan Frech
1

Stax , 18 bajtów

é├WüsOΩ↨÷╬6H╒σw[▐â

Uruchom i debuguj

Na każdym kroku próbuje zminimalizować kolejny licznik . Wydaje się, że działa, ale nie mogę tego udowodnić.

rekurencyjny
źródło
0

AXIOM, 753 bajty

L==>List FRAC INT
macro  M(q)==if c<m or(c=m and m<999 and reduce(max,map(denom,q))<xv)then(m:=c;a:=q;xv:=reduce(max,map(denom,a)))
f(x,n)==(y:=x;a:L:=[];c:=0;q:=denom x;q:=q^4;for i in n.. repeat((c:=c+1)>50=>(a:=[];break);1/i>y=>1;member?(1/i,a)=>1;a:=concat(a,1/i);(y:=y-1/i)=0=>break;numer(y)=1 and ~member?(y,a)=>(a:=concat(a,y);break);(i:=floor(1/y))>q=>(a:=[];break));a)
h(x:FRAC INT):L==(a:L:=[];x>1=>a;numer(x)=1=>[x];n:=max(2,floor(1/x));xv:=m:=999;d:=denom x;zd:=divisors d;z:=copy zd;for i in 2..30 repeat z:=concat(z,i*zd);d:=min(10*d,n+9*m);for i in n..d repeat((c:=maxIndex(b:=f(x,i)))=0=>1;c>m+1=>1;M(b);v:=reduce(+,delete(b,1));for j in z repeat((c:=1+maxIndex(q:=f(v,j)))=1=>1;member?(b.1,q)=>1;q:=concat(b.1,q);M(q)));reverse(sort a))

Pomysł polegałby na zastosowaniu „Chciwego algorytmu” z różnymi punktami początkowymi i zapisaniu listy o minimalnej długości. Ale nie zawsze znajdowałoby to minimalne rozwiązanie o mniej zróżnicowanym: „tablica A będzie mniejsza niż tablica B, i tylko wtedy, gdy A ma kilka elementów B lub jeśli liczba elementów A jest taka sama jak liczba elementów B , niż A jest mniejszy niż B, jeśli bardziej mały element A jest większy niż liczba, niż więcej mały element B ”. Nie golfisty i test

-- this would be the "Greedy Algorithm"
fracR(x,n)==
   y:=x;a:L:=[];c:=0;q:=denom x;q:=q^4
   for i in n.. repeat
      (c:=c+1)>50   =>(a:=[];break)
      1/i>y         =>1
      member?(1/i,a)=>1
      a:=concat(a,1/i)
      (y:=y-1/i)=0  =>break
      numer(y)=1 and ~member?(y,a)=>(a:=concat(a,y);break)
      (i:=floor(1/y))>q           =>(a:=[];break)
   a

-- Return one List a=[1/x1,...,1/xn] with xn PI and x=r/s=reduce(+,a) or return [] for fail
Frazione2SommaReciproci(x:FRAC INT):L==
    a:L:=[]
    x>1       =>a
    numer(x)=1=>[x]
    n:=max(2,floor(1/x));xv:=m:=999;d:=denom x;zd:=divisors d;z:=copy zd
    for i in 2..30 repeat z:=concat(z,i*zd)
    d:=min(10*d,n+9*m) 
    for i in n..d repeat
        (c:=maxIndex(b:=fracR(x,i)))=0=>1 
        c>m+1                         =>1
        M(b)
        v:=reduce(+,delete(b,1))
        for j in z repeat
              (c:=1+maxIndex(q:=fracR(v,j)))=1=>1
              member?(b.1,q)                  =>1
              q:=concat(b.1,q)
              M(q) 
    reverse(sort a)

(7) -> [[i,h(i)] for i in [1/23,2/23,43/48,8/11,5/121,2020/2064,6745/7604,77/79,732/733]]
   (7)
      1   1      2   1  1      43  1 1  1      8  1 1  1  1
   [[--,[--]], [--,[--,---]], [--,[-,-,--]], [--,[-,-,--,--]],
     23  23     23  12 276     48  2 3 16     11  2 6 22 66
      5    1  1   1      505  1 1 1  1    1
    [---,[--,---,---]], [---,[-,-,-,---,----]],
     121  33 121 363     516  2 3 7 602 1204
     6745  1 1  1  1    1      1       77  1 1 1  1  1   1
    [----,[-,-,--,---,-----,------]], [--,[-,-,-,--,---,---]],
     7604  2 3 19 950 72238 570300     79  2 3 8 79 474 632
     732  1 1 1  1   1    1     1
    [---,[-,-,-,--,----,-----,-----]]]
     733  2 3 7 45 7330 20524 26388
                                                      Type: List List Any
       Time: 0.07 (IN) + 200.50 (EV) + 0.03 (OT) + 9.28 (GC) = 209.88 sec
(8) -> h(124547787/123456789456123456)
   (8)
        1             1                         1
   [---------, ---------------, ---------------------------------,
    991247326  140441667310032  613970685539400439432280360548704
                                     1
    -------------------------------------------------------------------]
    3855153765004125533560441957890277453240310786542602992016409976384
                                              Type: List Fraction Integer
                     Time: 17.73 (EV) + 0.02 (OT) + 1.08 (GC) = 18.83 sec
(9) -> h(27538/27539)
         1 1 1  1  1    1      1        1
   (9)  [-,-,-,--,---,-----,------,----------]
         2 3 7 52 225 10332 826170 1100871525
                                              Type: List Fraction Integer
                     Time: 0.02 (IN) + 28.08 (EV) + 1.28 (GC) = 29.38 sec

referencje i numery z: http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fractions/egyptian.html

dla dodania czegoś, to poniżej byłoby zoptymalizowane pod kątem znajdowania ułamka o minimalnej długości, który ma maksymalny mianownik mniej (i nie jest zoptymalizowany dla długości)

L==>List FRAC INT

-- this would be the "Greedy Algorithm"
fracR(x,n)==
   y:=x;a:L:=[];c:=0;q:=denom x;q:=q^20
   for i in n.. repeat
      (c:=c+1)>1000  =>(a:=[];break)
      1/i>y          =>1
      member?(1/i,a) =>1
      a:=concat(a,1/i)
      (y:=y-1/i)=0  =>break
      numer(y)=1 and ~member?(y,a)=>(a:=concat(a,y);break)
      (i:=floor(1/y))>q           =>(a:=[];break)
   a

-- Return one List a=[1/x1,...,1/xn] with xn PI and x=r/s=reduce(+,a) or return [] for fail
Frazione2SommaReciproci(x:FRAC INT):L==
    a:L:=[]
    x>1       =>a
    numer(x)=1=>[x]
    n:=max(2,floor(1/x));xv:=m:=999;d:=denom x;zd:=divisors d;z:=copy zd; 
    w1:= if d>1.e10 then 1000 else 300; w2:= if d>1.e10 then 1000 else if d>1.e7 then 600 else if d>1.e5 then 500 else if d>1.e3 then 400 else 100;
    for i in 2..w1 repeat(mt:=(i*zd)::List PI;mv:=[yy for yy in mt|yy>=n];z:=sort(removeDuplicates(concat(z,mv)));#z>w2=>break)
    for i in z repeat
        (c:=maxIndex(b:=fracR(x,i)))=0=>1 
        c>m+1                         =>1
        if c<m or(c=m and m<999 and reduce(max,map(denom,b))<xv)then(m:=c;a:=b;xv:=reduce(max,map(denom,a)))
        v:=reduce(+,delete(b,1))
        for j in z repeat
              (c:=1+maxIndex(q:=fracR(v,j)))=1=>1
              member?(b.1,q)                  =>1
              q:=concat(b.1,q)
              if c<m or(c=m and m<999 and reduce(max,map(denom,q))<xv)then(m:=c;a:=q;xv:=reduce(max,map(denom,a)))
    reverse(sort a)

wyniki:

(5) -> [[i,Frazione2SommaReciproci(i)] for i in [1/23,2/23,43/48,8/11,5/121,2020/2064,6745/7604,77/79,732/733]]
   (5)
      1   1      2   1  1      43  1 1  1      8  1 1  1  1
   [[--,[--]], [--,[--,---]], [--,[-,-,--]], [--,[-,-,--,--]],
     23  23     23  12 276     48  2 3 16     11  2 6 22 66
      5    1  1   1      505  1 1 1  1    1
    [---,[--,---,---]], [---,[-,-,-,---,----]],
     121  33 121 363     516  2 3 7 602 1204
     6745  1 1  1  1    1      1       77  1 1 1  1  1   1
    [----,[-,-,--,---,-----,------]], [--,[-,-,-,--,---,---]],
     7604  2 3 19 950 72238 570300     79  2 3 8 79 474 632
     732  1 1 1  1   1    1     1
    [---,[-,-,-,--,----,-----,-----]]]
     733  2 3 7 45 7330 20524 26388
                                                      Type: List List Any
                     Time: 0.08 (IN) + 53.45 (EV) + 3.03 (GC) = 56.57 sec
(6) -> Frazione2SommaReciproci(124547787/123456789456123456)
   (6)
        1            1               1                  1
   [---------, ------------, ----------------, -------------------,
    994074172  347757767307  2764751529594496  1142210063701888512
                      1
    -------------------------------------]
    2531144929865351036156388364636113408
                                              Type: List Fraction Integer
         Time: 0.15 (IN) + 78.30 (EV) + 0.02 (OT) + 5.28 (GC) = 83.75 sec
(7) -> Frazione2SommaReciproci(27538/27539)
         1 1 1  1   1     1       1       1
   (7)  [-,-,-,--,----,-------,-------,-------]
         2 3 7 43 1935 3717765 5204871 7105062
                                              Type: List Fraction Integer
                     Time: 0.05 (IN) + 45.43 (EV) + 2.42 (GC) = 47.90 sec

Wydaje się, że wiele dobrych mianowników ma jako dzielniki czynnika mianownika frakcji wejściowej.

RosLuP
źródło
0

C, 85 78 bajtów

Poprawiony przez @ceilingcat , 78 bajtów:

n,d;main(i){for(scanf("%i%i",&n,&d);n;n*++i/d&&printf("%i ",i,d*=i,n=n*i-d));}

Wypróbuj online!


Moja oryginalna odpowiedź, 85 bajtów:

n,d,i=1;main(){for(scanf("%i%i",&n,&d);n&&++i;n*i/d?printf("%i ",i),n=n*i-d,d*=i:0);}

Wypróbuj online!

Częścią uznania powinien być Jonathan Frech , który napisał to 94-bajtowe rozwiązanie, które ulepszyłem.

OverclockedSanic
źródło
0

APL (NARS), 2502 bajtów

fdn←{1∧÷⍵}⋄fnm←{1∧⍵}⋄ffl←{m←⎕ct⋄⎕ct←0⋄r←⌊⍵⋄⎕ct←m⋄r}⋄divisori←{a[⍋a←{∪×/¨{0=≢⍵:⊂⍬⋄s,(⊂1⌷⍵),¨s←∇1↓⍵}π⍵}⍵]}

r←frRF w;x;y;c;q;i;j
(x i)←w⋄i-←1⋄y←x⋄r←⍬⋄c←0⋄q←fdn x⋄q←q*20
i+←1
→4×⍳∼1000<c+←1⋄→6
j←÷i⋄→2×⍳j>y⋄→2×⍳(⊂j)∊r⋄r←r,(⊂j)⋄y←y-j⋄→0×⍳y=0⋄→5×⍳1≠fnm y⋄→5×⍳(⊂y)∊r⋄r←r,⊂y⋄→0
→2×⍳∼q<i←ffl ÷y
r←⍬

r←fr2SumF x;n;xv;m;d;zd;z;i;b;c;t;v;j;k;q;w1;w2;t;b1
z←r←⍬⋄→0×⍳1≤ffl x
:if 1=fnm x⋄r←,⊂x⋄→0⋄:endif
n←2⌈ffl÷x⋄xv←m←999⋄d←fdn x⋄zd←divisori d
w1←1000⋄w2←50⋄:if d>1.e10⋄w2←700⋄:elseif d>1.e7⋄w2←600⋄:elseif d>1.e5⋄w2←500⋄:elseif d>1.e3⋄w2←400⋄:elseif d>1.e2⋄w2←100⋄:endif
:for i :in ⍳w1⋄z←∪z∪k/⍨{⍵≥n}¨k←i×zd⋄:if w2<≢z⋄:leave⋄:endif⋄:endfor
z←∪z∪zd⋄z←z[⍋z]
:for i :in z
    :if 0=c←≢b←frRF x i ⋄:continue⋄:endif
    :if      c>m+1      ⋄:continue⋄:endif
    :if      c<m        ⋄m←c⋄r←b⋄xv←⌈/fdn¨b
    :elseif (c=m)∧(m<999)
         :if xv>t←⌈/fdn¨b⋄m←c⋄r←b⋄xv←t⋄:endif
    :endif
    :if c≤2⋄:continue⋄:endif
    v←↑+/1↓b⋄b1←(⊂↑b)
    :for j :in z
       :if 1=c←1+≢q←frRF v j⋄:continue⋄:endif
       :if        b1∊q      ⋄:continue⋄:endif
       q←b1,q
       :if  c<m⋄m←c⋄r←q     ⋄xv←⌈/fdn¨q
       :elseif (c=m)∧(m<999)
           :if xv>t←⌈/fdn¨q⋄m←c⋄r←q⋄xv←t⋄:endif
       :endif
    :endfor
:endfor
→0×⍳1≥≢r⋄r←r[⍋fdn¨r]

Trasacja z kodu AXIOM dla tego problemu, do APL, używając po raz pierwszy (dla mnie) typu ułamka (czyli bignum ...).

103r233 oznacza ułamek 103/233. Test:

  ⎕fmt fr2SumF 1r23
┌1────┐
│ 1r23│
└~────┘
  ⎕fmt fr2SumF 2r23
┌2──────────┐
│ 1r12 1r276│
└~──────────┘
  ⎕fmt fr2SumF 43r48
┌3────────────┐
│ 1r2 1r3 1r16│
└~────────────┘
  fr2SumF 8r11
1r2 1r6 1r22 1r66 
  fr2SumF 5r121
1r33 1r121 1r363 
  fr2SumF 2020r2064
1r2 1r3 1r7 1r602 1r1204 
  fr2SumF 6745r7604
1r2 1r3 1r19 1r950 1r72238 1r570300 
  fr2SumF 77r79
1r2 1r3 1r8 1r79 1r474 1r632 
  fr2SumF 732r733
1r2 1r3 1r7 1r45 1r7330 1r20524 1r26388 
  fr2SumF 27538r27539
1r2 1r3 1r7 1r43 1r1935 1r3717765 1r5204871 1r7105062 
  fr2SumF 124547787r123456789456123456
1r994074172 1r347757767307 1r2764751529594496 1r1142210063701888512 
  1r2531144929865351036156388364636113408 
RosLuP
źródło