Timbal balik berulang

11

Yang perlu Anda lakukan adalah membuat fungsi / program yang mengambil desimal sebagai input, dan mengeluarkan hasil berulang-ulang mengambil bagian fraksional dari angka tersebut, hingga angka tersebut menjadi bilangan bulat.

Lebih khusus, prosesnya adalah sebagai berikut:

  1. Biarkan x menjadi input

  2. Jika x adalah bilangan bulat, output saja.

  3. Sebaliknya: . Kembali ke 2.x1frac(x)

frac(x) adalah komponen fraksional dari , dan sama dengan . adalah lantai x, yang merupakan bilangan bulat terbesar kurang dari .xxxxx

Kasus uji:

0 = 0
0.1 = 1/10 -> 10
0.2 = 1/5 -> 5
0.3 = 3/10 -> 10/3 -> 1/3 -> 3
0.4 = 2/5 -> 5/2 -> 1/2 -> 2
0.5 = 1/2 -> 2
0.6 = 3/5 -> 5/3 -> 2/3 -> 3/2 -> 1/2 -> 2
0.7 = 7/10 -> 10/7 -> 3/7 -> 7/3 -> 1/3 -> 3
0.8 = 4/5 -> 5/4 -> 1/4 -> 4
0.9 = 9/10 -> 10/9 -> 1/9 -> 9
1 = 1
3.14 = 157/50 -> 7/50 -> 50/7 -> 1/7 -> 7
6.28 = 157/25 -> 7/25 -> 25/7 -> 4/7 -> 7/4 -> 3/4 -> 4/3 -> 1/3 -> 3

Ringkasan untuk 0 hingga 1 dengan penambahan 0,1: 0, 10, 5, 3, 2, 2, 2, 3, 4, 9, 1

Ini adalah , byte paling sedikit menang.

Klarifikasi:

  • "Poin bonus" tanpa kesalahan pembulatan
  • Harus berfungsi untuk nomor rasional yang tidak negatif (mengabaikan kesalahan pembulatan)
  • Anda bisa, tetapi tidak harus menampilkan langkah-langkah yang diambil
  • Anda dapat mengambil input sebagai desimal, pecahan, atau pasangan angka, yang bisa dalam string.

Maaf untuk semua masalah, ini adalah pertanyaan pertama saya di situs web ini.

Solomon Ucko
sumber
Fakta bahwa penghentian ini berkaitan erat dengan kemungkinan menyatakan desimal dalam pecahan lanjutan.
Leaky Nun
4
Apakah kita diharapkan untuk menghasilkan float? Mereka menyebabkan beberapa masalah presisi.
Leaky Nun
7
Bisakah Anda sedikit merinci prosesnya? Saya tidak yakin dengan apa yang "berbalasan dengan bagian fraksional dari angka", dan kasus-kasus uji juga tidak banyak membantu
Ad Hoc Garf Hunter
4
Bisakah kita mengambil dua bilangan bulat sebagai input untuk mewakili bilangan rasional?
Leaky Nun
1
Ini sama dengan elemen terakhir dari fraksi lanjutan sederhana dari input.
isaacg

Jawaban:

5

J, 18 byte

%@(-<.)^:(~:<.)^:_

Dalam J, idiom u ^: v ^:_berarti "Tetap menerapkan kata kerja usementara kondisi vmengembalikan true.

Dalam kasus kami, kondisi akhir ditentukan oleh pengait ~:<., yang berarti "dasar angka <.tidak sama ~:dengan angka itu sendiri" - jadi kami akan berhenti ketika kata kerja utama umengembalikan int.

udalam hal ini adalah pengait lain -<.- nomor minus lantainya - yang nilai kembaliannya dimasukkan ke @dalam kata kerja timbal balik %.

Cobalah online!

Jonah
sumber
Juga 18, namun memiliki beberapa imprecisions floating point karena toleransi mungkin: _2{(%@-<.) ::]^:a:.
cole
%@|~&1^:(~:<.)^:_
FrownyFrog
5

