เรียงลำดับการปีนเขา


33

โพสต์กอล์ฟรหัสแรกของฉันขอโทษสำหรับข้อผิดพลาดใด ๆ ...

บริบท

ในการปีนหน้าผา (การขึ้นรูปหินโดยเฉพาะ ) เกรด V / Vermin (สหรัฐอเมริกา) เริ่มต้นที่ 'VB' (เกรดที่ง่ายที่สุด) จากนั้นไปที่ 'V0', 'V0 +', 'V1', 'V2', 'V3' , 'V4', 'V5' ฯลฯ จนถึง 'V17' (เกรดที่ยากที่สุด)

งาน

คุณจะป้อนรายการ / อาร์เรย์ของคะแนนการปีนเขาและคุณจะต้องส่งคืนหรือพิมพ์รายการ / อาร์เรย์ของคะแนนที่เรียงลำดับจากง่ายที่สุดไปหายากที่สุด

ถ้าอินพุตว่างให้ส่งคืนโครงสร้างข้อมูลเปล่า มิฉะนั้นการป้อนข้อมูลจะถูกต้องเสมอ

กรณีทดสอบ

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

นี่คือความท้าทาย


ครั้งต่อไปโพสต์สิ่งนี้บนแซนด์บ็อกซ์เพื่อรับข้อเสนอแนะก่อนโพสต์ ประการที่สองคุณควรตอบคำถามท้าทายของคุณเองหรือไม่?
เอียนเอช.

เกรดที่ซ้ำกันจะปรากฏในอินพุตหรือไม่
Mr. Xcoder

@ Mr.Xcoder ไม่มีการซ้ำซ้อน
Chris_Rands

7
ยินดีต้อนรับสู่ PPCG! ค่อนข้างชัดเจนและดีสำหรับคำถามแรก (y)
เป็นทางการเมื่อ

3
คำถามแรกที่ดีมาก! คำตอบที่นำไปสู่การเปลี่ยนแปลงและสร้างสรรค์ :)
ลินน์

คำตอบ:


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" ถึง 8 เป็นทศนิยมสำหรับ "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

1
@ kamoroso94 FWIW นี่คือรหัสที่ฉันเขียนเพื่อค้นหาฐานและ modulo มันให้คำตอบอื่น ๆ ที่เป็นไปได้ (ด้วย m <1,000)
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"])ฉันไม่แน่ใจว่าทำไม รุ่นที่เข้ากันได้กับขอบใช้งานได้ดีกับโครม
Ra8

1
@ Ra8 อ่าใช่ ดูเหมือนว่าจะไม่เสถียรสำหรับ Chrome เช่นกัน การคืนค่าบูลีนจากการเรียงกลับ () เป็นเพียงแฮ็คที่เกิดขึ้นกับการทำงานใน Firefox แต่เราควรจะคืนค่าที่เซ็นชื่อจริง ๆ ขอบคุณสำหรับความคิดเห็นของคุณ!
Arnauld

12

Husk , 5 ไบต์

ÖiÖm±

ลองออนไลน์! ผลลัพธ์จะถูกพิมพ์หนึ่งรายการต่อบรรทัด แต่ภายในนี้เป็นฟังก์ชันที่รับและส่งคืนรายการสตริง

คำอธิบาย

