To pytanie nie musi dotyczyć tylko kończenia miejsc po przecinku - powtarzające się miejsca po przecinku można również konwertować na ułamki za pomocą algorytmu.
Twoim zadaniem jest stworzenie programu, który pobiera dziesiętną liczbę dziesiętną jako dane wejściowe, i wypisuje odpowiedni licznik i mianownik (w najniższych terminach), który generuje to rozwinięcie dziesiętne. Ułamki większe niż 1 powinny być reprezentowane jako ułamki niewłaściwe, takie jak 9/5
. Możesz założyć, że dane wejściowe będą dodatnie.
Powtarzany ułamek dziesiętny zostanie podany w tym formacie:
5.3.87
z powtórzeniem wszystkiego po drugiej kropce:
5.3878787878787...
Twój program wyświetli dwie liczby całkowite reprezentujące licznik i mianownik, oddzielone ukośnikiem (lub równoważną formą w twoim języku, jeśli nie wypisujesz zwykłego tekstu):
889/165
Zauważ, że kończące miejsca po przecinku nie będą miały nic po drugiej kropce, a miejsca po przecinku bez powtarzalnych części dziesiętnych nie będą miały nic między dwiema kropkami.
Przypadki testowe
Te przypadki testowe obejmują wszystkie wymagane przypadki narożne:
0..3 = 1/3
0.0.3 = 1/30
0.00.3 = 1/300
0.6875. = 11/16
1.8. = 9/5
2.. = 2/1
5..09 = 56/11
0.1.6 = 1/6
2..142857 = 15/7
0.01041.6 = 1/96
0.2.283950617 = 37/162
0.000000.1 = 1/9000000
0..9 = 1/1
0.0.9 = 1/10
0.24.9 = 1/4
Jeśli chcesz, możesz również założyć, że ułamki bez części całkowitych nie mają nic po lewej stronie pierwszej kropki. Możesz to przetestować za pomocą tych opcjonalnych przypadków testowych:
.25. = 1/4
.1.6 = 1/6
..09 = 1/11
.. = 0/1
źródło
9/99
?(in lowest terms)
tzn. frakcja musi zostać uproszczona.13
zamiast13/1
?1.9999...
i wyjściowe2/1
1.9999.
jest19999/10000
,2/1
jeśli potrzebujesz1..9
, prawda?Odpowiedzi:
Dyalog APL (
75736968 znaków)Oto kolejna i piąta próba (najprawdopodobniej moja ostatnia); Spędziłem dzień próbując napisać fragment kodu krótszy niż 80 znaków i zachowując pełną zgodność z regułami. To wyzwanie sprawiło, że mój dzień!
W końcu otrzymałem wiersz APL złożony z 75 znaków, współpracujący z Dyalog APL (ale nie na stronie interpretera online, ponieważ korzystam z funkcji
⍎
wykonywania ), który jest następujący:Oczywiście mógłbym to zrobić nieco krócej, ale w szczególnych przypadkach, gdy brakuje jednego, dwóch lub trzech pól. Mój kod może nawet obsłużyć
..
przypadek wejściowy.Wiem, że APL jest trudny do odczytania, a ponieważ ludzie lubią rozumieć, jak fragment kodu faktycznie działa, oto kilka wyjaśnień. Zasadniczo obliczam ostateczny mianownik w zmiennej D i końcowy licznik w zmiennej N.
APL jest analizowany od prawej do lewej.
I←
).P←'.'=
). Na przykład „1.2.3” zostanie zamapowane na 0 1 0 1 0.10⊥
); teraz „1.2.3” to 1010.1-⍨
albo z¯1+
, tutaj wybrałem drugi). Teraz „1.2.3” to 1009.⍕
), dwie początkowe cyfry są usuwane (2↓
), co powoduje, że 09 z naszego początkowego przykładu „1.2.3”; ciąg jest odwrócony (⌽
).'0',
ale zrobiłem to, aby uniknąć błędu, gdy oba pola: drugi i trzeci są puste. Ciąg jest konwertowany z powrotem na liczbę (⍎
) i jest przechowywany w D, który jest mianownikiem, z wyjątkiem sytuacji, gdy oba ostatnie pola są puste, ponieważ w takim przypadku D jest równe 0.D←D+0=
Element zestawu kodu D 1, jeżeli jest to obecnie pusty, a teraz D zawiera mianownik (przed podziałem GCD jednak).×
) przez zawartość początkowego ciągu I aż do drugiej kropki, od(⍎'0',I/⍨2>+\P)
której zaczyna się ponownie od P (0 1 0 1 0 w moim przykładzie), dodaje kolejne liczby poprzez ich kumulację (co daje 0 1 1 2 2 w moim przykładzie), sprawdź, które wartości są mniejsze niż 2 (tworząc wektor boolowski 1 1 1 0 0) i przyjmując odpowiednie znaki w I; kolejne 0 jest dodawane przed ciągiem, aby zapobiec kolejnej pułapce (jeśli dwa początkowe pola są puste), a całość jest konwertowana na liczbę.(⍎'0',1↓I/⍨2=+\P)
, który ponownie pobiera P, dodaje, kumulując ponownie, sprawdza, które wartości są równe 2 (patrz poprzednie wyjaśnienie), pobiera znaki, usuwa pierwszy, który jest kropką , dodaje zapobiegający początkowy znak 0 i konwertuje na liczbę.edycja: Oto poprawka dla 73 znaków:
Ideą tego hacka jest obliczenie pierwszego przypadku, w którym sumowanie sumaryczne ma wartości równe 2, przechowywanie ich na później i odwracanie tej bitowej maski w celu uzyskania pierwszego przypadku; dlatego obliczenie następnego przypadku wymaga mniej znaków.
edycja: Oto kolejna poprawka dla 69 znaków:
Ideą tego hacka jest osadzenie najbardziej skomplikowanego specjalnego przypadku jako kodu APL w ciągu do oceny (na etapie konwersji ciągu na liczbę).
edycja: Oto kolejna poprawka dla 68 znaków:
Ideą tego hacka jest zastąpienie dodawania -1 do wartości odejmowania 1 do tej wartości przez operację odejmowania tej wartości do 1, a następnie usunięcie jednego znaku więcej na początku (który będzie znakiem minus).
edycja: Zmiana kosmetyczna:
Bez poprawy wielkości, ale bardziej zadowolony z uzyskania maksymalnej funkcji z kodu do oceny.
źródło
INVALID TOKEN
. Wiesz dlaczego?I
): patrz ten bezpośredni linkPerl 6 (
93101100806866 bajtów)Rozmiar został zwiększony, aby nic nie obsługiwać, zamiast po prostu zawodzić. Mouq zaproponował użycie
$/
, więc teraz jest używane, a kod jest o 20 bajtów krótszy. Ayiko zaproponowano zastąpienie/
się, tak, że kod jest nawet krótszy (po 12 bajtów). Następnie Mouq zaproponowała zastąpienie
chars
zcomb
(w kontekście numerycznym, są identyczne, ponieważ lista znaków po konwersji do liczby jest liczba znaków).Przykładowe dane wyjściowe:
źródło
0..09
zwraca1/11
, ale0.0.09
zwraca1/110
.0.1 + 0.2 == 0.3
w Perlu 6.$/=split ".",get;say join "/",($0+($1+$2/(9 x chars $2 or 1))/10**$1.chars).nude
:)J (
859089 znaków)Moja pierwotna funkcja, która była o 5 znaków krótsza od drugiej, zawierała kilka błędów: nie wyświetlała liczb całkowitych jako „n / 1” i dawała błędną odpowiedź na liczbach zawierających więcej niż kilkanaście cyfr. Oto poprawiona funkcja w J, która zawiera także sugestię Eelvex dotyczącą uratowania postaci:
Otrzymuje ciąg i zwraca ciąg. Oto przykładowa sesja:
źródło
0/1
i3/1
inf pierwszych dwóch przypadków testowych, Zobacz ten komentarz('0','x',~])
i zapisz bajt.C 171
Dosyć długo. Można jeszcze bardziej zmniejszyć. Nie
scanf
, co naprawdę nie poradzi sobie, jeśli między kropkami nie ma żadnych liczb. Niestrtol
. Po prostu chrupanie liczb:Test:
źródło
DC (nie w pełni ogólny, skrócony do 76 znaków)
Nie do końca ogólne, ale proszę, pomyśl, że zrobiłem to z jedną z najstarszych rzeczy na świecie:
Edytuj: edytuję swoje rozwiązanie; nie jest bardziej ogólny, ale nieco krótszy:
Użyj go jako:
Pierwsze pole nie jest wymagane:
jest OK
Pole drugie i pragnienie wymagają co najmniej jednej cyfry
źródło
JavaScript, 203
Zbyt długo, ale nadal fajnie. Nowe linie, ponieważ średniki są nieczytelne.
źródło
889/NaN
kiedy biegnę5.3.87
... Czy robię coś złego?"889/165"
do konsoli. Jak to działa? @rafaelcastrocoutob=1
część do środkaprompt()
.f=(P(10,s[2].length)-1)*P(10,l),f=f?f:1
=>f=(P(10,s[2].length)-1)*P(10,l)||1
J (inna metoda)
Kolejne rozwiązanie oparte na zupełnie innej metodzie; tym razem jest to w pełni ogólne; brakuje tylko 1-mianownika, gdy podana jest liczba całkowita:
źródło
GolfScript (67 znaków)
Uwaga: Obsługuje puste części całkowite.
Jeżeli łańcuch ma postać
'n.p.q'
to wartość jestn + p/E + q/(DE) = ((nD + p)E + q)/DE
gdzieD = 10^(len p)
iE = 10^(len q) - 1
, z wyjątkiem przypadkulen q = 0
, w tym przypadkuE = 1
(w celu uniknięcia dzielenie przez 0).Sekcja:
Demo online, które symuluje uruchamianie programu z każdym wejściem testowym, pojedynczo.
źródło
0.1.
Pyton
Brak bibliotek - 156 znaków
Używanie
fractions
- 127 znakówźródło
fractions
drukuje wersja rzeczy jak „frakcja (7, 5)” zamiast „7/5”, prawda?_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),
ValueError: need more than 1 value to unpack
print
używa,str
gdy jest dostępna, a nierepr
. Oto wynik na moim końcu: puu.sh/7w64w.png_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),(10**len(c)-bool(c))*10**len(b);f=_(d,e);print'%i/%i'%(d/f,e/f)
powinny iść wszystkie w jednej linii.Mathematica, 143
Jak zwykle Mathematica oferuje wiele funkcji wysokiego poziomu do wykonania zadania, ale nadaje im pełne nazwy.
Przykładowe dane wyjściowe zostaną dodane później, gdy będę miał czas.
źródło
n/1
na redukcjęn
? Dodam dodatkowe ~ 50 bajtów, aby później przekonwertować liczby całkowite.FromDigits
więc postanowiłem go opublikować.Rubin - 112
To mój pierwszy eksperyment z rubinem, więc sugeruj ulepszenia.
źródło
If you wish
. Nie chcę, więc nie obsługuję ułamków bez pierwszej lub trzeciej grupy cyfr. Popieram jednak ułamki pozbawione drugiej grupy cyfr, która pasuje do specyfikacji.C, 164
Jest to podobne do rozwiązania C Oriona, mimo że zrobiłem to od zera. Przyznaję jednak, że kradną wiele jego optymalizacji. Nie jest dużo krótszy, ale obsługuje 0,25. = 1/4 i 0,000000,1 = 1/9000000.
źródło
Dwie odpowiedzi na python bez bibliotek. Pierwszy obsługuje opcjonalne wprowadzanie bez cyfry przed pierwszym. i ma 162 znaki
Drugi nie obsługuje niczego przed pierwszą cyfrą, ale poprawnie obsługuje wszystkie wymagane dane wejściowe i ma 150 znaków
źródło
Haskell
źródło
span
zaimplementować s, dodać krótkie aliasy dla funkcji, w miarę możliwości usunąć miejsce.import Data.Ratio v=span(/='.');w=tail;l=length;f n=(r x)%1+(r y)%p+(r z)%((10^t-1)*p)where{(x,b)=v n;(y,d)=v(w b);z=w d;p=10^(l y);r""=0;r n=read n;t=if null z then 9 else l z}
- 178 znaków, w dół od 321. NBTrue
jest synonimemotherwise
,null z
jestlength z==0
JavaScript (ECMASCript 6)
180175Chociaż nie jest to wyraźny zwycięzca nagrody za 300, to jest najkrótszy z możliwych:
P
funkcji Mocy poprzez zmianę na+("1e"+a)
zamiastMath.pow(10,a)
zapisywania kilku dodatkowych znaków ...źródło
Mathematica 175
Większość rutyny zajmuje się masowaniem danych wejściowych. Około 50 znaków poszło na obsługę liczb całkowitych.
Przykłady
Więcej przykładów:
Jak to normalnie można osiągnąć w Mathematica
FromDigits
może otrzymać ułamek bezpośrednio z powtarzającego się powtarzającego się miejsca po przecinku, pod warunkiem, że dane wejściowe mają określoną postać. Liczby całkowite są wyświetlane jako liczby całkowite.źródło
J (96 znaków)
Nie używam symbolu ukośnika jako separatora (ale rozwiązanie w Mathematica też tego nie robi, ponieważ używa graficznej reprezentacji, która i tak jest lepsza); w języku J ułamek wyświetlany jest
r
zamiast jako/
:źródło
APL (nie w pełni ogólny)
Nie do końca ogólne (jak moje rozwiązanie dla DC); współpracuje z Dyalog APL (ale nie w wersji online Dyalog APL, nie wiem dlaczego):
Pierwsze pole jest opcjonalne, ale co najmniej jedna cyfra jest wymagana dla obu pozostałych pól.
źródło
JavaScript (189)
Przykład:
Wkład:
Wydajność:
źródło
C (420 znaków jak napisano; mniej po usunięciu niepotrzebnych białych znaków)
Zauważ, że zakłada to 64-bit
long
(np. 64-bitowy Linux); nie powiedzie się w przypadku testowym0.2.283950617
w systemach używających 32-bitówlong
. Można to naprawić kosztem niektórych znaków, zmieniając odpowiednio typlong long
iprintf
ciąg formatu.źródło
'0'
na48
.switch
instrukcję jakoif(c==46) n[++i]=1; else d[i]=10*d[i]+c-48,n[i]*=10;
.GTB , 81
Przykład
źródło
GTB
link powyżej, jeśli mi nie wierzysz. Dostaniesz skompresowane pliki do zastrzeżonego programu, a następnie poszukasz tego programu i zobaczysz, że strona, która twierdzi, że zapewnia pobieranie, twierdzi, że nie jest dostępna. Jak to skompilujemy?