Penghitungan yang efisien


35

Ketika saya masih kecil, dan ingin menghitung uang dolar dalam tabungan hidup saya, saya akan menghitung dengan keras:

satu dua tiga empat lima enam tujuh delapan sembilan sepuluh;
sebelas, dua belas, tiga belas, empat belas, lima belas, enam belas, tujuh belas, delapan belas, sembilan belas, dua puluh;
dua puluh satu, dua puluh dua, dua puluh tiga, dua puluh empat, dua puluh lima ...

Akhirnya saya bosan mengucapkan masing-masing angka multi-suku kata ini. Berpikir matematis, saya menciptakan metode penghitungan yang jauh lebih efisien:

satu dua tiga empat lima enam tujuh delapan sembilan sepuluh;
satu, dua, tiga, empat, lima, enam, tujuh, delapan, sembilan, dua puluh;
satu, dua, tiga, empat, lima, enam, tujuh, delapan, sembilan, tiga puluh ...

Seperti yang Anda lihat, saya hanya akan mengucapkan digit yang telah berubah dari angka sebelumnya. Ini memiliki keuntungan tambahan bahwa itu jauh lebih berulang daripada nama-nama bahasa Inggris untuk angka, dan karenanya membutuhkan lebih sedikit kekuatan otak untuk menghitung.

Tantangan

Tulis sebuah program / fungsi yang mengambil bilangan bulat positif dan menghasilkan / mengembalikan bagaimana saya akan menghitungnya: yaitu, digit paling kanan bukan nol dan semua nol tertinggal.

Contohnya

   1    1
   2    2
  10   10
  11    1
  29    9
  30   30
  99    9
 100  100
 119    9
 120   20
 200  200
 409    9
1020   20

Daftar lengkap kasus uji seharusnya tidak perlu. Ini adalah A274206 pada OEIS.

Aturan

  • Entri Anda secara teoritis harus bekerja untuk semua bilangan bulat positif, mengabaikan masalah presisi dan memori.
  • Input dan output harus dalam desimal.
  • Anda dapat memilih untuk mengambil input dan / atau output sebagai angka, string, atau array angka.
  • Input dijamin bilangan bulat positif. Entri Anda dapat melakukan apa saja untuk input yang tidak valid.

Ini adalah , jadi kode terpendek dalam byte menang.


Jadi, apakah "dalam desimal" menyertakan daftar angka desimal, seperti [1,0,2,0]-> [2,0]untuk kasus uji terakhir? (Saya tidak jelas pada frasa "array item tunggal").
Jonathan Allan

1
@ JonathanAllan Dengan "array satu-item" yang saya maksud adalah array yang berisi nomor tunggal atau string yang mewakili integer. Saya tidak berpikir mengizinkan array angka adalah ide yang baik, tetapi sekarang sepertinya semacam pembatasan sewenang-wenang karena string diizinkan (dan string sangat mirip dengan array dalam banyak bahasa). Jadi saya akan mengizinkan array angka kecuali ada alasan bagus untuk tidak melakukannya.
ETHproduk

5
Sial, kau mencuri rahasiaku: P
LegionMammal978

1
Saya pikir hampir semua orang menganggap ini sebagai anak-anak. ;) Setidaknya saya melakukannya juga. :)
Kevin Cruijssen

7
@KevinCruijssen "sebagai seorang anak"?
Martin Ender

Jawaban:


19

Python 2 , 28 byte

f=lambda n:n%10or 10*f(n/10)

Cobalah online!

Formula rekursif bekerja dengan sangat bersih. Jika digit terakhir bukan nol, keluarkan. Jika tidak, hapus nol akhir, hitung output untuk itu, dan kalikan dengan 10.


11

Jelly , 6 3 byte

-3 byte dengan memiliki I / O sebagai daftar angka desimal .

ṫTṪ

Test suite di Coba online!

Bagaimana?

ṫTṪ - Main link: listOfDigits  e.g.  [1,    0,    2,    0]  or [1,      1,    9  ]
 T  - truthy indexes                 [1,          3      ]     [1,      2,    3  ]
ṫ   - tail (vectorises)              [[1,0,2,0],  [2,0]  ]     [[1,1,9],[1,9],[9]]
  Ṫ - tail pop                                    [2,0]                       [9]

Jika kita tidak bisa mengambil daftar desimal, 6 byter adalah:

DµṫTṪḌ

Yang bisa Anda lihat di sini .

Ini melakukan hal yang sama, tetapi mengonversi bilangan bulat ke daftar desimal sebelumnya dan mengonversi kembali ke bilangan bulat setelahnya.


