Classifique estas classificações de James Bond

31

Introdução

Meu avô é fã de James Bond, mas ele sempre tem dúvidas sobre como classificar seus atores favoritos. Como tal, ele está sempre fazendo listas, o que dá muito trabalho. Ele me pediu para elaborar um programa que tornasse sua vida mais fácil, mas não tenho tempo para isso, tenho que trabalhar! Então eu vou contar com vocês.

Desafio

O desafio é simples. A entrada consistirá em uma lista, no seguinte formato:

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

Sua tarefa é classificá-los com base no número no início da linha, começando pelo último e terminando com o primeiro. Todos os números devem ser removidos.

No entanto, meu avô às vezes comete erros. Como tal, você precisará validar os dados. Se um dos nomes da lista não se referir a um dos atores que interpretou Bond, será necessário descartá-lo. No caso de repetições, as repetições devem ser removidas e o nome deve manter o menor peso ao qual foi associado (exemplo # 3).

Não há limite para quantas linhas podem existir.

A saída precisa ser apenas uma lista de algum tipo, seja uma matriz, uma sequência separada por vírgula, apenas valores separados por espaços ou algo completamente diferente, ou seja,

Pierce Brosnan, Sean Connery, David Niven

Uma nova linha ou espaço à direita é permitida.

Exemplo de entrada e saída

Entrada:

1 Sean Connery

2 Emma Watson

5 Timothy Dalton

4 Roger Moore

3 Daniel Craig

Saída:

Timothy Dalton, Roger Moore, Daniel Craig, Sean Connery

Entrada:

2 Timothy Dalton

4 George Lazenby

5 George Lazenby

3 Bob Simmons

Saída:

George Lazenby, Bob Simmons, Timothy Dalton

Entrada:

3 Sean Connery

2 Pierce Brosnan

1 Sean Connery

Saída:

Pierce Brosnan, Sean Connery

Como este é um código de golfe, o código mais curto (em bytes) vence!

Apêndice

Lista de atores que desempenharam o papel de Bond:

  • Barry Nelson
  • Bob Simmons
  • Sean Connery
  • Roger Moore
  • David Niven
  • George Lazenby
  • Timothy Dalton
  • Pierce Brosnan
  • Daniel Craig
MKII
fonte
3
Bem-vindo ao PPCG, e bom desafio! Observe que Sean Connery aparece duas vezes na sua lista.
Denham Coote
@DenhamCoote Corrigido isso e o erro no exemplo de saída.
MKII
2
Podemos assumir que todos os atores possíveis serão identificados por duas palavras (nome e sobrenome)?
Luis Mendo
17
Emma Watson foi ótima como James Bond.
Alex A.
3
hmm minha resposta é echo Sean Conneryporque todo mundo sabe, existe apenas uma ligação
user902383

Respostas:

2

Pitão, 136 132 bytes

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

Experimente aqui!

Explicação

_ {mtcd \ f} stcTdc "BarryNelson BobSimmons ..." dS.z # .z = lista de todas as linhas de entrada
                                             Sz # Classificar entrada ascendente
        f # filtra as linhas classificadas com T sendo a linha atual
            cTd # Divide uma linha em espaços
          st # Decida o número e entre com o nome e o sobrenome
               c "BarryNelson BobSimmons ..." d # Divida a lista de atores de títulos em espaços ...
         } # mantenha apenas as linhas que estão na lista de atores
   mtcd \ # remove o número das linhas filtradas
