Classificar as notas de escalada

33

Meu primeiro código de golfe, desculpas por qualquer erro ...

Contexto

Na escalada ( especificamente em pedregulho ), as notas de escalada V / Vermin (EUA) começam em 'VB' (a nota mais fácil) e depois passam 'V0', 'V0 +', 'V1', 'V2', 'V3' , 'V4', 'V5' etc. até 'V17' (a série mais difícil).

Tarefa

Você terá como entrada uma lista / matriz de notas de escalada e precisará retornar ou imprimir uma lista / matriz das notas classificadas da mais fácil à mais difícil.

Se a entrada estiver vazia, retorne uma estrutura de dados vazia; caso contrário, a entrada sempre será válida.

Casos de teste

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

Este é um desafio do .

Chris_Rands
fonte
Da próxima vez, publique isso na sandbox para obter feedback antes de publicá-lo. Em segundo lugar, você deve realmente responder ao seu próprio desafio?
Ian H.
Aparecerão notas duplicadas na entrada?
Mr. Xcoder
@ Mr.Xcoder Não há duplicatas
Chris_Rands
7
Bem-vindo ao PPCG! Muito claro e agradável para uma primeira pergunta. (y)
officialaimm
3
Muito boa primeira pergunta! As respostas que ele levou são muito variadas e criativas. :)
Lynn

Respostas:

23

Python 2 , 58 54 bytes

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

Experimente online!

Como funciona

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
fonte
Parece que portar isso para o ES6 não supera a abordagem de Arnauld: a=>a.sort((a,b,B10=0)=>(g=s=>eval(s.slice(1)+10))(a)>g(b))tem 58 bytes.
Lynn
1
a=>a.sort((a,b)=>(g=s=>eval(s.slice(B10=1)+10))(a)-g(b))é 2 bytes mais curto, mas ainda é muito longo.
Arnauld
@ GB Acho que era válido, mas agora é definitivamente válido.
Lynn
Por que usar '10' e não algo mais curto? Por exemplo '2' salva 2 bytes.
GB
1
O truque é acionar a tradução da notação octal "010" para 8 como decimal para "V0". Com 2, você obteria "02" = 2, que é igual a "0 + 2".
Arnauld
15

JavaScript (ES6) / Firefox, 53 bytes

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

Casos de teste

Para o Firefox:

Para Chrome ou Edge (+4 bytes):

Quão?

Aplicamos três transformações sucessivas que levam a seqüências lexicograficamente comparáveis.

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
fonte
Você teve a ideia básica de conversão / módulo? Brilhante!
precisa saber é o seguinte
1
@ kamoroso94 FWIW, aqui está o código que escrevi para encontrar a base e o módulo. Dá outras respostas possíveis (com m <1000).
Arnauld
Eu tentei a=>a.sort((a,b)=>(g=s=>parseInt(s,32)%334+s)(a)>g(b))no Chrome, ele não dá a resposta correta, f(["VB","V0","V0+","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17"])não sei por que; a versão compatível com borda funciona bem no chrome.
Ra8
1
@ Ra8 Ah, sim. Parece ser instável para o Chrome também. Retornar um booleano a partir de um retorno de chamada sort () é apenas um hack que funciona no Firefox, mas realmente devemos retornar um valor assinado. Obrigado pelo seu feedback!
Arnauld
12

Casca , 5 bytes

ÖiÖm±

Experimente online! Os resultados são impressos um por linha, mas internamente esta é uma função que pega e retorna uma lista de cadeias.

Explicação

Isso é surpreendentemente semelhante à resposta de Martin na Retina . Primeiro, o que Öm±significa "ordenar pelo mapeamento é um dígito". Isso coloca VB, V0e V0+na ordem correta, uma vez que são comparados como [0,0], [0,1]e [0,1,0]. Em seguida, fazemos o que Öisignifica "ordenar por valor inteiro". Dada uma string, iretorna a primeira sequência de dígitos que ocorrem nela como um número inteiro, ou 0 se um não for encontrado. As três seqüências acima são todas mapeadas para 0 e a classificação é estável, portanto, elas estarão na ordem correta na saída.

Zgarb
fonte
11

Retina , 14 bytes

B
!
O`
!
B
O#`

Experimente online!

Explicação

B
!

Substitua Bpor !para que a ordem lexicográfica das notas fique VB(ou então V!) na frente de todas as notas numéricas.

O`

Classifique todas as linhas de entrada lexicograficamente. Isso não dá o resultado certo, mas faz o pedido V! < V0 < V0+corretamente.

!
B

Volte V!para VB.

O#`

