Latar Belakang:
Matematika operasi standar seperti penjumlahan dasar dan perkalian di dunia nyata bekerja seperti ini:
12 + 123 = 135
dan
12 * 123 = 1476
Itu tidak menarik dan tidak membosankan! Banyak sekolah sudah menafsirkan ini sebagai praktik, praktik, praktik algoritma formal. Itu menyiratkan diet matematika yang cukup kaku dan membosankan dan bukan yang dimaksudkan dalam tantangan ini. Bersiaplah untuk bersenang-senang di situs tercinta kami.
Pertimbangkan proses menambahkan dua bilangan bulat positif, lalu tambahkan lagi semua digit hasilnya. Mengulangi dengan penambahan sampai hanya satu digit yang diperoleh. Sebagai contoh:
- Hasilnya
12 + 123
adalah 135. - Menambahkan semua angka 135 kita dapatkan
1 + 3 + 5 = 9
.
Jumlah langkah yang diperlukan untuk mendapatkan nilai satu digit 9 dalam penambahan berulang ini adalah 2.
Seperti halnya proses penambahan sebelumnya, perkalian dua bilangan bulat positif mengikuti proses yang sama. Lipat gandakan semua digit hasilnya dan ulangi proses ini sampai hanya satu digit yang tersisa. Ambil contoh di atas:
- Hasilnya
12 * 123
adalah 1476. - Lipat gandakan semua angka 1476 yang kita dapatkan
1 * 4 * 7 * 6 = 168
. - Kalikan lagi semua angka 168 yang kita dapatkan
1 * 6 * 8 = 48
. - Kalikan lagi semua angka 48 yang kita dapatkan
4 * 8 = 32
. - Kalikan sekali lagi semua angka 32 yang kita peroleh
3 * 2 = 6
.
Jumlah langkah yang diperlukan untuk mendapatkan nilai satu digit 6 perkalian berulang ini adalah 5.
Demi tantangan ini dan menghindari penyalahgunaan notasi matematika, saya memperkenalkan dua notasi dummy ini: (+)
dan (*)
, tetapi Anda dapat menggunakan notasi yang Anda suka , yang berfungsi seperti berikut:
- Operasi proses penambahan berulang untuk mendapatkan nilai tunggal adalah
12 (+) 123 = 9
. - Pengoperasian proses multiplikasi berulang untuk mendapatkan nilai tunggal adalah
12 (*) 123 = 6
.
Tantangan:
Tantangannya adalah untuk menulis baik program atau fungsi yang dapat melakukan kedua operasi seperti yang dijelaskan di bagian latar belakang: (+)
dan (*)
.
Memasukkan:
Input dari program atau fungsi adalah dua bilangan bulat positif dan satu operasi baik (+)
dan (*)
. Format input adalah pilihan sewenang-wenang dari programmer . Anda dapat memformat input, misalnya, a (+) b
atau F(a, (+), b)
format apa pun yang Anda inginkan.
Keluaran:
Output dari program atau fungsi harus berisi hasil operasi dan jumlah langkah yang diperlukan dengan format gaya bebas seperti yang Anda inginkan.
Kasus Uji (abaikan format input dan output):
81 (+) 31 --> (4 ; 2)
351 (+) 14568 --> (6 ; 3)
21 (*) 111 --> (8 ; 3)
136 (*) 2356 --> (0 ; 2)
Aturan umum:
- Ini adalah kode-golf , jadi jawaban tersingkat dalam byte memenangkan tantangan.
Jangan biarkan esolang mencegah Anda mengirim jawaban dengan bahasa biasa. Nikmati tantangan ini dengan memberikan jawaban sesingkat mungkin dengan bahasa pemrograman Anda. Jika Anda memposting jawaban yang cerdas dan penjelasan yang jelas, jawaban Anda akan dihargai (karenanya upvotes) terlepas dari bahasa pemrograman yang Anda gunakan. - Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat, program lengkap, dll. Pilihan ada di tangan Anda.
- Jika memungkinkan, program Anda dapat menangani jumlah besar dengan benar. Jika tidak, itu akan baik-baik saja.
sumber
Jawaban:
Dyalog APL ,
33323029 byteIni meluas APL untuk memasukkan notasi awalan
+/A n₁ n₂
dan×/A n₁ n₂
. (Bahkan, Anda dapat menggunakan operasi apa pun di sebelah kiri/A
.) Mengembalikan daftar {result, count pengulangan}.TryAPL online! (
⍎
telah ditiru dengane
alasan keamanan.)Terima kasih kepada @ngn untuk menghemat satu byte.
0 byte (bercanda)
Dyalog APL sebenarnya sudah memiliki dukungan penuh untuk matematika Anastasiyan; bukannya
(+)
dan(×)
, itu menggunakan+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
dan×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
.Coba
81 +{(⊃,≢)⍺⍺{∪⍵,⍨⍺⍺e¨⍕⊃⍵}⍣≡⍺⍺/⍺⍵} 31
dan21 ×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/e¨⍕⍵}⍣=⍵⍺⍺⍨⍺} 111
.sumber
⎕FR←1287
(yaitu menggunakan IEEE 754-2008 128-bit desimal F representasi titik rating-titik R ) dan⎕PP←34
(yaitu menggunakan resi P rint P P karakter 34 karakter ), Anda dapat menggunakan bilangan bulat di bawah 10³⁴.+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
dan×{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
masih beberapa byte? Saya bingung tentang bagaimana ini 0 byte ..: S(+)
akan menjadi Anastasiyan +. Dyalog APL memang mendukung matematika Anastasiyan, tetapi ia menggunakan multi-char glyph yang berbeda, sama seperti*
kekuatan dan Anda perlu×
untuk perkalian, sementara itu/
berarti replikasi dan Anda perlu÷
untuk pembagian.(+)
Anda+{n←0⋄n,⍺⍺{n+←1⋄⍺⍺/⍎¨⍕⍵}⍣=⍵⍺⍺⍨⍺}
sebagai input, tetapi karena OP memang menyatakan format input apa pun akan dilakukan, Anda dapat menggunakan fungsi sebagai parameter. Hmm, saya bertanya-tanya apakah ini juga mungkin dalam bahasa pemrograman lain yang mendukung fungsi sebagai input.Haskell, 108 byte
Mendefinisikan fungsi
#
yang pertama mengambila
danb
kemudian operatoro
. Fakta menyenangkan: ini berfungsi dengan semua operator (sebenarnya, fungsi apa pun) yang Anda inginkan!sumber
Integer
tipe Haskell tidak terikat.Pyke, 16 byte
Coba di sini!
Mengambil multiply as
B
dan add ass
. Dua input numerik dipisahkan oleh koma.sumber
JavaScript (ES6), 59
Fungsi rekursif, format input dirancang untuk menyederhanakan panggilan rekursif:
Uji
sumber
Python 2, 60 byte
Input adalah string seperti
81+31
, output adalah tupel dari string tunggal dan penghitung (misalnya('4', 2)
,.Uji di Ideone .
sumber
f(['81', '31'],'+')
byte lebih lanjut dapat disimpan, tetapi rasanya seperti meregangkan aturan agak terlalu jauh ...operator.add
atauoperator.mul
masing - masing;)Pyth, 16
Mengambil input seperti
"+ 123 12"
untuk penambahan, dan"* 123 12"
untuk perkalian. Output sepertiresult<linefeed>steps
.Cobalah di sini , atau jalankan Test Suite , tetapi perhatikan bahwa ini bergantung pada eval, jadi hanya varian tambahan yang akan berfungsi di penerjemah online. Perkalian bekerja dengan benar dengan penerjemah offline.
Ini menggunakan fungsi reduksi kumulatif untuk membuat daftar hasil antara, jadi untuk
"+ 351 14568"
kita dapatkan[14919, 24, 6]
. Ini berfungsi karena angka satu digit adalah titik tetap dari penambahan dan perkalian Anastasiya. Kemudian kita hanya mendapatkan elemen terakhir dari array serta panjang array.Ini akan bekerja untuk jumlah besar yang sewenang-wenang, setidaknya sampai Anda kehabisan memori.
sumber
R,
175167164140134127126119 byteTidak Disatukan:
ifelse
kembali ! Ya!Tidak
Penggunaan:
Terima kasih banyak kepada @plannapus karena bermain golf 24 byte!
-7 byte berkat ide bagus dari @Vlo !
sumber
strtoi
! 4 byte lagi, Anda telah mengalahkan saya.05AB1E ,
2015 bytePenjelasan
Operator adalah 1 untuk penambahan, 0 untuk perkalian.
Cobalah online
sumber
Jelly ,
1110 byteInput adalah sepasang angka dan salah satu
+
atau×
.Cobalah online! atau verifikasi semua kasus uji .
Bagaimana itu bekerja
sumber
Kode Mesin ARM, 48 byte
Hex dump:
Fungsi ini tidak bergantung pada panggilan sistem atau fungsi pustaka. Ini adalah kode Thumb-2, yang merupakan pengodean instruksi panjang variabel (2 atau 4 byte) untuk ARM 32-bit. Dengan demikian, nilai maksimum yang dapat diproses adalah 2 ^ 32-1. 2 byte dapat dihapus jika tidak sesuai dengan AAPCS ( 46 byte ), karena kita tidak perlu menumpuk register di awal.
Perakitan tidak disatukan (sintaksis GNU):
Skrip pengujian dalam C:
sumber
R,
130124 karakterPendekatan yang agak berbeda dari @ Frédéric :
Diindentasi, dengan baris baru:
Baris 4 mungkin perlu penjelasan lebih lanjut:
Kasus uji:
sumber
f
menjadi nama fungsi dan salah satu argumennya :)Oktaf, 85 byte
MATLAB, 123, 114, 105, 94 byteMemutuskan untuk menerjemahkan ini ke Octace, untuk mengambil keuntungan dari pengindeksan langsung, dan meningkatkan kapabilitit. Mengambil input pada formulir:, di
f(a,operator)
manaa = [number1, number2]
, danoperator==1
memberikan produk, danoperator==2
memberikan jumlahnya.Penjelasan:
g={@prod,@sum}{o}
: Memilih fungsi, produk, atau jumlah yang sesuai dan menugaskannyag
x=g(a)
mengambil jumlah atau produk dari inputi=1; ... i++
: Incrementer untuk menghitung jumlah langkahMenghapus dua baris baru, spasi, dan menempatkan kedua angka input dalam vektor, bukan argumen terpisah. Ini menghemat 9 byte, terima kasih untuk pajonk! Dihapus
k=@(x)...
untuk menyimpan 11 byte lagi berkat gelas kimia =) Akhirnya, terjemahkan semuanya ke Octave untuk menyimpan 9 byte lagi ...sumber
Java,
164159146 byteArgumen pertama hanyalah penghitung, selalu 0
Argumen kedua adalah metode, 0 untuk ADD dan 1 untuk MULTIPLY.
Argumen ketiga adalah array dari Strings, yang berisi nilai-nilai untuk ditambahkan / dikalikan.
Tidak disatukan
terima kasih kepada @Kevin Cruijssen karena telah memotong beberapa byte.
terima kasih kepada @milk untuk mencukur 5 byte.
Program Tes
sumber
m==0
bisam<1
, danInteger.parseInt
bisaInteger.decode
.j
var pada akhirnya? Inlining(r+"")
dua kali kelihatannya akan mencukur beberapa byte.Jelly , 17 byte
Cobalah online!
Diberikan argumen seperti
x y 1
, ini menghitung jumlah Anastasiyax (+) y
.Diberikan argumen seperti
x y 0
, ini menghitung produk Anastasiyax (*) y
.Output diberikan sebagai
[number of steps, result]
.sumber
Python,
160146129 byteAkan segera memposting penjelasan.
Input dalam bentuk
12+12
atau5*35
(dengan tanda+
dan normal*
), dan mengasumsikan bahwa hanya dua operator itu.Ia dapat menangani input angka sebesar yang dimungkinkan oleh memori komputer Anda.
Saya hampir pasti yakin bahwa ini bisa lebih jauh.
EDIT:
1631 byte disimpan berkat @ Kopper.sumber
"+" if "+" in s else "*"
ke"*+"["+"in s]
, dan alih-alih menugaskannyat
, tambahkan saja inline dalamexec
panggilan.R, 110 byte
Menggunakan splitter @plannapus.
function(A,F,B){r=Reduce;x=r(F,A,B);y=1;while(x>9){m=nchar(x);x=r(F,x%%10^(1:m)%/%10^(1:m-1));y=y+1};cat(x,y)}
Keluaran
sunting: Saya tidak bisa menghitung.
sumber
Clojure 126 byte
Fungsi disebut seperti ini:
Berikut adalah kode yang tidak ditandai:
Ingatlah bahwa Clojure masih baru bagi saya, jadi ini mungkin bukan solusi terbaik. Tantangannya sama-sama menyenangkan. Selain itu, kode dijalankan dengan angka yang sangat besar tanpa kesulitan.
sumber
Perl 6 53 byte
Karena
( 12, &[+], 123 )
dapat diterima untuk input, saya bisa turun ke 53 byte.(
&[+]
kependekan&infix:<+>
yang merupakan "penghormatan" kepada operator penjumlahan infiks numerik)Jika argumen kedua harus berupa string,
(+)
itu akan menjadi 87 bytePenjelasan:
Uji:
Penggunaan Normal:
sumber
Python 2,
10797 byteFungsi anonim yang mengambil input melalui argumen dari operan pertama
a
, operatoro
('+'
atau'*'
) dan operan keduab
, dan mengembalikan daftar formulir[result, steps]
.Bagaimana itu bekerja
Fungsi anonim membuat string dengan menggabungkan operan dengan operator di antara mereka, dan kemudian mengevaluasinya; ini adalah langkah pertama yang dijelaskan dalam pertanyaan. Kemudian, nilai ini dan operator diteruskan ke fungsi rekursif
g
. Di sini, penghitungi
, yang ditambahkan untuk setiap panggilan rekursif, digunakan. Jika input kurang dari10
, satu digit pasti telah tercapai, jadi ini dani
dikembalikan. Jika tidak, input dikonversi ke string dan setiap karakter dalam string ini digabungkan dengan operator, memberikan perhitungan yang diinginkan, yang kemudian dievaluasi dan diteruskan ke fungsi secara rekursif.Cobalah di Ideone
sumber
Groovy, 102 byte
Merosot
Penjelasan
Berbasis pada solusi @Sean Bean untuk Java.
p
: Penutupan (fungsi, lambda, apa pun) yang mengimplementasikan solusit
: Kedalaman panggilan saat ini (jumlah iterasi),p
harus selalu dipanggil dengant=1
m
: Operasi untuk melakukan,0
untuk "tambah",1
untuk "multiply"d
: Daftar operan, setiap operan adalah objek Stringe
: Elemen-elemen darid
, masing-masing dikonversi ke Integerr
: Jumlah atau produke
, tergantung pada operasinyam
r > 9
:r > 9
), pasang kembali, tambah kedalamant
dan konversir
ke daftar string digit (dan kembalikan hasil).r
dant
sebagai daftar.Program Tes
Hasil
sumber
Haskell,
7670 byteMengembalikan daftar dua elemen dengan hasil dan jumlah langkah. Bekerja untuk jumlah besar yang sewenang-wenang. Contoh penggunaan:
(351#14568)(+)
->[6,3]
.Sunting: Terima kasih kepada @BlackCap selama 6 byte.
sumber
(-48+).fromEnum
denganread.pure
R, 91 byte
Menggunakan kode @ Vlo, yang menggunakan splitter @ plannapus, dan beberapa ide yang saya hasilkan saat bermain golf jawaban @ Frédéric, ini adalah jawaban R terpendek. (Sejumlah besar jawaban R di sini hari ini ...)
Yang terpenting, ini mensyaratkan bahwa input untuk operator adalah
sum
untuk (+) atauprod
untuk (*). Di bawah aturan tantangan, ini tampaknya baik-baik saja.Dengan lekukan:
Perbedaan utama dari jawaban @ Vlo adalah:
Reduce
, kami mengandalkan argumen input sebagai fungsi, dan sebut saja secara eksplisit. (Yay untuk fungsi menjadi objek kelas satu!)T
, yang dievaluasi menjadiTRUE
(alias1
), tetapi karena itu bukan variabel cadangan kami dapat memodifikasinya. Dengan demikianT+T
adalah2
. Jadi kami menggunakannya sebagai penghitung kami.cat
menggunakan output, kami hanya mengembalikannya dengan vektorc
. Serta menghemat dua byte, fakta bahwa output dipaksa menjadi vektor memastikanT
kelasnumeric
. Jika kami menggunakancat
, danT
belum bertambah, maka kami mendapatkan output yang salah seperti1 TRUE
.sumber
while
lingkaran sebagai berikut, mengubahF
menjadi sesuatu yang lain untuk konflik nama menghindari:function(A,O,B){x=O(A,B);while({F=F+1;x>9})x=O(x%/%10^(1:nchar(x)-1)%%10;c(x,F)}}
. Sungguh menakjubkan betapa banyak trik golf R yang kami buat dalam beberapa tahun terakhir :)T
danF
kontra dalam suatu fungsi sebenarnya tidak valid, karena itu berarti bahwa fungsi tersebut hanya dapat dipanggil sekali. Jadi jawaban ini (dan beberapa jawaban saya yang lain!) Tidak valid, kecuali ada yang eksplisitrm(T)
di bagian akhir. Aku akan terus mencari posting meta itu jadi aku bisa yakin aku tidak hanya memimpikannya.T
danF
trik benar-benar berlaku selama Anda tidak mengubahT
atauF
dalam lingkungan global. misalnya,f=function(){T=T+1;T}
secara konsisten kembali2
. Saya pikir ini adalah pos meta yang Anda referensikan.Ruby, 55 byte
Panggilan rekursif. Dulu sangat berbeda dari jawaban JavaScript @ edc65, tetapi ketika saya mengoptimalkannya akhirnya menjadi port langsung yang dikembangkan hampir secara independen dari jawaban mereka, minus satu optimasi akhir yang melibatkan memeriksa hasil yang dievaluasi alih-alih panjang daftar operan yang dilewatkan dalam , yang memungkinkan saya untuk melampaui jumlah byte mereka.
Input adalah string yang mewakili operator, dan array yang berisi operan.
Cobalah online.
sumber
i=0
dan saya agak lupa ketika refactoring.Perl, 38 byte
Termasuk +2 untuk
-ap
Jalankan dengan input pada STDIN dan spasi di sekitar operator:
Outputnya digit dan langkah dipisahkan oleh
+A
amath.pl
:Jika mengeluarkan langkah-langkah di unary adalah ok, versi 35 byte ini berfungsi lebih baik:
sumber
Mathematica,
10594 byteKode.
Pemakaian.
Penjelasan.
Dua fungsi
x
(untuk (+)) dany
(untuk (*)) diciptakan pada saat yang sama dengan mengganti parameterf
dano
didengan nilai-nilai yang sesuai. Karena
x
,f
menjadi#1 + #2
dano
menjadiPlus
; karenay
, mereka masing-masing menjadi#1 #2
danTimes
. Menulis ulang fungsix
untuk bagian terakhir dari penjelasan:sumber
Java 7,
203195192 byteIni menggunakan
long
(nilai maksimum 2 63 -1). Jika itu akan digunakanint
sebagai gantinya (nilai maksimum 2 31 -1) itu hanya akan menjadi 1 byte lebih sedikit ( 191 byte ):Kemungkinan besar bisa bermain golf lebih banyak. Namun, harus mencetak langkah-langkah serta jawaban untuk kedua operator memerlukan beberapa byte.
Menggunakan 0 (untuk
(+)
) dan 1 (untuk(*)
).Tidak digabungkan & kode uji:
Coba di sini.
Keluaran:
sumber