Triez les notes d'escalade


33

Mon premier post code golf, toutes mes excuses pour toute erreur ...

Le contexte

En escalade ( particulièrement en bloc ), les notes d’escalade V / Vermin (USA) commencent à «VB» (la note la plus facile), puis «V0», «V0 +», «V1», «V2», «V3» , 'V4', 'V5' etc. jusqu'à 'V17' (la classe la plus difficile).

Tâche

Vous prendrez en entrée une liste / un tableau de notes en montée et vous devrez retourner ou imprimer une liste / un tableau des notes triées du plus facile au plus difficile.

Si l'entrée est vide, retourne une structure de données vide. sinon, l'entrée sera toujours valide.

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

Ceci est un défi de .


La prochaine fois, postez ceci sur le bac à sable pour obtenir des commentaires avant de le poster. Deuxièmement, devriez-vous vraiment répondre à votre propre défi?
Ian H.

Les notes en double apparaissent-elles dans l'entrée?
M. Xcoder

@ Mr.Xcoder Pas de doublons
Chris_Rands

7
Bienvenue chez PPCG! Assez clair et agréable pour une première question. (y)
officialaimm

3
Très belle première question! Les réponses auxquelles il a abouti sont tellement variées et créatives. :)
Lynn

Réponses:


23

Python 2 , 58 54 octets

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

Essayez-le en ligne!

Comment ça marche

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

On dirait que le portage sur ES6 ne bat pas l'approche d'Arnauld: a=>a.sort((a,b,B10=0)=>(g=s=>eval(s.slice(1)+10))(a)>g(b))58 octets.
Lynn

1
a=>a.sort((a,b)=>(g=s=>eval(s.slice(B10=1)+10))(a)-g(b))est 2 octets plus court, mais c'est encore trop long.
Arnauld

@GB Je pense que c'était valide, mais maintenant c'est définitivement valide.
Lynn

Pourquoi utiliser '10' et pas quelque chose de plus court? Par exemple, "2" enregistre 2 octets.
GB

1
@GB L'astuce consiste à déclencher la traduction de la notation octale "010" en 8 sous forme décimale pour "V0". Avec 2, vous obtiendrez "02" = 2, ce qui correspond à "0 + 2".
Arnauld

15

JavaScript (ES6) / Firefox, 53 octets

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

Cas de test

Pour Firefox:

Pour Chrome ou Edge (+4 octets):

Comment?

Nous appliquons 3 transformations successives qui conduisent à des chaînes comparables lexicographiquement.

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"

Avez-vous eu l'idée de base conversion / modulo? Brillant!
kamoroso94

1
@ kamoroso94 FWIW, voici le code que j'ai écrit pour trouver la base et le modulo. Cela donne d'autres réponses possibles (avec m <1000).
Arnauld

J'ai essayé a=>a.sort((a,b)=>(g=s=>parseInt(s,32)%334+s)(a)>g(b))sur Chrome, il ne donne pas la réponse correcte à f(["VB","V0","V0+","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17"])je ne sais pas pourquoi; la version compatible avec les bords fonctionne bien sur le chrome.
Ra8

1
@ Ra8 Ah, oui. Cela semble également instable pour Chrome. Renvoyer un booléen à partir d'un rappel sort () n'est qu'un hack qui fonctionne dans Firefox, mais nous sommes censés renvoyer une valeur signée. Merci pour vos commentaires!
Arnauld

12

Husk , 5 octets

ÖiÖm±

Essayez-le en ligne! Les résultats sont imprimés un par ligne, mais en interne, il s’agit d’une fonction qui prend et retourne une liste de chaînes.

Explication

Ceci est étonnamment similaire à la réponse de Martin à la rétine . Nous commençons par le faire Öm±, ce qui signifie "ordre par mappage est numérique" Cela met VB, V0et V0+dans le bon ordre, car ils sont comparés comme [0,0], [0,1]et [0,1,0]. Ensuite nous le faisons Öi, ce qui signifie "ordre par valeur entière". Étant donné une chaîne, irenvoie la première séquence de chiffres apparaissant dans celle-ci sous la forme d'un entier ou de 0 si aucun n'est trouvé. Les trois chaînes ci-dessus sont toutes mappées sur 0 et le tri est stable. Elles seront donc dans le bon ordre dans la sortie.


11

Rétine , 14 octets

B
!
O`
!
B
O#`

Essayez-le en ligne!

Explication

B
!

Remplacez Bpar !afin que l'ordre lexicographique des notes soit placé VB(ou alors V!) devant toutes les notes numériques.

