Tulis fungsi pluralisasi untuk bahasa Rusia

25

Dalam bahasa Inggris, kata benda dapat mengambil dua bentuk yang berbeda tergantung pada apakah mereka tunggal (jamak) atau jamak (apa pun). Sebagai contoh, kita akan mengatakan "1 anjing" tetapi "2 anjing", "0 anjing", "57 anjing" dan sebagainya.

Di Rusia, ada tiga kategori. Alih-alih "1 anjing, 2 anjing, 5 anjing", dalam bahasa Rusia itu akan menjadi "1 собака, 2 собаки, 5 собак".

Kategori dibagi menurut logika berikut:

  • "Singular": digunakan untuk 1 dan angka apa pun yang berakhir dengan 1, kecuali untuk angka yang berakhir dengan 11.
    • Contoh: 1 собака, 21 собака, 101 собака
  • "Sedikit": digunakan untuk 2, 3, dan 4, dan angka apa pun yang berakhiran 2, 3, atau 4 kecuali untuk angka yang diakhiri dengan 12, 13, dan 14.
    • Contoh: 2 собаки, 3 собаки, 4 собаки, 32 собаки, 43 собаки, 104 собаки, 104 собаки
  • "Many": apa pun yang tidak dianggap "Singular" atau "Few".
    • Contoh: 0 собак, 5 собак, 11 собак, 13 собак, 25 собак, 111 собак, 114 собак, 114 собак

Tantangan

Diberikan input integer dalam rentang [0, 1000], kembalikan 1jika itu termasuk dalam kategori "tunggal", 2jika itu termasuk dalam kategori "beberapa", dan 5jika itu termasuk dalam kategori "banyak".

Program Anda mungkin sebuah fungsi atau dapat menggunakan STDIN. Anda dapat mencetak ke STDOUT atau mengembalikan nilai dari fungsi

Ini adalah tantangan kode golf , jadi solusi dengan jumlah byte paling sedikit menang.

Peter Olson
sumber
2
@Phoenix Tidak dalam bahasa Rusia.
Peter Olson
2
Kenapa 1,, 2dan 5khususnya? Juga, mengapa saya tidak bisa menggunakan kode keluar?
CalculatorFeline
6
@Phoenix Kedengarannya sangat salah bagi saya - bahasa Rusia yang rusak - Saya selalu menggunakan formulir dalam pertanyaan dan saya merasa benar, dan ternyata itu benar
dkudriavtsev
2
@CalculatorFeline Jika Anda mulai menghitung dari 1, Anda mendapatkan singular pada 1, beberapa pertama terjadi pada 2, banyak yang pertama muncul pada 5. Masuk akal :-)
LLlAMnYP
5
Menghitung dalam bahasa Rusia sangat sulit. Mungkin perlu dicatat bahwa angka terakhir menentukan kasusnya . 1 = Nominative singular 2,3,4 = Genitive singular, 5-0 Genitive jamak. Ini berubah dengan kasus frasa, dan karena ada 6 kasus, ada 24 bentuk 'satu' (yang maskulin), 24 bentuk 'dua' (yang feminin) dan sebagainya. Dikatakan bahwa profesor Rusia di universitas lokal saya tidak mungkin dapat menerjemahkan " dengan 2345 anjing", karena 'dengan' menuntut kasus instrumental (yang sulit).
smirkingman

Jawaban:

15

Python 2 , 36 byte

lambda n:'5521'[n%~9/-3>>n/10%~9/-9]

Cobalah online!

Panjang yang sama secara hitung:

lambda n:5/(n%~9/-3>>n/10%~9/-9or 1)

Pertama mari kita lihat kode sederhana yang tidak memperhitungkan remaja.

lambda n:'5521'[n%~9/-3]

Di sini, kami ingin pemetaan digit seseorang ke output yang berfungsi seperti

[5, 1, 2, 2, 2, 5, 5, 5, 5, 5][n%10]

Tapi, daripada mengambil nmodulo 10 ( %10), kita bisa melakukannya n%-10, yang memetakan pada interval [-9..0]untuk memberikan sisa:

> [n%~9 for n in range(10)]
[0, -9, -8, -7, -6, -5, -4, -3, -2, -1]

Ini menjanjikan karena dua entri pertama 0dan -9berjauhan, dan mereka perlu dikirim ke output yang berbeda. Juga, -10bisa disingkat menjadi ~9.

Dari sini, lantai-membagi dengan /-3memberikan potongan 3 dengan titik awal yang tepat

> [n%~9/-3 for n in range(10)]
[0, 3, 2, 2, 2, 1, 1, 1, 0, 0]

Untuk mendapatkan hasil yang diinginkan, kita sekarang hanya perlu memetakan 0->5, 1->5, 2->2, 1->1, yang kita lakukan dengan pemilihan string '5521'[_].

Sekarang, kita juga membutuhkan angka yang diakhiri dengan 11 hingga 15 untuk selalu memberi 5. Kami pertama-tama melakukan ini dengan mendeteksi apakah kemudian puluhan digit 1. Mengambil n/10untuk menghapus digit terakhir, kami kemudian menerapkan %~9seperti sebelumnya untuk mendapatkan hasilnya

[0, -9, -8, -7, -6, -5, -4, -3, -2, -1]

untuk masing-masing digit akhir. Angka 1 yang ingin kita deteksi dipetakan ke nilai ekstrem -9. Pembagian lantai dengan -9mengubahnya menjadi 1 dan yang lainnya menjadi 0.

> [k%~9/-9 for k in range(10)]
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]

Akhirnya, kami membuat indikator ini 1selalu memberikan output 5. Hal ini dilakukan dengan menggeser-bit hasil yang n%~9/-3benar oleh indikator. Hasil 0,1,2,3selalu bit-shift ke kanan ke 0 atau 1, yang memberikan output 5 seperti yang diinginkan.

Tidak
sumber
7
Tolong jelaskan.
CalculatorFeline
12

Python 2 , 45 byte

lambda n,s='5122255555':(s+'5'*10+s*8)[n%100]

Cobalah online!

tongkat
sumber
o_O saya terpesona ... Saya punya 56 byte: \
Mr. Xcoder
Juga, bukankah (s+'5'*10+s*9)110 karakter?
CalculatorFeline
@CalculatorFeline hmm, waktunya untuk minum kopi @. @
Rod
5
@Rod atau covfefe?
Nick T
8

Perl 5 , 26 byte

25 byte kode + -pbendera.

$_=/1.$|[5-90]$/?5:2-/1$/

Cobalah online!

Untuk satu byte lagi, ada $_=/(?<!1)[1-4]$/?2-/1$/:5.

Penjelasan: (pada versi 27 byte; angka 26 cukup simetris)
Baik "tunggal" dan "sedikit" diakhiri dengan "bukan angka 1 diikuti dengan angka dari 1 hingga 4" (diuji dengan (?<!1)[1-4]$/). Dalam kasus tersebut, hasilnya adalah 2, minus 1 jika angka berakhir dengan 1 ( 2-/1$/). Kalau tidak, hasilnya jika 5.

Dada
sumber
5
tfw Perl mengalahkan 05AB1E dengan jumlah yang wajar.
Erik the Outgolfer
7

JavaScript (ES6), 53 49 48 40 39 38 37 37 byte

n=>/[05-9]$|1.$/.test(n)?5:1+(n%5>1)

Cobalah

f=
n=>/[05-9]$|1.$/.test(n)?5:1+(n%5>1)
oninput=_=>o.innerText=f(+i.value);o.innerText=f(i.value=0)
<input id=i type=number><pre id=o>

Shaggy
sumber
1[1-4]bisa 1.dan /1$/.test(s)bisa +s%10==1. Jangan lupakan unary +!
CalculatorFeline
Terima kasih, @CalculatorFeline - terlihat bagus pada yang pertama :)
Shaggy
Saya tidak berpikir Anda perlu unary +sama sekali, s%10harus mengonversi ske nomor.
ETHproduksi
Yup, baru sadar juga, @ETHproductions.
Shaggy
1
n%10-> n%5menyimpan byte
Johan Karlsson
4

Jelly ,  19  18 byte

