Ordenar estas calificaciones de James Bond

31

Introducción

Mi abuelo es fanático de James Bond, pero siempre no está seguro de cómo clasificar a sus actores favoritos. Como tal, siempre está haciendo listas, lo cual es mucho trabajo. Me pidió que produjera un programa que le facilitara la vida, pero no tengo tiempo para eso, ¡tengo que trabajar! Así que contaré con ustedes, chicos.

Reto

El desafío es simple. La entrada consistirá en una lista, en el siguiente formato:

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

Su tarea es ordenarlos según el número al principio de la línea, comenzando desde el último y terminando con el primero. Todos los números deben ser eliminados.

Sin embargo, mi abuelo a veces comete errores. Como tal, deberá validar los datos. Si uno de los nombres en la lista no se refiere a uno de los actores que interpretaron a Bond, debe descartarlo. En caso de repeticiones, las repeticiones deben eliminarse y el nombre debe mantener el peso más bajo con el que estaba asociado (ejemplo # 3).

No hay límite para cuántas líneas puede haber.

La salida solo necesita ser una lista de algún tipo, ya sea una matriz, una cadena separada por comas, solo valores separados por espacios o algo completamente diferente, es decir

Pierce Brosnan, Sean Connery, David Niven

Se permite una nueva línea o espacio final.

Ejemplo de entrada y salida

Entrada:

1 Sean Connery

2 Emma Watson

5 Timothy Dalton

4 Roger Moore

3 Daniel Craig

Salida:

Timothy Dalton, Roger Moore, Daniel Craig, Sean Connery

Entrada:

2 Timothy Dalton

4 George Lazenby

5 George Lazenby

3 Bob Simmons

Salida:

George Lazenby, Bob Simmons, Timothy Dalton

Entrada:

3 Sean Connery

2 Pierce Brosnan

1 Sean Connery

Salida:

Pierce Brosnan, Sean Connery

Como se trata de un código de golf, ¡el código más corto (en bytes) gana!

Apéndice

Lista de actores que interpretaron el papel de Bond:

  • Barry Nelson
  • Bob Simmons
  • sean Connery
  • Roger Moore
  • David Niven
  • George Lazenby
  • Timothy Dalton
  • Pierce Brosnan
  • Daniel Craig
MKII
fuente
3
¡Bienvenido a PPCG, y buen desafío! Tenga en cuenta que Sean Connery aparece dos veces en su lista.
Denham Coote
@DenhamCoote Se corrigió eso y el error en el resultado del ejemplo.
MKII
2
¿Podemos suponer que todos los posibles actores serán identificados por dos palabras (nombre y apellido)?
Luis Mendo
17
Emma Watson fue genial como James Bond.
Alex A.
3
hmm mi respuesta es echo Sean Conneryporque todos lo saben, solo hay un vínculo
usuario902383

Respuestas:

2

Pyth, 136 132 bytes

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

Pruébalo aquí!

Explicación

_ {mtcd \ f} stcTdc "BarryNelson BobSimmons ..." dS.z # .z = lista de todas las líneas de entrada
                                             Sz # Ordenar entrada ascendente
        f # filtra las líneas ordenadas con T como la línea actual
            cTd # Divide una línea en espacios
          st # Dicard el número y unir nombre y apellido
               c "BarryNelson BobSimmons ..." d # Dividir la lista de actores de bonos en espacios ...
         } # solo mantiene las líneas que están en la lista de actores
   mtcd \ # elimina el número de las líneas filtradas