O`

Triez toutes les lignes d'entrée lexicographiquement. Cela ne donne pas le bon résultat mais ordonne V! < V0 < V0+correctement.

!
B

Retourner V!dans VB.

O#`

Triez les lignes numériquement. Retina cherche simplement le premier nombre décimal d'une chaîne pour déterminer sa clé de tri. S'il n'y a pas de nombre (comme pour VB), la valeur est définie sur 0. Cela signifie tous VB,V0 et V0+ont la même clé de tri. Mais la sorte de Retina est stable et nous les avons déjà placées dans le bon ordre relatif.


6

V , 3 octets

Úún

Essayez-le en ligne!

Comment ça marche?

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

Cette commande est presque une solution valide, car chaque ligne qui ne peut pas être triée par numéros (AKA, VB) sera placée au début, sans que l'ordre ne soit modifié. Cependant, comme il ne s'agit que de chiffres, il ne peut pas distinguer entre V0et V0+. Puisque Vim utilise une sorte stable, celle qui est arrivée en premier restera la première après le tri. Alors...

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

2
Quelle pertinence pour V de relever ce défi: P
Business Cat

5

C #, 121 83 82 83 octets

Sauvegardé 39 octets grâce à TheLethalCoder et LiefdeWen

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

Essayez-le en ligne!

Le décompte comprend using System.Linq.


Comment?

  • Obtient un tableau de chaînes en entrée.
  • Si l'entrée est égale à VB, définissez la valeur sur -1, si elle est égale à VB0+, définissez la valeur sur 0.
  • Commandez les entrées en fonction du nombre qui vient après le V.

Peut-être un peu un bidouillage, mais ça marche! :)



@LiefdeWen Vous n'avez pas besoin d' ToArray()un, ça IOrderedEnumerabledevrait aller.
TheLethalCoder

Désolé accidentellement supprimé référence System.Linq, corrigé
LiefdeWen

@TheLethalCoder Vous avez raison, comme toujours, 84 octets
LiefdeWen

@LiefdeWen .Remove(0,1)pour -1 octet supplémentaire :)
Ian H.

4

Ruby , 52 42 41 octets

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

Essayez-le en ligne!

Comment ça marche:

Tournez le problème, créez la liste complète triée, puis obtenez l'intersection avec notre entrée.

Merci Lynn d'avoir sauvegardé 1 octet.


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



2

Gelée , 9 octets

Ḋv-.F+LµÞ

Un lien monadique prenant une liste de listes de caractères et renvoyant la liste triée.

Essayez-le en ligne! (le pied de page formate bien le résultat)

Comment?

Ḋ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

Pour commencer, voici ma solution Python 3 ... Apologies, posté trop tôt contre la convention, maintenant en train de republier ...

Python 3 , 69 67 octets

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

Essayez-le en ligne!


5
Il est déconseillé de répondre immédiatement à votre propre défi. Laissez à d’autres personnes le temps de répondre, au moins 48 heures, probablement plus longtemps.
TheLethalCoder

@TheLethalCoder Oh oui, sur Stack Overflow, un tel comportement est encouragé! Dois-je supprimer ma réponse?
Chris_Rands

@Chris_Rands Oui, je vous suggère de le supprimer.
M. Xcoder

9
@Downvoter: Voter un nouveau membre pour avoir fait quelque chose qu'il ne savait pas était mal vu, ce n'est pas cool; beaucoup mieux de simplement souligner qu'ils ne devraient pas, comme Lethal a fait.
Shaggy

Notez que si quelqu'un ne publie pas votre solution, vous pouvez le faire. Après avoir attendu bien sûr
TheLethalCoder

1

Swift 3 , 102 octets

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

Ceci est une fonction. Vous pouvez l'appeler comme tel:

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

Essayez-le en ligne!


Comment cela marche-t-il?

Ceci est fondamentalement un port de la réponse Javascript incroyable par @Arnauld , mais optimisé pour Swift.

Il mappe chacune des valeurs sur des chaînes ordonnées lexicographiquement, comme indiqué dans le tableau ci-dessous:

Chaîne initiale -> Résultat

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

