Ordina queste valutazioni di James Bond


31

introduzione

Mio nonno è un fan di James Bond, ma non è sempre sicuro di come classificare i suoi attori preferiti. Come tale, crea sempre elenchi, il che richiede molto lavoro. Mi ha chiesto di produrre un programma che renderà la sua vita più semplice, ma non ho tempo per farlo, devo lavorare! Quindi conto su di voi ragazzi.

Sfida

La sfida è semplice L'input sarà costituito da un elenco, nel seguente formato:

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

Il tuo compito è di ordinarli in base al numero all'inizio della riga, iniziando dall'ultimo e finendo con il primo. Tutti i numeri dovrebbero essere rimossi.

Tuttavia, a volte mio nonno commette errori. Pertanto, dovrai convalidare i dati. Se uno dei nomi nell'elenco non si riferisce a uno degli attori che hanno interpretato Bond, devi scartarlo. In caso di ripetizioni, le ripetizioni dovrebbero essere rimosse e il nome dovrebbe mantenere il peso più basso a cui era associato (esempio n. 3).

Non c'è limite al numero di righe che possono esserci.

L'output deve essere solo un elenco di qualche tipo, che si tratti di un array, una stringa separata da virgola, solo valori separati da spazi o qualcos'altro interamente, ovvero

Pierce Brosnan, Sean Connery, David Niven

È consentita una nuova riga o spazio finale.

Esempio di input e output

Ingresso:

1 Sean Connery

2 Emma Watson

5 Timothy Dalton

4 Roger Moore

3 Daniel Craig

Produzione:

Timothy Dalton, Roger Moore, Daniel Craig, Sean Connery

Ingresso:

2 Timothy Dalton

4 George Lazenby

5 George Lazenby

3 Bob Simmons

Produzione:

George Lazenby, Bob Simmons, Timothy Dalton

Ingresso:

3 Sean Connery

2 Pierce Brosnan

1 Sean Connery

Produzione:

Pierce Brosnan, Sean Connery

Poiché si tratta di un codice golf, vince il codice più breve (in byte)!

Appendice

Elenco degli attori che hanno interpretato il ruolo di Bond:

  • Barry Nelson
  • Bob Simmons
  • Sean Connery
  • Roger Moore
  • David Niven
  • George Lazenby
  • Timothy Dalton
  • Pierce Brosnan
  • Daniel Craig

3
Benvenuto in PPCG e bella sfida! Si noti che Sean Connery appare due volte nell'elenco.
Denham Coote,

@DenhamCoote Risolto questo e l'errore nell'output di esempio.
MKII,

2
Possiamo presumere che tutti i possibili attori saranno identificati da due parole (nome e cognome)?
Luis Mendo,

17
Emma Watson è stata fantastica come James Bond.
Alex A.

3
hmm la mia risposta è echo Sean Conneryperché lo sanno tutti, c'è solo un legame
user902383

Risposte:


2

Pyth, 136 132 byte

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

Provalo qui!

Spiegazione

_ {mtcd \ f} stcTdc "BarryNelson BobSimmons ..." dS.z # .z = elenco di tutte le righe di input
                                             Sz # Ordina input crescente
        f # filtra le righe ordinate con T come linea corrente
            cTd # Dividi una linea sugli spazi
          st # Dice il numero e unisci nome e cognome
               c "BarryNelson BobSimmons ..." d # Dividi la lista degli attori obbligazionari negli spazi ...
         } # mantiene solo le righe che si trovano nell'elenco degli attori
   mtcd \ # rimuove il numero dalle linee filtrate
