Quais personagens de Friends eram realmente os melhores amigos?


30

Os seis principais membros do elenco da American comédia Amigos todos concordaram que seria pago o mesmo salário durante todo o prazo da série (após 2 ª temporada, pelo menos). Mas isso não significa que todos tiveram a mesma quantidade de tempo no ar ou que todos interagiram na tela uns com os outros a mesma quantidade.

Neste desafio, você escreverá um programa que poderá ajudar a determinar quais amigos de Friends são realmente os melhores.

Configuração

Considere assistir a um episódio ou cena de Friends e anotar exatamente quem está na tela durante cada foto da câmera e por quanto tempo.

Abreviaremos o nome de cada personagem:

Então, para cada foto da câmera (ou toda vez que um personagem entra / sai da foto), listamos quem estava na tela. Por exemplo:

504 CRS
200 J
345 MP
980
2000 CJMPRS

Isto está dizendo que:

  • Por 504ms, Chandler, Rachel e Ross estavam na tela.
  • Por 200ms, Joey estava.
  • Depois, por 345ms, Monica e Phoebe foram.
  • Depois, por 980ms, nenhum dos 6 personagens principais estava na tela.
  • Então, por 2 segundos, todos eles foram.

(Não é de um clipe real, eu inventei.)

Observe que o seguinte seria equivalente:

504 CRS
1 J
199 J
345 MP
980
2000 CJMPRS

Para analisar quais combinações de caracteres tiveram mais tempo de tela, analisamos todos os 64 subconjuntos possíveis dos 6 caracteres e totalizamos o tempo de tela que eles tiveram. Se todos os membros de um subconjunto aparecerem na tela durante uma captura de câmera, mesmo que haja mais caracteres do que apenas aqueles no subconjunto , o tempo para a captura da câmera será adicionado ao tempo total de tela desse subconjunto.

Há uma exceção para o subconjunto vazio - apenas as cenas com nenhum dos 6 personagens principais são contadas.

Portanto, a análise do exemplo acima seria:

980
2504 C
2200 J
2345 M
2345 P
2504 R
2504 S
2000 CJ
2000 CM
2000 CP
2504 CR
2504 CS
2000 JM
2000 JP
2000 JR
2000 JS
2345 MP
2000 MR
2000 MS
2000 PR
2000 PS
2504 RS
2000 CJM
2000 CJP
2000 CJR
2000 CJS
2000 CMP
2000 CMR
2000 CMS
2000 CPR
2000 CPS
2504 CRS
2000 JMP
2000 JMR
2000 JMS
2000 JPR
2000 JPS
2000 JRS
2000 MPR
2000 MPS
2000 MRS
2000 PRS
2000 CJMP
2000 CJMR
2000 CJMS
2000 CJPR
2000 CJPS
2000 CJRS
2000 CMPR
2000 CMPS
2000 CMRS
2000 CPRS
2000 JMPR
2000 JMPS
2000 JMRS
2000 JPRS
2000 MPRS
2000 CJMPR
2000 CJMPS
2000 CJMRS
2000 CJPRS
2000 CMPRS
2000 JMPRS
2000 CJMPRS

Podemos ver que J(apenas Joey) tinha 2200ms de tempo de tela porque ele tinha 200 sozinho e 2000 com todo mundo.

Desafio

Escreva um programa que inclua uma string ou arquivo de texto, como

504 CRS
200 J
345 MP
980
2000 CJMPRS

onde cada linha tem a forma [time in ms] [characters on screen]e gera a quantidade total de tempo que cada um dos 64 subconjuntos dos 6 caracteres passou na tela, onde cada linha tem a forma [total time in ms for subset] [characters in subset](exatamente como acima).

A entrada pode ser tomada como uma sequência de caracteres para stdin, a linha de comandos ou uma função, ou pode ser o nome de um arquivo de texto que contém os dados.

  • Os números de milissegundos serão sempre números inteiros positivos.
  • As letras dos caracteres sempre estarão na ordem CJMPRS(alfabética).
  • Opcionalmente, você pode assumir que há um espaço à direita quando não há personagens na cena (por exemplo 980 ).
  • Opcionalmente, você pode assumir que há uma nova linha à direita.
  • A entrada terá pelo menos 1 linha e pode ter várias arbitrariamente.

A saída deve ser impressa ou retornada ou gravada em outro arquivo de texto como uma seqüência de 64 linhas.

  • As linhas podem estar em qualquer ordem.
  • As letras dos caracteres não precisam estar na CJMPRSordem.
  • Subconjuntos com 0ms tempo total que precisa ser listado.
  • Opcionalmente, pode haver um espaço à direita após o total vazio do subconjunto.
  • Opcionalmente, pode haver uma nova linha à direita.

(É claro que esse problema pode ser generalizado para mais caracteres, mas continuaremos com os 6 CJMPRS amigos ).

O código mais curto em bytes vence.

Note que eu realmente gosto de Friends e não acho que alguns personagens sejam mais importantes que os outros. As estatísticas seriam interessantes. ;)


7
Recebemos uma recompensa se publicarmos uma análise da série? ;)
Decay Beta 07/07

