Sortuj te oceny Jamesa Bonda

31

Wprowadzenie

Mój dziadek jest fanem Jamesa Bonda, ale zawsze nie jest pewien, jak uszeregować swoich ulubionych aktorów. Jako taki zawsze tworzy listy, co jest bardzo pracochłonne. Poprosił mnie o opracowanie programu, który ułatwi mu życie, ale nie mam na to czasu, muszę pracować! Więc będę na was liczyć.

Wyzwanie

Wyzwanie jest proste. Dane wejściowe będą składały się z listy w następującym formacie:

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

Twoim zadaniem jest posortowanie ich na podstawie liczby na początku wiersza, zaczynając od ostatniego, a kończąc na pierwszym. Wszystkie numery powinny zostać usunięte.

Jednak mój dziadek czasami popełnia błędy. W związku z tym musisz zweryfikować dane. Jeśli jedno z nazwisk na liście nie odnosi się do jednego z aktorów, który grał w Bonda, musisz go odrzucić. W przypadku powtórzeń powtórzenia należy usunąć, a nazwa powinna zachować najniższą wagę, z jaką była skojarzona (przykład # 3).

Nie ma ograniczenia co do liczby linii.

Dane wyjściowe muszą być tylko pewnego rodzaju listą, bez względu na to, czy jest to tablica, łańcuch rozdzielany przecinkami, tylko wartości oddzielone spacjami lub coś zupełnie innego, tj.

Pierce Brosnan, Sean Connery, David Niven

Końcowy znak nowej linii lub spacja jest dozwolony.

Przykład wejścia i wyjścia

Wkład:

1 Sean Connery

2 Emma Watson

5 Timothy Dalton

4 Roger Moore

3 Daniel Craig

Wydajność:

Timothy Dalton, Roger Moore, Daniel Craig, Sean Connery

Wkład:

2 Timothy Dalton

4 George Lazenby

5 George Lazenby

3 Bob Simmons

Wydajność:

George Lazenby, Bob Simmons, Timothy Dalton

Wkład:

3 Sean Connery

2 Pierce Brosnan

1 Sean Connery

Wydajność:

Pierce Brosnan, Sean Connery

Ponieważ jest to kod golfowy, wygrywa najkrótszy kod (w bajtach)!

dodatek

Lista aktorów, którzy grali rolę Bonda:

  • Barry Nelson
  • Bob Simmons
  • Sean Connery
  • Roger Moore
  • David Niven
  • George Lazenby
  • Timothy Dalton
  • Pierce Brosnan
  • Daniel Craig
MKII
źródło
3
Witamy w PPCG i niezłe wyzwanie! Zauważ, że Sean Connery pojawia się dwa razy na twojej liście.
Denham Coote
@DenhamCoote Naprawiono to i błąd w przykładowym wyjściu.
MKII
2
Czy możemy założyć, że wszyscy potencjalni aktorzy zostaną zidentyfikowani na podstawie dwóch słów (imię i nazwisko)?
Luis Mendo,
17
Emma Watson była świetna jako James Bond.
Alex A.
3
hmm moja odpowiedź jest taka, echo Sean Conneryponieważ wszyscy wiedzą, że jest tylko jedna więź
użytkownik902383

Odpowiedzi:

2

Pyth, 136 132 bajtów

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

Wypróbuj tutaj!

Wyjaśnienie

_ {mtcd \ f} stcTdc "BarryNelson BobSimmons ..." dS.z # .z = lista wszystkich linii wejściowych
                                             Sz # Sortuj wejście rosnąco
        f # filtruje posortowane linie, gdzie T jest bieżącą linią
            cTd # Podziel linię na spacje
          st # Odrzuć numer i dołącz imię i nazwisko
               c „BarryNelson BobSimmons ...” d # Podziel listę aktorów obligacji na spacje ...
         } # zachowuje tylko linie znajdujące się na liście aktorów
   mtcd \ # usuń liczbę z filtrowanych linii