Explication du code

  • String((Int($0,radix:32) ?? 992)%334)- Convertit chaque chaîne d'un nombre base 32 en nombre décimal. Dans le cas où la valeur est "V0 +", l'appel à Int(_:radix:)retournera nil et nous prenons la valeur de "V0", 992. Nous prenons également le résultat de mod 334et finalement le convertissons en String.

  • +$0- Ajoute la valeur actuelle à la chaîne créée ci-dessus. Par exemple, si la chaîne est V9, la fonction ci-dessus retourne 333et nous ajoutons V9, résultant 333V9.

  • var r={...}- Déclare une variable rà une fermeture anonyme, car cela économise beaucoup d'octets puisqu'il est utilisé deux fois.

  • func f(l:[String])- Définit une fonction favec un paramètre l, une liste de chaînes.

  • print(l.sorted(by:{r($0)<r($1)}))- Imprime le résultat du tri de la liste donnée, la clé étant la variable rdéfinie ci-dessus.



1

Google Sheets, 142 octets

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

L'entrée est une chaîne A1avec chaque entrée séparée par une virgule.
La sortie est la cellule de la formule plus les n-1cellules en dessous, où nest le nombre d'entrées A1.

Résultat

C'est une longue formule en désordre, alors décompresons-la.

  • If(A1="","",~)corrige l'entrée nulle. Sans cela, une entrée vide renvoie un#VALUE! erreur car la Splitfonction ne fonctionne pas sur des entrées vides.
  • Transpose(Split(A1,","))se sépare A1à la virgule et le transpose dans une colonne car leSort fonction ne fonctionne que sur des colonnes.
  • Transpose(IfError(Find(),Value()+9)) est brise en ces morceaux:
    • Find(Split(A1,","),"VBV0V0+")essaie de trouver chaque paramètre dans cette chaîne. Ces trois premiers sont les seuls qui doivent être triés comme des chaînes de caractères afin que nous utilisionsFind pour obtenir leur ordre de tri.
    • Value(Mid(Split(A1,","),2,3))+9obtient la valeur numérique de la note. Cela ne concerne que la V1 et les versions ultérieures, ce qui leur permet de trier très bien numériquement. Le +9but ultime est de s’assurer que V1 vient après V0 + puisque sa Findvaleur serait 5. Techniquement, alors, seulement+5 faut, mais cela ne me coûte pas plus d’octets pour faire en sorte que le tri soit plus sûr.
    • IfError(Find(~),Value(~)) renvoie le Find valeur si la chaîne a été trouvée (c'est-à-dire que la note est VB, V0 ou V0 +). S'il ne peut pas être trouvé, il retourne la valeur numérique de la note plus neuf.
    • Transpose(IfError(~))à nouveau le transforme en une colonne afin de Sortpouvoir l'utiliser.
  • Sort(Transpose(Split(~)),Transpose(IfError(Find(~),Value(~)+9)),1) le tout en triant l'entrée fractionnée en utilisant l'ordre de tri personnalisé croissant.
  • ArrayFormula(~)encapsule tout le contenu pour qu'il renvoie les résultats sous forme de tableau au lieu de simplement renvoyer la première valeur de ce tableau. C'est la raison pour laquelle la formule d'une cellule remplit également les cellules situées en dessous.

Je pense que c'est la première fois que je vois l'utilisation de Google Sheets. Bravo à toi, et +1!
bruyère


1

Haskell , 90 84 83 61 octets

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

Essayez-le en ligne!

fest une fonction qui convertit les notes d’escalade en chaînes pouvant être comparées. Si VBla chaîne convertie pour obtenir la priorité la plus élevée, elle est remplacée V1par des Xchaînes de trois longues pour réduire la priorité de V10-V17 . Pour le reste, nous ne faisons rien.

Pour trier la liste, nous utilisons Data.Listsla sortOnfonction (suggérée par Lynn) pour créer une fonction sans point.


C'est juste g=sortOn f, qui est aussi dans Data.List.
Lynn

1
En outre, f(_:'1':a)='X':asauve 4 octets!
Lynn

1
@ Lynn La première suggestion fonctionne, mais la seconde ne fonctionne pas, j'ai besoin [a]sinon d' V1un motif adapté, c'est le problème que j'essaie de contourner.
Wheat Wizard

1

R , 45 octets

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

Comment cela marche-t-il?

  • Attribuez le vecteur de notes correctement ordonné à 'l';
    • Utilisez 'paste0' au lieu de 'paste' pour éviter de créer un argument 'sep = ""';
  • Indexez 'l' en fonction des correspondances de 'l' dans votre vecteur d'entrée de notes mélangées non triées.

0

Python2, 77 octets

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

Je pense que cela compte comme un extrait! Parce que vous n'imprimez ni le résultat ni la définition de fonction. Vous pouvez cependant en faire un lambda ou imprimer le résultat.
officialaimm

1
@officialaimm nice try mais ne fonctionne pas si V0 + s avant V0.
Setop


0

TXR Lisp : 45 octets

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

Courir:

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.