5
I pode ou não ter visto a cada dezenas de episódios de vezes e possuir todas as 10 temporadas ...
Alex A.

@AlexA. I pode ou não sabe o que está falando ...
bolov

O conjunto vazio é um caso especial - ele não obedece à regra "mesmo que haja mais caracteres do que apenas os do subconjunto", ou então seria 4029 no exemplo (a quantidade total de tempo que pelo menos não um está na tela), e não o 980.
hobbs 07/07

1
@BetaDecay Muito possivelmente, na verdade!
Calvin's Hobbies

Respostas:


10

Pitão, 37 bytes

Vy"CJMPRS"++smvhdf?q@eTNNN!eTcR\ .zdN

Experimente online: Demonstração

Explicação:

  "CJMPRS"                             string with all friends
 y                                     create all subsets
V                                      for loop, N iterates over ^:
                                 .z      all input lines
                             cR\         split each line at spaces
                 f                       filter for lines T, which satisfy:
                  ?      N                 if N != "":
                   q@eTNN                    intersection(T[1],N) == N
                                           else:
                          !eT                T[1] == ""
             m                           map each of the remaining d to:
              vhd                          eval(d[0]) (extract times)
            s                            sum
           +                       d     + " "
          +                         N    + N
                                         implicitly print

É quase nem vale a pena tentar quando eu escrever uma linha de minha solução e já mais do que toda a resposta :-P Pyth é
hobbs

4
@ Hobbs Essa é a desvantagem das competições de idiomas mistos. Mas não se deixe intimidar, as soluções em outros idiomas geralmente recebem mais votos. Basta olhar para a solução Haskell.
Jakube 07/07

3
36% mais curto e me fez perceber que eu tinha um bug no meu código ...
Dennis

É bastante lamentável que cMuse a .*expansão do mapa. Talvez uma exceção deve ser feita para cque eu não posso imaginar alguém querendo usá-lo como que em um mapa
FryAmTheEggman

Isso dá a 0 na primeira linha no exemplo de saída em vez de 980.
de Calvino Hobbies

13

Haskell, 187 bytes

f=g.(>>=(q.words)).lines
g t=p"CJMPRS">>=(\k->show(sum.map snd$filter((==k).fst)t)++' ':k++"\n")
q[n]=[("",read n)]
q[n,s]=[(k,read n)|k<-tail$p s]
p s=map concat$sequence[[[],[c]]|c<-s]

fé uma função que recebe a entrada, como uma única sequência de múltiplas linhas, e retorna a saída de várias linhas como uma única sequência. Provavelmente ainda resta muito para jogar golfe.

λ: putStr test1
504 CRS
1 J
199 J
345 MP
980
2000 CJMPRS

λ: putStr $ f test1
980 
2504 S
2504 R
2504 RS
2345 P
2000 PS
2000 PR
2000 PRS
2345 M
2000 MS
2000 MR
2000 MRS
2345 MP
2000 MPS
2000 MPR
2000 MPRS
2200 J
2000 JS
2000 JR
2000 JRS
2000 JP
2000 JPS
2000 JPR
2000 JPRS
2000 JM
2000 JMS
2000 JMR
2000 JMRS
2000 JMP
2000 JMPS
2000 JMPR
2000 JMPRS
2504 C
2504 CS
2504 CR
2504 CRS
2000 CP
2000 CPS
2000 CPR
2000 CPRS
2000 CM
2000 CMS
2000 CMR
2000 CMRS
2000 CMP
2000 CMPS
2000 CMPR
2000 CMPRS
2000 CJ
2000 CJS
2000 CJR
2000 CJRS
2000 CJP
2000 CJPS
2000 CJPR
2000 CJPRS
2000 CJM
2000 CJMS
2000 CJMR
2000 CJMRS
2000 CJMP
2000 CJMPS
2000 CJMPR
2000 CJMPRS

7

SWI-Prolog, 381 bytes

s([E|T],[F|N]):-E=F,(N=[];s(T,N));s(T,[F|N]).
a(A):-split_string(A," \n","",B),w(B,[],C),setof(L,s(`CJMPRS`,L),M),x(C,[` `|M]).
w([A,B|T],R,Z):-number_string(N,A),(B="",C=` `;string_codes(B,C)),X=[[N,C]|R],(T=[],Z=X;w(T,X,Z)).
x(A,[M|T]):-y(M,A,0,R),atom_codes(S,M),writef("%t %w\n",[R,S]),(T=[];x(A,T)).
y(_,[],R,R).
y(M,[[A,B]|T],R,Z):-subset(M,B),S is R+A,y(M,T,S,Z);y(M,T,R,Z).

Isso espera ser executado como:

a("504 CRS
200 J
345 MP
980 
2000 CJMPRS").

Note-se que pode ser necessário substituir cada `para "e cada "para 'se você tem uma versão antiga do SWI-Prolog.

Eu poderia cortar mais de 100 bytes se não tivesse que usar uma String como entrada.


7

Haskell, 150 136 bytes

import Data.List
f=(subsequences"CJMPRS">>=).g
g l c=show(sum[read x|(x,y)<-map(span(/=' '))$lines l,c\\y==[],c/=[]||c==y])++' ':c++"\n"

Exemplo de uso:

*Main> putStr $ f "504 CRS\n1 J\n199 J\n345 MP\n980\n2000 CJMPRS"
980 
2504 C
2200 J
2000 CJ
2345 M
2000 CM
2000 JM
2000 CJM
2345 P
2000 CP
2000 JP
2000 CJP
2345 MP
2000 CMP
2000 JMP
2000 CJMP
2504 R
2504 CR
2000 JR
2000 CJR
2000 MR
2000 CMR
2000 JMR
2000 CJMR
2000 PR
2000 CPR
2000 JPR
2000 CJPR
2000 MPR
2000 CMPR
2000 JMPR
2000 CJMPR
2504 S
2504 CS
2000 JS
2000 CJS
2000 MS
2000 CMS
2000 JMS
2000 CJMS
2000 PS
2000 CPS
2000 JPS
2000 CJPS
2000 MPS
2000 CMPS
2000 JMPS
2000 CJMPS
2504 RS
2504 CRS
2000 JRS
2000 CJRS
2000 MRS
2000 CMRS
2000 JMRS
2000 CJMRS
2000 PRS
2000 CPRS
2000 JPRS
2000 CJPRS
2000 MPRS
2000 CMPRS
2000 JMPRS
2000 CJMPRS

Abordagem diferente da resposta do @ MtnViewMark : para todas as combinações cde caracteres, encontre as linhas da sequência de entrada em que a diferença ce a lista das linhas yestão vazias (cuide do caso especial em que nenhum caractere está na tela (por exemplo 980) -> cnão deve estar vazio ou c == y). Extraia o número e a soma.



2

Perl 5 (5.10+), 128 bytes

2 bytes por linha de saída. use feature "say"não incluído na contagem de bytes.

@_=<>;for$i(0..63){@c=qw(C J M P R S)[grep$i&(1<<$_),0..5];
$r=@c?join".*","",@c:'$';$t=0;for(@_){$t+=$1 if/(.*) $r/}say"$t ",@c}

Sem golfe:

# Read the input into an array of lines.
my @lines = <>;
# For every 6-bit number:
for my $i (0 .. 63) {
    # Select the elements of the list that correspond to 1-bits in $i
    my @indices = grep { $i & (1 << $_) } 0 .. 5;
    my @characters = ('C', 'J', 'M', 'P', 'R', 'S')[@indices];

    # Build a regex that matches a string that contains all of @characters
    # in order... unless @characters is empty, then build a regex that matches
    # end-of-line.
    my $regex = @characters
      ? join ".*", ("", @c)
      : '$';

    my $time = 0;
    # For each line in the input...
    for my $line (@lines) {
        # If it contains the requisite characters...
        if ($line =~ /(.*) $regex/) {
            # Add to the time total
            $time += $1;
        }
    }

    # And print the subset and the total time.
    say "$time ", @characters;
}

2

K, 95

{(+/'{x[1]@&min'y in/:*x}[|"I \n"0:x]'b)!b:" ",?,/{x{,/y{x,/:y@&y>max x}\:x}[d]/d:"CJMPRS"}

Toma uma string como "504 CRS\n200 J\n345 MP\n980 \n2000 CJMPRS"

k){(+/'{x[1]@&min'y in/:*x}[|"I \n"0:x]'b)!b:" ",?,/{x{,/y{x,/:y@&y>max x}\:x}[d]/d:"CJMPRS"}["504 CRS\n200 J\n345 MP\n980  \n2000 CJMPRS"]
980 | " "
2504| "C"
2200| "J"
2345| "M"
2345| "P"
2504| "R"
2504| "S"
2000| "CJ"
2000| "CM"
2000| "CP"
2504| "CR"
2504| "CS"
2000| "JM"
2000| "JP"
2000| "JR"
2000| "JS"
2345| "MP"
2000| "MR"
2000| "MS"
2000| "PR"
2000| "PS"
2504| "RS"
2000| "CJM"
2000| "CJP"
2000| "CJR"
2000| "CJS"
2000| "CMP"
2000| "CMR"
2000| "CMS"
2000| "CPR"
2000| "CPS"
2504| "CRS"
2000| "JMP"
2000| "JMR"
2000| "JMS"
2000| "JPR"
2000| "JPS"
2000| "JRS"
2000| "MPR"
2000| "MPS"
2000| "MRS"
2000| "PRS"
2000| "CJMP"
2000| "CJMR"
2000| "CJMS"
2000| "CJPR"
2000| "CJPS"
2000| "CJRS"
2000| "CMPR"
2000| "CMPS"
2000| "CMRS"
2000| "CPRS"
2000| "JMPR"
2000| "JMPS"
2000| "JMRS"
2000| "JPRS"
2000| "MPRS"
2000| "CJMPR"
2000| "CJMPS"
2000| "CJMRS"
2000| "CJPRS"
2000| "CMPRS"
2000| "JMPRS"
2000| "CJMPRS"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.