Ordina i gradi di arrampicata


33

Il mio primo post di golf in codice, mi scuso per eventuali errori ...

Contesto

Nell'arrampicata su roccia (in particolare il boulder ), i gradi di arrampicata V / Vermin (USA) iniziano da 'VB' (il voto più semplice), quindi vanno 'V0', 'V0 +', 'V1', 'V2', 'V3' , 'V4', 'V5' ecc. Fino a 'V17' (il grado più difficile).

Compito

Prenderai come input un elenco / serie di gradi di arrampicata e dovrai tornare o stampare un elenco / matrice dei gradi ordinati dal più facile al più difficile.

Se l'input è vuoto, restituisce una struttura dati vuota; altrimenti l'input sarà sempre valido.

Casi test

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']

Questa è una sfida di .


La prossima volta, pubblicalo sulla sandbox per ricevere feedback prima di pubblicarlo. In secondo luogo, dovresti davvero rispondere alla tua sfida?
Ian H.

Verranno visualizzati voti duplicati nell'input?
Mr. Xcoder,

@ Mr.Xcoder Nessun duplicato
Chris_Rands

7
Benvenuti in PPCG! Abbastanza chiaro e carino per una prima domanda. (y)
officialaimm,

3
Molto bella la prima domanda! Le risposte che ha portato sono così diverse e creative. :)
Lynn,

Risposte:


23

Python 2 , 58 54 byte

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

Provalo online!

Come funziona

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

Sembra che il porting di questo su ES6 non superi l'approccio di Arnauld: a=>a.sort((a,b,B10=0)=>(g=s=>eval(s.slice(1)+10))(a)>g(b))è di 58 byte.
Lynn,

1
a=>a.sort((a,b)=>(g=s=>eval(s.slice(B10=1)+10))(a)-g(b))è più corto di 2 byte, ma è ancora troppo lungo.
Arnauld,

@GB Penso che fosse valido, ma ora è sicuramente valido.
Lynn,

Perché usare '10' e non qualcosa di più corto? Ad esempio '2' salva 2 byte.
GB

1
@IT Il trucco è innescare la traduzione dalla notazione ottale "010" a 8 come decimale per "V0". Con 2, otterrai "02" = 2, che equivale a "0 + 2".
Arnauld,

15

JavaScript (ES6) / Firefox, 53 byte

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

Casi test

Per Firefox:

Per Chrome o Edge (+4 byte):

Come?

Applichiamo 3 trasformazioni successive che portano a stringhe lessicograficamente comparabili.

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"

Ti è venuta l'idea di conversione / modulo di base? Brillante!
kamoroso94,

1
@ kamoroso94 FWIW, ecco il codice che ho scritto per trovare la base e il modulo. Fornisce alcune altre possibili risposte (con m <1000).
Arnauld,

Ho provato a=>a.sort((a,b)=>(g=s=>parseInt(s,32)%334+s)(a)>g(b))su Chrome, non dà la risposta corretta a f(["VB","V0","V0+","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17"])Non sono sicuro del perché; la versione compatibile con i bordi funziona bene su Chrome.
Ra8

1
@ Ra8 Ah, sì. Sembra essere instabile anche per Chrome. Restituire un valore booleano da una callback sort () è solo un trucco che sembra funzionare in Firefox, ma dovremmo davvero restituire un valore con segno. Grazie per il tuo feedback!
Arnauld,

12

Buccia , 5 byte

ÖiÖm±

Provalo online! I risultati vengono stampati uno per riga, ma internamente si tratta di una funzione che accetta e restituisce un elenco di stringhe.

Spiegazione

Questo è sorprendentemente simile alla risposta Retina di Martin . Per prima cosa Öm±, significa "ordina per mappatura is-digit". Questo mette VB, V0e V0+nell'ordine corretto, poiché sono confrontati come [0,0], [0,1]e [0,1,0]. Quindi lo facciamo Öi, intendendo "ordina per valore intero". Data una stringa, irestituisce la prima sequenza di cifre che si verificano in essa come numero intero o 0 se non viene trovata una. Le tre stringhe sopra sono tutte mappate su 0 e l'ordinamento è stabile, quindi saranno nell'ordine corretto nell'output.


11

Retina , 14 byte

B
!
O`
!
B
O#`

Provalo online!

Spiegazione

B
!

Sostituire Bcon in !modo che l'ordine lessicografico dei voti metta VB(o poi V!) davanti a tutti i voti numerici.

