Sortuj stopnie wspinaczkowe

33

Mój pierwszy kod do golfa, przepraszam za błędy ...

Kontekst

W wspinaczce skalnej ( konkretnie bouldering ) oceny wspinaczki V / Vermin (USA) zaczynają się od „VB” (najłatwiejszy stopień), a następnie „V0”, „V0 +”, „V1”, „V2”, „V3” , „V4”, „V5” itp. Aż do „V17” (najtrudniejsza klasa).

Zadanie

Jako dane wejściowe weźmiesz listę / tablicę ocen wspinania i musisz zwrócić lub wydrukować listę / tablicę ocen posortowanych od najłatwiejszych do najtrudniejszych.

Jeśli dane wejściowe są puste, zwróć pustą strukturę danych; w przeciwnym razie dane wejściowe zawsze będą prawidłowe.

Przypadki testowe

Input | Output
[] |  []
['V1'] |  ['V1']
['V7', 'V12', 'V1'] | ['V1', 'V7', 'V12']
['V13', 'V14', 'VB', 'V0'] |  ['VB', 'V0', 'V13', 'V14']
['V0+', 'V0', 'V16', 'V2', 'VB', 'V6'] | ['VB', 'V0', 'V0+', 'V2', 'V6', 'V16']

To wyzwanie dla .

Chris_Rands
źródło
Następnym razem opublikuj to w piaskownicy, aby uzyskać opinię przed opublikowaniem. Po drugie, czy naprawdę powinieneś odpowiedzieć na swoje wyzwanie?
Ian H.
Czy w danych wejściowych pojawią się zduplikowane oceny?
Mr. Xcoder,
@ Mr.Xcoder Brak duplikatów
Chris_Rands
7
Witamy w PPCG! Całkiem jasne i miłe na pierwsze pytanie. (y)
officialaimm
3
Bardzo miłe pierwsze pytanie! Odpowiedzi, do których doprowadziły, są tak różnorodne i kreatywne. :)
Lynn,

Odpowiedzi:

23

Python 2 , 58 54 bajtów

lambda x:sorted(x,key=lambda y,B10=0:eval(y[1:]+'10'))

Wypróbuj online!

Jak to działa

y         y[1:]+'10'   eval(y[1:]+'10')
=======================================
VB        B10          0  (a variable we defined)
V0        010          8  (an octal literal)
V0+       0+10         10
V1        110          110
V2        210          210
...       ...          ...
V17       1710         1710
Lynn
źródło
Wygląda na to, że przeniesienie tego do ES6 nie jest zgodne z podejściem Arnaulda: a=>a.sort((a,b,B10=0)=>(g=s=>eval(s.slice(1)+10))(a)>g(b))ma 58 bajtów.
Lynn,
1
a=>a.sort((a,b)=>(g=s=>eval(s.slice(B10=1)+10))(a)-g(b))jest o 2 bajty krótszy, ale to wciąż za długo.
Arnauld
@GB Myślę, że to było ważne, ale teraz jest zdecydowanie ważne.
Lynn,
Po co używać „10”, a nie czegoś krótszego? Na przykład „2” oszczędza 2 bajty.
GB
1
@ GB Sztuczka polega na tym, aby uruchomić tłumaczenie z notacji ósemkowej „010” na 8 jako dziesiętne dla „V0”. Przy 2 otrzymasz „02” = 2, czyli tyle samo, co „0 + 2”.
Arnauld
15

JavaScript (ES6) / Firefox, 53 bajty

a=>a.sort((a,b)=>(g=s=>parseInt(s,32)%334+s)(a)>g(b))

Przypadki testowe

W przeglądarce Firefox:

W przypadku Chrome lub Edge (+4 bajty):

W jaki sposób?

Stosujemy 3 kolejne transformacje, które prowadzą do leksykograficznie porównywalnych ciągów.