DµṖṚi1’ȧṪị“M;ọ6’D¤

Tautan monadik yang mengambil dan mengembalikan bilangan bulat non-negatif.

Cobalah online! atau lihat ketiga grup dari 0 hingga 1000 inklusif dalam test suite ini .

Bagaimana?

DµṖṚi1’ȧṪị“M;ọ6’D¤ - Main link: non-negative number, n  e.g. 301      311      313
D                  - cast to decimal list                [3,0,1]  [3,1,1]  [1,3,3]
 µ                 - monadic chain separation, call that d
  Ṗ                - pop d                               [3,0]      [3,1]    [1,3]
   Ṛ               - reverse                             [0,3]      [1,3]    [3,1]
     1             - literal 1
    i              - first index of (0 if not found)      0          1        2      
      ’            - decrement                           -1          0        1
        Ṫ          - tail d                               1          1        3
       ȧ           - logical and                          1          0        3
                 ¤ - nilad followed by link(s) as a nilad:
          “M;ọ6’   -   base 250 literal = 1222555555
                D  -   cast to decimal list [1,2,2,2,5,5,5,5,5,5]
         ị         - index into (1-based and modular)     1          5        2
Jonathan Allan
sumber
1
Mohon penjelasannya.
CalculatorFeline
@CalculatorFeline masih bekerja untuk bermain golf ...
Jonathan Allan
@ CalculatorFeline baik saya tidak dapat menemukan yang lebih baik; penjelasan ditambahkan.
Jonathan Allan
Dalam pengkodean karakter apa 18 karakter tersebut dapat diwakili oleh 18 byte?
exebook
@exebook Jelly menggunakan halaman kode
GamrCorps
3

05AB1E , 38 19 byte

Menggunakan trik indeks dari jawaban python Rod

•1rꢰ•©5T×®9×JIт%è

Cobalah online!

Penjelasan

•1rꢰ•              # push the number 5122255555
       ©             # store a copy in register
        5T×          # push 5 repeated 10 times
           ®         # retrieve the first number from register
            9×       # repeat it 9 times
              J      # join everything to string
               Iт%   # push input mod 100
                  è  # use this to index into the string of digits
Emigna
sumber
8
Anda kalah dari Perl, saya pikir ada sesuatu yang salah di sini.
Pavel
@Phoenix: Ya. Entah tantangan ini sangat cocok untuk regex atau saya melakukan sesuatu yang sangat salah :) Agar adil, Perl sering sangat golf.
Emigna
4
@ Enigma ... dan pegolf Perl sering sangat baik, bukan? ;-)
Dada
@Dada: Sangat benar!
Emigna
Mohon penjelasannya.
CalculatorFeline
2

PHP> = 7.1, 44 Bytes

<?=$argn[-2]!=1&($m=($argn+9)%10)<4?2-!$m:5;

Versi Online

Jörg Hülsermann
sumber
1
3 byte pendek: <?=$argn[-2]!=1&($m=($argn+9)%10)<4?2-!$m:5;.
user63956
2

Majelis MCxxxx , 123 Bytes

e:slx x0
mov x0 acc
dst 2 0
tlt acc 11
-tgt acc 14
-jmp v
+dgt 0
teq acc 1
+mov 1 x1
+jmp e
tlt acc 5
+mov 2 x1
v:-mov 5 x1

catatan:

TiO tidak mendukung bahasa ini, yang digunakan dalam game Zachtronics, Shenzhen I / O , jadi tidak ada tautan untuk menguji ini.

Penjelasan:

Ini adalah fungsi yang mengambil input melalui port XBus x0, dan output melalui port x1. Ini terlalu lama untuk dieksekusi pada MC4000, tetapi cocok dengan baik ke dalam memori MC6000. Port XBus, bagi mereka yang tidak terbiasa, memungkinkan pengiriman paket data digital diskrit.

Sepotong informasi yang dapat membantu dalam membaca ini: dalam perakitan MCxxxx, instruksi tes menetapkan bendera yang menunjukkan cabang mana yang harus diambil. Baris yang dimulai dengan +hanya dieksekusi jika tes terbaru dikembalikan benar, dan garis yang dimulai dengan -hanya dieksekusi jika tes itu salah.