Ketika saya bergulir melewati beberapa jawaban pertama, saya berkata pada diri saya sendiri, "Saya bertaruh ada solusi Jelly 3-byte ..."
DLosc

9

C, 30 29 27 byte

Bangga dengan ini ketika saya menyalahgunakan dua eksploitasi C untuk golf ini (dijelaskan di akhir posting); Ini khusus untuk C (GCC)


3) b=10;f(a){a=a%b?:b*f(a/b);}// 27 byte

2) b;f(a){b=a=a%10?:10*f(a/10);}// 29 byte

1) f(i){return i%10?:10*f(i/10);}// 30 byte

Cobalah online (versi 27 byte)


Upaya pertama (30 byte): Menyalahgunakan fakta bahwa dalam GCC jika tidak ada nilai yang dinyatakan dalam ternary, nilai kondisional akan dikembalikan. Karenanya mengapa operator ternary saya kosong untuk nilai pengembalian kebenaran.

Upaya kedua (29 byte): Menyalahgunakan memori bug di GCC di mana, sejauh yang saya mengerti, jika suatu fungsi tidak memiliki nilai balik, ketika lebih dari dua variabel telah dimanfaatkan secara bermakna dalam fungsi, nilai set terakhir dari variabel argumen pertama akan dikembalikan.
   (Edit: tetapi "nilai setel" ini harus ditetapkan dengan cara tertentu, misalnya mengatur variabel dengan =atau +=berfungsi tetapi menyetelnya dengan %=tidak berfungsi; aneh)

Upaya ketiga (27 byte): Karena saya harus secara bermakna memanfaatkan variabel kedua (b) untuk menyalahgunakan bug memori yang disebutkan di atas, saya juga dapat menggunakannya sebagai variabel aktual untuk "10" untuk substitusi.
   (Catatan: Saya harus bisa bertukar a=a%bdengan a%=buntuk menyimpan byte lain tapi sayangnya ini menyebabkan exploit bug memori di atas berhenti "bekerja", jadi saya tidak bisa)


Anda mungkin ingin menambahkan "GCC" ke judul jawaban Anda karena itu spesifik GCC (tidak berfungsi pada dentang). Juga, "bug memori" mungkin hanya perilaku tidak terdefinisi yang terjadi karena susunan bingkai stack spesifik yang digunakan GCC. Mungkin tidak bekerja pada platform lain, bahkan dengan GCC.
simon

@gurka Selesai, terima kasih
Albert Renshaw

7

Retina , 7 6 byte