_ {# Remova duplicatas do resultado do mapeamento e inverta o resultado

Denker
fonte
Pequena falha, a ordem é inversa (deve passar do último ao primeiro, enquanto o seu é o primeiro ao último).
MKII
@MKII Acho que eu li demais essa parte ... Corrigida!
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+ 

Experimente online!

6 bytes salvos graças ao Martin!

Whee, tipo de bolha com regex. Observe que dez bytes são gastos na conversão de decimal para unário no início, se a entrada unária estiver OK, isso não será necessário. Além disso, se os números não puderem estar no nome das pessoas, mais alguns bytes poderão ser salvos movendo a linha que remove os atores não Bond até o fim e removendo o1+ (não testado com a \Dversão).

Explicação:

Um programa Retina é composto de várias etapas, portanto, explicarei cada etapa separadamente.

Estágio 1:

\d+
$0$*1

Substitui os números na entrada por unário. Isso usa o token de substituição especial da Retina: $*que repete o caractere depois de um número de vezes igual ao valor base 10 do token anterior.

Etapa 2:

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

O material antes de um `estágio altera o modo que está sendo usado. Isso ativa o modo grep, o que significa que cada linha que não corresponde ao regex é descartada. As âncoras são necessárias para impedir que as partidas próximas deslizem.

Etapa 3:

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

Este é o estágio de classificação. O +modo significa que esse estágio deve ser repetido até que a substituição não faça alterações quando aplicada (ou seja, atingimos um ponto fixo). A regex encontra um limite de palavras, seguido por um número de se 1depois todo o restante da linha até a nova linha. Então, se a próxima linha tiver mais 1s do que ela, a regex corresponderá e trocamos as linhas.

Etapa 4:

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

Este estágio usa o +modo novamente, mas também usa spara fazer o. meta-caractere corresponda às novas linhas. Isso remove as linhas duplicadas, correspondendo às duplicatas exatas após os se 1capturando o material após a primeira duplicata para substituir a correspondência inteira por elas. Isso funcionará sem a necessidade de considerar a ordem de desempate, porque os nomes já estão classificados adequadamente, com os números maiores acima, portanto, sempre manteremos os valores menores.

Etapa 5:

1+ 

Realmente simples aqui, tudo está em ordem, exceto que temos um monte de 1s na frente dos nossos Bonds, então os substituímos e o espaço depois deles por nada.

FryAmTheEggman
fonte
... Droga, essa linguagem me impressiona cada vez mais a cada dia. Muito bem, Martin!
Fund Monica's Lawsuit
6

TSQL 426 bytes (incluindo dados de entrada + entrada)

Solução Golfed:

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

Experimente aqui

O SQL se destaca (sem trocadilhos) nesse tipo de tarefa: relacionando conjuntos, pedidos, eliminando duplicatas etc.

Tudo que você precisa é criar e preencher uma tabela de atores como este:

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

Agora, se usarmos uma variável de tabela como entrada, apenas precisamos obter a interseção dos dois conjuntos. Remoção de duplicatas e pedidos no SQL são realmente fáceis.

Exemplo 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

Exemplo 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

A versão golfada é a coisa completa, por exemplo, entrada 3

Além disso, esse SQL pode funcionar para versões mais antigas do DBMS (até ser reescrito para ANSI SQL) e executar sem problemas em computadores mais antigos que a maioria dos idiomas.

brim
fonte
Funciona com qualquer número no início da linha ou apenas com um dígito?
MKII
1
@MKII eu usei INT tipo por isso mal aceitar qualquer coisa no intervalo de -2147483648 a 2147483647 também a mal aceitar que número de linhas também =)
jean
Você não precisa de uma subseleção. Você pode apenas usar order by min(R) desccom a seleção interna e remover min(R)a seleção. Isso deve economizar 21 bytes.
raznagul
Também existem alguns espaços desnecessários na versão golfed.
raznagul
Usar em charvez de varcharsalvará outros 6 bytes.
raznagul
5

Perl, 242 179 217 bytes

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

Versão melhorada, com comentários:

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)

A maior parte do tamanho é a lista de títulos; Não consigo encontrar uma boa maneira de comprimir esse regex sem permitir falsos positivos.

David Morris
fonte
Bem-vindo à programação de quebra-cabeças e código de golfe. Resposta brilhante, +1. Eu sugeriria que você adicionasse uma explicação, mas depois vi a edição. Talvez seja possível comprimir a lista de atores de alguma forma ...
wizzwizz4
@ wizzwizz4 Tentei algumas coisas para tornar esse regex menor, mas a decodificação sempre parece custar mais do que você economiza --- é muito escasso no que aceita.
David Morris
Infelizmente, ele precisa trabalhar com números, não apenas com um dígito. Sinto muito, mas usei o termo errado na pergunta.
MKII
@MKII aww, isso me custa 38 bytes :(
David Morris
Se há uma evalem Perl, e um built-in sistema de compressão ...
wizzwizz4
4

Python 2, 250 bytes:

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
fonte
Vamos continuar esta discussão no chat .
Rɪᴋᴇʀ
Eu apenas usei a compreensão do dicionário para preservar os nomes exclusivos, em vez da compreensão do conjunto.
21416 Kasramvd
10
Eu pagaria para ver Emma Watson como James Bond.
DJClayworth
Funciona com qualquer número no início da linha ou apenas com um dígito?
MKII
2

PowerShell v3 +, 227 219 bytes

$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 bytes disso é apenas a lista de atores ...

Pega entrada $argse -splitlança em novas linhas com `n. Canalize isso para sort, que classificará as entradas numericamente ascendentes, o que é bom por enquanto. Nós os canalizamos para um loop foreach |%{...}, cada iteração leva a entrada, -splitem espaços, e -joina segunda metade de volta com um espaço (ou seja, eliminando os números desde o início). Os nomes classificados (ascendentes) agora são deixados no pipeline. Encaminhamos aqueles a um lugar onde ?isso garante que eles sejam -ina lista aprovada de atores. Por fim, selectapenas as -uentradas nique, que, para duplicados, selecionam a primeira que encontrar (ou seja, a mais baixa) e descartam o restante. Armazenamos a matriz de nomes resultante em $a.

Então, agora temos uma lista crescente de atores. Como o desafio exige uma descida, fazemos uma operação de reversão no local $a, indexando de $a.countbaixo para 0.

Exemplo

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

Editar - não precisa usar [array] :: Reverse () quando a indexação for executada

AdmBorkBork
fonte
Você não pode apenas usar sort -Dese não a inversão da matriz? Concedido, isso poderia ser quebrado em versões posteriores do PowerShell, mas eu não acho que seja provável ou um problema real;)
VisualMelon
@VisualMelon Eu tinha considerado isso, mas então select -uele pegaria e manteria a ordem de maior valor, e não a menor, então, no meu exemplo, as posições de Daniel Craig e Roger Moore seriam trocadas. Minhas tentativas de corrigir isso resultaram em um código mais longo que a inversão da matriz.
AdmBorkBork 12/02
ah, sim, que faz sentido, eu não era capaz de executá-lo e perdeu que completamente - é uma vergonha não é tanto desperdiçar apenas para essa reversão ...
VisualMelon
2

Python 309 286 bytes

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
fonte
Funciona com qualquer número no início da linha ou apenas com um dígito?
MKII
isso não aconteceu, ele faz agora embora :)
mtp
Parece que você pode se livrar de alguns espaços extras aqui, por exemplo, após printou depois de um )ou]
wnnmaw
1

JavaScript (ES6), 232 bytes

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

Explicação

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>

user81655
fonte