Baris demi baris:

e:slx x0    # Label this line e, then sleep until input is available on XBus port x0
mov x0 acc  # Move the input into register acc 
dst 2 0     # Set the leftmost digit of the input to 0
tlt acc 11  # Test if the value in acc is less than 11
-tgt acc 14 # If it's not, check if it's greater than 14
-jmp v      # If it's not, jump to the line labeled v (the last line)
+dgt 0      # If either of the previous tests returned true,
            #     set acc to the value of acc's rightmost digit
teq acc 1   # Test if acc equals 1
+mov 1 x1   # If it does, return 1
+jmp e      # Then jump to label e, which ends execution
tlt acc 5   # Test if acc is less than 5
+mov 2 x1   # If it is, return 2
v:-mov 5 x1 # If the previous test is false, return 5

Catatan tentang penilaian: Perakitan MCxxxx tidak memiliki fungsi per se, tapi ini sedekat fungsi yang bisa Anda dapatkan - ini adalah program yang cocok dalam satu simpul eksekusi, mengambil input melalui satu port dan output melalui yang lain. Sebagai hasilnya, saya telah mencetak ini seperti fungsi (yaitu tanpa menghitung byte yang diperlukan untuk membuat file emulator MCxxxx yang valid).

Pengawas
sumber
2

Retina , 25 21 byte

1.$
5
T`d`512225
!`.$

Cobalah online! -4 byte terima kasih kepada Neil.

CalculatorFeline
sumber
1
Simpan 4 byte dengan menggunakan !`.$untuk mengekstrak digit terakhir. Cobalah online!
Neil
Saya tahu ada cara yang lebih baik!
CalculatorFeline
1

Haskell , 62 58 byte

f n|s<-"5122255555"=(s++('5'<$[0..9])++cycle s)!!mod n 100

Cobalah online!

Penjelasan

Ini membangun string berikut:

5122255555555555555551222555555122255555512225555551222555555122255555512225555551222555555122255555 ...

Yang merupakan tabel di mana sel nberisi jawaban untuk nthnomor tersebut. Tabel hanya benar untuk 100 elemen pertama, karenanya mod.

bartavelle
sumber
Bisakah Anda jelaskan apa yang terjadi di sini? Anda pasti bisa mempersingkatnya menggunakanf n|s<-"5122255555"=(s++('5'<$[0..9])++cycle s)!!mod n 100
flawr
Saya tidak tahu itu mungkin!
bartavelle
1
Ada banyak tips dan trik di codegolf.stackexchange.com/questions/19255/… benar-benar layak dibaca =)
flawr
0

Scala, 110 byte

n=>Stream.iterate("512225555555555555555")(_=>"1222555555").flatMap(_.toCharArray).map(_.toInt).take(n-1).head
Phoenix
sumber
0

Turtlèd, 35 byte

!--.(1#0#)+.@3(1@1)(2@2)(3@2)(4@2),

Cobalah online!

Fungsi ini mensyaratkan bahwa input dimulai dengan>, yang saya kira tidak masalah karena python2 menggunakan input semi secara teratur, dan itu membutuhkan tanda kutip.

Penjelasan:

!             input the number as a string, complete with the >
 --.          wrap around to the end of the string, and then move one back. if this
              is a single digit, we end up on the >,
              otherwise we end up on the second to last digit. write the digit/>

    (1#0#)    if it is 1, set the string to 0. this way it will always write 3 at the end.



          +.       write the last digit (or 0 if the second last digit was 1)
            @3      set the character variable to 3. this means if what was written was not
                       in (1, 2, 3, 4), then it will write 3 at the end
              (1@1)    if the character written was a 1, set the character to be written
                       at the end to 1
                   (2@2)(3@2)(4@2)
                     if it is any of 2,3,4, set the character to be written at the end to 2
                                  ,    write the character that was set
Lemon dirusak
sumber
Apakah >melayani tujuan dalam Turtled atau itu karakter sewenang-wenang yang telah Anda tambahkan ke input?
Shaggy