排序攀登成绩


33

我的第一个代码高尔夫球场,对任何错误表示歉意...

语境

在攀岩(特别是抱石)中,V / Vermin(美国)攀爬等级从“ VB”(最简单的等级)开始,然后是“ V0”,“ V0 +”,“ V1”,“ V2”,“ V3” ,“ V4”,“ V5”等,直至“ V17”(最难的等级)。

任务

您将输入一个爬坡等级的列表/数组,并且必须返回或打印从最简单到最困难的爬坡等级的列表/数组。

如果输入为空,则返回一个空的数据结构;否则为0。否则,输入将始终是有效的。

测试用例

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

这是一个挑战。


下次,将此内容发布到沙盒上以获得反馈,然后再发布。其次,您是否应该真正应对自己的挑战?
伊恩H.17年

输入中是否会出现重复成绩?
Xcoder先生17年

@ Mr.Xcoder没有重复
Chris_Rands

7
欢迎来到PPCG!很清楚,第一个问题很好。(y)
Officialaimm

3
非常好的第一个问题!它所导致的答案是如此多样且富有创意。:)
Lynn

Answers:


23

Python 2中58个 54字节

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

在线尝试!

怎么运行的

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

看起来,将其移植到ES6并不比Arnauld的方法好:a=>a.sort((a,b,B10=0)=>(g=s=>eval(s.slice(1)+10))(a)>g(b))58字节。
林恩

1
a=>a.sort((a,b)=>(g=s=>eval(s.slice(B10=1)+10))(a)-g(b))短2个字节,但这仍然太长。
Arnauld

@GB我认为这是有效的,但现在绝对有效。
林恩

为什么使用10而不是更短的数字?例如,“ 2”保存2个字节。
GB

1
@GB诀窍是触发从八进制表示法“ 010”到八进制“ V0”的转换。使用2,您将获得“ 02” = 2,与“ 0 + 2”相同。
Arnauld

15

JavaScript(ES6)/ Firefox,53字节

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

测试用例

对于Firefox:

对于Chrome或Edge(+4字节):

怎么样?

我们应用了3个连续的转换,这些转换导致了按字典顺序可比较的字符串。

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"

您是否提出了基本的转换/模数想法?辉煌!
kamoroso94 '17

1
@ kamoroso94 FWIW,这是我编写的用于查找基数和模数的代码。它给出了其他可能的答案(m <1000)。
Arnauld

a=>a.sort((a,b)=>(g=s=>parseInt(s,32)%334+s)(a)>g(b))在Chrome上尝试过,但并不f(["VB","V0","V0+","V1","V2","V3","V4","V5","V6","V7","V8","V9","V10","V11","V12","V13","V14","V15","V16","V17"])确定我为什么会给出正确的答案;兼容边缘的版本在chrome上可以正常使用。
Ra8

1
@ Ra8啊,是的。Chrome也似乎不稳定。从sort()回调返回一个布尔值只是碰巧在Firefox中起作用,但是我们确实应该返回一个带符号的值。感谢您的反馈意见!
Arnauld

12

外壳,5个字节

ÖiÖm±

在线尝试! 结果每行打印一个,但是在内部,这是一个获取并返回字符串列表的函数。

说明

这出乎意料地类似于马丁对视网膜的回答。首先,我们做的Öm±意思是“通过映射is-digit排序”。这使得VBV0V0+以正确的顺序,因为它们相比[0,0][0,1][0,1,0]。接下来,我们做的Öi意思是“按整数顺序排序”。给定一个字符串,i以整数形式返回其中出现的第一个数字序列;如果未找到,则返回0。上面的三个字符串都映射为0,并且排序是稳定的,因此它们在输出中的顺序正确。


11

视网膜,14字节

B
!
O`
!
B
O#`

在线尝试!

说明

B
!

替换B!,以便等级的字典顺序在所有数字等级的前面VB(然后是V!)。

O`

按字典顺序对所有输入行进行排序。这不会给出正确的结果,但是可以V! < V0 < V0+正确排序。

!
B

V!VB

O#`

对行进行数字排序。Retina只是在字符串中寻找第一个十进制数字,以确定其排序键。如果没有数字(例如for VB),则将值设置为0。这意味着所有VBV0并且V0+具有相同的排序键。但是Retina的排序是稳定的,我们已经按照正确的相对顺序进行了排列。


6

V,3个字节

Úún

在线尝试!

它是如何工作的?

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

该命令几乎是一个有效的解决方案,因为无法按数字(AKA,VB)进行排序的每一行都将放置在开头,而无需更改顺序。但是,由于仅查看数字,因此无法区分V0V0+。由于Vim使用稳定的排序方式,因此在排序之后,无论哪种先出现都将保留在第一位。所以...

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

2
V在此挑战中表现出色的恰当程度:P
Business Cat

5

C#,121 83 82 83字节

感谢TheLethalCoder和LiefdeWen,节省了39个字节

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

在线尝试!

字节数包括using System.Linq


怎么样?

  • 获取字符串数组作为输入。
  • 如果输入等于VB,则将值设置为-1,如果等于VB0+,则将值设置为0。
  • 根据后面的数字值对输入进行排序V

可能会有点hack,但它可以工作!:)



@LiefdeWen你不需要ToArray()IOrderedEnumerable应该罚款。
TheLethalCoder

抱歉,意外删除了System.Linq参考,并对其进行了修复
LiefdeWen

@TheLethalCoder您一如既往地正确,有84个字节
LiefdeWen

@LiefdeWen .Remove(0,1)附加-1个字节:)
Ian H.

