เรียงลำดับ James Bond เหล่านี้


31

บทนำ

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

ท้าทาย

ความท้าทายนั้นง่าย อินพุตจะประกอบด้วยรายการในรูปแบบต่อไปนี้:

<number> <space> <actor's name> <newline>

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

อย่างไรก็ตามบางครั้งคุณปู่ของฉันทำผิดพลาด ดังนั้นคุณจะต้องตรวจสอบข้อมูล หากหนึ่งในรายชื่อไม่ได้อ้างถึงนักแสดงคนใดคนหนึ่งที่เล่นบอร์นคุณต้องยกเลิกมัน ในกรณีของการทำซ้ำควรลบซ้ำและชื่อควรรักษาน้ำหนักต่ำสุดที่เกี่ยวข้อง (ตัวอย่าง # 3)

ไม่มีการ จำกัด จำนวนบรรทัดที่อาจมี

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

Pierce Brosnan, Sean Connery, David Niven

ขึ้นบรรทัดใหม่หรือช่องว่างที่ได้รับอนุญาต

ตัวอย่างอินพุตและเอาต์พุต

การป้อนข้อมูล:

1 ฌอนคอนเนอรี่

2 เอ็มม่าวัตสัน

5 ทิโมธีดัลตัน

4 โรเจอร์มัวร์

3 Daniel Craig

เอาท์พุท:

Timothy Dalton, Roger Moore, Daniel Craig, Sean Connery

การป้อนข้อมูล:

2 Timothy Dalton

4 George Lazenby

5 George Lazenby

3 Bob Simmons

เอาท์พุท:

George Lazenby, Bob Simmons, Timothy Dalton

การป้อนข้อมูล:

3 ฌอนคอนเนอรี่

2 เพียร์ซบรอสแนน

1 ฌอนคอนเนอรี่

เอาท์พุท:

Pierce Brosnan, Sean Connery

เช่นนี้เป็นรหัสกอล์ฟรหัสที่สั้นที่สุด (เป็นไบต์) ชนะ!

ภาคผนวก

รายชื่อนักแสดงที่เล่นบทบอนด์:

  • Barry Nelson
  • Bob Simmons
  • Sean Connery
  • โรเจอร์มัวร์
  • เดวิดนิเวน
  • George Lazenby
  • ทิโมธีดาลตัน
  • เพียร์ซบรอสแนน
  • Daniel Craig

3
ยินดีต้อนรับสู่ PPCG และความท้าทายที่ดี! โปรดทราบว่า Sean Connery ปรากฏสองครั้งในรายการของคุณ
Denham Coote

@DenhamCoote แก้ไขข้อผิดพลาดนั้นในตัวอย่างผลลัพธ์
MKII

2
เราสามารถสันนิษฐานได้ว่านักแสดงที่เป็นไปได้ทั้งหมดจะถูกระบุด้วยสองคำ (ชื่อและนามสกุล)?
Luis Mendo

17
Emma Watson นั้นยอดเยี่ยมเหมือน James Bond
Alex A.

3
อืมคำตอบของฉันคือecho Sean Conneryเพราะทุกคนรู้ว่ามีเพียงหนึ่งพันธบัตร
user902383

คำตอบ:


2

Pyth, 136 132 ไบต์

_{mtcd\ f}stcTdc"BarryNelson BobSimmons SeanConnery RogerMoore DavidNiven GeorgeLazenby TimothyDalton PierceBrosnan DanielCraig"dS.z

ลองที่นี่!

คำอธิบาย

_ {mtcd \ f} stcTdc "BarryNelson BobSimmons ... " dS.z # .z = รายการบรรทัดอินพุตทั้งหมด
                                             Sz # เรียงอินพุตจากน้อยไปมาก
        f # filter เรียงลำดับบรรทัดโดย T เป็นบรรทัดปัจจุบัน
            cTd # แยกบรรทัดบนช่องว่าง
          st # ยกเลิกหมายเลขและเข้าร่วมชื่อและนามสกุล
               c "BarryNelson BobSimmons ... " d # แยกรายการดารานักแสดงออกเป็นช่องว่าง ...
         } # เก็บเฉพาะบรรทัดที่อยู่ในรายชื่อนักแสดง
   mtcd \ # ลบหมายเลขออกจากบรรทัดที่กรอง
