Posortuj te oceny obligacji

23

Zadanie

Te agencje ratingowe przyznają oceny obligacji w odpowiedniej zdolności kredytowej emitenta, a „Big Three” agencje ratingowe mają podobną (choć nie identyczne) wielopoziomowy system oceny . Mają one wyraźną, logiczną kolejność - przy użyciu warstw S&P, AAA> AA +> AA> AA-> A +> ...> BBB> B> ...> C. Moody's używa podobnego systemu, ale nazywa swoje poziomy inaczej ( Aaa> Aa1> Aa2> ...> Baa1> ...> C).

Twoim zadaniem jest zaprojektowanie programu, który jako dane wejściowe przyjmuje listę ciągów reprezentujących poziomy oceny obligacji i wyświetla tę samą listę, posortowaną w kolejności malejącej od najwyższego poziomu (AAA / Aaa) do najniższego poziomu (C).

Wejście wyjście

Możesz wybrać format danych wejściowych (lista, jeden na argument, plik CSV). Możesz założyć, że każdy element na liście danych wejściowych jest prawidłowym ciągiem oceny i że wszystkie ciągi oceny na liście pochodzą od tej samej agencji ratingowej . Dodatkowo możesz założyć, że nie będzie uwzględniona żadna z ocen funky NA, takich jak „NR” lub „WR” - dotyczy to wyłącznie „Aaa / AAA” do „C”. Na liście danych wejściowych mogą znajdować się zduplikowane oceny i jeśli zostaną znalezione, nie należy ich usuwać.

Możesz także wybrać format wyjściowy odpowiedni dla twojego języka, z jedynym ograniczeniem, że powinien on wypisywać jakieś standardowe kodowanie tekstu, takie jak UTF-8 lub ASCII.

Zasady i punktacja

To jest kod golfowy, więc wygrywa najmniej bajtów, standardowe luki są niedozwolone. Proszę określić, jaki jest format wejściowy i wyjściowy.

Przykładowy program i przypadki testowe

Przykładowy program Python poniżej może być używany jako standardowy przykład prawidłowej kolejności sortowania. Listy Moodyi SPsą kolejność korzystania.

Moody = ['Aaa', 'Aa1', 'Aa2', 'Aa3', 'A1', 'A2', 'A3',
         'Baa1', 'Baa2', 'Baa3', 'Ba1', 'Ba2', 'Ba3',
         'B1', 'B2', 'B3', 'Caa', 'Ca', 'C']

SP = ['AAA', 'AA+', 'AA', 'AA-', 'A+', 'A', 'A-',
      'BBB+', 'BBB', 'BBB-', 'BB+', 'BB', 'BB-',
      'B+', 'B', 'B-', 'CCC', 'CC', 'C']

test_cases = [
    (['Aa2', 'Aaa', 'Aa1'], ['Aaa', 'Aa1', 'Aa2']),
    (['AA', 'AA-', 'AA+'], ['AA+', 'AA', 'AA-']),
    (['Baa1', 'Ba1', 'A1', 'B1', 'Aaa', 'C', 'Caa', 'Aa1'],
     ['Aaa', 'Aa1', 'A1', 'Baa1', 'Ba1', 'B1', 'Caa', 'C']),
    (['BBB+', 'BB+', 'A+', 'B+', 'AAA', 'C', 'CCC', 'AA+'],
     ['AAA', 'AA+', 'A+', 'BBB+', 'BB+', 'B+', 'CCC', 'C']),
    (['B3', 'B1', 'B2'], ['B1', 'B2', 'B3']),
    (['B-', 'B+', 'B'], ['B+', 'B', 'B-']),
    (['B3', 'Caa', 'Aa1', 'Caa', 'Ca', 'B3'],
     ['Aa1', 'B3', 'B3', 'Caa', 'Caa', 'Ca']),
    (['B-', 'CCC', 'AA+', 'CCC', 'CC', 'B-'],
     ['AA+', 'B-', 'B-', 'CCC', 'CCC', 'CC'])
]

mdy_sort = lambda x: Moody.index(x)
sp_sort = lambda x: SP.index(x)

for l_in, l_out in test_cases:
    sort_key = mdy_sort if set(l_in).issubset(set(Moody)) else sp_sort
    assert sorted(l_in, key=sort_key) == l_out

