Urutkan peringkat James Bond ini

31

pengantar

Kakek saya adalah penggemar James Bond, tetapi dia selalu tidak yakin tentang bagaimana menentukan peringkat aktor favoritnya. Karena itu, ia selalu membuat daftar, yang banyak pekerjaannya. Dia meminta saya untuk membuat program yang akan membuat hidupnya lebih mudah, tetapi saya tidak punya waktu untuk itu, saya harus bekerja! Jadi saya akan mengandalkan kalian.

Tantangan

Tantangannya sederhana. Input akan terdiri dari daftar, dalam format berikut:

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

Tugas Anda adalah mengurutkannya berdasarkan nomor di awal baris, mulai dari yang terakhir, dan berakhir dengan yang pertama. Semua nomor harus dihapus.

Namun, kakek saya terkadang membuat kesalahan. Karena itu, Anda perlu memvalidasi data. Jika salah satu nama dalam daftar tidak merujuk ke salah satu aktor yang bermain Bond, Anda harus membuangnya. Dalam hal pengulangan, pengulangan harus dihapus, dan nama harus mempertahankan bobot terendah yang dikaitkan dengan (contoh # 3).

Tidak ada batasan berapa banyak garis yang mungkin ada.

Output hanya perlu daftar semacam, apakah itu array, string yang dipisahkan koma, hanya nilai yang dipisahkan oleh spasi, atau sesuatu yang lain sama sekali, yaitu

Pierce Brosnan, Sean Connery, David Niven

Baris atau spasi tambahan baru diperbolehkan.

Contoh Input dan Output

Memasukkan:

1 Sean Connery

2 Emma Watson

5 Timothy Dalton

4 Roger Moore

3 Daniel Craig

Keluaran:

Timothy Dalton, Roger Moore, Daniel Craig, Sean Connery

Memasukkan:

2 Timothy Dalton

4 George Lazenby

5 George Lazenby

3 Bob Simmons

Keluaran:

George Lazenby, Bob Simmons, Timothy Dalton

Memasukkan:

3 Sean Connery

2 Pierce Brosnan

1 Sean Connery

Keluaran:

Pierce Brosnan, Sean Connery

Karena ini adalah kode golf, kode terpendek (dalam byte) menang!

Lampiran

Daftar aktor yang memainkan peran Bond:

  • Barry Nelson
  • Bob Simmons
  • Sean Connery
  • Roger Moore
  • David Niven
  • George Lazenby
  • Timothy Dalton
  • Pierce Brosnan
  • Daniel Craig
MKII
sumber
3
Selamat datang di PPCG, dan tantangan yang menyenangkan! Perhatikan bahwa Sean Connery muncul dua kali dalam daftar Anda.
Denham Coote
@DenhamCoote Memperbaiki itu dan kesalahan dalam contoh output.
MKII
2
Bisakah kita menganggap semua aktor yang mungkin akan diidentifikasi dengan dua kata (nama depan dan nama belakang)?
Luis Mendo
17
Emma Watson hebat seperti James Bond.
Alex A.
3
hmm jawaban saya adalah echo Sean Connerykarena semua orang tahu, hanya ada satu ikatan
user902383

Jawaban:

2

Pyth, 136 132 byte

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

Coba di sini!

Penjelasan

_ {mtcd \ f} stcTdc "BarryNelson BobSimmons ..." dS.z # .z = daftar semua jalur input
                                             Sz # Sortir input naik
        f # menyaring garis yang diurutkan dengan T sebagai garis saat ini
            cTd # Pisahkan garis pada spasi
          st # Dicard nomornya dan gabung nama depan dan belakang
               c "BarryNelson BobSimmons ..." d # Membagi daftar aktor obligasi pada spasi ...
         } # hanya simpan baris yang ada di daftar aktor
   mtcd \ # menghapus nomor dari garis yang difilter
_ {# Hapus duplikat dari hasil pemetaan dan balikkan hasilnya

Denker
sumber
Kelemahan kecil, pemesanannya adalah cara yang salah (seharusnya beralih dari yang terakhir ke yang pertama, sedangkan pesanan Anda yang pertama ke yang terakhir).
MKII
@ MKII Tebak saya membaca bagian itu ... Memperbaikinya!
Denker
12

Retina ,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) $
+ `\ b ((1 +) \ D *) ¶ (\ 2. +)
$ 3¶ $ 1
+ s`1 + (\ D +) ¶ (. * * 1)
$ 2
1+ 