s     | Base32 -> dec. | MOD 334 | +s
------+----------------+---------+---------
"VB"  |           1003 |       1 | "1VB"
"V0"  |            992 |     324 | "324V0"
"V0+" |            992 |     324 | "324V0+"
"V1"  |            993 |     325 | "325V1"
"V2"  |            994 |     326 | "326V2"
"V3"  |            995 |     327 | "327V3"
"V4"  |            996 |     328 | "328V4"
"V5"  |            997 |     329 | "329V5"
"V6"  |            998 |     330 | "330V6"
"V7"  |            999 |     331 | "331V7"
"V8"  |           1000 |     332 | "332V8"
"V9"  |           1001 |     333 | "333V9"
"V10" |          31776 |      46 | "46V10"
"V11" |          31777 |      47 | "47V11"
"V12" |          31778 |      48 | "48V12"
"V13" |          31779 |      49 | "49V13"
"V14" |          31780 |      50 | "50V14"
"V15" |          31781 |      51 | "51V15"
"V16" |          31782 |      52 | "52V16"
"V17" |          31783 |      53 | "53V17"
Arnauld
źródło
Czy wpadłeś na pomysł konwersji bazowej / modulo? Znakomity!
kamoroso94,
1
@ kamoroso94 FWIW, oto kod, który napisałem, aby znaleźć bazę i moduł. Daje kilka innych możliwych odpowiedzi (przy m <1000).
Arnauld
Próbowałem a=>a.sort((a,b)=>(g=s=>parseInt(s,32)%334+s)(a)>g(b))na Chrome, to nie daje poprawnej odpowiedzi. f(["VB","V0","V0+","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17"])Nie jestem pewien, dlaczego; wersja kompatybilna z Edge działa dobrze na Chrome.
Ra8
1
@ Ra8 Ah, tak. Wydaje się również niestabilny w przypadku Chrome. Zwracanie wartości logicznej z wywołania zwrotnego sort () to tylko hack, który działa w przeglądarce Firefox, ale naprawdę powinniśmy zwrócić podpisaną wartość. Dziekuję za odpowiedź!
Arnauld
12

Łuska , 5 bajtów

ÖiÖm±

Wypróbuj online! Wyniki są drukowane po jednym w wierszu, ale wewnętrznie jest to funkcja, która pobiera i zwraca listę ciągów.

Wyjaśnienie

Jest to zaskakująco podobne do odpowiedzi Retina Martina . Najpierw to robimy Öm±, co oznacza „porządek przez odwzorowanie jest cyfrą”. Stawia to VB, V0i V0+we właściwej kolejności, ponieważ są one porównywane jak [0,0], [0,1]i [0,1,0]. Następnie robimy Öi, co oznacza „uporządkuj według wartości całkowitej”. Podany ciąg izwraca pierwszą sekwencję występujących w nim cyfr jako liczbę całkowitą lub 0, jeśli nie zostanie znaleziona. Wszystkie trzy ciągi powyżej są odwzorowane na 0, a sortowanie jest stabilne, więc będą w prawidłowej kolejności na wyjściu.

Zgarb
źródło
11

Siatkówka , 14 bajtów

B
!
O`
!
B
O#`

Wypróbuj online!

Wyjaśnienie

B
!

Wymień Bsię !więc, że kolejność ocen leksykograficzny put VB(lub potem V!) w obecności wszystkich klas numerycznych.

O`

Posortuj wszystkie wiersze wejściowe leksykograficznie. To nie daje właściwego wyniku, ale porządkuje V! < V0 < V0+poprawnie.

!
B

Zamień się z V!powrotem w VB.

O#`

Sortuj linie numerycznie. Siatkówka po prostu szuka pierwszej liczby dziesiętnej w ciągu, aby określić jej klucz sortowania. Jeśli nie ma liczby (np. For VB), ustawia wartość na 0. Oznacza to, że wszyscy VB, V0i V0+mieć ten sam klucz sortowania. Ale rodzaj Retiny jest stabilny i już umieściliśmy je we właściwej kolejności względnej.

Martin Ender
źródło
6

V , 3 bajty

Úún

Wypróbuj online!

Jak to działa?

ú   # Sort on...
 n  #   the first decimal number on the line

To polecenie jest prawie prawidłowym rozwiązaniem, ponieważ każdy wiersz, którego nie można posortować według liczb (AKA, VB), zostanie umieszczony na początku, bez zmiany kolejności. Ponieważ jednak patrzy tylko na liczby, nie można rozróżnić między V0i V0+. Ponieważ Vim używa stabilnego sortowania, cokolwiek z tych, które pojawiły się pierwsze, pozostanie pierwsze po posortowaniu. Więc...