นี้เป็นที่น่าแปลกใจที่คล้ายกับคำตอบ Retina มาร์ติน ก่อนอื่นเราÖm±หมายถึง "ลำดับโดยการจับคู่เป็นหลัก" ทำให้นี้VB, V0และV0+ในลำดับที่ถูกต้องเนื่องจากพวกเขาจะเทียบเป็น[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 จะค้นหาตัวเลขทศนิยมครั้งแรกในสตริงเพื่อกำหนดคีย์การเรียงลำดับ หากมีจำนวนไม่ (เช่นVB) 0จะกำหนดค่าให้ นั่นหมายความว่าทั้งหมดของVB, V0และV0+มีคีย์การเรียงลำดับเดียวกัน แต่การจัดเรียงของ Retina นั้นมีความเสถียรและเราได้นำไปใช้ในลำดับที่ถูกต้องแล้ว


6

V , 3 ไบต์

Úún

ลองออนไลน์!

มันทำงานยังไง?

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

คำสั่งนี้เกือบจะเป็นทางออกที่ถูกต้องเนื่องจากทุกบรรทัดที่ไม่สามารถเรียงลำดับตามตัวเลข (AKA, VB) จะถูกวางไว้ที่จุดเริ่มต้นโดยไม่เปลี่ยนลำดับ แต่เนื่องจากเป็นเพียงการมองที่ตัวเลขจะไม่สามารถแยกแยะความแตกต่างระหว่างและV0 V0+เนื่องจาก Vim ใช้การเรียงลำดับที่เสถียรสิ่งใดก็ตามที่มาก่อนจะยังคงอยู่ก่อนหลังจากเรียงลำดับ ดังนั้น...

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

2
ความเหมาะสมที่วีทำได้ดีกับความท้าทายนี้: P
Business Cat

5

C #, 121 83 82 83 ไบต์

บันทึก39ไบต์ขอบคุณ TheLethalCoder และ LiefdeWen

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

ลองออนไลน์!

Bytecount using System.Linqรวมถึง


อย่างไร?

  • รับอาร์เรย์ของสตริงเป็นอินพุต
  • หากอินพุตเท่ากับVBตั้งค่าเป็น -1 ถ้าเท่ากับให้VB0+ตั้งค่าเป็น 0
  • Vสั่งซื้อการป้อนข้อมูลที่อยู่บนพื้นฐานของค่าตัวเลขที่มาหลังจากที่

อาจจะเป็นบิตของการแฮ็ก แต่มันได้ผล! :)



@LiefdeWen คุณไม่จำเป็นต้องควรจะปรับ ToArray()IOrderedEnumerable
TheLethalCoder

ขออภัยลบ System.Linq ออกโดยไม่ได้ตั้งใจซ่อมมัน
LiefdeWen

@TheLethalCoder คุณถูกต้องเช่นเคย84 ไบต์
LiefdeWen

@LiefdeWen .Remove(0,1)เพิ่มเติม -1 ไบต์ :)
เอียนเอช

4

Ruby , 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µÞ

ลิงก์ monadic ที่ใช้รายการรายการอักขระและส่งคืนรายการที่เรียงลำดับ

ลองออนไลน์! (ส่วนท้ายจัดรูปแบบผลลัพธ์เป็นอย่างดี)

อย่างไร?

Ḋ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 โอ้ถูกต้องบน Stack Overflow พฤติกรรมดังกล่าวได้รับการสนับสนุน! ฉันควรลบคำตอบของฉัน?
Chris_Rands

@Chris_Rands ใช่ฉันขอแนะนำให้คุณลบออก
Mr. Xcoder

9
@Downvoter: การลงสมาชิกใหม่สำหรับทำสิ่งที่พวกเขาไม่ทราบว่าเป็นขมวดคิ้วเมื่อไม่เย็น; ดีกว่ามากที่จะชี้ให้เห็นว่าไม่ควรทำอย่างที่ Lethal ทำ
Shaggy

โปรดทราบว่าหากมีคนไม่โพสต์โซลูชันของคุณคุณสามารถทำได้ หลังจากรอแน่นอน
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+"])

ลองออนไลน์!


มันทำงานอย่างไร