O`

Ordina lessicograficamente tutte le linee di input. Questo non dà il risultato giusto ma ordina V! < V0 < V0+correttamente.

!
B

Girare V!nuovamente dentro VB.

O#`

Ordina le linee numericamente. Retina cerca semplicemente il primo numero decimale in una stringa per determinare la sua chiave di ordinamento. Se non è presente alcun numero (come for VB), imposta il valore su 0. Ciò significa che tutti VB, V0e V0+hanno la stessa chiave di ordinamento. Ma il tipo di Retina è stabile e li abbiamo già messi nell'ordine relativo corretto.


6

V , 3 byte

Úún

Provalo online!

Come funziona?

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

Questo comando è quasi una soluzione valida, poiché ogni riga che non può essere ordinata per numero (AKA, VB) verrà posizionata all'inizio, senza che l'ordine sia cambiato. Tuttavia, poiché guarda solo i numeri, non è in grado di distinguere tra V0e V0+. Poiché Vim utilizza un ordinamento stabile, qualunque di questi sia venuto per primo rimarrà per primo dopo averlo selezionato. Così...

Ú   # Sort lexicographically (will place 'V0' before 'V0+')
 ú  # Sort by...
  n #   The first number on the line

2
È appropriato che V vada bene in questa sfida: P
Business Cat

5

C #, 121 83 82 83 byte

Risparmiato 39 byte grazie a TheLethalCoder e LiefdeWen

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

Provalo online!

Bytecount include using System.Linq.


Come?

  • Ottiene una matrice di stringhe come input.
  • Se l'ingresso è uguale a VB, imposta il valore su -1, se è uguale a VB0+, imposta il valore su 0.
  • Ordinare l'input in base al valore numerico che segue il V.

Potrebbe essere un po 'un trucco, ma funziona! :)



@LiefdeWen Non è necessario che ToArray()un IOrderedEnumerabledovrebbe andare bene.
TheLethalCoder

Siamo spiacenti accidentalmente rimosso riferimento System.Linq, risolto
LiefdeWen

@TheLethalCoder Hai ragione come sempre, 84 byte
LiefdeWen

@LiefdeWen .Remove(0,1)per ulteriori -1 byte :)
Ian H.

4

Rubino , 52 42 41 byte

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

Provalo online!

Come funziona:

Risolvi il problema, crea l'elenco completo, quindi ottieni l'intersezione con il nostro input.

Grazie Lynn per aver salvato 1 byte.


Intelligente! ->x{[?B,0,"0+",*1..17].map{|a|"V#{a}"}&x}salva un byte.
Lynn,



2

Gelatina , 9 byte

Ḋv-.F+LµÞ

Un collegamento monadico che prende un elenco di elenchi di caratteri e restituisce l'elenco ordinato.

Provalo online! (il piè di pagina formatta bene il risultato)

Come?

Ḋ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, ...


2

A dare il via alle cose qui è la mia soluzione Python 3 ... Mi scuso, pubblicato troppo presto contro la convenzione, ora ripubblicando ...

Python 3 , 69 67 byte

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

Provalo online!


5
È scoraggiato rispondere immediatamente alla propria sfida. Dare un po 'di tempo affinché altre persone rispondano, almeno 48 ore, probabilmente più a lungo.
TheLethalCoder il

@TheLethalCoder Oh giusto, su Stack Overflow tale comportamento è incoraggiato! Devo cancellare la mia risposta?
Chris_Rands

@Chris_Rands Sì, ti consiglio di eliminarlo.
Mr. Xcoder,

9
@Downvoter: downvoting di un nuovo membro per aver fatto qualcosa che non sapeva era malvisto non è bello; molto meglio sottolineare semplicemente che non dovrebbero, come ha fatto Lethal.
Shaggy

Nota però se qualcuno non pubblica la tua soluzione, sei invitato a farlo. Dopo aver ovviamente
aspettato

1

Swift 3 , 102 byte

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

Questa è una funzione Puoi chiamarlo come tale:

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

Provalo online!


Come funziona?

Questa è fondamentalmente una porta della straordinaria risposta Javascript di @Arnauld , ma ottimizzata per Swift.

Associa ciascuno dei valori alle stringhe lessicograficamente ordinabili, come mostrato nella tabella seguente:

Stringa iniziale -> Risultato

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