Classifique as linhas numericamente. O Retina simplesmente procura o primeiro número decimal em uma string para determinar sua chave de classificação. Se não houver um número (como para VB), ele define o valor como 0. Isso significa que todos VB, V0e V0+têm a mesma chave de classificação. Mas a classificação de Retina é estável e já as colocamos na ordem relativa correta.

Martin Ender
fonte
6

V , 3 bytes

Úún

Experimente online!

Como funciona?

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

Este comando é quase uma solução válida, pois todas as linhas que não podem ser classificadas por números (AKA VB) serão colocadas no início, sem que a ordem seja alterada. No entanto, como ele está apenas olhando para números, não pode distinguir entre V0e V0+. Como o Vim usa uma classificação estável, o que ocorrer primeiro ocorrerá após a classificação. Tão...

Ú   # Sort lexicographically (will place 'V0' before 'V0+')
 ú  # Sort by...
  n #   The first number on the line
DJMcMayhem
fonte
2
Como apropriado que V faz bem este desafio: P
Cat Negócios
5

C #, 121 83 82 83 bytes

Economizou 39 bytes graças a TheLethalCoder e LiefdeWen

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

Experimente online!

Bytecount inclui using System.Linq.


Quão?

  • Obtém uma matriz de seqüências de caracteres como entrada.
  • Se a entrada for igual a VB, defina o valor como -1, se for igual VB0+, defina o valor como 0.
  • Solicite a entrada com base no valor numérico que vem após o V.

Pode ser um pouco complicado, mas funciona! :)

Ian H.
fonte
94 bytes
LiefdeWen
@LiefdeWen Você não precisa de ToArray()um IOrderedEnumerabledeve ficar bem.
TheLethalCoder
Desculpe referência System.Linq acidentalmente removido, fixa-lo
LiefdeWen
@TheLethalCoder Você está certo, como sempre, 84 bytes
LiefdeWen
@LiefdeWen .Remove(0,1)para -1 bytes adicionais :)
Ian H.
4

Ruby , 52 42 41 bytes

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

Experimente online!

Como funciona:

Vire o problema, produza a lista completa de classificação e faça o cruzamento com a entrada.

Obrigado Lynn por economizar 1 byte.

GB
fonte
Inteligente! ->x{[?B,0,"0+",*1..17].map{|a|"V#{a}"}&x}salva um byte.
Lynn
2

05AB1E , 17 13 8 bytes

Σþï}„VB†

Experimente online!

Erik, o Outgolfer
fonte
Ha ... é melhor do que D"VB"åiÁpor um tiro no escuro.
Magic Octopus Urn
2

Geléia , 9 bytes

Ḋv-.F+LµÞ

Um link monádico que obtém uma lista de listas de caracteres e retorna a lista classificada.

Experimente online! (o rodapé formata bem o resultado)

Quão?

Ḋ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
fonte
2

Para começar aqui, está a minha solução em Python 3 ... Desculpas, postadas cedo demais contra a convenção, agora republicando novamente ...

Python 3 , 69 67 bytes

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

Experimente online!

Chris_Rands
fonte
5
É desencorajado a responder seu próprio desafio imediatamente. Reserve algum tempo para que outras pessoas respondam, pelo menos 48 horas, provavelmente por mais tempo.
TheLethalCoder
@TheLethalCoder Oh, certo, no Stack Overflow esse comportamento é incentivado! Devo excluir minha resposta?
Chris_Rands
@ Chris_Rands Sim, sugiro que você o exclua.
Mr. Xcoder
9
@Downvoter: Diminuir o voto de um novo membro por fazer algo que eles não sabiam que era desaprovado não é legal; muito melhor simplesmente apontar que não deveriam, como Lethal fez.
Shaggy
Observe que, se alguém não publicar sua solução, você poderá fazê-lo. Depois de esperar, é claro
TheLethalCoder 2/17/17
1

Swift 3 , 102 bytes

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

Esta é uma função. Você pode chamá-lo assim:

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

Experimente online!


Como é que isso funciona?

Esta é basicamente uma porta da incrível resposta Javascript do @Arnauld , mas otimizada para o Swift.

Ele mapeia cada um dos valores para Strings lexicograficamente ordenáveis, conforme mostrado na tabela abaixo:

Sequência inicial -> resultado

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

Código Explicação

  • String((Int($0,radix:32) ?? 992)%334)- Converte cada String de um número base 32 em decimal. Caso o valor seja "V0 +", a chamada Int(_:radix:)retornará nulo e assumimos o valor de "V0", 992. Além disso, pegamos o resultado de mod 334e finalmente o convertemos em String.

  • +$0- Adiciona o valor atual à String criada acima. Por exemplo, se a String for V9, a função acima retornará 333e nós adicionamos V9, resultando em 333V9.

  • var r={...}- Declara uma variável rpara um fechamento anônimo, porque salva muitos bytes, pois é usado duas vezes.

  • func f(l:[String])- Define uma função fcom um parâmetro l, uma lista de Strings.

  • print(l.sorted(by:{r($0)<r($1)}))- Imprime o resultado da classificação da lista fornecida, com a chave sendo a variável rdefinida acima.

