Karakter Teman mana yang benar-benar teman terbaik?

30

Keenam anggota pemeran utama sitkom Amerika Friends semuanya setuju bahwa mereka akan dibayar gaji yang sama sepanjang seri (setelah musim 2, setidaknya). Tetapi itu tidak berarti bahwa mereka semua memiliki jumlah waktu tayang yang sama atau bahwa mereka semua berinteraksi di layar dengan jumlah yang sama.

Dalam tantangan ini, Anda akan menulis sebuah program yang dapat membantu menentukan teman mana yang benar - benar teman terbaik.

Mendirikan

Pertimbangkan untuk menonton episode atau adegan Teman dan mencatat dengan tepat siapa yang ada di layar selama setiap pemotretan kamera dan untuk berapa lama.

Kami akan menyingkat nama setiap karakter:

Kemudian untuk setiap bidikan kamera (atau setiap kali karakter masuk / keluar dari bidikan), kami akan mencantumkan siapa yang ada di layar. Sebagai contoh:

504 CRS
200 J
345 MP
980
2000 CJMPRS

Ini mengatakan bahwa:

  • Untuk 504ms, Chandler, Rachel, dan Ross ada di layar.
  • Kemudian untuk 200 ms, Joey adalah.
  • Kemudian untuk 345 ms, Monica dan Phoebe berada.
  • Kemudian untuk 980ms, tidak ada 6 karakter utama yang ada di layar.
  • Kemudian selama 2 detik, semuanya.

(Ini bukan dari klip aktual, saya membuatnya.)

Perhatikan bahwa yang berikut ini akan setara:

504 CRS
1 J
199 J
345 MP
980
2000 CJMPRS

Untuk menganalisis kombinasi karakter mana yang memiliki waktu layar terbanyak, kami melihat semua 64 kemungkinan subset dari 6 karakter dan total waktu layar yang dimilikinya. Jika semua orang dalam subset muncul di layar selama pengambilan gambar kamera, bahkan jika ada lebih banyak karakter daripada yang ada dalam subset , waktu untuk pengambilan gambar kamera ditambahkan ke waktu layar total subset itu.

Ada pengecualian untuk subset kosong - hanya adegan dengan tidak ada dari 6 karakter utama yang dihitung.

Jadi analisis contoh di atas adalah:

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

Kita dapat melihat bahwa J(hanya Joey) memiliki 2200ms waktu layar karena ia memiliki 200 sendiri dan 2000 dengan semua orang.

Tantangan

Tulis program yang menggunakan string atau file teks seperti

504 CRS
200 J
345 MP
980
2000 CJMPRS

di mana setiap baris memiliki formulir [time in ms] [characters on screen], dan menampilkan jumlah total waktu yang masing-masing dari 64 himpunan bagian dari 6 karakter yang dihabiskan di layar, di mana setiap baris memiliki formulir [total time in ms for subset] [characters in subset](seperti di atas).

Input dapat diambil sebagai string ke stdin, baris perintah, atau fungsi, atau dapat berupa nama file teks yang berisi data.

  • Angka milidetik akan selalu berupa bilangan bulat positif.
  • Huruf karakter akan selalu berurutan CJMPRS(abjad).
  • Secara opsional Anda dapat mengasumsikan ada spasi tambahan ketika tidak ada karakter dalam adegan (mis 980 .).
  • Secara opsional Anda dapat mengasumsikan ada baris baru yang tertinggal.
  • Input akan memiliki setidaknya 1 baris dan mungkin memiliki banyak arbitrer.

Keluaran harus dicetak atau dikembalikan atau ditulis ke file teks lain sebagai string 64 baris.

  • Garis mungkin dalam urutan apa pun.
  • Huruf karakter tidak perlu dalam CJMPRSurutan.
  • Subset dengan 0ms total waktu yang perlu dicantumkan.
  • Secara opsional mungkin ada ruang tambahan setelah total bagian yang kosong.
  • Secara opsional mungkin ada baris tambahan.