_ {# Usuń duplikaty z wyniku mapowania i odwróć wynik

Denker
źródło
Mała wada, porządkowanie jest niewłaściwe (powinno przechodzić od ostatniego do pierwszego, podczas gdy twoje jest od pierwszego do ostatniego).
MKII
@MKII Chyba przesadziłem z tą częścią ... Naprawiłem to!
Denker
12

Siatkówka ,201 197 191

\ d +
0 USD * 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 USD 1 USD
+ s`1 + (\ D +) ¶ (. * \ 1)
2 USD
1+ 

Wypróbuj online!

6 bajtów zapisanych dzięki Martinowi!

Whee, sortowanie bąbelkowe z wyrażeniem regularnym. Zauważ, że dziesięć bajtów jest zużywanych na konwersję dziesiętną na jednoargumentową na początku, jeśli jednoargumentowe wejście jest OK, to nie jest potrzebne. Ponadto, jeśli liczby nie mogą znajdować się w nazwach ludzi, można zaoszczędzić jeszcze kilka bajtów, przesuwając linię, która usuwa aktorów niezwiązanych z Bondem do końca i usuwając 1+(niesprawdzoną z \Dwersją).

Wyjaśnienie:

Program Retina składa się z kilku etapów, więc wyjaśnię każdy etap osobno.

Scena 1:

\d+
$0$*1

Zamienia liczby na wejściu na jednoargumentowe. Używa to specjalnego tokena zastępczego Retiny: $*który powtarza postać po liczbie razy równej wartości podstawowej 10 poprzedniego tokena.

Etap 2:

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

Rzeczy `na etapie zmieniają używany tryb. Włącza to tryb grep, co oznacza, że ​​każda linia, która nie pasuje do wyrażenia regularnego, jest odrzucana. Kotwice są niezbędne, aby zapobiec zsuwaniu się w pobliżu zapałek.

Etap 3:

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

To jest etap sortowania. +W trybie oznacza, że etap ten należy powtarzać aż do zastąpienia powoduje żadnej zmiany po nałożeniu (tj docieramy stały punkt). Wyrażenie regularne znajduje granicę słów, po której następuje pewna liczba 1s, a następnie cała reszta wiersza aż do nowej linii. Następnie, jeśli następna linia ma więcej 1s niż to, wyrażenie regularne będzie pasować i zamienimy linie.

Etap 4:

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

Ten etap +ponownie korzysta z trybu, ale także wykorzystuje, saby .meta-znak pasował również do nowych linii. To usuwa zduplikowane linie, dopasowując dokładne duplikaty po 1s i przechwytując rzeczy po pierwszym duplikacie, aby zastąpić je całym dopasowaniem. Będzie to działać bez konieczności rozważania kolejności rozłączania remisów, ponieważ nazwy są już odpowiednio posortowane, z większą liczbą powyżej, dlatego zawsze będziemy zachowywać mniejsze wartości.

Etap 5:

1+ 

Tutaj jest naprawdę prosty, wszystko jest w porządku, z tym wyjątkiem, że 1przed naszymi Obligacjami mamy kilka s, więc zastępujemy je i przestrzeń za nimi niczym.

FryAmTheEggman
źródło
... Cholera, ten język robi na mnie coraz większe wrażenie. Dobra robota, Martin!
Pozew Fund Moniki w
6

426 bajtów TSQL (w tym dane + dane wejściowe)

Rozwiązanie w golfa:

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

Wypróbuj tutaj

SQL wyróżnia się (bez zamierzonej gry słów) w tego rodzaju zadaniach: powiązanie zbiorów, porządkowanie, odcinanie duplikatów itp.

Wystarczy utworzyć i wypełnić tabelę aktorów w następujący sposób:

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

Teraz, jeśli użyjemy zmiennej tabeli jako danych wejściowych, wystarczy uzyskać przecięcie obu zestawów. Usuwanie duplikatów i porządkowanie w SQL są naprawdę łatwe.

Przykład 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

Przykład 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

Wersja w golfa jest po prostu pełna, na przykład wejście 3

Plus ten SQL może działać dla starszych wersji DBMS (nawet przepisać na ANSI SQL) i działać bez problemu na starszych komputerach niż w większości języków.

drelich
źródło
Czy działa z dowolną liczbą na początku wiersza, czy tylko z pojedynczymi cyframi?
MKII
1
@MKII Użyłem typu INT, więc nie akceptuję niczego w zakresie –2,147,483,648 do 2 147 483 647, a także nie akceptuję tej liczby wierszy =)
jean
Nie potrzebujesz podselekcji. Możesz po prostu użyć order by min(R) descz wewnętrznym wyborem i usunąć min(R)z niego. To powinno zaoszczędzić 21 bajtów.
Raznagul
W wersji golfowej jest też kilka niepotrzebnych miejsc.
raznagul
Użycie charzamiast varcharspowoduje zapisanie kolejnych 6 bajtów.
raznagul
5