Cobalah online!

6 byte disimpan berkat Martin!

Wah, semacam gelembung dengan regex. Perhatikan bahwa sepuluh byte dihabiskan untuk melakukan konversi desimal ke unary di awal, jika input unary OK maka itu tidak diperlukan. Juga, jika angka tidak bisa atas nama orang, maka beberapa byte lagi dapat disimpan dengan memindahkan garis yang menghapus aktor non-Bond ke ujung dan menghapus 1+(belum teruji dengan \Dversi).

Penjelasan:

Program Retina terdiri dari beberapa tahap, jadi saya akan menjelaskan setiap tahap secara terpisah.

Tahap 1:

\d+
$0$*1

Mengganti angka dalam input dengan unary. Ini menggunakan token pengganti khusus Retina: $*yang mengulang karakter setelah beberapa kali sama dengan nilai basis 10 token sebelumnya.

Tahap 2:

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

Hal-hal sebelum `dalam tahap mengubah mode yang digunakan. Ini mengaktifkan mode grep, yang berarti bahwa setiap baris yang tidak cocok dengan regex dibuang. Jangkar diperlukan untuk mencegah agar korek dekat tidak tergelincir.

Tahap 3:

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

Ini adalah tahap penyortiran. Dalam +mode menandakan bahwa tahap ini harus diulang sampai penggantian tidak membuat perubahan ketika diterapkan (yaitu kita mencapai titik tetap). Regex menemukan batas kata, diikuti oleh beberapa 1s dan kemudian semua sisa baris hingga baris baru. Kemudian, jika baris berikutnya memiliki lebih 1dari itu, regex akan cocok dan kami menukar garis.

Tahap 4:

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

Tahap ini menggunakan +mode lagi, tetapi juga digunakan suntuk membuat .meta-karakter juga cocok dengan baris baru. Ini menghapus garis duplikat, dengan mencocokkan duplikat yang tepat setelah 1dan mengambil barang-barang setelah duplikat pertama untuk menggantikan seluruh pertandingan dengan itu. Ini akan bekerja tanpa perlu mempertimbangkan urutan pemecahan dasi, karena nama-nama sudah diurutkan dengan tepat, dengan angka yang lebih besar di atas, oleh karena itu kami akan selalu menjaga nilai yang lebih kecil.

Tahap 5:

1+ 

Sangat sederhana di sini, semuanya beres, kecuali kita memiliki banyak 1di depan Obligasi kita, jadi kita ganti mereka dan ruang setelah mereka tanpa apa-apa.

FryAmTheEggman
sumber
... Sial, bahasa ini membuatku semakin terkesan setiap hari. Bagus, Martin!
Dana Gugatan Monica
6

TSQL 426 byte (termasuk data + input)

Solusi golf:

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

Coba di sini

SQL unggul (tidak ada permainan kata-kata yang dimaksudkan) dalam jenis tugas ini: menghubungkan set, memesan, memotong duplikat dll.

Yang Anda butuhkan hanyalah membuat dan mengisi tabel Aktor seperti ini:

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

Sekarang jika kita menggunakan variabel tabel sebagai input, kita hanya perlu mendapatkan persimpangan dari kedua set. Menghapus duplikat dan pemesanan di SQL sangat mudah.

Contoh 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

Contoh 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

Versi golf hanya lengkap misalnya input 3

Sebagai nilai tambah, SQL ini dapat berfungsi untuk versi DBMS yang lebih lama (bahkan ditulis ulang menjadi ANSI SQL) dan berjalan tanpa masalah di komputer yang lebih lama daripada kebanyakan bahasa.

jean
sumber
Apakah itu berfungsi dengan angka apa pun di awal baris, atau hanya satu digit?
MKII
1
@ MKII Saya menggunakan tipe INT sehingga ia tidak dapat menerima apapun dalam kisaran –2,147.483.648 hingga 2.147.483.647 juga ia tidak menerima jumlah baris juga =)
jean
Anda tidak perlu subselect. Anda bisa menggunakan order by min(R) descdengan pilih dalam dan menghapus min(R)dari pilih. Itu seharusnya menghemat 21 byte.
raznagul
Juga ada beberapa ruang yang tidak perlu dalam versi golf.
raznagul
Menggunakan charbukannya varcharakan menghemat 6 byte lagi.
raznagul
5

Perl, 242 179 217 byte

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]}<>;

Versi berformat lebih bagus, dengan komentar:

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)

Sebagian besar ukurannya adalah daftar Obligasi; Saya tidak dapat menemukan cara yang bagus untuk mengompresi regex itu tanpa membiarkan positif palsu.

David Morris
sumber
Selamat datang di Programming Puzzles and Code Golf. Jawaban cemerlang, +1. Saya akan menyarankan agar Anda menambahkan penjelasan, tetapi kemudian saya melihat hasil edit. Mungkin mungkin untuk mengompresi daftar aktor entah bagaimana ...
wizzwizz4
@ wizzwizz4 Saya mencoba beberapa hal untuk membuat regex itu lebih kecil, tetapi decoding tampaknya selalu lebih mahal daripada yang Anda simpan --- terlalu jarang dalam apa yang diterimanya.
David Morris
Sayangnya, ini harus bekerja dengan angka, tidak hanya satu digit. Maaf, tapi saya menggunakan istilah yang salah dalam pertanyaan.
MKII
@MKII aww, biaya saya 38 byte :(
David Morris
Jika ada evaldi Perl, dan sistem kompresi
bawaan
4

Python 2, 250 byte:

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]

Demo:

>>> 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')
Kasramvd
sumber
Saya hanya menggunakan pemahaman kamus untuk melestarikan nama-nama unik, alih-alih mengatur pemahaman.
Kasramvd
10
Saya akan membayar untuk melihat Emma Watson sebagai James Bond.
DJClayworth
Apakah itu berfungsi dengan angka apa pun di awal baris, atau hanya satu digit?
MKII
2

PowerShell v3 +, 227 219 byte

$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 byte itu hanya daftar aktor ...

Mengambil input $argsdan -splits pada baris baru dengan `n. Pipa itu untuk sort, yang akan mengurutkan entri naik secara numerik, yang OK untuk saat ini. Kami menyalurkannya ke loop foreach |%{...}, setiap iterasi mengambil entri, -splitpada spasi, lalu -joinbabak kedua kembali bersama dengan spasi (yaitu, menghilangkan nomor dari awal). Nama-nama (naik) yang disortir sekarang tersisa di pipa. Kami menyalurkan mereka melalui mana dengan ?yang memastikan mereka adalah -indaftar aktor yang disetujui. Akhirnya, kami selecthanya -uentri unik, yang untuk duplikat akan memilih yang pertama ditemui (yaitu, yang berbobot terendah) dan membuang sisanya. Kami menyimpan array nama yang dihasilkan ke dalam $a.

