Pentomino Validator

9

Jako ktoś, komu nie przeszkadza, aby spojrzeć na swoje pentominos i sprawdzić, czy ma kształt prostokątny, postanowiłem napisać program, który to robi.

Twoje zadanie

Biorąc pod uwagę część danych wejściowych podzielonych na nowe wiersze zawierające 12 unikalnych znaków, zdecyduj, czy jest to prawidłowe rozwiązanie.

Prawidłowe rozwiązanie MUSI

  • Posiadaj 5 każdego znaku (z wyjątkiem nowych linii)
  • Każdy zestaw znaków musi być w pełni połączony
  • Każdy zestaw znaków musi mieć unikalny kształt
  • Mają regularny prostokątny kształt

Jeśli jest to poprawne rozwiązanie, wypisz prawdziwą wartość, w przeciwnym razie wypisz wartość fałsz.

Twój program może być funkcją lub pełnym programem, ale musi pobierać dane wejściowe ze standardowego wejścia i wyjściowe na standardowe wyjście.

Przypadki testowe

Prawidłowe rozwiązania

000111
203331
203431
22 444
2   46
57 666
57769!
58779!
58899!
5889!!

00.@@@ccccF111//=---
0...@@c))FFF1//8===-
00.ttttt)))F1/8888=-

Niepoprawne konfiguracje

invalid (doesn't contain 12 unique characters)

111112222233333444445555566666
77777888889999900000qqqqqwwwww (Each set has the same shape)

1234567890qw
w1234567890q
qw1234567890
0qw123456789
90qw12345678 (None of the characters are connected)

1234567890qw (Not 5 characters in every set)

1111122222333334444455555666666
77777888889999900000qqqqqwwwwww (More than 5 characters in some sets)

00
0                   
00.@@@ccccF111//=---
 ...@@c))FFF1//8===-
  .ttttt)))F1/8888=- (Doesn't form a rectangular shape)
niebieski
źródło
1. Czy odbicie pentomina ma taki sam kształt jak oryginał? 2. Czy możemy założyć, że dane wejściowe będą się składały z drukowalnych znaków ASCII i znaków nowej linii?
Dennis
@Dennis Yes and Yes
Blue
@DigitalTrauma To nie jest zduplikowana kopia tego. BTW to było niesamowite pytanie, szkoda, że ​​nie miałem czasu na nie odpowiedzieć, kiedy zostało zadane nowe pytanie.
Level River St
@steveverill masz rację - nie przeczytałem poprawnie tego pytania
Digital Trauma

Odpowiedzi:

3

JavaScript (ES6), 237 235 222 bajtów

f=p=>(m=[],s=[],d=0,l=p.indexOf`
`+1,[...p].map((c,i)=>(i+1)%l&&!m[i]?g=d-2<s.indexOf((t=a=>m[a]|p[a]!=c?r=0:(m[a]=y.push(a),n=a<n?a:n,t(a+1)+t(a-1)+t(a+l)+t(a-l)+1))(n=i,y=[])!=5?g=0:s[d++]=y.map(a=>r+=a-n)|r):0),d==12&g)

2 bajty zapisane dzięki @DankMemes !

Stosowanie

f(`000111
203331
203431
22 444
2   46
57 666
57769!
58779!
58899!
5889!!`);
=> true

Wyjaśnienie

Kilka uwag na temat tego rozwiązania:

  • Możliwe, że ta odpowiedź jest nieprawidłowa. W rzeczywistości nie sprawdza, czy obrócone pentomino mają ten sam kształt, ale próbowałem, ale nie mogłem znaleźć prawidłowego prostokąta pentomino, który spełnia wymagania określone w regułach i zawiera dwa lub więcej obróconych tego samego kształtu. Ale nie jestem ekspertem od pentomino, więc jeśli znajdziesz prawidłową kombinację, która się nie powiedzie, daj mi znać.
  • Reguły wymagają również odpowiedzi do użycia STDINoraz STDOUTdo wprowadzania i wyprowadzania, ale prompt()są przeznaczone tylko do wprowadzania jednowierszowego, a mój komputer (Windows) automatycznie wstawia \r\nznaki w każdym nowym wierszu podczas wklejania, dlatego ustawiłem funkcję, która akceptuje ciąg.
f=p=>(
  m=[],                      // m = map of checked characters
  s=[],                      // s = list of shapes found (stored as integer)
  d=0,                       // d = number shapes found
  l=p.indexOf`
`+1,                         // l = length of each line (including newline character)
  [...p].map((c,i)=>         // iterate through each character of the input
    (i+1)%l&&                // skip newline characters
      !m[i]?                 // skip the character if it has already been mapped
        g=                   // g = pentomino is valid
          d-2<s.indexOf(     // check if shape already existed before just now
            (t=a=>           // t() checks if character is part of the shape then maps it
              m[a]|          // skip if character is already mapped
                p[a]!=c      //    or if the current character is part of the shape
              ?r=0:(
                m[a]=        // mark the character as mapped
                  y.push(a), // y = list of shape character indices
                n=a<n?a:n,   // n = minimum index of all characters in the shape
                t(a+1)+      // check and map adjacent characters
                t(a-1)+
                t(a+l)+
                t(a-l)+
                1
              )
          )(n=i,y=[])
            !=5?g=0:         // make sure there are only 5 characters in the shape
            s[d++]=          // add the shape to the list
              y.map(a=>      // sum of (index of each character in the shape - minimum
                r+=a-n)|r    //     index) = unique integer representing the shape
        ):0
  ),
  d==12&g                    // ensure there is 12 shapes and return the 'is valid' result
)
użytkownik 81655
źródło
1
Możesz nadużywać oznakowanych szablonów, l=p.indexOf`<newline here>`aby zaoszczędzić 2 bajty
DankMemes
@DankMemes Dzięki za złapanie! Byłem naprawdę zmęczony, kiedy to napisałem i jeszcze tego nie sprawdziłem. : P
user81655