Napisz funkcję pluralizacyjną dla języka rosyjskiego


25

W języku angielskim rzeczowniki mogą przybierać dwie różne formy w zależności od tego, czy są w liczbie pojedynczej (jedna) czy mnogiej (cokolwiek innego). Na przykład powiedzielibyśmy „1 pies”, ale „2 psy”, „0 psów”, „57 psów” i tak dalej.

W języku rosyjskim istnieją trzy kategorie. Zamiast „1 pies, 2 psy, 5 psów”, w języku rosyjskim byłoby to „1 собака, 2 собака, 5 собак”.

Kategorie są podzielone zgodnie z następującą logiką:

  • „Liczba pojedyncza”: używana dla 1 i dowolnej liczby kończącej się na 1, z wyjątkiem liczb kończących się na 11.
    • Przykłady: 1 собака, 21 собака, 101 собака
  • „Niewiele”: używane dla 2, 3 i 4 oraz dowolnej liczby kończącej się na 2, 3 lub 4, z wyjątkiem liczb kończących się na 12, 13 i 14.
    • Przykłady: 2 собаки, 3 собаки, 4 собаки, 32 собаки, 43 собаки, 104 собаки
  • „Wiele”: wszystko, co nie jest uważane za „Liczba pojedyncza” lub „Mało”.
    • Przykłady: 0 lat, 5 lat, 11 lat, 13 lat, 25 lat, 111 lat, 114 lat, 114 lat

Wyzwanie

Biorąc pod uwagę liczbę całkowitą z zakresu [0, 1000], zwróć, 1jeśli należy do kategorii „liczba pojedyncza”, 2jeśli należy do kategorii „kilka” i 5jeśli należy do kategorii „wiele”.

Twój program może być funkcją lub może korzystać ze STDIN. Możesz wydrukować do STDOUT lub zwrócić wartość z funkcji

Jest to wyzwanie dla golfa , więc wygrywa rozwiązanie z najmniejszą liczbą bajtów.



2
Dlaczego 1, 2oraz 5w szczególności? Ponadto, dlaczego nie mogę używać kodów wyjścia?
CalculatorFeline

6
@Phoenix To brzmi dla mnie zupełnie źle - zepsuty rosyjski - zawsze użyłem formularza w pytaniu i uważam, że jest poprawny, i najwyraźniej tak jest
dkudriavtsev

2
@CalculatorFeline Jeśli zaczniesz odliczać od 1, masz liczbę pojedynczą na 1, kilka pierwszych pojawia się o 2, wiele pojawia się po raz pierwszy na 5.
Ma

5
Liczenie w języku rosyjskim jest niezwykle trudne. Być może warto zauważyć, że ostatnia cyfra określa wielkość liter . 1 = Nominatywna liczba pojedyncza 2,3,4 = Dopełniacz liczba pojedyncza, 5-0 Dopełniacz liczba mnoga. Zmienia się to w przypadku frazy, a ponieważ jest 6 przypadków, istnieją 24 formy „jednego” (które jest męskie), 24 formy „dwóch” (które jest żeńskie) i tak dalej. Mówi się, że profesor rosyjskiego na moim lokalnym uniwersytecie raczej nie byłby w stanie tłumaczyć „ z 2345 psami”, ponieważ „z” wymaga skrzyni instrumentalnej (trudnej).
smirkingman

Odpowiedzi:


15

Python 2 , 36 bajtów

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

Wypróbuj online!

Ta sama długość arytmetycznie:

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

Najpierw spójrzmy na prostszy kod, który nie uwzględnia nastolatków.

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

Chcemy tutaj odwzorować cyfrę tej cyfry na wyjście, które działa podobnie

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

Ale zamiast wziąć nmodulo 10 ( %10), możemy to zrobić n%-10, który odwzorowuje interwały, [-9..0]dając resztki:

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

To obiecujące, ponieważ dwie pierwsze pozycje 0i -9są daleko od siebie, a oni muszą być wysyłane do różnych wyjść. Ponadto, -10może być skrócony do ~9.

Odtąd dzielenie podłogi /-3daje 3 kawałki z właściwym punktem początkowym

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

Aby uzyskać pożądany wynik, musimy teraz tylko zmapować 0->5, 1->5, 2->2, 1->1 , co robimy z wyborem ciągu '5521'[_].

Teraz potrzebujemy również liczb kończących się od 11 do 15, aby zawsze podawać 5. Najpierw robimy to, wykrywając, czy jest to cyfra dziesiątek 1. Biorąc n/10do usunięcia ostatnią cyfrę, aplikujemy %~9jak poprzednio, aby uzyskać wyniki

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

dla odpowiednich cyfr końcowych. Cyfra 1, którą chcemy wykryć, jest odwzorowana na wartość ekstremalną -9. Dzielenie podłogi -9zmienia się na 1, a wszystko inne na 0.

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

Wreszcie, sprawiamy, że ten wskaźnik 1zawsze daje wynik 5. Robi się to poprzez przesunięcie bitowe wyniku n%~9/-3prawo o wskaźnik. Wynik 0,1,2,3zawsze przesuwa bit w prawo do 0 lub 1, co daje wynik 5 zgodnie z potrzebami.


7
Proszę wytłumacz.
CalculatorFeline


8

Perl 5 , 26 bajtów

25 bajtów kodu + -pflaga.

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

Wypróbuj online!

Jeszcze jeden bajt $_=/(?<!1)[1-4]$/?2-/1$/:5.