Przypadki testowe

W przypadku, gdy formatowanie przypadków testowych w stylu python jest niewygodne, wypisuję je jako ciągi znaków rozdzielane spacjami (pogrupowane w pary dwuwierszowe, a następnie dane wyjściowe):

Aa2 Aaa Aa1
Aaa Aa1 Aa2

AA AA- AA+
AA+ AA AA-

Baa1 Ba1 A1 B1 Aaa C Caa Aa1
Aaa Aa1 A1 Baa1 Ba1 B1 Caa C

BBB+ BB+ A+ B+ AAA C CCC AA+
AAA AA+ A+ BBB+ BB+ B+ CCC C

B3 B1 B2
B1 B2 B3

B- B+ B
B+ B B-

B3 Caa Aa1 Caa Ca B3
Aa1 B3 B3 Caa Caa Ca

B- CCC AA+ CCC CC B-
AA+ B- B- CCC CCC CC

Uwaga : Wspominam o „wielkiej trójce”, ale tutaj określam tylko Moody's i S&P - powodem jest to, że trzeci, Fitch, używa tego samego systemu co S&P, jeśli nie bierzesz pod uwagę ocen w stylu NA, więc włączenie Fitcha być zbędnym.

Paweł
źródło
3
Koleś, jeśli to twój pierwszy post, jestem pod wielkim wrażeniem. +1
Addison Crump
9
@VoteToClose Słuchacz od dawna, osoba dzwoniąca po raz pierwszy. ;)
Paweł
1
Czy w danych wyjściowych należy rozróżniać wielkość liter?
andlrc
@ dev-null Tak, dane wyjściowe powinny być tymi samymi wejściowymi ciągami, zmienionymi w kolejności.
Paul
1
Czy listy wejściowe mogą zawierać równe oceny? Jeśli tak, to czy wszystkie równe powinny być wyprowadzane, czy usuwane duplikaty?
Digital Trauma

Odpowiedzi:

1

Pyth, 16 bajtów

o+Xs}RGrN0N\z\,Q

Sortujemy leksykograficznie według klucza, stosując podejście @ Neila. Dane wejściowe i wyjściowe są jak listy; to nie powoduje mutacji listy.

o+Xs}RGrN0N\z\,Q       Implicit: Q = input list
                        lambda N  (N is a bond rating)
       rN0               Convert N to lowercase
    }RG                  Map is-in G, the lowercase alphabet.
   s                     Sum the list of bools; the number of letters in N.
  X       N\z            Insert "z" at that position in N.
 +           \,          Append "," to the end.
                         This works because "," is between "+" and "-" lexicographically.
o              Q       Sort Q, using that lambda as a key.

Wypróbuj tutaj . Przypadki testowe to wszystkie oceny obligacji dla każdego schematu ratingowego, z wprowadzonym duplikatem.

lirtosiast
źródło
7

ES6, 71 65 bajtów

a=>a.sort((b,c)=>r(b)>r(c)||-1,r=s=>s.replace(/[^A-z]*$/,"z$&,"))

Wstawiając zpo literach i sufiksie a, ,musimy po prostu posortować ciągi leksykalne.

Edycja: Zapisano 6 bajtów dzięki @ user81655.

Neil
źródło
Dobry pomysł. Może być również nieco krótszy, definiując osobną funkcję dla replacei używając $&w nim:a=>a.sort((b,c)=>(r=t=>t.replace(/[^A-z]*$/,"z$&,"))(b)>r(c)||-1)
user81655
@ user81655 Bah, pierwotnie miałem s="$1z$2,"i chociaż zdałem sobie sprawę, że mogę grać w golfa $1, nie przyszło mi do głowy, że teraz mogę też grać w golfa $2...
Neil
2

Narzędzia Bash + GNU, 45

Kredyt należny jest @Neil za podejście .

sed s/$/e/|tr +-3 d-l|sort|tr -d e|tr d-l +-3

W moim lokalnym porządku sortowania liczby są sortowane przed literami, a -sortowane przed +. Tak więc te znaki są transliterowane do zakresu alfabetu, aby sortować w odpowiedniej kolejności.

Wypróbuj online.

Cyfrowa trauma
źródło