Czy pizza jest uczciwa?

27

To pytanie jest inspirowane i jest odwrotnością tego .

Dennis ( E), Doorknob ( D), Martin ( M) i Chris ( C) zamówili pizzę. Prostokątna pizza jest podzielona na kwadratowe kawałki, z których każdy jest oznaczony odpowiednim jedzeniem.

Napisz program lub funkcję, która podając prostokątną pizzę składającą się z 0 lub więcej każdej litery określa, czy:

  1. Każdy plasterek dla każdej osoby jest powiązany ze ścieżką . Oznacza to, że wszystkie litery, które są takie same, powinny bezpośrednio przylegać do siebie (brak przekątnych połączeń).

  2. Liczba plasterków na osobę jest taka sama dla wszystkich.

Musisz podać wartość prawda / fałsz z opcjonalnym znakiem nowej linii, który wskazuje, czy dana pizza jest uczciwa.

Prawidłowe przypadki testowe:

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

Nieprawidłowe przypadki testowe:

EDM
EDMCCMDE
DDDDDDDDDDDDMCCCCCCCCCCC
DEEEEEEEEEEDMMMMMMMCCCCC
DEEEEEEEEEEMDMMCCCCCCCCC
DEEEEEEEEEEDMMMMMMMMCCCC
DDDDDDDDDDDDMMMMMMMMMMMC
DDMMEECC
DMMEECCC

Najkrótszy kod w bajtach wygrywa.

orlp
źródło
1. Jakie formy wprowadzania danych są akceptowane przez funkcję? ciąg z nowymi liniami? tablica z jednym ciągiem dla każdej linii? Tablica 2D? Wszystkie powyższe? 2. Rozumiem, że dane wyjściowe są zgodne z prawdą, a fałsz - z nieuczciwymi, czy też można je odwrócić?
Level River St
52
Prawidłowe przypadki testowe: DDDDDDDDDDDDD<- uczciwa pizza
Klamka
@steveverrill Do tego wyzwania dopuszczalny jest tylko ciąg znaków z nowymi liniami. Musisz zwrócić prawdę za uczciwe, a fałsz za niesprawiedliwe.
orlp
Oprócz nowych linii, tylko CDEM na wejściu?
edc65
@ edc65 Prawidłowo.
orlp

Odpowiedzi:

5

Pyth, 53 bajty

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

Demonstracja

Jest to zasadniczo wypełnienie zalewowe dla każdej litery, a następnie sprawdzenie, czy wszystkie wynikowe zestawy mają odpowiedni rozmiar.

Aby wypełnić obszar zalewowy, zaczyna się od wystąpienia lewej górnej litery każdej litery, a następnie generuje wszystkich sąsiadów znalezionych dotychczas lokalizacji, filtruje lokalizacje z właściwą literą i powtarza, aż zestaw przestanie się zmieniać.

isaacg
źródło
6

Ślimaki , 129

Drukuje 1 za uczciwą pizzę i 0 za nieuczciwą pizzę.

&
={(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,~},~

Wersja rozszerzona:

&
={ (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,~)}, ~

&oznacza, że ​​wzór musi pasować do wszystkich lokalizacji na siatce. Pierwszy wiersz sprawdza równą liczbę każdego z E, D, M, C. używa instrukcji teleportacji t, która jest doskonałym sposobem na tworzenie programów o złożoności czynnikowej. Jeśli wejście ma nierówne plasterki z kilkoma jednostkami dla każdego z 4 modów, program zawiesi się mniej więcej na zawsze. Następnie sprawdzana jest ciągła ścieżka do lewego górnego wystąpienia dowolnej litery, od której wzorzec się zaczął.

feersum
źródło
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*=

Wypróbuj online

Jest to absurdalnie długie, ponieważ CJam (jeszcze) nie ma wbudowanego wypełniania zalewania ani wyszukiwania związków. Zaimplementowałem program find-union .

Wyjaśnienie:

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
źródło
4

JavaScript (ES6), 153 166

Używając ciągów szablonów, nowa linia jest znacząca i liczona

Przetestuj uruchomienie fragmentu kodu w 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
źródło
2

JavaScript ES6, 360

Sprawdza równą liczbę C, D, E, M, a następnie wypełnia zalanie i sprawdza wszelkie osierocone litery. Nie jestem zwycięzcą, ale musiałem spróbować.

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

Skrzypce

DankMemes
źródło
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))

Wyjaśnienie:

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
źródło
1
Interesujący kod (pokonałeś mój!) Sugestia: użyj funkcji strzałek es6 (jak w mojej odpowiedzi), aby zapisać kilka bajtów. Afaik, nie musisz przypisywać go do zmiennej, używając prostej deklaracji funkcji, np. l=>{...}Jest w porządku.
DankMemes
2
Usuń także nawiasy, k=(o)=>aby zaoszczędzić jeszcze 2 bajty. Funkcje strzałek z jednym parametrem nie wymagają nawiasów.
DankMemes