(Masalah ini tentu saja dapat digeneralisasi ke lebih banyak karakter, tetapi kami akan tetap menggunakan 6 karakter CJMPRS Teman .)

Kode terpendek dalam byte menang.

Perhatikan bahwa saya benar-benar menikmati Teman dan tidak berpikir beberapa karakter lebih penting daripada yang lain. Statistiknya akan menarik. ;)

Hobi Calvin
sumber
7
Apakah kita mendapatkan hadiah jika kita memposting analisis seri? ;)
Beta Decay
5
Saya mungkin atau mungkin tidak pernah melihat setiap episode puluhan kali dan memiliki semua 10 musim ...
Alex A.
@AlexA. Saya mungkin atau mungkin tidak tahu apa yang Anda bicarakan ...
bolov
Set kosong adalah kasus khusus - itu tidak mematuhi aturan "bahkan jika ada lebih banyak karakter daripada yang ada di subset", atau jika tidak maka akan mencetak 4029 dalam contoh (jumlah total waktu yang setidaknya tidak ada satu ada di layar), dan bukan 980.
hobbs
1
@ BetaDecay Sangat mungkin, sebenarnya!
Hobi Calvin

Jawaban:

10

Pyth, 37 byte

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

Cobalah online: Demonstrasi

Penjelasan:

  "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
Jakube
sumber
Ini bahkan tidak layak untuk dicoba ketika saya menulis satu baris dari solusi saya dan itu sudah lebih panjang daripada seluruh jawaban Pyth :-P
hobbs
4
@ hobbs Itulah kelemahan dari kompetisi bahasa campuran. Tapi jangan diintimidasi, solusi dalam bahasa lain biasanya menerima lebih banyak suara. Lihat saja Solusi Haskell.
Jakube
3
36% lebih pendek dan membuat saya sadar bahwa saya memiliki bug dalam kode saya ...
Dennis
Sangat disayangkan cMmenggunakan .*ekspansi peta. Mungkin pengecualian harus dibuat karena csaya tidak bisa membayangkan seseorang ingin menggunakannya seperti itu di peta
FryAmTheEggman
Ini memberi 0 pada baris teratas dalam contoh output bukan 980.
Calvin's Hobbies
13

Haskell, 187 byte

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]

fadalah fungsi yang mengambil input, sebagai string multi-line tunggal, dan mengembalikan output multi-line sebagai string tunggal. Mungkin banyak yang tersisa untuk bermain golf di sini.

λ: 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
MtnViewMark
sumber
7

SWI-Prolog, 381 byte

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

Ini diharapkan dijalankan sebagai:

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

Perhatikan bahwa Anda mungkin perlu mengganti setiap `ke "dan setiap "ke 'jika Anda memiliki versi lama dari SWI-Prolog.

Saya bisa memotong 100+ byte jika saya tidak harus menggunakan String sebagai input.

Fatalisasi
sumber
7

Haskell, 150 136 byte

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"

Contoh penggunaan:

*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

Pendekatan berbeda dari jawaban @ MtnViewMark : Untuk semua kombinasi ckarakter, temukan garis-garis string input di mana perbedaan cdan daftar dari garis-garis ykosong ( urus kasus khusus di mana tidak ada karakter di layar (mis. 980) -> ctidak boleh kosong atau c == y). Ekstrak angka dan jumlah.

nimi
sumber
6

CJam, 67 58 byte

"CJMPRS"6m*_.&:$_&qN/_{_el=},:~1bpf{{1$\-!},Sf/0f=:i1bS\N}

Cobalah online di juru bahasa CJam .

Dennis
sumber
2

Perl 5 (5.10+), 128 byte

2 byte per baris output. use feature "say"tidak termasuk dalam jumlah byte.

@_=<>;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}

Tidak golf:

# 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;
}
hobbs
sumber
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"}

Mengambil string seperti "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"
tmartin
sumber