นี่เป็นพอร์ตของคำตอบ Javascript ที่น่าทึ่งโดย @Arnauldแต่ได้รับการปรับให้เหมาะกับ 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)- แปลงสตริงแต่ละตัวจาก base-32 Number เป็นทศนิยม ในกรณีที่ค่าเป็น "V0 +" การเรียกเพื่อInt(_:radix:)จะส่งกลับศูนย์และเรารับค่าของ "V0" 992 เราได้รับผลลัพธ์เพิ่มเติมmod 334และแปลงเป็นสตริง

  • +$0- เพิ่มมูลค่าปัจจุบันให้กับสตริงที่สร้างขึ้นด้านบน ตัวอย่างเช่นถ้าสตริงเป็นV9ฟังก์ชั่นข้างต้นผลตอบแทน333และเราเพิ่มผลในการV9333V9

  • var r={...}- ประกาศตัวแปรrให้เป็นการปิดแบบไม่ระบุชื่อเพราะมันช่วยประหยัดจำนวนไบต์นับตั้งแต่มีการใช้สองครั้ง

  • func f(l:[String])- กำหนดฟังก์ชั่นที่fมีพารามิเตอร์lรายการของสตริง

  • print(l.sorted(by:{r($0)<r($1)}))- พิมพ์ผลลัพธ์ของการเรียงลำดับรายการที่กำหนดโดยมีคีย์เป็นตัวแปรที่rกำหนดไว้ข้างต้น


1

PowerShellขนาด 45 ไบต์

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

ลองออนไลน์!

ใช้กระบวนการเดียวกันกับคำตอบ Ruby ของ GBเพื่อสร้างรายการอาร์กิวเมนต์แบบเต็มตามลำดับเรียงจากนั้นเลือกรายการที่เป็น-inรายการอินพุต


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เซลล์ด้านล่างที่เป็นจำนวนของรายการในnA1

Result

มันเป็นสูตรที่ยุ่งและยาวมาก

  • 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 ​​+) หากไม่พบมันจะส่งคืนค่าตัวเลขของเกรดบวกเก้า
    • Transpose(IfError(~))เปลี่ยนเป็นคอลัมน์อีกครั้งเพื่อให้Sortสามารถใช้งานได้
  • Sort(Transpose(Split(~)),Transpose(IfError(Find(~),Value(~)+9)),1) ล้อมรอบทั้งหมดด้วยการเรียงลำดับอินพุตแยกโดยใช้ลำดับการเรียงลำดับที่กำหนดเองจากน้อยไปมาก
  • ArrayFormula(~)ล้อมรอบสิ่งทั้งหมดดังนั้นจึงส่งกลับผลลัพธ์เป็นอาร์เรย์แทนที่จะส่งกลับค่าแรกในอาร์เรย์นั้น นี่คือสิ่งที่ทำให้สูตรในเซลล์เดียวเติมเซลล์ด้านล่างด้วย

ฉันคิดว่านี่เป็นครั้งแรกที่ฉันเคยเห็น Google ชีตใช้ ขอชื่นชมคุณและ +1!
ทุ่งหญ้า


1

Haskell , 90 84 83 61 ไบต์

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

ลองออนไลน์!

fเป็นฟังก์ชั่นที่แปลงเกรดการปีนเป็นสตริงที่สามารถเปรียบเทียบได้ ถ้าแปลงVBให้เป็นสตริงว่างจึงได้รับความสำคัญสูงสุดแล้วแทนที่V1ด้วยXในสายที่สามยาวเพื่อลดความสำคัญของ-V10 V17เวลาที่เหลือเราไม่ได้ทำอะไรเลย

เพื่อจัดเรียงรายการที่เราใช้Data.ListsของsortOnฟังก์ชั่น (แนะนำโดยลินน์) เพื่อสร้างฟังก์ชันจุดฟรี


นั่นเป็นเพียงซึ่งยังอยู่ใน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")))

ฉันคิดว่านี่ถือว่าเป็นตัวอย่าง! เพราะคุณไม่ได้พิมพ์ผลลัพธ์หรือนี่คือนิยามฟังก์ชัน คุณสามารถทำให้เป็นแลมบ์ดาหรือพิมพ์ผลลัพธ์ได้
เป็นทางการ

1
@officialaimm ลองดี แต่ไม่ทำงานถ้า V0 + s ก่อน 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")

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.