Objaśnienia: (w wersji 27-bajtowej; 26 jest dość symetryczny)
Zarówno „liczba pojedyncza”, jak i „kilka” kończą się na „nie 1, a po nim cyfra od 1 do 4” (testowane na (?<!1)[1-4]$/). W takim przypadku wynikiem jest 2, minus 1, jeśli liczba kończy się na 1 ( 2-/1$/). W przeciwnym razie wynik, jeśli 5.


5
tfw Perl pokonuje 05AB1E o godziwą kwotę.
Erik the Outgolfer

7

JavaScript (ES6), 53 49 48 40 39 38 37 36 bajtów

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

Spróbuj

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>


1[1-4]może być 1.i /1$/.test(s)może być +s%10==1. Nigdy nie zapomnij o jednym +!
CalculatorFeline

Dzięki, @CalculatorFeline - dobrze zauważony na pierwszym :)
Shaggy

Nie sądzę, żebyś +w ogóle potrzebował jedności , s%10powinien konwertować sna liczbę.
ETHprodukcje

Tak, właśnie zdałem sobie z tego sprawę, @ETHproductions.
Kudłaty

1
n%10-> n%5zapisuje bajt
Johan Karlsson

4

Galaretka ,  19  18 bajtów

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

Łącze monadyczne przyjmujące i zwracające nieujemne liczby całkowite.

Wypróbuj online!lub zobacz trzy grupy od 0 do 1000 włącznie w tym zestawie testów .

W jaki sposób?

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

1
Proszę o wyjaśnienie.
CalculatorFeline

@CalculatorFeline nadal pracuje nad golfem ...
Jonathan Allan

@CalculatorFeline dobrze nie mogę znaleźć lepiej; wyjaśnienie dodane.
Jonathan Allan

W jakim kodowaniu znaków te 18 znaków może być reprezentowanych przez 18 bajtów?
exebook

@exebook Jelly używa własnej strony kodowej
GamrCorps

3

05AB1E , 38 19 bajtów

Używa sztuczki indeksu z odpowiedzi pytona Rod

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

Wypróbuj online!

Wyjaśnienie

•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

8
Przegrywasz z Perlem, myślę, że coś tu jest nie tak.
Pavel

@Phoenix: Tak. Albo to wyzwanie nadaje się do wyrażenia regularnego, albo robię coś strasznie złego :) Szczerze mówiąc, Perl jest często golfistą.
Emigna

4
@Enigma ... i golfiści Perl są często bardzo dobrzy, prawda? ;-)
Dada

@Dada: Bardzo prawda!
Emigna

Proszę o wyjaśnienie.
CalculatorFeline


2

Zestaw MCxxxx , 123 bajty

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

Uwaga:

TiO nie obsługuje tego języka, który jest używany w grze Zachtronics Shenzhen I / O , więc nie ma łącza do przetestowania tego.

Wyjaśnienie:

Ta funkcja pobiera dane wejściowe przez port XBus x0 i dane wyjściowe przez port x1. Jest zbyt długi, aby wykonać go na MC4000, ale ładnie pasuje do pamięci MC6000. Porty XBus, dla osób nieznanych, umożliwiają przesyłanie dyskretnych pakietów danych cyfrowych.

Jedna informacja, która może być pomocna w czytaniu tego: w zestawie MCxxxx instrukcje testowe ustawiają flagę wskazującą, którą gałąź należy podjąć. Linie rozpoczynające się od +są wykonywane tylko wtedy, gdy ostatni test zwrócił wartość true, a linie rozpoczynające się od- są wykonywane tylko wtedy, gdy test był fałszywy.

Linia po linii:

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

Uwaga na temat punktacji: zestaw MCxxxx nie ma funkcji jako takich, ale jest to tak blisko funkcji, jak to tylko możliwe - to program, który pasuje do jednego węzła wykonawczego, pobiera dane wejściowe przez jeden port i dane wyjściowe przez inny. W rezultacie zdobyłem to jak funkcję (tj. Bez zliczania bajtów niezbędnych do utworzenia prawidłowego pliku emulatora MCxxxx).



1

Haskell , 62 58 bajtów

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

Wypróbuj online!

Wyjaśnienie

To buduje następujący ciąg:

5122255555555555555551222555555122255555512225555551222555555122255555512225555551222555555122255555 ...

Która jest tabelą, w której komórka nzawiera odpowiedź na nthliczbę. Tabela jest poprawna tylko dla pierwszych 100 elementów, stąd mod.


Czy możesz wyjaśnić, co się tutaj dzieje? Z pewnością można go skrócić, używającf n|s<-"5122255555"=(s++('5'<$[0..9])++cycle s)!!mod n 100
flawr

Nie wiedziałem, że to możliwe!
bartavelle

1
Istnieje wiele innych wskazówek i wskazówek w codegolf.stackexchange.com/questions/19255/… naprawdę warto przeczytać =)
flawr

0

Scala, 110 bajtów

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

0

Turtlèd, 35 bajtów

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

Wypróbuj online!

Ta funkcja wymaga, aby dane wejściowe zaczynały się od>, co, jak sądzę, jest w porządku, ponieważ python2 używa danych wejściowych semi regularnie, a to wymaga cudzysłowów.

Wyjaśnienie:

!             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

Czy ma >jakiś cel w Turtled, czy jest to dowolna postać, którą dodałeś do wkładu?
Shaggy
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.