pengantar
Dalam tantangan ini, tugas Anda adalah membuat kode ISBN-10 untuk buku-buku yang diberi kode ISBN-13-nya, dengan asumsi kode tersebut ada. Kode ISBN-13 tersebut terdiri dari beberapa bagian yang dipisahkan oleh -
:
978-GG-PPPP-TTT-C
Huruf G
(grup), P
(penerbit), T
(judul) dan C
(checksum) semuanya merupakan satu digit. Untuk tujuan tantangan ini pengelompokan dan perhitungan C
(lihat tantangan ini ) tidak menarik dan kami akan membatalkan semua tanda hubung untuk membuat tugas ini lebih sederhana.
Nomor ISBN-10 memiliki tata letak yang sangat mirip:
GG-PPPP-TTT-c
Huruf-hurufnya G
, P
dan T
sama dengan ISBN 13 digit, namun c
berbeda (dan dihitung menggunakan algoritma yang berbeda). Digit c
dipilih sedemikian rupa sehingga kesetaraan berikut berlaku (angka berurutan):
10*G + 9*G + 8*P + … + 3*T + 2*T + 1*c = 0 (mod 11)
Contoh
Mari kita pertimbangkan nomor ISBN 9780345391803
: Untuk mendapatkan kode ISBN-10 yang sesuai, kita cukup meninggalkan yang terdepan 978
dan 3
menghasilkan checksum 034539180
.
Selanjutnya kita perlu menghitung checksum baru:
10*0 + 9*3 + 8*4 + 7*5 + 6*3 + 5*9 + 4*1 + 3*8 + 2*0 = 185
Angka berikutnya yang dapat dibagi 11
adalah 187
, sehingga checksum baru adalah 2
dan dengan demikian menghasilkan kode ISBN-10 0345391802
.
Aturan
- Input Anda akan selalu memiliki nomor ISBN-10 yang sesuai (mis. Panjangnya persis 13 digit dan dimulai dengan
978
) - Input tidak harus harus berupa ISBN-13 yang valid (mis.
9780000000002
) - Anda dijamin bahwa ISBN yang dihasilkan tidak akan berakhir dengan
X
- Anda dapat mengambil input sebagai integer atau string (dengan atau tanpa tanda hubung) namun daftar digit yang dihitung sebelumnya tidak diizinkan
- Output Anda harus nomor ISBN-10 yang valid (dengan atau tanpa tanda hubung)
- Output Anda mungkin bilangan bulat atau string (sekali lagi tidak ada daftar digit)
Testcases
9780000000002 -> 0000000000
9780201882957 -> 0201882957
9781420951301 -> 1420951300
9780452284234 -> 0452284236
9781292101767 -> 1292101768
9780345391803 -> 0345391802
Perhatikan nol terkemuka!
0-684-84328-5
dan99921-58-10-7
, bagian pertama (0
dan99921
masing - masing) adalah grup pendaftaran, bagian kedua adalah penerbit, dan sebagainya.Jawaban:
Retina ,
443928 byteCobalah online!
Penjelasan
Saatnya memamerkan beberapa fitur Retina baru. :)
Kami mencocokkan seluruh input dengan
.+
, mengembalikan kecocokan ituL
, tetapi hanya memilih karakter 3 (berbasis nol) hingga -2 (kedua dari belakang), inklusif. Kami juga mencetak hasilnya tanpa linefeed tambahan (>
).Sekarang, mengurangi hal-hal di Retina agak menyebalkan. Tapi untungnya, kita sedang bekerja modulo 11, jadi kita bisa membalikkan koefisien kombinasi linear (mod 11) dan menambahkan semuanya. Dengan kata lain, jika batasannya adalah:
lalu kita dapatkan:
Itu menyederhanakan banyak hal di sini:
Kami mengganti setiap karakter dengan hal di bagian bawah.
*
adalah operator pengulangan Retina. Ini asosiatif-kanan dan memiliki operan implisit$&
di sebelah kiri dan_
di kanan, sehingga substitusi sebenarnya adalah kependekan$.>`*$&*_
.$&*_
menciptakan string garis bawah d , di mana d adalah digit yang saat ini kami gantikan. Kemudian$.>`
adalah panjang string hingga dan termasuk kecocokan. 1 Oleh karena itu, seluruh ekspresi menghasilkan representasi unary dari n istilah ke- dari kombinasi linier kami.Melakukan modulo yang sebenarnya adalah sepele di unary: kami hanya membuang semua set lengkap 11 garis bawah.
Akhirnya, kami menghitung berapa banyak garis bawah yang tersisa dan mencetak hasilnya, yang melengkapi ISBN-10.
1 Bagaimana cara
$.>`
memberikan panjang string hingga dan termasuk kecocokan? Anda mungkin terbiasa dengan$`
substitusi regex, yang memberi Anda string hingga (tetapi tidak termasuk) pertandingan. Dengan menyisipkan>
, kita bisa menggeser konteks$`
ke pemisah antara pertandingan saat ini dan berikutnya (yang merupakan string kosong antara digit saat ini dan berikutnya). Pemisah itu$`
akan mencakup pertandingan saat ini. Begitu$>`
juga cara menulis yang lebih pendek$`$&
. Akhirnya, untuk semua$x
elemen subtitusi semua jenis, Retina memungkinkan Anda memasukkan.
setelah$
untuk mendapatkan panjangnya.sumber
-2 ≡ 9 (mod 11)
(karena menambah atau mengurangi angka 11 dari angka tidak mengubah "nilainya" di kelas congruence mod 11). Dan penambahan dan multiplikasi menghormati kelas kongruensi, sehingga Anda dapat mengganti nilai apa pun dalam kombinasi linear dengan nilai setara di bawah modulo saat ini. Alasan saya berbicara tentang angka negatif adalah karena saya telah mengatur ulang persamaan yang adac
di satu sisi dan semua istilah lain (sebagai negatif) di sisi lain.c
menjadi-c = ...
dan bukannya mengalikannya dengan10 9 8...
mengurangi11
dari masing-masing untuk mendapatkan-1 -2 -3...
dan kemudian mengalikan semuanya dengan -1 untuk mendapatkanc
.05AB1E ,
17151312 byteCobalah online!
Penjelasan
sumber
PowerShell ,
9684 byteCobalah online!
Mengambil input
"$args"
, melakukan regex-replace
untuk mendapatkan hanya bagian yang bersangkutan, menyimpannya menjadi$x
string. Lalu kami memberikannya sebagaichar
-array dan loop melalui setiap huruf. Di dalam loop, kami melakukan pra-pengurangan$a
(yang default-nya0
) dan berkembang biak sesuai dengan perhitungan checksum. Perhatikan gips untukint
, kalau tidak ini akan menggunakan nilai ASCII.Kami kemudian
-join
angka-angka itu bersama-sama dengan+
dan pipa itu keiex
(Invoke-Expression
dan mirip denganeval
). Kami menerima%11
dan menyimpan checksum itu$y
. Akhirnya, kami merangkai string$x + $y
, dan meninggalkannya di saluran pipa. Output tersirat.Disimpan 12 byte berkat Emigna.
sumber
Oktaf ,
46 41 3937 byteCobalah online!
Kode mengambil input sebagai string, dan mengembalikan string.
Kode rusak sebagai berikut:
@(a)
menciptakan fungsi anonim.Dengan
[c=a(4:12) ... ]
kami mengekstrak karakter yang membentuk kode utama, menyimpan salinanc
untuk digunakan nanti, dan menambahkan salinan lain ke string hasil akhir.Berdasarkan @ cara cerdas MartinEnter ini swapping
10:-1:2
ke1:10
, kita dapat dengan mudah menghasilkan berbagai itu dan memindahkannya untuk mendapatkan vektor kolom.c*(1:10)'
melakukan perkalian array dari vektor barisc
dan vektor rentang kolom. Ini setara dengan melakukan perkalian elemen-bijaksana kemudian menjumlahkan.Checksum biasanya akan
mod(11-sum,11)
menghitung jumlah yang diperlukan untuk jumlah menjadi kelipatan 11. Namun, karenac
karakter string, jumlah sebenarnya akan lebih besar daripada yang seharusnya pada 2592 (48 * 54) karena kami dikalikan dengan angka yang 48 lebih besar dari nilai sebenarnya.Ketika kita melakukan modulo, modulo itu akan secara otomatis menghilangkan semua kecuali 7 dari 2592 itu. Dengan demikian, dan memperhitungkan negasi dari rentang, perhitungan aktual menjadi
48+mod(7+sum,11)
. Kami menambahkan pada 48 hasil untuk mengkonversi kembali ke karakter ASCII.Karakter checksum ditambahkan ke akhir hasil, dan nilai dikembalikan.
sumber
Jelly , 12 byte
Ini adalah program lengkap yang menggunakan string untuk I / O.
Cobalah online!
Bagaimana itu bekerja
sumber
JavaScript (ES6),
5956 byteTampilkan cuplikan kode
-3 byte terima kasih atas saran @ Shaggy .
sumber
Perl 5 , 49 + 1 (
-p
) = 50 byteCobalah online!
sumber
Pyth , 16 byte
Coba di sini!
Pyth , 17 byte
Coba di sini!
Penjelasan
sumber
Japt ,
1615 byteDatang dengan ini di pub malam itu dan lupa semua tentang itu.
Cobalah
sumber
s3J
danU+¬x_*°TÃuB
U
- D'oh!Hexagony ,
7761 byteCobalah online!
Berwarna:
Ini adalah versi yang lebih besar. Ada beberapa jalur penyeberangan, tetapi karena semua sel itu
.
(tidak ada dalam Hexagony), Anda tidak perlu khawatir tentang mereka:(Saya juga mencoba menyimpan cermin lama, tetapi kadang-kadang saya perlu mengubah sesuatu)
Perintah linear yang dijalankan adalah:
Penjelasan: Alih-alih menjaga penghitung dan melakukan penggandaan di setiap digit, program ini:
p
dant
)(-p-t)%11
, di mana%
selalu mengembalikan hasil positif.sumber
K (oK) ,
29252423 byteLarutan:
Cobalah online!
Contoh:
Penjelasan:
Evaluasi dilakukan dari kanan ke kiri.
Dua trik diambil dari solusi lain:
Kerusakan:
Catatan:
7
jumlahnya)sumber
C (gcc),
96 95 87 8685 byte(-1 terima kasih kepada ceilingcat)
Cobalah online!
Untuk disebut sebagai
f(s)
, di manas
adalah penunjuk ke elemen pertama dari array karakter yang dapat dimodifikasi. Memodifikasi array input, mengembalikan pointer ke array input.sumber
Python 2 , 62 byte
Cobalah online!
Mengambil string sebagai input; dan menghasilkan string.
sumber
Jelly , 14 byte
Suite uji!
Jelly , 17 byte
Cobalah online! atau Test suite!
Mengambil input dan output sebagai string.
sumber
ECMAScript 6 ,
8667 byteCobalah online!
Terima kasih untuk komentar Arnauld ini , beralih dari
reduce
kemap
dan menyingkirkanreturn
kata kunci.sumber
map()
,reduce()
dll. Dengan beberapa penulisan ulang tambahan, seringkali mungkin untuk menyingkirkan{}
danreturn
. Juga, dalam kasus khusus ini,map()
mungkin lebih pendek darireduce()
. ( Ini adalah versi 65-byte.)f=
tidak perlu. Anda juga dapat menginisialisasic
pada spread untuk sesuatu seperti ini:a=>{i=10;s=[...c=a.substr(3,9)].reduce((g,v)=>+g+(i--)*v,0)%11;return c+=s?11-s:0}
(-4 bytes)Retina 0.8.2 ,
7251 byteCobalah online! Karena saya belum belajar Retina 1.0. Penjelasan:
Hapus karakter yang tidak diinginkan dan buat salinan kedua dari angka yang sesuai.
Sufiks setiap digit pada salinan kedua dengan sufiksnya. Ini secara efektif mengulangi setiap digit dalam suffix dengan posisinya.
Konversikan digit pada salinan kedua menjadi unary sehingga menambahkannya bersama-sama.
Kurangi modulo 11. (Hanya ada 9 digit di salinan pertama, jadi ini tidak akan pernah mempengaruhinya.)
Ubah hasilnya kembali menjadi desimal dan hapus baris baru lagi.
sumber
APL (Dyalog Unicode) ,
2624 byteCobalah online!
Fungsi awalan Tacit. Mengambil input sebagai string.
2 byte disimpan berkat @ngn.
Bagaimana?
sumber
Bersih ,
10410298 byteCobalah online!
sumber
Kotlin , 83 byte
Yg diperindahkan
Uji
TIO
TryItOnline
sumber
Ruby ,
69 6864 byteCobalah online!
sumber
PHP, 64 byte
Sayangnya, dalam PHP
(-$c)%11
sama dengan-($c%11)
; jadi saya harus mendapatkan perbedaan setidaknya jumlah terbesar yang mungkin (55 * 9 = 495 = 45 * 11) daripada hanya menggunakan-$c%11
.atau
Jalankan sebagai pipa dengan
-nR
atau coba online .sumber
Java 10, 110 byte
Mengambil input dan output sebagai
long
integer. Cobalah online di sini .Versi tidak disatukan:
sumber