Python 3 , 101 byte

lambda s:g(int(s.replace(".","")),10**s[::-1].index("."))
g=lambda a,b:a and(b%a and g(b%a,a)or b//a)

Cobalah online!

Format: string harus mengandung titik desimal.

Biarawati Bocor
sumber
.replace(".","")-> .replace(*"._")simpan 1 byte
tsh
5

Mathematica, 36 byte

Last@*ContinuedFraction@*Rationalize

Demo

In[1]:= f = Last@*ContinuedFraction@*Rationalize

Out[1]= Last @* ContinuedFraction @* Rationalize

In[2]:= f[0]

Out[2]= 0

In[3]:= f[0.1]

Out[3]= 10

In[4]:= f[0.2]

Out[4]= 5

In[5]:= f[0.3]

Out[5]= 3

In[6]:= f[0.4]

Out[6]= 2

In[7]:= f[0.5]

Out[7]= 2

In[8]:= f[0.6]

Out[8]= 2

In[9]:= f[0.7]

Out[9]= 3

In[10]:= f[0.8]

Out[10]= 4

In[11]:= f[0.9]

Out[11]= 9

In[12]:= f[1]

Out[12]= 1
Anders Kaseorg
sumber
Apa yang terjadi tanpa Rationalize?
Greg Martin
1
@GregMartin Tanpa Rationalize, Mathematica berpikir tidak ada cukup presisi untuk menghasilkan semua fraksi lanjutan. Misalnya ContinuedFraction[0.1]saja {0}.
Anders Kaseorg
4

Perl 6 , 42 byte

{($_,{1/($_-.floor)}...*.nude[1]==1)[*-1]}

Cobalah online!

The nudeMetode mengembalikan nu merator dan de nominator dari sejumlah rasional sebagai daftar dua elemen. Lebih pendek untuk mendapatkan penyebut dengan cara ini daripada memanggil denominatormetode secara langsung.

Sean
sumber
4

Haskell , 47 byte

Ini mengalahkan jawaban Wheat Wizard karena GHC.Realmemungkinkan kita untuk mencocokkan pola pada penggunaan rasional :%, serta memiliki nama yang lebih pendek

import GHC.Real
f(x:%1)=x
f x=f$1/(x-floor x%1)

Cobalah online!

fmengambil Rationalangka sebagai input, walaupun ghc memungkinkannya ditulis dalam format desimal, dalam ketelitian tertentu.

H.Piz
sumber
4

Haskell , 40 34 byte

Edit:

  • -6 byte: @WheatWizard menunjukkan fraksi mungkin dapat diberikan sebagai dua argumen terpisah.

(Tidak dapat menahan memposting ini setelah melihat jawaban Haskell dengan impor verbose - sekarang saya melihat beberapa jawaban bahasa lain juga pada dasarnya menggunakan metode ini.)

!mengambil dua argumen integer (pembilang dan penyebut dari fraksi; mereka tidak perlu dalam istilah terkecil tetapi penyebutnya harus positif) dan mengembalikan integer. Sebut sebagai 314!100.

n!d|m<-mod n d,m>0=d!m|0<1=div n d

Cobalah online!

  • Mengabaikan ketidakcocokan jenis, bagian fraksional n/d(dengan asumsi dpositif) adalah mod n d/d, jadi kecuali mod n d==0, !berulang dengan representasi d/mod n d.
Ørjan Johansen
sumber
@WheatWizard Hm, saya mengartikan "pair" sebagai pasangan daripada dua argumen yang berbeda. Saya kira itu interpretasi yang terlalu Haskell-sentris.
Ørjan Johansen
3

Python 3 + sympy , 67 byte

from sympy import*
k=Rational(input())
while k%1:k=1/(k%1)
print(k)

Cobalah online!

Sympy adalah paket matematika simbolik untuk Python. Karena ini simbolis dan bukan biner, tidak ada ketidakakuratan floating point.

HyperNeutrino
sumber
3

PHP , 69 byte

for(;round(1e9*$a=&$argn)/1e9!=$o=round($a);)$a=1/($a-($a^0));echo$o;

Cobalah online!

PHP , 146 byte

for($f=.1;(0^$a=$argn*$f*=10)!=$a;);for(;1<$f;)($x=($m=max($a,$f))%$n=min($a,$f))?[$f=$n,$a=$x]:$f=!!$a=$m/$n;echo($o=max($a,$f))>1?$o:min($a,$f);

Cobalah online!

Jörg Hülsermann
sumber
2

Jelly , 8 byte

®İ$%1$©¿

Cobalah online!

Ketidaktepatan titik mengambang.

Erik the Outgolfer
sumber
Semoga berhasil melakukannya untuk 0.7
Leaky Nun
@ LeakyNun Keberuntungan itu berarti loop tak terbatas atau loop tak terbatas ...
Erik the Outgolfer
Gunakan Muntuk memperbaiki floating-point ketidakakuratan: P . Ini Jelly tetapi dengan matematika presisi yang sewenang-wenang. Tidak memperbaiki loop 0,7 sekalipun.
HyperNeutrino
@HyperNeutrino M adalah versi Jelly yang sudah ketinggalan zaman.
Erik the Outgolfer
5 byte
caird coinheringaahing
2

JavaScript ES6, 25 byte

f=(a,b)=>a%b?f(b,a%b):a/b

Panggilan f(a,b)untuka/b

l4m2
sumber
Jika gcd(a,b)=1dapat menghapus/b
l4m2
2

Haskell , 62 61 byte

import Data.Ratio
f x|denominator x==1=x|u<-x-floor x%1=f$1/u

Cobalah online!

Menggunakan Data.Ratioperpustakaan Haskell untuk rasional presisi yang sewenang-wenang. Andai saja nama-nama bawaannya tidak begitu panjang.

Ad Hoc Garf Hunter
sumber
@ H.PWiz Bagus! Saya telah mencoba untuk mencocokkan pola Data.Ratio. Saya belum pernah mendengarnya GHC.Real. Jangan ragu untuk memposting itu sebagai jawaban Anda sendiri.
Ad Hoc Garf Hunter
diposting
H.PWiz
1

APL (Dyalog Classic) , 18 byte

{1e¯9>t1|⍵:⍵⋄∇÷t}

Cobalah online!

APL NARS, 18 karakter

-1 byte berkat tes Uriel

f←{1e¯9>t1|⍵:⍵⋄∇÷t}
v0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1 3.14
⎕←vf¨v
  0 0  0.1 10  0.2 5  0.3 3  0.4 2  0.5 2  0.6 2  0.7 3  0.8 4  0.9 9  1 1  3.14 7 
RosLuP
sumber
⍵-⌊⍵1|⍵untuk satu byte
Uriel
@Uriel terima kasih ... Jadi byte sebagai solusi J
RosLuP
1

Smalltalk, 33 byte

[(y:=x\\1)>0]whileTrue:[x:=1/y].x
Leandro Caniglia
sumber
1

Stax , 8 byte

ç▄é⌠á◙àù

Jalankan dan debug itu

"Poin bonus" tanpa kesalahan presisi. Tidak ada aritmatika floating point yang digunakan. Ini (akhirnya) memanfaatkan tipe rasional bawaan stax.

rekursif
sumber
0

JavaScript, 70 byte

x=>(y=(x+'').slice(2),p=(a,b)=>b?a%b?p(b,a%b):a/b:0,p(10**y.length,y))

Jika kita dapat mengubah tipe input menjadi string, maka itu dapat menghemat 5 byte.

tsh
sumber
Ini tidak akan berfungsi untuk angka> = 10.
Shaggy
@Shaggy Apakah nomor pendukung> 1 diperlukan?
tsh
Ya, itu harus bekerja untuk bilangan rasional apa pun (mengabaikan kesalahan pembulatan).
Solomon Ucko