Tantangan
Diberikan matriks stochastic kiri atau kanan di mana batas x mendekati tak terhingga dari matriks ke kekuatan x mendekati matriks dengan semua nilai terbatas, kembalikan matriks yang menjadi titik konvergensi matriks. Pada dasarnya, Anda ingin terus mengalikan matriks dengan sendirinya sampai hasilnya tidak lagi berubah.
Uji Kasus
[[7/10, 4/10], [3/10, 6/10]] -> [[4/7, 4/7], [3/7, 3/7]]
[[2/5, 4/5], [3/5, 1/5]] -> [[4/7, 4/7], [3/7, 3/7]]
[[1/2, 1/2], [1/2, 1/2]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/3, 2/3], [2/3, 1/3]] -> [[1/2, 1/2], [1/2, 1/2]]
[[1/10, 2/10, 3/10], [4/10, 5/10, 6/10], [5/10, 3/10, 1/10]] -> [[27/130, 27/130, 27/130], [66/130, 66/130, 66/130], [37/130, 37/130, 37/130]]
[[1/7, 2/7, 4/7], [2/7, 4/7, 1/7], [4/7, 1/7, 2/7]] -> [[1/3, 1/3, 1/3], [1/3, 1/3, 1/3], [1/3, 1/3, 1/3]]
Aturan
- Celah Standar Berlaku
- Anda dapat memilih apakah Anda ingin matriks stochastic kanan atau kiri
- Anda dapat menggunakan jenis angka yang masuk akal, seperti mengapung, rasional, desimal presisi tak terbatas, dll
- Ini adalah kode-golf , jadi pengiriman terpendek dalam byte untuk setiap bahasa dinyatakan sebagai pemenang untuk bahasanya. Tidak ada jawaban yang akan diterima
Jawaban:
R ,
4443 byteCobalah online!
Teruslah mengalikan hingga menemukan matriks yang diperbaiki. Rupanya
X!=(X=X%*%m)
melakukan perbandingan, kemudian ditugaskan kembaliX
, jadi itu rapi.Terima kasih kepada @Vlo karena telah memangkas satu byte; meskipun dicoret 44 masih tetap 44.
sumber
function(m){ while(any(m!=(m=m%*%m)))0 m}
tidak berhasil. Ketidakakuratan numerik mencegah pemutusan kondisi dari memicu?Oktaf ,
454235 byteCobalah online!
Disimpan 3 byte berkat Giuseppe, dan 7 lagi berkat Luis Mendo!
Ini menggunakan vektor eigen yang sesuai dengan nilai eigen 1 (juga nilai eigen maksimum) adalah vektor kolom yang diulang untuk setiap nilai matriks pembatas. Kita harus menormalkan vektor untuk memiliki jumlah 1 agar stochastic, maka kita cukup mengulanginya untuk mengisi matriks. Saya tidak terlalu pandai bermain golf Oktaf, tapi saya belum bisa menemukan cara fungsional untuk melakukan perkalian berulang, dan program lengkap sepertinya akan selalu lebih lama dari ini.
Kita dapat menggunakan
any(A)
karena dari pembatasan kita tahu bahwa matriks harus menggambarkan rantai Markov yang tidak dapat direduksi, sehingga setiap negara bagian harus dapat dijangkau dari negara bagian lain. Oleh karena itu setidaknya satu nilai di setiap kolom harus bukan nol.sumber
eigs
selalu mengembalikan vektor eigen sesuai dengan1
? Ingatan saya tentang rantai markov agak kabur.eigs
kembali mulai dari nilai eigen terbesar. Juga, terima kasih untuk golfnya!Bahasa Wolfram (Mathematica) , 14 byte
Output mengapung:
Cobalah online!
Bahasa Wolfram (Mathematica) , 30 byte
Fraksi keluaran:
Cobalah online!
sumber
Jelly , 6 byte
Ini adalah program lengkap.
Cobalah online!
sumber
APL (Dyalog) ,
186 byte12 byte disimpan berkat @ H.PWiz
Cobalah online!
sumber
+.×⍨⍣≡
untuk 6 byte. Artinya,k / q, 10 byte
k / q karena program ini identik dalam kedua bahasa. Kode ini benar-benar hanya idiomatis k / q.
Penjelasan
{..}
keluar sintaks lambda, denganx
sebagai parameter implisit$[x]
memiliki $ sebagai operator perkalian matriks biner, menyediakan hanya satu parameter yang menciptakan operator unary yang meninggalkan dikalikan oleh Markov Matrix/[x]
menerapkan perkalian kiri hingga konvergensi, dimulai dengan x itu sendiri.sumber
C (gcc) ,
207192190181176 bytes + 2 flag bytes-lm
lima belastujuh belasdua puluh dua byte berkat ceilingcat .return A;
.Cobalah online!
sumber
Python 3 ,
7561 byteCobalah online!
Dalam kasus uji ada ketidaktepatan float, sehingga nilai mungkin berbeda sedikit dari fraksi yang tepat.
PS.
numpy.allclose()
digunakan karenanumpy.array_equal()
lebih panjang dan rawan melayang ketidaktepatan.-14 byte Terima kasih HyperNeutrino;) Oh ya saya lupa operator @; P
sumber
dot
sebagai gantimatmul
: Dx=n@n
: P tio.run/…f=
di depan karena secara rekursif disebut;)Java 8,
356339 byte-17 byte terima kasih kepada @ceilingcat .
Jelas bukan bahasa yang tepat .. Presisi titik apung sialan ..
Penjelasan:
Cobalah online.
sumber
float
/double
tidak memiliki presisi floating point yang tepat,java.math.BigDecimal
harus digunakan sebagai gantinya. Dan bukan hanya+-*/
, BigDecimals menggunakan.add(...)
,.subtract(...)
,.multiply(...)
,.divide(...)
. Jadi sesuatu sesederhana7/10
menjadinew BigDecimal(7).divide(new BigDecimal(10))
. Selain itu,,scale,RoundingMode
dalamdivide
diperlukan untuk nilai-nilai dengan nilai desimal 'tak terbatas' (seperti1/3
sedang0.333...
). Metode utama tentu saja bisa golf, tapi saya tidak repot-repot ketika saya melakukan pencarian & ganti untuk mengubah floats ke BigDecimals.