Jadi, sekarang kita punya daftar aktor yang naik. Karena tantangan membutuhkan penurunan, kami melakukan operasi pembalikan di tempat $adengan mengindeks dari $a.countbawah ke 0.

Contoh

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

Edit - tidak perlu menggunakan [array] :: Reverse () saat pengindeksan akan dilakukan

AdmBorkBork
sumber
Bisakah Anda tidak hanya menggunakan sort -Desdaripada pembalikan array? Memang, ini bisa dipecahkan di versi PowerShell nanti, tapi saya rasa itu tidak mungkin atau masalah nyata;)
VisualMelon
@VisualMelon saya telah mempertimbangkan itu, tetapi kemudian select -uakan mengambil dan mempertahankan pemesanan bernilai tinggi , bukan yang terendah, jadi untuk contoh saya posisi Daniel Craig dan Roger Moore akan bertukar. Upaya saya untuk memperbaikinya menghasilkan kode yang lebih panjang daripada pembalikan array.
AdmBorkBork
ah, ya, itu masuk akal, saya tidak bisa menjalankannya dan melewatkannya sepenuhnya - sungguh memalukan ada begitu banyak pemborosan hanya untuk pembalikan itu ...
VisualMelon
2

Python 309 286 byte

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)
mtp
sumber
Apakah itu berfungsi dengan angka apa pun di awal baris, atau hanya satu digit?
MKII
itu tidak, sekarang ya :)
mtp
Sepertinya Anda dapat menyingkirkan beberapa ruang ekstra di sini, misalnya setelah printatau setelah )atau]
wnnmaw
1

JavaScript (ES6), 232 byte

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

Penjelasan

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>

pengguna81655
sumber