!`.0*$

Cobalah secara online (semua test case)

Output cocok dengan digit diikuti oleh nol di akhir string input. Meskipun tidak diperlukan, ini juga berlaku untuk 0.


Huh, saya pikir [1-9](atau [^0]) akan diperlukan sebagai gantinya \d. Saya kira keserakahan *memastikan hasil yang benar setiap saat.
ETHproduksi

@ ETHproductions Ini tidak ada hubungannya dengan keserakahan *tetapi dengan fakta bahwa kecocokan dicari dari kiri ke kanan. \d0*?$juga akan bekerja.
Martin Ender

menggunakan regex .0*$harus bekerja
12Me21

Jika ada cara (cukup singkat) untuk menghasilkan hanya pertandingan terakhir, Anda bisa menggunakan.0*
12Me21

@ 12Me21 Satu-satunya cara untuk melakukannya adalah dengan hanya mencocokkan kejadian terakhir, atau menggunakan pengganti atau sesuatu. Itu tidak akan lebih pendek.
mbomb007

7

Cubix , 18 32 byte

Saya pikir saya harus meluangkan waktu untuk ini nanti dan melihat apakah saya bisa mengompresnya sedikit. Tapi untuk saat ini dia.
Ternyata saya benar-benar salah memikirkan hal ini. Sekarang proses secara bertahap menerapkan mod (1,10.100.1000, ...) ke integer input dan mencetak yang pertama yang bukan nol. Sedikit lebih membosankan, tetapi lebih pendek.

!N%*I1^\.u;u@O\;;r

Coba di sini

    ! N
    % *
I 1 ^ \ . u ; u
@ O \ ; ; r . .
    . .
    . .

Selalu senang melihat jawaban Cubix :)
Oliver

@obarakon Mendapat yang lebih baik untuk segera dipasang. Benar-benar melakukan ini dengan cara yang salah
MickyT

5

JavaScript, 21 byte

f=n=>n%10||10*f(n/10)

Uji kasus


5

Javascript 19 18 byte

Berkat produk ETH untuk bermain golf satu byte dan Patrick Roberts karena bermain golf dua byte

x=>x.match`.0*$`

Mengembalikan array string yang cocok dengan regex berada di akhir string input dengan karakter apa pun diikuti dengan jumlah nol terbesar yang mungkin.

Cobalah secara Online


5
Saya tidak berpikir Anda perlu g, karena hanya ada satu pertandingan yang cocok.
ETHproduk

Hemat 2 byte dengan menggunakanx=>x.match`.0*$`
Patrick Roberts


3

Grime , 5 byte

d\0*e

Cobalah online!

Penjelasan

       Find the longest substring of the input matching this pattern:
d      a digit, then
 \0*   zero or more 0s, then
    e  edge of input (which is handled as an Nx1 rectangle of characters).

3

Brachylog , 2 byte

a₁

Cobalah online!

Sufiks bawaan a₁, untuk bilangan bulat, diimplementasikan sebagai:

brachylog_adfix('integer':1, 'integer':0, 'integer':0).
brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
    H #\= 0,
    H2 #\= 0,
    abs(P) #=< abs(I),
    integer_value('integer':Sign:[H|T], I),
    integer_value('integer':Sign:[H2|T2], P),
    brachylog_adfix('integer':1, [H|T], [H2|T2]).

Brachylog suka dapat memperlakukan bilangan bulat sebagai daftar digit, dan untuk itu ia menggunakan predikat utilitas khusus integer_value/2. Hal yang menarik di integer_value/2sini adalah karena harus dapat menerjemahkan dengan benar daftar digit dengan nol di depan, akhirnya juga bisa menerjemahkan bilangan bulat ke daftar digit dengan nol di depan, jadi predikat yang tidak ingin itu menerjemahkan terjadi (kebanyakan dari mereka, terutama yang tidak seperti a) melarang kepala daftar digit mereka menjadi 0. Jadi, ketika a₁menghasilkan sufiks yang terpendek pertama untuk daftar dan string, ia melompati sufiks dari setiap bilangan bulat dari bilangan bulat dengan 0 yang memimpin, yang pada Selain menghapus duplikat, juga berarti bahwa sufiks pertama yang dihasilkan adalah digit bukan nol paling kanan dengan semua nol trailing.


2

Brain-Flak , 74 byte

{({}<>)<>}(()){{}<>(({}<>)[((((()()()){}){}){}){}]<(())>){((<{}{}>))}{}}{}

Cobalah online!

Hanya mencetak non-0 terakhir dan semua 0 di belakang.

Penjelasan:

{({}<>)<>}                    # Move everything to the other stack (reverse the input)
(())                          # Push a 1 to get started
{                             # do...
  {}<>                        #   pop the result of the equals check (or initial 1)
  (                           #   push...
    ({}<>)                    #     the top value from the other stack (also put this on the stack)
    [((((()()()){}){}){}){}]  #     minus the ASCII value of 0
    <(())>                    #     on top of a 1
  )                           #   close the push   
  {                           #   if not zero (ie. if not equal)
    ((<{}{}>))                #     replace the 1 from 3 lines back with a 0
  }{}                         #   end if and pop the extra 0
}                             # while the copied value != "0"
{}                            # pop the result of the equals check


2

TI-Basic, 18 byte

If fPart(.1Ans
Return
Ans.1
prgmA
10Ans

2

R, 33 byte

Diimplementasikan sebagai fungsi yang tidak disebutkan namanya

function(x)rle(x%%10^(0:99))$v[2]

Ini berlaku mod 10 ^ 0 hingga 10 ^ 99. rledigunakan untuk mengurangi hasil sehingga item kedua selalu hasil yang kita inginkan.
Cobalah online!


2

Zsh , 18 16 byte

<<<${(M)1%[^0]*}

Cobalah online! Cobalah online!

Bash , 25 byte

r=${1%[^0]*}
echo ${1#$r}

Cobalah online!


Shell perlu memanggil program eksternal untuk menggunakan regex, jadi kita harus puas dengan globbing.

The ${1%[^0]*}ekspansi sesuai dengan akhiran terpendek dimulai dengan karakter nol, dan menghapusnya.

  • Di Zsh, menambahkan (M)bendera menyebabkan akhiran yang cocok disimpan dan bukannya dihapus.
  • Di Bash, ${1% }ekspansi menghapus sebagai awalan apa pun yang tersisa.

1

GNU sed , 17 14 +1 (r flag) = 15 byte

Sunting: 2 byte lebih sedikit berkat Riley

s:.*([^0]):\1:

Ia bekerja dengan menghapus semuanya sampai digit paling kanan bukan nol, yang kemudian dicetak bersama dengan nol trailing yang ada. Script dapat menangani beberapa tes dalam satu kali, masing-masing pada baris terpisah.

Cobalah online! (semua contoh uji)


1

Mathematica, 26 byte

Fungsi murni yang mengambil daftar digit dan menampilkan daftar digit:

#/.{___,x_,y:0...}:>{x,y}&

Penjelasan

#                           First argument
 /.                           Replace
   {                              start of list followed by
    ___,                          zero or more elements followed by
        x_,                       an element (referred to later as x) followed by
           y:0...                 a sequence of zero or more 0s (referred to later as y) followed by
                 }                end of list
                  :>            with
                    {x,y}         {x,y}
                         &   End of function.

Ini berfungsi karena menemukan kecocokan paling kiri untuk x, yang harus menjadi elemen bukan nol paling kanan dari daftar karena diikuti oleh urutan nol 0s lebih banyak dan kemudian akhir daftar.


1

Java 8, 47 byte

ini adalah ekspresi lambda yang ditugaskan untuk IntUnaryOperator:

x->{int m=1;for(;x%m<1;m*=10);return x%m*m/10;}

PENJELASAN: kalikan m dengan 10 hingga x%mtidak 0. return x%m*m/10memerlukan pembagian karena m adalah urutan besarnya lebih dari hasil yang diinginkan.



1

MATL , 10 7 byte

3 byte disimpan berkat @B. Mehta!

tfX>Jh)

Input dan output adalah array angka.

Cobalah online!

Atau verifikasi semua kasus uji .

Penjelasan

t     % Input string implicitly. Duplicate
f     % Push indices of non-zero digits
X>    % Keep maximum, say k
Jh    % Attach 1j to give [k, 1j]. This is interpreted as an index "k:end"
)     % Index into original string. Display implcitly

Karena kami diizinkan untuk mengambil input dan output sebagai vektor bilangan bulat, Anda dapat menghapus 48-seluruhnya, menghemat 3 byte: Coba online!
B. Mehta

1

C #, 30 28 byte

Berdasarkan jawaban JavaScript ini , jadi saya kira semua kredit agak jatuh ke dia.

Golf

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 byte dengan menghapus ()sekitar aberkat Emigna

1
Saya pikir Anda perlu secara eksplisit menyebutkan fungsi iagar ini berfungsi saat Anda menggunakan rekursi.
Emigna

@Emigna kamu benar! Saya benar-benar merindukan itu :(
Metoniem

Diperbarui tetapi saya tidak 100% yakin apakah itu benar seperti ini
Metoniem

1
Saya tidak tahu konsensus tentang ini dalam C #. Sintaks itu valid, tetapi hanya akan bekerja jika delegasi telah dinyatakan (jika tidak iakan dideklarasikan untuk panggilan rekursif).
Emigna

1
Tanda kurung di sekitar atidak diperlukan juga.
Emigna

1

J, 27 byte

10&|`(10*(p%&10))@.(0=10&|)