_ {# Rimuovi i duplicati dal risultato della mappatura e inverti il ​​risultato


Piccolo difetto, l'ordinamento è nel modo sbagliato (dovrebbe andare dall'ultimo al primo, mentre il tuo è il primo all'ultimo).
MKII,

@MKII Immagino di aver letto male quella parte ... Risolto!
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+ 

Provalo online!

6 byte salvati grazie a Martin!

Whee, ordina le bolle con regex. Si noti che dieci byte vengono spesi per eseguire la conversione da decimale a unaria all'inizio, se l'input unario è OK, quindi non è necessario. Inoltre, se i numeri non possono essere nei nomi delle persone, è possibile salvare un paio di byte in più spostando la linea che rimuove gli attori non Bond fino alla fine e rimuovendo il 1+(non verificato con la \Dversione).

Spiegazione:

Un programma Retina è composto da più fasi, quindi spiegherò ciascuna fase separatamente.

Fase 1:

\d+
$0$*1

Sostituisce i numeri nell'input con unario. Questo utilizza il token di sostituzione speciale di Retina: $*che ripete il personaggio dopo un numero di volte uguale al valore di base 10 del token precedente.

Fase 2:

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

Le cose prima di a `in uno stage cambiano la modalità in uso. Questo attiva la modalità grep, il che significa che ogni riga che non corrisponde al regex viene scartata. Le ancore sono necessarie per impedire lo scivolamento dei fiammiferi vicini.

Fase 3:

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

Questa è la fase di smistamento. Il +nella modalità indica che questa fase deve essere ripetuta fino a quando la sostituzione non apporta modifiche quando viene applicata (ovvero raggiungiamo un punto fisso). Il regex trova una parola diversa, seguita da un certo numero di se 1quindi da tutto il resto della riga fino alla nuova riga. Quindi, se la riga successiva ha più 1s di essa, la regex corrisponderà e scambiamo le righe.

Fase 4:

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

Questa fase utilizza di +nuovo la modalità, ma usa anche sper far .corrispondere anche il meta-personaggio alle nuove righe. Questo rimuove le linee duplicate, abbinando i duplicati esatti dopo la 1s e catturando le cose dopo il primo duplicato per sostituire l'intera corrispondenza con essa. Questo funzionerà senza la necessità di considerare l'ordine del pareggio, perché i nomi sono già ordinati in modo appropriato, con i numeri più grandi sopra, quindi manterremo sempre i valori più piccoli.

Fase 5:

1+ 

Uno davvero semplice qui, tutto è in ordine, tranne che abbiamo un mucchio di 1s davanti ai nostri legami, quindi sostituiamo loro e lo spazio dopo di loro con niente.


... Accidenti, questa lingua mi colpisce sempre di più ogni giorno. Ben fatto, Martin!
Finanzia la causa di Monica l'

6

TSQL 426 byte (inclusi dati + input)

Soluzione golfizzata:

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

Provalo qui

SQL eccelle (nessun gioco di parole) in questo tipo di attività: set correlati, ordinamento, taglio di duplicati ecc.

Tutto ciò che serve è creare e popolare una tabella di attori come questa:

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

Ora, se utilizziamo una variabile di tabella come input, dobbiamo solo ottenere l'intersezione di entrambi gli insiemi. Rimuovere i duplicati e ordinare in SQL è davvero semplice.

Esempio 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

Esempio 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

La versione giocata a golf è la cosa completa per esempio input 3

Inoltre, questo SQL può funzionare con versioni precedenti di DBMS (può anche essere riscritto in ANSI SQL) ed essere eseguito senza problemi nei computer meno recenti rispetto alla maggior parte delle lingue.


Funziona con qualsiasi numero all'inizio della riga o solo singole cifre?
MKII,

1
@MKII Ho usato il tipo INT, quindi non accetterò nulla nell'intervallo compreso tra –2.147.483.648 e 2.147.483.647 ma non accetterà anche quel numero di righe =)
jean

Non hai bisogno di una sottoselezione. Puoi semplicemente usare order by min(R) desccon la selezione interna e rimuovere la min(R)dalla selezione. Ciò dovrebbe salvare 21 byte.
raznagul,

Inoltre ci sono alcuni spazi non necessari nella versione golf.
raznagul,

L'uso di charinvece di varcharsalverà altri 6 byte.
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]}<>;

Versione formattata più gradevole, con commenti:

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)

La maggior parte delle dimensioni è l'elenco delle obbligazioni; Non riesco a trovare un modo carino per comprimere quella regex senza consentire falsi positivi.


Benvenuti in Programming Puzzle and Code Golf. Risposta brillante, +1. Stavo per suggerirti di aggiungere una spiegazione, ma poi ho visto la modifica. Forse è possibile comprimere l'elenco degli attori in qualche modo ...
wizzwizz4,

@ wizzwizz4 Ho provato alcune cose per ridurre quella regex, ma la decodifica sembra sempre costare più di quanto risparmi --- è troppo scarso in ciò che accetta.
David Morris,

Purtroppo, deve lavorare con i numeri, non solo con singole cifre. Mi dispiace, ma ho usato il termine sbagliato nella domanda.
MKII,

@MKII aww, che mi costa 38 byte :(
David Morris,

Se c'è un evalin Perl e un sistema di compressione integrato ...
wizzwizz4,

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


Ho appena usato la comprensione del dizionario al fine di preservare i nomi univoci, anziché impostare la comprensione.
Kasramvd,

10
Pagherei per vedere Emma Watson nei panni di James Bond.
DJClayworth,

Funziona con qualsiasi numero all'inizio della riga o solo singole cifre?
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 di questo è solo l'elenco degli attori ...

Prende input $argse -splitlo fa su newline con `n. Installa quello a sort, che ordinerà le voci numericamente in ordine crescente, il che è OK per ora. Li reindirizziamo a un ciclo foreach |%{...}, ogni iterazione prende l'entrata, -splitquesta su spazi, quindi -joinla seconda metà torna insieme con uno spazio (cioè, togliendo i numeri dall'inizio). Quei nomi (in ordine crescente) ordinati ora vengono lasciati sulla pipeline. Condividiamo quelli attraverso un dove con ?quello assicuriamo che siano -inl'elenco approvato degli attori. Infine, abbiamo selectsolo le -uvoci di nicchia, che per i duplicati selezioneranno la prima che incontra (cioè la più ponderata) e scarteremo il resto. Archiviamo la matrice risultante di nomi in $a.

Quindi, ora abbiamo un elenco crescente di attori in ordine crescente. Poiché la sfida richiede il declino, eseguiamo un'operazione di inversione sul posto $aindicizzando da $a.countgiù a 0.

Esempio

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

Modifica - non è necessario utilizzare [array] :: Reverse () quando l'indicizzazione lo farà


Non puoi semplicemente usare sort -Despiuttosto che l'inversione dell'array? Certo, questo potrebbe essere risolto nelle versioni successive di PowerShell, ma non credo sia probabile o un problema reale;)
VisualMelon,

@VisualMelon L'avevo considerato, ma poi select -uavrei afferrato e conservato l' ordinamento più prezioso, piuttosto che il più basso, quindi per il mio esempio le posizioni di Daniel Craig e Roger Moore sarebbero state scambiate. I miei tentativi di correzione hanno comportato un codice più lungo rispetto all'inversione dell'array.
AdmBorkBork,

ah, sì, questo ha senso, non sono stato in grado di eseguirlo e l'ho perso del tutto - è un peccato che ci siano così tanti sprechi solo per quella inversione ...
VisualMelon,

2

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

Funziona con qualsiasi numero all'inizio della riga o solo singole cifre?
MKII,

non è così, ora lo fa :)
mtp

Sembra che tu possa liberarti di alcuni spazi extra qui, ad esempio dopo printo dopo un )o]
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))

Spiegazione

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.