Haskell memiliki tupel yang dapat ditulis sebagai
(a,b,c)
Namun ini hanya gula sintaksis
(,,)a b c
Secara umum n tupel dapat dibentuk dengan n-1 ,
s antara (
... )
diikuti oleh unsur-unsurnya dipisahkan oleh spasi. Misalnya 7-tuple, (1,2,3,4,5,6,7)
dapat dibentuk oleh
(,,,,,,)1 2 3 4 5 6 7
Karena Haskell tidak memiliki 1-tupel, mereka tidak dapat dibentuk. Anda juga tidak akan dianggap bertanggung jawab atas tuple kosong.
Tuple bersarang dapat dibentuk menggunakan parens untuk mengesampingkan urutan operasi.
((1,2),3) == (,)((,)1 2)3
Sebagai bagian dari upaya kami untuk menghapus semua gula sintaksis dari Haskell, saya akan meminta Anda untuk menulis sebuah program yang menghilangkan gula sintaksis dari tupel Haskell juga.
Program Anda harus menggunakan tuple, array, atau string yang mewakili tuple manis dan harus menampilkan string yang mewakili tuple "bebas gula". Input tuple hanya akan berisi bilangan bulat positif atau tuple lainnya.
Karena kita bermain golf di sini, output Anda harus pendek. Seharusnya tidak mengandung yang tidak perlu
Spasi. Spasi harus digunakan hanya untuk memisahkan argumen dari fungsi tuple dan seharusnya tidak muncul setelah a
)
atau sebelum a(
Tanda kurung. Kurung harus digunakan hanya ketika membentuk fungsi tuple atau ketika tuple bersarang.
Ini adalah pertanyaan kode-golf sehingga jawaban akan dinilai dalam byte dengan lebih sedikit byte yang lebih baik.
Uji kasus
(1,2) -> (,)1 2
(1,2,3) -> (,,)1 2 3
((1,2),3) -> (,)((,)1 2)3
(1,2,3,4) -> (,,,)1 2 3 4
(1,(2,3)) -> (,)1((,)2 3)
(10,1) -> (,)10 1
,
((1,(2,3)),4,(5,6))
dan(1,(2,3),4)
.Jawaban:
Haskell ,
169148 byteCobalah online! Mengambil tuple sebagai string.
init.tail.fst.([]%)
adalah fungsi utama anonim. Ikatkan ke egf
dan gunakan likef "(3,(14,1),4,7)"
, yang menghasilkan"(,,,)3((,)14 1)4 7"
.Mengapa input tidak disediakan sebagai tuple Haskell, Anda bertanya? Karena Haskell sangat diketik, tupel
(1,2)
memiliki tipe(Int,Int)
1 dan tupel(1,(2,3))
memiliki tipe(Int,(Int,Int))
. Dengan demikian fungsi yang menerima jenis tuple pertama tidak dapat diterapkan ke jenis kedua, dan terutama tidak ada fungsi yang mengambil tuple 2 sewenang-wenang .Penjelasan:
p:k="(,"
adalah cara singkat untuk menetapkanp
ke'('
dank
untuk","
.(%)
adalah fungsi penguraian dan konversi rekursif. Argumen pertama adalah daftar entri tuple yang sudah diuraikan, argumen kedua adalah sisa dari string asli. Setiap panggilan mengembalikan satu tupel dari tupel yang dikonversi saat ini (sebagai string dan terlampir dalam tanda kurung) dan sisa dari string.l%('(':r)
Jika string dimulai dengan braket pembuka, kita perlu mengurai entri tuple baru.(y,x:s)<-[]%r
Kami menerapkan secara rekursif%
dan mendapatkan entri tupley
dan string yang tersisa dipisah menjadi karakter berikutnyax
dan seluruh strings
.m<-y:l
Kami menambahkan entri baruy
ke daftar entri yang sudah ditemukan saat inil
dan memanggil hasilnyam
.x
sekarang adalah koma,
atau braket penutup)
. Inilast$ <B> :[ <A> |x<',']
hanya cara penulisan yang lebih pendekif x == ')' then <A> else <B>
.,
adalah yang berikutnya, kita perlu mengurai entri berikutnya secara rekursif:m%(p:s)
Kami menambahkan braket pembuka untuk berakhir di case yang tepat dan meneruskan daftar entri yang sudah ditemukanm
.x == ')'
, kami menyelesaikan tuple saat ini dan perlu melakukan transformasi yang diperlukan:(p:p:(l>>k)++x:foldl(\r x->x++[' '|x>k,r>k]++r)[x]m,s)
p:p:(l>>k)++x:
Jika kita telah menemukan n entri, makam
memiliki n elemen dany
, daftar sebelum menambahkan elemen yang paling baru ditemukan, memiliki n-1 entri. Ini berguna karena kita membutuhkan n-1,
untukn
elemen tuple danl>>k
bekerja pada daftar sebagai "menyatukan daftark
dengan dirinya sendiri sebanyak yangy
dimiliki elemen" . Jadi bagian pertama ini menghasilkan beberapa string seperti"((,,,)"
.foldl(\r x->x++[' '|x>k,r>k]++r)[x]m
merangkai elemen-elemenm
(dalam urutan terbalik, karena dengan menambahkan entri baru ke depanm
itu sendiri dibangun dalam urutan terbalik) sambil menambahkan hanya ruang di antara dua elemen jika keduanya angka:[' '|x>k,r>k]
kami memeriksa apakah entri saat inix
danr
angka dengan membandingkan secara leksikografis mereka ke","
- jika mereka bukan angka, mereka sudah representasi tuple terlampir dalam tanda kurung, dan'(' < ','
memegang.l%('(':r)
yang tepat di awal gagal, maka kita berakhir di baris terakhir:l%r=lex r!!0
. Ini berarti kita perlu mengurai angka dan mengembalikan nomor dan sisa string. Untungnya adalex
fungsi yang melakukan hal itu (Ini mem-parsing token Haskell valid berikutnya, bukan hanya angka). Namun tupel yang dihasilkan dibungkus ke dalam daftar, jadi kami gunakan!!0
untuk mendapatkan elemen pertama dari daftar.init.tail.fst.([]%)
adalah fungsi utama yang mengambil string dan berlaku%
dengan daftar kosong. Misalnya untuk input"(1,2)"
, menerapkan([]%)
hasil("((,)1 2)","")
, sehingga tupel luar dan kurung perlu dihapus.fst
mendapatkan elemen pertama dari tuple,tail
menghapus braket penutup daninit
yang membuka.Sunting: Banyak terima kasih kepada @ Ørjan Johansen karena bermain golf total 21 byte !
1 Sebenarnya, tipenya adalah (Num t1, Num t) => (t, t1) , tapi itu cerita yang berbeda.
2 Mengabaikan fungsi polimorfik seperti id , yang sebenarnya tidak bisa bekerja dengan inputnya.
sumber
Desugarable
, tetapi kita harus mendeklarasikan instance untukInt
, dan semua tipe tuple.g
dapat dipersingkatfoldr1(\x r->x++[' '|x>k,r>k]++r)
dan digariskan.show (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5)
di GHCi, lalu tambahkan a,6
di akhir dan coba lagi.)m<-y:l
, lipat kiri bukan kanan, dan gunakan[x]
sebagai nilai awal. Cobalah online!f
bisa anonim:init.tail.fst.([]%)
.Haskell,
141 byte138 byte (Terima kasih kepada Ørjan Johansen)f
memiliki tipeExp -> String
.Input: Templat Haskell
Exp
ression (yaitu, representasi AST standar dari nilai Haskell tipe arbitrer - pada dasarnya, menguraikan kode Haskell sebelum memeriksa jenis); harus mewakili sebuah tuple yang hanya berisi angka integer non-negatif dan tuple lain semacam itu.Output: string yang berisi sintaks yang diinginkan untuk ekspresi tuple itu.
Demo:
sumber
")"++
ke')':
dalam dua tempat, dan menghemat ruang setelahtail
dengan bergerak kurung luar.Haskell , 119 byte
Cobalah online! Ini menggunakan tipe data khusus
T
untuk mewakili tupel, yaitu tupel((1,2),3)
direpresentasikan sebagaiU[U[I 1,I 2],I 3]
. Contoh penggunaan:init.tail.f $ U[U[I 1,I 2],I 3]
hasil(,)((,)1 2)3
.sumber
Python 2 , 110 byte
Cobalah online!
Mengambil a
tuple
.sumber
GNU sed,
14982 + 2 = 84 byte+2 byte untuk
-r
bendera.Cobalah online!
Penjelasan
sumber
((1,(2,3)),4,(5,6))
dan(1,(2,3),4)
.JavaScript, 75 byte
Input array angka | array, string output.
Berkat Neil, simpan 2 byte
sumber
(1/t?' ':0)+v
bisa1/t?' '+v:v
.Mathematica, 94 byte
Berisi fungsi bawaan yang tidak patut
U+F4A1
dicetakFunction
.Membawa
List
bilangan bulatString
s. Jika ini tidak diperbolehkan, ini bisa diperbaiki dengan menambahkan 10 byte lagi (versi ini mengambilList
dariList
s /Integer
s):sumber
Pip , 45 byte
Ini adalah fungsi yang mengambil daftar sebagai argumen. Cobalah online!
Versi yang dikomentari
sumber
JavaScript (ES6),
8884 byteMengambil array bilangan bulat dan array. Sunting: Disimpan 1 byte dengan menggunakan
s+=
alih-alih dua penggunaan terpisahs+
. Menyelamatkan 3 byte lebih lanjut sekarang sehingga saya dapat menyederhanakan bagian dalam batin. Jika saya mencuri ide @ tsh maka saya bisa mendapatkannya hingga 76 byte:sumber
Your program should take either a tuple or a string representing a sugary tuple
Saya menduga bahwa array array / integer harus baik-baik saja.R, 316 byte?
(Harus keluar dan tidak yakin cara yang tepat untuk menghitung byte ... plus itu bukan solusi yang bagus tetapi ingin mempostingnya karena saya menghabiskan waktu membuatnya ...)
Kasus uji:
sumber
JavaScript (ES6), 72 byte
Input: Array yang berisi angka dan / atau array
Output: string
Penggunaan: f ([...])
Selesaikan semua kasus uji, selamat datang perbaikan
sumber
C, 308 atau 339 byte
308 atau 339 byte, tergantung pada apakah atau tidaknya melewatkan pointer ke akhir string input diperbolehkan; baris terakhir hanya ada di sana untuk memungkinkan melewati string literal secara langsung tanpa harus menghitung panjangnya.
Penjelasan
Algoritma yang cukup sederhana. Ia menghitung jumlah koma pada kedalaman saat ini, mencetaknya sebagai konstruktor tuple, kemudian menindaklanjuti dengan argumen tuple, lolos (spasi di antara angka, tupel bersarang di antara kurung), secara rekursif.
Uji kasus dan aplikasi
sumber