_ {# Eliminar duplicados del resultado del mapeo e invertir el resultado

Denker
fuente
Pequeño defecto, el orden es al revés (se supone que debe ir del último al primero, mientras que el suyo es el primero al último).
MKII
@MKII Supongo que leí demasiado esa parte ... ¡Lo arreglé!
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+ 

Pruébalo en línea!

¡6 bytes guardados gracias a Martin!

Whee, tipo burbuja con expresiones regulares. Tenga en cuenta que al principio se gastan diez bytes haciendo la conversión de decimal a unario, si la entrada unaria es correcta, entonces eso no es necesario. Además, si los números no pueden estar en los nombres de las personas, se pueden guardar un par de bytes más moviendo la línea que elimina a los actores que no pertenecen a Bond hasta el final y eliminando el 1+(no probado con la \Dversión).

Explicación:

Un programa de Retina se compone de varias etapas, por lo que explicaré cada etapa por separado.

Nivel 1:

\d+
$0$*1

Reemplaza los números en la entrada con unario. Utiliza el token de reemplazo especial de Retina: $*que repite el personaje después de varias veces igual al valor base 10 del token anterior.

Etapa 2:

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

Las cosas antes de un `en una etapa cambian el modo que se utiliza. Esto activa el modo grep, lo que significa que cada línea que no coincide con la expresión regular se descarta. Los anclajes son necesarios para evitar que se acerquen cerillas cercanas.

Etapa 3:

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

Esta es la etapa de clasificación. En +el modo significa que esta etapa debe repetirse hasta que el reemplazo no cambie cuando se aplica (es decir, llegamos a un punto fijo). La expresión regular encuentra un límite de palabras, seguido de un número de 1sy luego todo el resto de la línea hasta la nueva línea. Luego, si la siguiente línea tiene más 1s que ella, la expresión regular coincidirá y cambiaremos las líneas.

Etapa 4:

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

Esta etapa usa el +modo nuevamente, pero también usa spara hacer que el .meta-personaje también coincida con las nuevas líneas. Esto elimina las líneas duplicadas, haciendo coincidir los duplicados exactos después del 1s y capturando las cosas después del primer duplicado para reemplazar la coincidencia completa con él. Esto funcionará sin necesidad de considerar el orden de desempate, ya que los nombres ya están ordenados adecuadamente, con los números más grandes arriba, por lo tanto, siempre mantendremos los valores más pequeños.

Etapa 5:

1+ 

Una muy simple aquí, todo está en orden, excepto que tenemos un montón de 1s delante de nuestros Bonos, por lo que los reemplazamos y el espacio después de ellos con nada.

FryAmTheEggman
fuente
... Maldición, este lenguaje me impresiona cada vez más. ¡Bien hecho, Martin!
Financia la demanda de Mónica el
6

TSQL 426 bytes (incluye datos + entrada)

Solución de 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

Pruébalo aquí

SQL sobresale (sin juego de palabras) en este tipo de tarea: relacionar conjuntos, ordenar, cortar duplicados, etc.

Todo lo que necesitas es crear y completar una tabla de actores como esta:

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

Ahora, si usamos una variable de tabla como entrada, solo necesitamos obtener la intersección de ambos conjuntos. Eliminar duplicados y ordenar en SQL es realmente fácil.

Ejemplo 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

Ejemplo 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 versión de golf es lo más completo, por ejemplo, la entrada 3

Como ventaja, este SQL puede funcionar para versiones anteriores de DBMS (incluso reescribir en ANSI SQL) y ejecutarse sin problemas en computadoras más antiguas que la mayoría de los idiomas.

vaquero
fuente
¿Funciona con algún número al comienzo de la línea, o solo con un solo dígito?
MKII
1
@MKII Usé el tipo INT, así que no aceptaré nada en el rango –2,147,483,648 a 2,147,483,647 también aceptaré esa cantidad de filas también =)
jean
No necesita una subselección. Puede usarlo order by min(R) desccon la selección interna y eliminar la min(R)de la selección. Eso debería ahorrar 21 bytes.
raznagul
También hay algunos espacios innecesarios en la versión de golf.
raznagul
Usar en charlugar de varcharguardará otros 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]}<>;

Versión con mejor formato, con comentarios:

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 mayor parte del tamaño es la lista de Bonos; No puedo encontrar una buena manera de comprimir esa expresión regular sin permitir falsos positivos.

David Morris
fuente
Bienvenido a Programming Puzzles y Code Golf. Respuesta brillante, +1. Iba a sugerir que agregue una explicación, pero luego vi la edición. Tal vez sea posible comprimir la lista de actores de alguna manera ...
wizzwizz4
@ wizzwizz4 Intenté algunas cosas para hacer que la expresión regular sea más pequeña, pero la decodificación siempre parece costar más de lo que ahorras --- es demasiado escasa en lo que acepta.
David Morris
Lamentablemente, necesita trabajar con números, no solo dígitos individuales. Lo siento, pero usé el término incorrecto en la pregunta.
MKII
@MKII aww, eso me cuesta 38 bytes :(
David Morris
Si hay un evalen Perl y un sistema de compresión incorporado ...
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]

Manifestación:

>>> 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
fuente
Continuemos esta discusión en el chat .
Rɪᴋᴇʀ
Acabo de utilizar la comprensión del diccionario para preservar los nombres únicos, en lugar de la comprensión establecida.
Kasramvd
10
Pagaría por ver a Emma Watson como James Bond.
DJClayworth
¿Funciona con algún número al comienzo de la línea, o solo con un solo 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 de eso es solo la lista de actores ...

Toma información $argsy -splitla envía a nuevas líneas con `n. Canalice eso a sort, que ordenará las entradas numéricamente ascendentes, lo cual está bien por ahora. Los canalizamos a un bucle foreach |%{...}, cada iteración toma la entrada, -spliten espacios, luego -joinla segunda mitad de vuelta junto con un espacio (es decir, quitando los números del principio). Esos nombres ordenados (ascendentes) ahora se dejan en la tubería. Los canalizamos a través de un lugar donde ?eso garantiza que sean -inla lista aprobada de actores. Finalmente, selectsolo las -uentradas de nique, que para duplicados seleccionarán la primera que encuentre (es decir, la de menor ponderación) y descartaremos el resto. Almacenamos la matriz resultante de nombres en $a.

Entonces, ahora tenemos una lista ascendente ordenada de actores. Dado que el desafío requiere descender, hacemos una operación de reversión en el lugar $aal indexar de $a.countabajo a 0.

Ejemplo

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: no es necesario usar [array] :: Reverse () cuando la indexación servirá

AdmBorkBork
fuente
¿No puede simplemente usar en sort -Deslugar de la inversión de la matriz? De acuerdo, esto podría romperse en versiones posteriores de PowerShell, pero no creo que sea probable o un problema real;)
VisualMelon
@VisualMelon Lo había considerado, pero luego select -utomaría y retendría el orden de mayor valor , en lugar del más bajo, por lo que, por ejemplo, las posiciones de Daniel Craig y Roger Moore cambiarían. Mis intentos de arreglar eso resultaron en un código más largo que la inversión de la matriz.
AdmBorkBork
ah, sí, eso tiene sentido, no pude ejecutarlo y lo perdí por completo, es una pena que haya tantos desperdicios solo por esa inversión ...
VisualMelon
2

Pitón 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
fuente
¿Funciona con algún número al comienzo de la línea, o solo con un solo dígito?
MKII
no lo hizo, pero ahora sí :)
mtp
Parece que puede deshacerse de algunos espacios adicionales aquí, por ejemplo, después printo después de un )o]
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))

Explicación

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>

usuario81655
fuente