Itu didasarkan dari formula xnor, jadi kredit untuknya.


1

Kotlin, 49 byte

lambda, ditugaskan untuk (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • nama parameter implisit itdiindexOfLast
  • .. untuk rentang bangunan

1

Perl 5, 12 byte

11, ditambah 1 untuk -nEbukan-e

say/(.0*$)/



1

Stax , 5 byte

æΩ$3╚

Jalankan dan debug itu

Prosedur:

  1. Hitung "multiplisitas" dengan 10. (Itu adalah jumlah kali 10 membagi input secara merata)
  2. Tambahkan 1.
  3. Simpan banyak karakter dari kanan (input sebagai string).

1

05AB1E , 4 byte

ĀÅ¡θ

I / O sebagai daftar angka.

Cobalah secara online atau verifikasi semua test case (test suite berisi gabungan untuk keterbacaan yang lebih baik).

Penjelasan:

Ā     # Python-style truthify each digit in the (implicit) input-list (0 if 0; 1 if [1-9])
      #  i.e. [9,0,4,0,3,0,0] → [1,0,1,0,1,0,0]
 Å¡   # Split the (implicit) input-list on truthy values (1s)
      #  i.e. [9,0,4,0,3,0,0] and [1,0,1,0,1,0,0] → [[],[9,0],[4,0],[3,0,0]]
   θ  # And only leave the last inner list
      #  i.e. [[],[9,0],[4,0],[3,0,0]] → [3,0,0]
      # (after which it is output implicitly as result)


0

Haskell 57 Bytes

f(x:s)a|x=='0'=f s$'0':a|1>0=x:a
t x=f(reverse.show$x)[]

Input    -> Output
t 120    -> "20"
t 30200  -> "200"
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.