Mr. Xcoder
fonte
1

PowerShell , 45 bytes

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

Experimente online!

Usa o mesmo processo que a resposta Ruby do GB para construir a lista completa de argumentos em ordem classificada e, em seguida, selecione aqueles que são -ina lista de entrada.

AdmBorkBork
fonte
1

Planilhas Google, 142 bytes

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

Entrada é uma cadeia de caracteres A1com cada entrada separada por vírgula.
Saída é a célula da fórmula mais as n-1células abaixo dela, onde nestá o número de entradas A1.

Resultado

É uma fórmula longa e confusa, então vamos desempacotá-la.

  • If(A1="","",~)corrige a entrada nula. Sem isso, uma entrada vazia retorna um #VALUE!erro porque a Splitfunção não funciona em entradas vazias.
  • Transpose(Split(A1,","))divide A1nas vírgulas e a transpõe para uma coluna porque a Sortfunção funciona apenas em colunas.
  • Transpose(IfError(Find(),Value()+9)) é quebras nessas partes:
    • Find(Split(A1,","),"VBV0V0+")tenta encontrar cada parâmetro nessa sequência. Esses três primeiros são os únicos que devem ser classificados como cadeias de caracteres, para que possamos Findobter sua ordem de classificação.
    • Value(Mid(Split(A1,","),2,3))+9obtém o valor numérico da nota. Isso só importa para V1 e superior, para que eles sejam classificados numericamente. O +9objetivo final é garantir que V1 venha após V0 +, pois seu Findvalor seria 5. Tecnicamente, então, +5é apenas necessário, mas não me custa mais bytes para ter o dobro extra de certeza de que está classificado corretamente.
    • IfError(Find(~),Value(~))retorna o Findvalor se a sequência foi encontrada (ou seja, a nota é VB, V0 ou V0 +). Se não puder ser encontrado, ele retornará o valor numérico da nota mais nove.
    • Transpose(IfError(~))novamente o transforma em uma coluna para que você Sortpossa usá-lo.
  • Sort(Transpose(Split(~)),Transpose(IfError(Find(~),Value(~)+9)),1) quebra tudo, classificando a entrada dividida usando a ordem de classificação personalizada crescente.
  • ArrayFormula(~)envolve a coisa toda para que ele retorne os resultados como uma matriz em vez de apenas retornar o primeiro valor nessa matriz. É isso que faz com que a fórmula em uma célula também preencha as células abaixo dela.
Engenheiro Toast
fonte
Acho que é a primeira vez que vejo o Google Sheets usado. Parabéns a você e +1!
Heather #
1

Haskell , 90 84 83 61 bytes

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

Experimente online!

fé uma função que converte escaladas em cordas que podem ser comparadas. Se a conversão VBfor a sequência vazia, obtendo a prioridade mais alta, ela será substituída V1por Xsequências de três anos para diminuir a prioridade de V10- V17. Quanto ao restante, não fazemos nada.

Para classificar a lista, usamos Data.Listsa sortOnfunção (como sugerida por Lynn) para criar uma função sem pontos.

Assistente de Trigo
fonte
Isso é apenas g=sortOn f, que também está em Data.List.
Lynn
1
Além disso, f(_:'1':a)='X':aeconomiza 4 bytes!
Lynn
1
@ Lynn A primeira sugestão funciona, no entanto, a segunda não, eu preciso de [a]outra forma V1, será o padrão correspondente, que é o problema que estou tentando contornar.
Wheat Wizard
1

R , 45 bytes

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

Como é que isso funciona?

  • Atribua o vetor de notas ordenado corretamente a 'l';
    • Use 'paste0' em vez de 'paste' para evitar criar um argumento 'sep = ""';
  • Índice 'l' com base em correspondências de 'l' no vetor de entrada de notas mistas e não ordenadas.
Mendizale
fonte
0

Python2, 77 bytes

sorted(input(),key=lambda s:float(s[1:].replace("B","-1").replace("+",".5")))
Setop
fonte
Eu acho que isso conta como um trecho! Porque você não está imprimindo o resultado nem esta é uma definição de função. Você pode transformá-lo em um lambda ou imprimir o resultado.
officialaimm
1
@officialaimm boa tentativa, mas não funciona se V0 + s antes de V0.
Setop
0

TXR Lisp : 45 bytes

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

Corre:

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
fonte
0

Perl 5 , 56 + 1 (-a) = 57 bytes

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

Experimente online!

Xcali
fonte