Ú   # Sort lexicographically (will place 'V0' before 'V0+')
 ú  # Sort by...
  n #   The first number on the line
DJMcMayhem
źródło
2
Jak dobrze V radzi sobie dobrze z tym wyzwaniem: P
Business Cat
5

C #, 121 83 82 83 bajty

Zaoszczędź 39 bajtów dzięki TheLethalCoder i LiefdeWen

a=>a.OrderBy(x=>x[1]>65?-1:x=="V0+"?0.5:int.Parse(x.Remove(0,1)))

Wypróbuj online!

Liczba bajtów obejmuje using System.Linq.


W jaki sposób?

  • Pobiera tablicę ciągów jako dane wejściowe.
  • Jeśli wartość wejściowa jest równa VB, ustaw wartość na -1, jeśli jest równa VB0+, ustaw wartość na 0.
  • Porządkuj dane wejściowe na podstawie wartości liczbowej następującej po V.

Może to być trochę hack, ale działa! :)

Ian H.
źródło
94 bajty
LiefdeWen
@LiefdeWen Nie potrzebujesz ToArray(), IOrderedEnumerablepowinno być dobrze.
TheLethalCoder
Niestety, przypadkowo usunięto odniesienie do System.Linq, naprawiono
LiefdeWen
@TheLethalCoder Masz rację, jak zawsze, 84 bajtów
LiefdeWen
@LiefdeWen .Remove(0,1)za dodatkowe -1 bajt :)
Ian H.
4

Rubin , 52 42 41 bajtów

->x{[?B,0,"0+",*1..17].map{|a|"V#{a}"}&x}

Wypróbuj online!

Jak to działa:

Odwróć problem, utwórz pełną posortowaną listę, a następnie uzyskaj skrzyżowanie z naszymi danymi wejściowymi.

Dzięki Lynn za uratowanie 1 bajtu.

GB
źródło
Sprytny! ->x{[?B,0,"0+",*1..17].map{|a|"V#{a}"}&x}zapisuje bajt.
Lynn,
2

05AB1E , 17 13 8 bajtów

Σþï}„VB†

Wypróbuj online!

Erik the Outgolfer
źródło
Ha ... jest lepszy niż D"VB"åiÁstrzelanie z dystansu.
Magic Octopus Urn
2

Galaretka , 9 bajtów

Ḋv-.F+LµÞ

Monadyczny link prowadzący do listy list znaków i zwracający posortowaną listę.

Wypróbuj online! (stopka ładnie formatuje wynik)

W jaki sposób?

Ḋv-.F+LµÞ - Link: list of lists of characters
       µÞ - sort by key:
Ḋ         -   dequeue (remove the 'V' from the item)
  -.      -   literal -0.5
 v        -   evaluate as Jelly code with argument -0.5
          -   ...this means `VB` and `V0+` become -0.5
          -      (to binary and addition respectively)
          -      while others become their literal numbers
    F     -   flatten
     +L   -   add the length of the item
          -   ...'VB', 'V0', 'V0+', 'V1', 'V2'... -> 1.5, 2, 2.5, 3, 4, ...
Jonathan Allan
źródło
2

Na początek jest moje rozwiązanie Python 3 ... Przepraszam, opublikowałem to zbyt wcześnie wbrew konwencji, teraz ponownie publikuję ...

Python 3 , 69 67 bajtów

lambda l:sorted(l,key=lambda x:'B00+'.find(x[1:])+1or int(x[1:])+3)

Wypróbuj online!

Chris_Rands
źródło
5
Odradza się natychmiastową odpowiedź na własne wyzwanie. Daj trochę czasu innym osobom na odpowiedź, co najmniej 48 godzin, prawdopodobnie dłużej.
TheLethalCoder
@TheLethalCoder No tak, w przypadku przepełnienia stosu takie zachowanie jest zalecane! Czy powinienem usunąć swoją odpowiedź?
Chris_Rands,
@Chris_Rands Tak, sugeruję, aby go usunąć.
Mr. Xcoder,
9
@Downvoter: Oddawanie głosu nowemu członkowi za zrobienie czegoś, o czym nie wiedzieli, nie było fajne; o wiele lepiej po prostu zaznaczyć, że nie powinni, tak jak to zrobił Lethal.
Shaggy
Pamiętaj jednak, że jeśli ktoś nie opublikuje Twojego rozwiązania, możesz to zrobić. Po czekaniu oczywiście
TheLethalCoder
1