Spiegazione del codice

  • String((Int($0,radix:32) ?? 992)%334)- Converte ogni stringa da un numero di base 32 a decimale. Nel caso in cui il valore sia "V0 +", la chiamata a Int(_:radix:)restituirà zero e prendiamo il valore di "V0", 992. Inoltre prendiamo il risultato mod 334e infine lo convertiamo in String.

  • +$0- Aggiunge il valore corrente alla stringa creata sopra. Ad esempio, se la stringa è V9, la funzione sopra ritorna 333e noi aggiungiamo V9, risultando 333V9.

  • var r={...}- Dichiara una variabile ra una chiusura anonima, poiché consente di risparmiare molti byte poiché viene utilizzata due volte.

  • func f(l:[String])- Definisce una funzione fcon un parametro l, un elenco di stringhe.

  • print(l.sorted(by:{r($0)<r($1)}))- Stampa il risultato dell'ordinamento dell'elenco specificato, con la chiave come variabile rsopra definita.



1

Fogli Google, 142 byte

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

L'input è una stringa A1con ogni voce separata da una virgola.
L'output è la cella della formula più le n-1celle sottostanti dove nè il numero di voci in A1.

Risultato

È una formula lunga e disordinata, quindi scompattiamola.

  • If(A1="","",~)corregge l'input null. Senza questo, un input vuoto restituisce un #VALUE!errore perché la Splitfunzione non funziona su input vuoti.
  • Transpose(Split(A1,","))si divide A1in virgole e lo traspone in una colonna perché la Sortfunzione funziona solo su colonne.
  • Transpose(IfError(Find(),Value()+9)) si rompe in questi pezzi:
    • Find(Split(A1,","),"VBV0V0+")prova a trovare ogni parametro in quella stringa. Questi primi tre sono gli unici che devono essere ordinati come stringhe, quindi usiamo Findper ottenere il loro ordinamento.
    • Value(Mid(Split(A1,","),2,3))+9ottiene il valore numerico del voto. Questo è importante solo per V1 e superiori, quindi si ordinano numericamente bene. Alla +9fine è assicurarsi che V1 venga dopo V0 + poiché il suo Findvalore sarebbe 5. Tecnicamente, quindi, +5è richiesto solo ma non mi costa più byte per assicurarmi che sia ordinato correttamente.
    • IfError(Find(~),Value(~))restituisce il Findvalore se la stringa è stata trovata (ovvero, il grado è VB, V0 o V0 +). Se non può essere trovato, restituisce il valore numerico del voto più nove.
    • Transpose(IfError(~))lo trasforma di nuovo in una colonna in modo da Sortpoterlo usare.
  • Sort(Transpose(Split(~)),Transpose(IfError(Find(~),Value(~)+9)),1) termina tutto ordinando l'input diviso usando l'ordinamento personalizzato crescente.
  • ArrayFormula(~)racchiude tutto in modo che restituisca i risultati come un array invece di restituire il primo valore in tale array. Questo è ciò che fa sì che la formula in una cella riempia anche le celle sottostanti.

Penso che questa sia la prima volta che vedo utilizzare Fogli Google. Complimenti a te, e +1!
heather,


1

Haskell , 90 84 83 61 byte

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

Provalo online!

fè una funzione che converte i gradi di arrampicata in corde che possono essere confrontati. Se converte VBin una stringa vuota in modo che ottenga la priorità più alta, sostituisce V1con Xstringhe lunghe tre per ridurre la priorità di V10- V17. Per il resto non facciamo nulla.

Per ordinare l'elenco usiamo Data.Listsla sortOnfunzione (come suggerito da Lynn) per creare una funzione senza punti.


Questo è giusto g=sortOn f, che è anche dentroData.List .
Lynn,

1
Inoltre, f(_:'1':a)='X':asalva 4 byte!
Lynn,

1
@Lynn Il primo suggerimento funziona, anche se il secondo no, in caso [a]contrario avrò bisogno di V1un pattern match che è il problema che sto cercando di eludere.
Wheat Wizard

1

R , 45 byte

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

Come funziona?

  • Assegna il vettore dei voti correttamente ordinato a 'l';
    • Usa 'paste0' invece di 'paste' per evitare di creare un argomento 'sep = ""';
  • Indicizza 'l' in base alle corrispondenze di 'l' nel tuo vettore di input di voti misti e non ordinati.

0

Python2, 77 byte

sorted(input(),key=lambda s:float(s[1:].replace("B","-1").replace("+",".5")))

Penso che questo valga come un frammento! Perché non si sta stampando il risultato né questa è una definizione di funzione. Puoi trasformarlo in una lambda o stampare il risultato però.
officialaimm,

1
@officialaimm bel tentativo ma non funziona se V0 + s prima di V0.
Setop


0

TXR Lisp : 45 byte

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

Correre:

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")

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.