Apakah pizza itu adil?

27

Pertanyaan ini diinspirasi oleh, dan merupakan kebalikan dari yang ini .

Dennis ( E), Doorknob ( D), Martin ( M) dan Chris ( C) telah memesan pizza. Pizza persegi panjang dibagi menjadi potongan-potongan persegi, masing-masing ditandai dengan pemakan yang dituju.

Tulis program atau fungsi yang diberi pizza persegi panjang yang terdiri dari 0 atau lebih dari setiap huruf menentukan apakah:

  1. Setiap irisan untuk setiap orang terhubung dengan jalur . Ini berarti bahwa semua huruf yang sama harus berbatasan langsung dengan satu sama lain (tidak ada koneksi diagonal).

  2. Jumlah irisan per orang adalah sama untuk semua.

Anda harus menampilkan nilai true / falsy dengan baris tambahan opsional yang menunjukkan apakah pizza yang diberikan itu adil atau tidak.

Testis yang valid:

DDDDDDDDDDDDMCCCCCCCCCCC
DEEEEEEEEEEDMMMMMMMCCCCC
DEEEEEEEEEEDMMMCCCCCCCCC
DEEEEEEEEEEDMMMMMMMMCCCC
DDDDDDDDDDDDMMMMMMMMMMMC
DEMC
DD
EE
MC
MC
EEDDMMMCCC
EEEDDDMMCC

Testis tidak valid:

EDM
EDMCCMDE
DDDDDDDDDDDDMCCCCCCCCCCC
DEEEEEEEEEEDMMMMMMMCCCCC
DEEEEEEEEEEMDMMCCCCCCCCC
DEEEEEEEEEEDMMMMMMMMCCCC
DDDDDDDDDDDDMMMMMMMMMMMC
DDMMEECC
DMMEECCC

Kode terpendek dalam byte menang.

orlp
sumber
1. Apa bentuk input yang dapat diterima oleh suatu fungsi? string dengan baris baru? array dengan satu string untuk setiap baris? Array karakter 2D? Semua yang di atas? 2. Saya mengerti bahwa hasil adalah benar untuk adil, palsu untuk tidak adil, atau dapatkah mereka dibalik?
Level River St
52
Kasing uji yang valid: DDDDDDDDDDDDD<- pizza yang adil
Gagang Pintu
@steveverrill Untuk tantangan ini, hanya string dengan baris baru yang dapat diterima. Anda harus mengembalikan kebenaran untuk adil, dan palsu untuk tidak adil.
orlp
Selain baris baru, hanya input CDEM?
edc65
@ edc65 Benar.
orlp

Jawaban:

5

Pyth, 53 byte

!f-lJs.z*4lu&G{smfqT@JY@UJ+Ld[Z1_1Klh.z_K)G]xJT)"CDEM

Demonstrasi

Ini pada dasarnya adalah pengisian banjir untuk setiap huruf, diikuti oleh cek bahwa semua set yang dihasilkan berukuran sesuai.

Untuk mengisi banjir, ini dimulai dengan kemunculan paling kiri atas setiap huruf, kemudian menghasilkan semua tetangga lokasi yang ditemukan sejauh ini, menyaring lokasi dengan huruf yang tepat, dan mengulangi sampai set berhenti berubah.

isaacg
sumber
6

Siput , 129

Mencetak 1 untuk pizza yang adil dan 0 untuk pizza yang tidak adil.