Swift 3 , 102 bajty

var r={String((Int($0,radix:32) ?? 992)%334)+$0};func f(l:[String]){print(l.sorted(by:{r($0)<r($1)}))}

To jest funkcja. Możesz to tak nazwać:

f(l:["V0","VB","V13","V0+"])

Wypróbuj online!


Jak to działa?

Jest to w zasadzie część niesamowitej odpowiedzi JavaScript na @ Arnauld , ale zoptymalizowanej dla Swift.

Odwzorowuje każdą z wartości na uporządkowane leksykograficznie ciągi, jak pokazano w poniższej tabeli:

Początkowy ciąg -> Wynik

V1 -> 325 V1
V10 -> 46 V10
V11 -> 47 V11
V12 -> 48 V12
V13 -> 49 V13
V14 -> 50 V14
V15 -> 51V15
V16 -> 52V16
V17 -> 53V17
V2 -> 326 V2
V3 -> 327 V3
V4 -> 328 V4
V5 -> 329 V5
V6 -> 330V6
V7 -> 331 V7
V8 -> 332 V8
V9 -> 333 V9
V0 + -> 324 V0 +
V0 -> 324 V0
VB -> 1 VB

Objaśnienie kodu

  • String((Int($0,radix:32) ?? 992)%334)- Konwertuje każdy ciąg z liczby podstawowej-32 na liczbę dziesiętną. W przypadku, gdy wartość wynosi „V0 +”, wywołanie do Int(_:radix:)zwróci zero, i przyjmujemy wartość „V0”, 992. Dodatkowo bierzemy wynik mod 334i ostatecznie przekształcamy go na String.

  • +$0- Dodaje bieżącą wartość do Ciągu utworzonego powyżej. Na przykład, jeśli String jest V9, funkcja powyżej zwraca 333i dodajemy V9, w wyniku czego 333V9.

  • var r={...}- Deklaruje zmienną rdo anonimowego zamknięcia, ponieważ oszczędza wiele bajtów, ponieważ jest używana dwukrotnie.

  • func f(l:[String])- Definiuje funkcję fz parametrem l, listę ciągów.

  • print(l.sorted(by:{r($0)<r($1)}))- Drukuje wynik sortowania podanej listy, przy czym klucz jest zmienną rzdefiniowaną powyżej.

Pan Xcoder
źródło
1

PowerShell , 45 bajtów

param($a)'B',0,'0+'+1..17|%{"V$_"}|?{$_-in$a}

Wypróbuj online!

Używa tego samego procesu co odpowiedź Ruby GB w celu utworzenia pełnej listy argumentów w posortowanej kolejności, a następnie wybierz te, które są -inlistą wejściową.

AdmBorkBork
źródło
1

Arkusze Google, 142 bajty

=ArrayFormula(If(A1="","",Sort(Transpose(Split(A1,",")),Transpose(IfError(Find(Split(A1,","),"VBV0V0+"),Value(Mid(Split(A1,","),2,3))+9)),1)))

Dane wejściowe to ciąg znaków A1z każdą pozycją oddzieloną przecinkiem.
Dane wyjściowe to komórka formuły oraz n-1komórki pod nią, w których nznajduje się liczba wpisów A1.

Wynik