Perl, 242 179 217 bajtów

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

Bardziej sformatowana wersja z komentarzami:

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)

Większość wielkości to lista Obligacji; Nie mogę znaleźć dobrego sposobu na skompresowanie tego wyrażenia regularnego bez dopuszczenia fałszywych trafień.

David Morris
źródło
Witamy w Programowaniu zagadek i Code Golf. Genialna odpowiedź, +1. Chciałem zasugerować dodanie wyjaśnienia, ale potem zobaczyłem zmianę. Może
uda się w
@ wizzwizz4 Próbowałem kilku rzeczy, aby zmniejszyć ten regex, ale dekodowanie zawsze wydaje się kosztować więcej niż oszczędzasz --- jest zbyt rzadkie w tym, co akceptuje.
David Morris
Niestety musi działać z liczbami, a nie tylko z pojedynczymi cyframi. Przepraszam, ale użyłem niewłaściwego terminu w pytaniu.
MKII
@ MKII aww, który kosztuje mnie 38 bajtów :(
David Morris
Jeśli istnieje evalPerl i wbudowany system kompresji ...
wizzwizz4
4

Python 2, 250 bajtów:

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]

Próbny:

>>> 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
źródło
Daj nam kontynuować tę dyskusję w czacie .
Rɪᴋᴇʀ
Po prostu użyłem rozumienia słownikowego, aby zachować unikalne nazwy, zamiast ustawiać rozumienie.
Kasramvd
10
Zapłaciłbym za to, by zobaczyć Emmę Watson jako Jamesa Bonda.
DJClayworth,
Czy działa z dowolną liczbą na początku wiersza, czy tylko z pojedynczymi cyframi?
MKII
2

PowerShell v3 +, 227 219 bajtów

$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 bajtów to tylko lista aktorów ...

Pobiera dane $argsi -splitjest na nowych liniach z `n. Potokuj do sort, który posortuje wpisy rosnąco według liczb, co na razie jest OK. Przeciągamy je do pętli foreach |%{...}, każda iteracja zajmuje wejście, -splitspacje, a następnie -joindrugą połowę z powrotem razem ze spacją (tj. Usuwając liczby od początku). Te (rosnąco) posortowane nazwy są teraz pozostawione w kolejce. Przesuwamy ich przez miejsce ?, dzięki czemu jest -into zatwierdzona lista aktorów. Wreszcie, my selecttylko -unijakie wpisy, które dla duplikatów wybiorą pierwszy napotkany (tj. Ten o najniższym ciężarze) i odrzucą resztę. Przechowujemy wynikową tablicę nazw w $a.

Mamy teraz posortowaną rosnącą listę aktorów. Ponieważ wyzwanie wymaga zejścia, wykonujemy operację odwracania w miejscu $a, indeksując od $a.countdo do 0.

Przykład

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

Edycja - nie trzeba używać [array] :: Reverse () podczas indeksowania

AdmBorkBork
źródło
Czy nie możesz po prostu użyć sort -Deszamiast odwrócenia tablicy? To prawda, że ​​może to zostać zepsute w późniejszych wersjach programu PowerShell, ale nie wydaje mi się, aby to był prawdziwy problem;)
VisualMelon
@VisualMelon Zastanawiałem się nad tym, ale wtedy select -uprzechwyciliby i zachowali najwyższą wartość, a nie najniższą, więc w moim przykładzie pozycje Daniela Craiga i Rogera Moore'a ulegną zamianie. Moje próby naprawienia spowodowały dłuższy kod niż odwrócenie tablicy.
AdmBorkBork
ah, tak, to ma sens, nie byłem w stanie go uruchomić i całkowicie tego przegapiłem - szkoda, że ​​jest tyle marnotrawstwa tylko na to odwrócenie ...
VisualMelon
2

Pyton 309 286 bajtów

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
źródło
Czy działa z dowolną liczbą na początku wiersza, czy tylko z pojedynczymi cyframi?
MKII
tak się nie stało, ale teraz :)
mtp
Wygląda na to, można pozbyć się kilku dodatkowych miejsc tu, na przykład po printlub po )lub]
wnnmaw
1

JavaScript (ES6), 232 bajty

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

Wyjaśnienie

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>

użytkownik 81655
źródło