_ {# ลบรายการที่ซ้ำกันออกจากผลการจับคู่และย้อนกลับผลลัพธ์


ข้อบกพร่องเล็ก ๆ การสั่งซื้อเป็นวิธีที่ผิดไปรอบ ๆ (มันควรจะไปจากครั้งแรกไปก่อนในขณะที่คุณเป็นคนแรกที่ผ่านมา)
MKII

@MKII เดาว่าฉันทำส่วนนั้นมากเกินไป ... แก้ไขได้!
Denker

12

จอประสาทตา201 197 191

\ D +
0 $ $ * 1
G` ^ 1 + (Barry Nelson | Bob Simmons | Sean Connery | Roger Moore | David Niven | George Lazenby | Timothy Dalton | Pierce Brosnan | Daniel Craig) $
+ `\ ข ((1 +) \ D *) ¶ (\ 2 +)
$ 3¶ $ 1
+ + s`1 (\ + D) ¶ (. * \ 1)
$ 2
1+ 

ลองออนไลน์!

บันทึกไปแล้ว 6 ไบต์ด้วย Martin!

Whee เรียงฟองด้วย regex โปรดทราบว่ามีการใช้สิบไบต์เพื่อแปลงทศนิยมให้กลายเป็น unary ที่จุดเริ่มต้นถ้าอินพุตแบบ unary นั้นเป็น OK ก็ไม่จำเป็นต้องใช้ นอกจากนี้หากตัวเลขไม่สามารถอยู่ในชื่อของคนอื่นได้อีกสองไบต์สามารถบันทึกได้โดยการย้ายบรรทัดที่ลบนักแสดงที่ไม่ใช่พันธบัตรไปยังจุดสิ้นสุดและลบ1+(ยังไม่ทดลองกับ\Dรุ่น)

คำอธิบาย:

โปรแกรม Retina ประกอบด้วยหลายขั้นตอนดังนั้นฉันจะอธิบายแต่ละขั้นตอนแยกกัน

ด่าน 1:

\d+
$0$*1

แทนที่ตัวเลขในอินพุตด้วย unary สิ่งนี้ใช้โทเค็นการทดแทนพิเศษของ Retina $*ซึ่งทำซ้ำอักขระหลังจากหลายครั้งเท่ากับค่าฐาน 10 ของโทเค็นก่อนหน้า

ด่าน 2:

G`^1+ (Barry Nelson|Bob Simmons|Sean Connery|Roger Moore|David Niven|George Lazenby|Timothy Dalton|Pierce Brosnan|Daniel Craig)$

เนื้อหาก่อน`ในเวทีจะเปลี่ยนโหมดที่ใช้ สิ่งนี้จะเปิดโหมด grep ซึ่งหมายความว่าแต่ละบรรทัดที่ไม่ตรงกับ regex จะถูกยกเลิก แองเคอมีความจำเป็นเพื่อป้องกันไม่ให้การแข่งขันใกล้ลื่นไถล

ด่าน 3:

+`\b((1+)\D*)¶(\2.+)
$3¶$1

นี่คือขั้นตอนการเรียงลำดับ +ในโหมดหมายที่ขั้นตอนนี้ควรจะทำซ้ำจนกว่าจะเปลี่ยนทำให้ไม่มีการเปลี่ยนแปลงเมื่อนำมาใช้ (เช่นเราไปถึงจุดคงที่) regex ค้นหาขอบเขตของคำตามด้วยจำนวน1s จากนั้นส่วนที่เหลือทั้งหมดของบรรทัดจนถึงบรรทัดใหม่ จากนั้นหากบรรทัดถัดไปมีจำนวน1มากกว่านั้น regex จะจับคู่และเราสลับบรรทัด

ด่าน 4:

+s`1+(\D+)¶(.*\1)
$2

ขั้นตอนนี้ใช้+โหมดอีกครั้ง แต่ยังใช้sเพื่อทำให้.เมตาอักขระตรงกับการขึ้นบรรทัดใหม่ สิ่งนี้จะลบบรรทัดที่ซ้ำกันโดยการจับคู่สำหรับการซ้ำที่ซ้ำกันหลังจาก1s และจับภาพสิ่งหลังจากที่ซ้ำกันครั้งแรกเพื่อแทนที่การแข่งขันทั้งหมดด้วย สิ่งนี้จะทำงานได้โดยไม่จำเป็นต้องพิจารณาลำดับการแตกหักเนื่องจากชื่อมีการจัดเรียงอย่างเหมาะสมแล้วโดยมีตัวเลขที่ใหญ่กว่าด้านบนดังนั้นเราจะเก็บค่าที่น้อยลง

ด่าน 5:

1+ 

ง่าย ๆ ที่นี่จริง ๆ ทุกอย่างเป็นระเบียบยกเว้นว่าเรามีพวง1อยู่ข้างหน้าพันธบัตรของเราดังนั้นเราจึงแทนที่พวกเขาและพื้นที่หลังจากพวกเขาไม่มีอะไร


... เอ่อภาษานี้ทำให้ฉันประทับใจมากขึ้นทุกวัน ทำได้ดีมาร์ติน!
คดีฟ้องร้องกองทุนโมนิก้า

6

TSQL 426 ไบต์ (รวมข้อมูล + อินพุต)

สารละลายกอล์ฟ:

create table A(Name varchar(99))insert into A values('Barry Nelson'),('Bob Simmons'),('Sean Connery'),('Roger Moore'),('David Niven'),('George Lazenby'),('Timothy Dalton'),('Pierce Brosnan'),('Daniel Craig')declare @I as table (R int, N varchar(99))insert into @I values(3,'Sean Connery'),(2,'Pierce Brosnan'),(1,'Sean Connery')select N from(select N,min(R) R from @I where N in (select N from A) group by N) x order by R desc

ลองที่นี่

SQL excels (ไม่มีการเล่นสำนวนเจตนา) ในงานประเภทนี้: ชุดที่เกี่ยวข้อง, การสั่งซื้อ, การตัดการทำซ้ำเป็นต้น

สิ่งที่คุณต้องมีก็คือการสร้างและเติมสารบัญของนักแสดงเช่นนี้:

create table Actor (Name varchar(99))
insert into Actor values
 ('Barry Nelson')
,('Bob Simmons')
,('Sean Connery')
,('Roger Moore')
,('David Niven')
,('George Lazenby')
,('Timothy Dalton')
,('Pierce Brosnan')
,('Daniel Craig')

ทีนี้ถ้าเราใช้ตัวแปรตารางเป็นอินพุตเราแค่ต้องตัดกันของทั้งสองเซต การลบรายการที่ซ้ำกันและการสั่งซื้อใน SQL นั้นง่ายมาก

ตัวอย่างที่ 1:

declare @Input as table (Rnk int, Name varchar(99))
insert into @Input values
 (1,'Sean Connery')
,(2,'Emma Watson')
,(5,'Timothy Dalton')
,(4,'Roger Moore')
,(3,'Daniel Craig')

select Name
from
(
    select Name, min(Rnk) as R
    from @Input
    where Name in (select Name from Actor)
    group by Name
) x
order by R desc

ตัวอย่างที่ 2:

declare @Input as table (Rnk int, Name varchar(99))
insert into @Input values
 (2,'Timothy Dalton')
,(4,'George Lazenby')
,(5,'George Lazenby')
,(3,'Bob Simmons')

select Name
from
(
    select Name, min(Rnk) as R
    from @Input
    where Name in (select Name from Actor)
    group by Name
) x
order by R desc

เวอร์ชัน golfed เป็นเพียงสิ่งที่สมบูรณ์เช่นอินพุท 3

ในฐานะที่เป็นบวก SQL นี้สามารถทำงานได้สำหรับรุ่น DBMS ที่เก่ากว่า (แม้จะเขียนใหม่ ANSI SQL) และทำงานได้อย่างไม่มีปัญหาในคอมพิวเตอร์ที่มีอายุมากกว่าภาษาส่วนใหญ่


มันทำงานกับหมายเลขใด ๆ ที่จุดเริ่มต้นของบรรทัดหรือตัวเลขเดียวเท่านั้น?
MKII

1
@MKII ฉันใช้ประเภทINTดังนั้นจึงไม่รับอะไรเลยในช่วง–2,147,483,648ถึง2,147,483,647และมันก็แย่เช่นกันที่ยอมรับจำนวนแถวด้วย =)
jean

คุณไม่จำเป็นต้องเลือกย่อย คุณสามารถใช้order by min(R) descกับตัวเลือกด้านในและลบออกmin(R)จากตัวเลือก ที่ควรประหยัด 21 ไบต์
raznagul

นอกจากนี้ยังมีช่องว่างที่ไม่จำเป็นในเวอร์ชั่น golfed
raznagul

การใช้charแทนที่จะเป็นvarcharจะบันทึกอีก 6 ไบต์
raznagul

5

Perl, 242 179 217 ไบต์

print reverse grep{/^(Barry Nelson|Bob Simmons|Sean Connery|Roger Moore|David Niven|George Lazenby|Timothy Dalton|Pierce Brosnan|Daniel Craig)$/&&!$s{$_}++}map{s/\d+ //;$_}sort{($a=~/(\d+)/)[0]<=>($b=~/(\d+)/)[0]}<>;

เวอร์ชันที่จัดรูปแบบแล้ว Nicer พร้อมความคิดเห็น:

print
     # reverse ranking order
     reverse
     # filter entries...
     grep {
         # only actual bonds
         /^(Barry Nelson|Bob Simmons|Sean Connery|Roger Moore|David Niven|George Lazenby|Timothy Dalton|Pierce Brosnan|Daniel Craig)$/
         # only new bonds
         && !$s{$_}++
     } map {s/\d+ //;$_}         # remove leading digits+space
     # sort according to embedded numbers
     sort {($a=~/(\d+)/)[0] <=> ($b=~/(\d+)/)[0]}
     <>;                        # slurp input as list (list context)

ขนาดส่วนใหญ่เป็นรายการของพันธบัตร ฉันไม่สามารถหาวิธีบีบอัด regex ที่ดีได้โดยไม่ยอมให้มีการบวกผิด ๆ


ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ คำตอบที่ยอดเยี่ยม +1 ฉันจะแนะนำให้คุณเพิ่มคำอธิบาย แต่หลังจากนั้นฉันเห็นการแก้ไข อาจเป็นไปได้ที่จะบีบอัดรายชื่อนักแสดงอย่างใดอย่างหนึ่ง ...
wizzwizz4

@ wizzwizz4 ฉันลองบางสิ่งเพื่อทำให้ regex นั้นเล็กลง แต่การถอดรหัสดูเหมือนจะแพงกว่าที่คุณประหยัด --- มันเบาบางเกินไปในสิ่งที่ยอมรับ
David Morris

น่าเศร้าที่มันต้องทำงานกับตัวเลขไม่ใช่แค่เลขตัวเดียว ฉันขอโทษ แต่ฉันใช้คำผิดในคำถาม
MKII

@MKII aww มีค่าใช้จ่ายฉัน 38 ไบต์ :(
David Morris

หากมีevalใน Perl และในตัวระบบการบีบอัด ...
wizzwizz4

4

Python 2, 250 ไบต์:

lambda I:zip(*sorted({k:v for v,k in[x.split(' ',1)for x in I.split('\n')]if k in'Barry Nelson,Bob Simmons,Sean Connery,Roger Moore,David Niven,George Lazenby,Timothy Dalton,Pierce Brosnan,Daniel Craig'.split(',')}.items(),key=lambda t:-int(t[1])))[0]

การสาธิต:

>>> L = ["Barry Nelson",
...     "Bob Simmons",
...     "Sean Connery",
...     "Roger Moore",
...     "David Niven",
...     "George Lazenby",
...     "Timothy Dalton",
...     "Pierce Brosnan",
...     "Daniel Craig"]

>>> I="""2 Timothy Dalton
... 4 George Lazenby
... 5 George Lazenby
... 3 Bob Simmons"""
>>> F(I,L)
('George Lazenby', 'Bob Simmons', 'Timothy Dalton')

>>> I = """1 Sean Connery
... 2 Emma Watson
... 5 Timothy Dalton
... 4 Roger Moore
... 3 Daniel Craig"""
>>> 
>>> F(I,L)
('Timothy Dalton', 'Roger Moore', 'Daniel Craig', 'Sean Connery')

ขอให้เรายังคงอภิปรายนี้ในการแชท
Rɪᴋᴇʀ

ฉันเพิ่งใช้ความเข้าใจในพจนานุกรมเพื่อรักษาชื่อเฉพาะไว้แทนที่จะตั้งความเข้าใจ
Kasramvd

10
ฉันจะจ่ายเงินเพื่อดู Emma Watson เป็น James Bond
DJClayworth

มันทำงานกับหมายเลขใด ๆ ที่จุดเริ่มต้นของบรรทัดหรือตัวเลขเดียวเท่านั้น?
MKII

2

PowerShell v3 +, 227 219 ไบต์

$a=$args-split"`n"|sort|%{$c,$b=-split$_;$b-join' '}|?{$_-in('Barry Nelson,Bob Simmons,Sean Connery,Roger Moore,David Niven,George Lazenby,Timothy Dalton,Pierce Brosnan,Daniel Craig'-split',')}|select -u
$a[$a.count..0]

121 ไบต์เป็นเพียงรายชื่อนักแสดง ...

จะเข้า$argsและ-splits `nมันเกี่ยวกับการขึ้นบรรทัดใหม่ด้วย ไพพ์ไปยังsortซึ่งจะเรียงลำดับรายการจากน้อยไปมากซึ่งก็โอเคสำหรับตอนนี้ เราโยงไปยังวง foreach |%{...}แต่ละการวนซ้ำใช้รายการ-splitมันในช่องว่างจากนั้น-joinในช่วงครึ่งหลังกลับมาพร้อมกับช่องว่าง (เช่นการลอกตัวเลขออกจากจุดเริ่มต้น) ตอนนี้ชื่อที่เรียงลำดับจากน้อยไปมาก เราส่งผ่านสิ่งเหล่านี้?เพื่อให้มั่นใจว่า-inเป็นรายชื่อนักแสดงที่ได้รับการอนุมัติ ในที่สุดเราselectมีเพียง-uรายการที่ไม่ซ้ำซึ่งสำหรับรายการที่ซ้ำกันจะเลือกรายการแรกที่พบ (เช่นรายการที่มีน้ำหนักต่ำที่สุด) และทิ้งส่วนที่เหลือ $aเราเก็บอาร์เรย์ผลลัพธ์ของชื่อลงไป

ตอนนี้เรามีรายชื่อนักแสดงที่เรียงลำดับจากน้อยไปมาก ตั้งแต่ความท้าทายที่ต้องเสด็จลงมาเราจะดำเนินการกลับรายการในสถานที่บน$aโดยการจัดทำดัชนีจากลงไป$a.count0

ตัวอย่าง

PS C:\Tools\Scripts\golfing> .\sort-these-james-bond-ratings.ps1 "1 Sean Connery`n2 Emma Watson`n5 Daniel Craig`n4 Roger Moore`n3 Daniel Craig"
Roger Moore
Daniel Craig
Sean Connery

แก้ไข - ไม่จำเป็นต้องใช้ [array] :: Reverse () เมื่อการจัดทำดัชนีจะทำ


คุณไม่สามารถใช้sort -Desมากกว่าแค่การกลับรายการอาร์เรย์ได้หรือไม่? จริงอยู่นี่อาจถูกทำลายใน PowerShell รุ่นใหม่กว่า แต่ฉันไม่คิดว่ามันจะเป็นปัญหาจริง);
VisualMelon

@VisualMelon ฉันได้พิจารณาแล้ว แต่จากนั้นselect -uจะคว้าและรักษาลำดับที่มีมูลค่าสูงสุดแทนที่จะเป็นต่ำที่สุดดังนั้นสำหรับตัวอย่างของฉันตำแหน่งของ Daniel Craig และ Roger Moore จะสลับกัน ความพยายามของฉันในการแก้ไขที่ทำให้โค้ดยาวกว่าการกลับอาร์เรย์
AdmBorkBork

อาใช่ที่เหมาะสมฉันไม่สามารถเรียกใช้และพลาดอย่างสมบูรณ์ - มันเป็นความอัปยศที่มีเสียมากเพียงแค่สำหรับการกลับรายการที่ ...
VisualMelon

2

หลาม 309 286 ไบต์

import sys
i='Barry Nelson.Bob Simmons.Sean Connery.Roger Moore.David Niven.George Lazenby.Timothy Dalton.Pierce Brosnan.Daniel Craig'.split('.')
print ', '.join(i.pop(i.index(x)) for x in zip(*sorted((x.strip().split(' ',1) for x in sys.stdin),None,lambda x:int(x[0]),1))[1] if x in i)

มันทำงานกับหมายเลขใด ๆ ที่จุดเริ่มต้นของบรรทัดหรือตัวเลขเดียวเท่านั้น?
MKII

มันไม่ได้ทำตอนนี้ :)
mtp

ดูเหมือนว่าคุณสามารถกำจัดช่องว่างเพิ่มเติมบางส่วนในที่นี่ตัวอย่างเช่นหลังจากprintหรือหลังจาก)หรือ]
wnnmaw

1

JavaScript (ES6), 232 ไบต์

s=>s.split`
`.sort((a,b)=>(p=parseInt)(a)<p(b)).map(l=>l.replace(/\d+ /,"")).filter(l=>!p[l]&/^(Barry Nelson|Bob Simmons|Sean Connery|Roger Moore|David Niven|George Lazenby|Timothy Dalton|Pierce Brosnan|Daniel Craig)$/.test(p[l]=l))

คำอธิบาย

var solution =

s=>
  s.split`
`
  .sort((a,b)=>                 // sort the list by the number
    (p=parseInt)(a)<p(b)        // parseInt reads only the first number in a string
                                // the variable p also holds names that appeared in the
                                //     list previously
  )
  .map(l=>l.replace(/\d+ /,"")) // remove the number at the beginning of each line
  .filter(l=>
    !p[l]&                      // remove duplicates
    
    // Bond actor regex
    /^(Barry Nelson|Bob Simmons|Sean Connery|Roger Moore|David Niven|George Lazenby|Timothy Dalton|Pierce Brosnan|Daniel Craig)$/
    
    .test(p[l]=l)               // test for bondness and add the line to p
  )
<textarea id="input" rows="6" cols="40">1 Sean Connery
2 Emma Watson
5 Timothy Dalton
4 Roger Moore
3 Daniel Craig</textarea><br />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

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