To długa, niechlujna formuła, więc rozpakujmy ją.

  • If(A1="","",~)naprawia wejście zerowe. Bez tego puste wejście zwraca #VALUE!błąd, ponieważ Splitfunkcja nie działa na pustych danych wejściowych.
  • Transpose(Split(A1,","))dzieli A1przecinki i przenosi je do kolumny, ponieważ Sortfunkcja działa tylko na kolumnach.
  • Transpose(IfError(Find(),Value()+9)) rozpada się na następujące części:
    • Find(Split(A1,","),"VBV0V0+")próbuje znaleźć każdy parametr w tym ciągu. Te trzy pierwsze są jedynymi, które muszą być sortowane jako ciągi, więc używamy Findich do sortowania.
    • Value(Mid(Split(A1,","),2,3))+9pobiera wartość liczbową oceny. Ma to znaczenie tylko dla wersji V1 i wyższych, więc sortowanie liczbowe jest w porządku. Na +9końcu jest upewnienie się, że V1 występuje po V0 +, ponieważ jego Findwartość to 5. Technicznie więc tylko +5wymagane jest, ale nie kosztuje mnie więcej bajtów, aby upewnić się podwójnie, że sortuje poprawnie.
    • IfError(Find(~),Value(~))zwraca Findwartość, jeśli łańcuch został znaleziony (tj. ocena to VB, V0 lub V0 +). Jeśli nie można go znaleźć, zwraca wartość liczbową oceny plus dziewięć.
    • Transpose(IfError(~))ponownie zamienia go w kolumnę, aby Sortmóc go użyć.
  • Sort(Transpose(Split(~)),Transpose(IfError(Find(~),Value(~)+9)),1) podsumowuje wszystko, sortując podzielone dane wejściowe przy użyciu niestandardowej kolejności sortowania rosnąco.
  • ArrayFormula(~)opakowuje całość, więc zwraca wyniki jako tablicę zamiast tylko zwracać pierwszą wartość w tej tablicy. To powoduje, że formuła w jednej komórce wypełnia również komórki poniżej.
Inżynier Toast
źródło
Wydaje mi się, że po raz pierwszy korzystam z Arkuszy Google. Uznanie dla ciebie i +1!
wrzos
1

Haskell , 90 84 83 61 bajtów

import Data.List
f"VB"=[]
f(_:'1':[a])='X':[a]
f x=x
sortOn f

Wypróbuj online!

fto funkcja konwertująca stopnie wspinaczkowe na struny, które można porównywać. Jeśli konwertuje VBna pusty ciąg, aby uzyskać najwyższy priorytet, zastępuje V1go Xciągami o długości trzech, aby obniżyć priorytet V10- V17. Przez resztę nic nie robimy.

Aby posortować listę używamy Data.Lists„s sortOnfunkcję (jako sugerowane przez Lynn), aby utworzyć funkcję point-free.

Kreator pszenicy
źródło
To po prostu g=sortOn fjest Data.List.
Lynn,
1
Ponadto f(_:'1':a)='X':aoszczędza 4 bajty!
Lynn,
1
@ Lynn Pierwsza sugestia działa, jednak druga nie, potrzebuję [a]inaczej V1dopasowanego wzoru, który jest problemem, który próbuję obejść.
Wheat Wizard
1

R , 45 bajtów

l=paste0('V',c('B','0','0+',1:17));l[l%in%x]

Jak to działa?

  • Przypisz poprawnie uporządkowany wektor ocen do „l”;
    • Użyj „paste0” zamiast „paste”, aby uniknąć tworzenia argumentu „sep =" ”;
  • Indeksuj „l” na podstawie dopasowań „l” w wektorze wejściowym mieszanych, nieposortowanych ocen.
Mendizale
źródło
0

Python2, 77 bajtów

sorted(input(),key=lambda s:float(s[1:].replace("B","-1").replace("+",".5")))
Setop
źródło
Myślę, że liczy się to jako fragment! Ponieważ nie drukujesz wyniku ani nie jest to definicja funkcji. Możesz zrobić z niego lambda lub wydrukować wynik.
officialaimm
1
@officialaimm fajna próba, ale nie działa, jeśli V0 + s przed V0.
Setop
0

TXR Lisp : 45 bajtów

(op sort @1 :(ret`@(mod(toint @1 32)334)@1`))

Biegać:

1> (op sort @1 :(ret`@(mod(toint @1 32)334)@1`))
#<interpreted fun: lambda (#:arg-01-0168 . #:rest-0167)>
2> [*1 ()]
nil
3> [*1 (list "V0+" "V0" "V16" "V2" "VB" "V6")]
("VB" "V0" "V0+" "V2" "V6" "V16")
Kaz
źródło
0

Perl 5 , 56 + 1 (-a) = 57 bajtów

map{$i=$_;s/V//;$a[/B/?0:/^0/?length:$_+2]=$i}@F;say"@a"

Wypróbuj online!

Xcali
źródło