&
={(t\Dt\Et\Ct\M),!(t.}{(o\D)+l^D,=~u{^D=(r^D,~},~|o\E`+l^E,=~u{^E=(r^E,~},~|o\C`+l^C,=~u{^C=(r^C,~},~|o\M`+l^M,=~u{^M=(r^M,~},~

Versi yang diperluas:

&
={ (t\Dt\Et\Ct\M), !(t.)}   {
(o\D)+ l^D,=~ u{^D=(r^D,~)}, ~ |
(o\E)+ l^E,=~ u{^E=(r^E,~)}, ~ |
(o\C)+ l^C,=~ u{^C=(r^C,~)}, ~ |
(o\M)+ l^M,=~ u{^M=(r^M,~)}, ~

&berarti bahwa polanya harus cocok di semua lokasi di grid. Baris pertama memeriksa jumlah E, D, M, C. yang sama, menggunakan instruksi teleport t, yang merupakan cara terbaik untuk membuat program dengan kompleksitas faktorial. Jika input memiliki irisan berukuran tidak sama dengan beberapa unit untuk masing-masing dari 4 mod, program akan lebih atau kurang menggantung selamanya. Setelah itu, ada tanda centang untuk jalan yang berdekatan ke contoh kiri atas dari mana huruf dimulai pola.

feersum
sumber
6

CJam, 93

qN/_z,:W;s:A,,:B_{{{_B=_@-}g}%$}:F;{a+_Af=)#{F~B\@t:B}|;}:U;W>{_W-U}/{W%},{_(U}/BFe`0f=_1<4*=

Cobalah online

Ini sangat lama karena CJam (belum) memiliki built-in fill banjir atau union-find. Saya menerapkan pencarian serikat dalam program ini.

Penjelasan:

qN/_         read input, split into lines and duplicate
z,:W;        transpose, get length (original width) and store in W
s:A          convert to string (without newlines) and store in A
,,           make an array [0..n-1] (n = pizza size)
:B_          store in B (initial structure) and duplicate (will be used in 2 loops)
{…}:F;       define function F ("Find" for multiple indices and sort)
  {…}%       for each value (x)
    {…}g     do…while
      _B=    duplicate x and get B[x]
      _@-    leave a B[x] on the stack and calculate B[x] - x
              if non-zero, repeat the loop with B[x]
  $          sort the results
{…}:U;       define function U ("Union" for 2 indices)
  a+         make an array of the 2 indices
  _Af=       get the corresponding letters from A
  )#         check if the letters are different
  {…}|       if not, execute…
    F~       call F on the array and dump the 2 results on the stack
    B\@t     join the sets - B[bigger index] = smaller index
    :B       store back in B
  ;          pop the last value (either array if indices or B)
W>           remove the first row of indices
{…}/         for each index
  _W-        duplicate and subtract W ("go up")
  U          call U to join sets if they match
{W%},        remove the first column of indices
{…}/         for each index
  _(         duplicate and decrement ("go left")
  U          call U to join sets if they match
BF           call F on B, to get the final sets and sort
e`           RLE encoding
0f=          keep only the repetition counts
_1<4*=       check if it's the first value (if any) repeated 4 times
aditsu
sumber
4

JavaScript (ES6), 153 166

Menggunakan string template, ada baris baru yang signifikan dan dihitung

Tes menjalankan cuplikan di FireFox.

f=z=>![...'CDEM'].some(c=>((l=p=>z[p]==c&&[-1,1,w,-w].map(o=>l(p+o),z[p]='',++k))(z.indexOf(c),h=k,k=0),~h&&h-k),w=~z.search`
`,z=[...z],k=-1)&z.join``-1

// Ungolfed
U=z=>{
  w = ~z.search`\n`
  z = [...z]
  fill = p=>(
    c = z[p],
    z[p] = '',
    [-1,1,w,-w].forEach(o=>z[o+=p] == c && fill(o)),
    ++k
  )
  h = -1
  r = ['C','D','E','M'].every( c =>(
    k = 0,
    y = z.indexOf(c),
    y >= 0 && fill(y),
    v = h >= 0 ? h == k : true,
    h = k,
    v
  ))
  return r & 1-z.join``
}  

// Test
out=x=>O.innerHTML+=x+'\n';

// Valid test cases
valid=[`DDDDDDDDDDDDMCCCCCCCCCCC
DEEEEEEEEEEDMMMMMMMCCCCC
DEEEEEEEEEEDMMMCCCCCCCCC
DEEEEEEEEEEDMMMMMMMMCCCC
DDDDDDDDDDDDMMMMMMMMMMMC`,
`DEMC`,
`DD
EE
MC
MC`,
`EEDDMMMCCC
EEEDDDMMCC`];
out('Valid')
valid.forEach(t=>out(t+'\n'+f(t)+'\n'));
invalid=[`EDM`,
`EDMCCMDE`,
`DDDDDDDDDDDDDD`,         
`DDDDDDDDDDDDMCCCCCCCCCCC
DEEEEEEEEEEDMMMMMMMCCCCC
DEEEEEEEEEEMDMMCCCCCCCCC
DEEEEEEEEEEDMMMMMMMMCCCC
DDDDDDDDDDDDMMMMMMMMMMMC`,
`DDMMEECC
DMMEECCC`
];
out('Invalid')
invalid.forEach(t=>out(t+'\n'+f(t)+'\n'))
<pre id=O></pre>

edc65
sumber
2

Javascript ES6, 360

Memeriksa jumlah C, D, E, M yang sama, lalu mengisi banjir dan memeriksa surat-surat yatim. Bukan pemenang, tetapi saya harus mencoba.

i=>(I=i.split`
`.map(e=>e.split``),c=(i[m='match'](/C/g)||[])[l='length'],a=(x,y,z)=>{if(I[x][y]!=z)return;I[x][y]=0;x>0&&a(x-1,y,z);x<I[l]-1&&a(x+1,y,z);y>0&&a(x,y-1,z);y<I[0][l]-1&&a(x,y+1,z)},![...'CDEM'].some(k=>{if((i[m](eval(`/${k}/g`))||[])[l]!=c)return 1;I.some((w,x)=>(g=-1<(y=w.indexOf(k)),g&&a(x,y,k),g));})&&!I.map(e=>e.join``).join``[m](/[CDEM]/))

Biola

DankMemes
sumber
2

JavaScript ES6, 328 318 316 269 178

l=>(d=[0,0,0,0],s=[...l.split`
`.join``].map(i=>(d["EDMC".search(i)]++,i)),!l||d.every(i=>i==d[0])&&(s.every((r,i)=>[1,-1,X=l.split`
`[0].length,-X].some(o=>s[o+i]==r))||d[0]<2))

Penjelasan:

l => (
  d = [0,0,0,0],          // array containing each letter count
  s = [...l.split`                    
`.join``]                 // removes newlines from input and converts it into array
  .map(i => (             // loops through the array
    d["EDMC".search(i)]++ // increases letter count
    ,i)),                 // returns unchanged value in order to preserve original array
  !l                      // input is empty
  || d.every(i=>i==d[0])  // each letter count is equal
  && (
    s.every((r, i) =>     // there is no orphaned letters 
      [1,-1,X=l.split`
`[0].length,-X]           // letters on respectively: right, left, bottom, top
      .some               // at least one of them
        (o=>s[o+i]==r))   // equals original letter
    || d[0] < 2           // count of each letter equals 1
  )
)
Michał Perłakowski
sumber
1
Kode yang menarik (Anda mengalahkan milik saya!) Saran: gunakan fungsi panah ES6 (seperti dalam jawaban saya) untuk menyimpan beberapa byte. Afaik Anda tidak perlu menetapkannya ke variabel, menggunakan deklarasi fungsi sederhana misalnya l=>{...}baik-baik saja
DankMemes
2
Hapus juga tanda kurung k=(o)=>untuk menghemat 2 byte lagi. Fungsi tanda panah parameter tunggal tidak perlu tanda kurung.
DankMemes