4

红宝石52 42 41字节

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

在线尝试!

怎么运行的:

解决问题,产生完整排序的列表,然后得到与我们输入的交集。

感谢Lynn保存1个字节。


聪明!->x{[?B,0,"0+",*1..17].map{|a|"V#{a}"}&x}保存一个字节。
林恩



2

果冻,9 个字节

Ḋv-.F+LµÞ

单字链接,获取字符列表并返回排序后的列表。

在线尝试!(页脚很好地格式化了结果)

怎么样?

Ḋ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

首先要介绍的是我的Python 3解决方案...抱歉,过早将其发布为违反约定,现在重新发布...

Python 3中69个 67字节

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

在线尝试!


5
不建议立即回答自己的挑战。给其他人一些时间,至少48小时,可能更长一些。
TheLethalCoder

@TheLethalCoder哦,对了,在堆栈溢出时,鼓励这种行为!我应该删除答案吗?
Chris_Rands '17

@Chris_Rands是的,我建议您删除它。
Xcoder先生17年

9
@Downvoter:对新成员的不满意行为投票否决,这是一件很酷的事;最好简单地指出他们不应该这样做,就像致命杀手那样。
毛茸茸的

请注意,但是如果有人不发布您的解决方案,我们欢迎您这样做。当然等待之后
TheLethalCoder

1

雨燕 3,102字节

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

这是一个功能。您可以这样称呼它:

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

在线尝试!


这是如何运作的?

这基本上是@Arnauld提供的令人惊叹的Javascript答案的一部分,但已针对Swift进行了优化。

它将每个值映射到按字典顺序可排序的字符串,如下表所示:

初始字符串->结果

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

代码说明

  • String((Int($0,radix:32) ?? 992)%334)-将每个字符串从基数32转换为十进制。如果值是“ V0 +”,则对的调用Int(_:radix:)将返回nil,并且我们将值“ V0”设为992。我们还采用的结果mod 334,最后将其转换为String。

  • +$0-将当前值添加到上面创建的字符串中。例如,如果String为V9,则上面的函数返回333,我们添加V9,结果为333V9

  • var r={...}-将变量声明为r匿名闭包,因为使用了两次,它节省了大量字节。

  • func f(l:[String])- f使用参数l(字符串列表)定义一个函数。

  • print(l.sorted(by:{r($0)<r($1)}))-打印给定列表排序的结果,键是r上面定义的变量。



1

Google表格,142个字节

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

输入是一个字符串A1,每个条目之间用逗号分隔。
输出是公式的单元格及其n-1下方的单元格,其中n是中的条目数A1

结果

这是一个漫长而混乱的公式,所以让我们打开它的包装。

  • If(A1="","",~)修复空输入。否则,空输入将返回#VALUE!错误,因为该Split功能不适用于空输入。
  • Transpose(Split(A1,","))分裂A1的逗号和它转置成列,因为该Sort功能只能在列。
  • Transpose(IfError(Find(),Value()+9)) 分为以下几部分:
    • Find(Split(A1,","),"VBV0V0+")尝试在该字符串中查找每个参数。这前三个是唯一必须按字符串排序的字符串,因此我们可以Find用来获取它们的排序顺序。
    • Value(Mid(Split(A1,","),2,3))+9获取等级的数值。这仅对V1和更高版本有意义,因此它们在数字上排序就很好。将+9在年底是确保V1配备V0 +后,因为它的Find价值将是5。从技术上讲,+5这仅是必需的,但它不会花费我更多的字节来确保其正确排序。
    • IfError(Find(~),Value(~))Find如果找到了字符串,则返回值(即,等级是VB,V0或V0 +)。如果找不到,则返回成绩的数值加9。
    • Transpose(IfError(~))再次将其变成一列,以便Sort可以使用它。
  • Sort(Transpose(Split(~)),Transpose(IfError(Find(~),Value(~)+9)),1) 通过使用自定义排序顺序升序对拆分的输入进行排序来包装所有内容。
  • ArrayFormula(~)包装整个内容,以便将结果作为数组返回,而不仅仅是返回该数组中的第一个值。这就是导致一个单元格中的公式也填充其下方的单元格的原因。

我认为这是我第一次看到Google表格。恭喜您,+ 1!
heather


1

哈斯克尔90 84 83 61字节

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

在线尝试!

f是将攀登坡度转换为可以比较的弦的功能。如果将其转换VB为空字符串,以便获得最高优先级,则将其替换V1X在三个长降低的优先级串V10- V17。对于其余部分,我们什么也不做。

为了对列表进行排序,我们使用Data.ListssortOn函数(由Lynn建议)来创建无点函数。


这只是g=sortOn f,这也是Data.List
林恩

1
另外,f(_:'1':a)='X':a节省4个字节!
林恩

1
@Lynn第一个建议有效,但是第二个建议无效,[a]否则我V1将需要模式匹配,这是我要规避的问题。
小麦巫师

1

R,45个字节

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

这是如何运作的?

  • 将正确排序的等级向量分配为“ l”;
    • 使用'paste0'而不是'paste'以避免产生'sep =“”'参数;
  • 基于混合的,未排序成绩的输入向量中的“ l”匹配项来索引“ l”。

0

Python2,77个字节

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

我认为这算是一个片段!因为您既不打印结果也不是函数定义。您可以将其设置为lambda或打印结果。
Officialaimm

1
@officialaimm不错的尝试,但是如果V0之前的V0 +不起作用。
Setop


0

TXR Lisp:45个字节

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

跑:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.