Nie ma czegoś takiego jak „pół pusta szklanka”

15

Prawdopodobnie znasz retoryczne pytanie, czy szklanka jest w połowie pełna, czy w połowie pusta . Trochę mnie to znudziło, więc zdecydowałem, że nadszedł czas, aby programowo wyeliminować to zamieszanie związane ze szklaną pełnią lub pustką.

Twoim zadaniem jest napisanie programu, który pobiera grafikę ASCII brzydkiego szkła i generuje grafikę ASCII odpowiedniego ładnego szkła . Należy również zdecydować, czy szyba jest full, mostly full, mostly emptyi emptyi Efekt ten również (4 dowolny stały, różne wartości wyjściowe do).

TL; DR

Dane wejściowe to sztuka ASCII szkła ( #znaków) i cieczy ( a-z) rozmieszczonych losowo wewnątrz i na zewnątrz szkła. Ciecz wewnątrz szklanki opada i gromadzi się na jej dnie, ciecz na zewnątrz zostaje odrzucona. Wyjmij sztukę szklaną ASCII po ustabilizowaniu się cieczy na dnie. Określić, jak pełne jest szkło i wydrukować to również.

Brzydkie i ładne okulary

Szkło w ogóle jest pojemnik wykonany z #znaków z dna, dwóch ścian bocznych i nie ma górnej.

  • W ważnych okularach nie ma dziur. (Wszystkie #postacie muszą być połączone.)
  • W #każdej linii wejściowej grafiki ASCII będą albo co najmniej dwa znaki, albo brak. Nie będzie linii z dokładnie jedną #.
  • Górny wiersz wejściowej grafiki ASCII zawsze będzie miał dokładnie dwa #.
  • Prawidłowe okulary mają dokładnie jedno lokalne minimum w ograniczającej ścianie #postaci. Oznacza to, że ciecz nie może gdzieś zostać uwięziona.
  • Ograniczająca ściana szkła nie będzie miała lokalnych maksimów.
  • Pod #dnem szklanki nie będzie żadnych .
  • Wnętrze szkła zawsze będzie połączoną przestrzenią .
  • Na wejściu mogą znajdować się początkowe / końcowe białe znaki i znaki nowej linii.

Przykłady prawidłowych i nieprawidłowych okularów:

VALID (possible input to your program):

#  # 
#  # 
#### 

  #        #
   #      #
    #    #
    #    #
    #    #
     #  #
      ##

#      #
#      #
 ###   #
    #  #
    ####

#       #
 #      #
  #     #
 #      #
#       #
 ########


#   #
#   #
#   ###
#   ###
#   ###
#####


INVALID (you won't get one of those as input to your program):

#  #
   #  Has a hole.
####

#      #
   #  #  This is also considered a hole.
    ##

#   #
 # #  Less than two # on a line.
  #

## #
 # #  More than two # on the first line.
 ###

   #
 # #  Less than two # on the first line.
 ###

#               #
 #     #       #  More than one local minimum.
  #   # #     #   Liquid might get trapped.
   ###   #   #
          ###

#  #
#  #
####  Interior is not a connected space.
#  #
#  #
####

#   #
#   #######
#   ###   #
#   ##   #  Has a local maximum.
#   #   #
#      #
#     #
######

#    #
#    #
#     #
 #####
 #  #    <--- # below the bottom of the glass.

#     #
#  #  #  This is also a glass with a hole. The #'s aren't all connected.
#  #  #
#     #
#######

Brzydki szkło to szkło z cieczą tylko krąży w jego wnętrzu.

  • Ciecz jest reprezentowana małymi literami a-z.
  • Nie będzie płynu powyżej pierwszej linii #znaków. Oznacza to, że nie jest wymagane, aby płyn dostał się do szklanki.
  • Na zewnątrz szkła może znajdować się ciecz . Ten płyn zostanie odrzucony podczas przekształcania brzydkiego szkła w ładne szkło.

Przykłady brzydkich szklanek :

        # y    b #      i
   x   v#p  q   l#   l
  a     # a   zj # p   g
     g  #ppcg   c#
   u    #  r   n #   r
        ##########
Discard    Keep    Discard

                   <-- There will never be liquid above the glass
   #  tz  g#
    #y abc # d
 av z#ox s #  l
   c#y abth# b
   #vg y rm#   a
    ########
 e   a  b c  d     <-- Discard this as well (not within interior)

Ładne szkło jest szkłem gdzie cały płyn zgromadził na dole.

  • Od dołu do góry wnętrze ładnej szklanki składa się z kilku linii, które są całkowicie wypełnione literami, po których następuje co najwyżej jedna linia, która nie jest całkowicie wypełniona literami, a następnie liczba linii, które są puste.
  • Na zewnątrz dobrego szkła nie może znajdować się żaden płyn.

Przekształcenie brzydkiego szkła w ładny kieliszek

  • Ciecz wewnątrz szklanki opada i gromadzi się na dole.
  • Ciecz na zewnątrz szkła zostaje odrzucona.
  • Podczas przekształcania brzydkiego szkła w ładne szkło należy zachować dokładne litery w nim. Na przykład, jeśli brzydkie szkło ma trzy a, to ładne szkło musi również mieć trzy a. (Soda nagle nie zamienia się w wodę.)
  • Litery w ładnej szklance nie muszą być zamawiane.
  • Kształt szkła musi zostać zachowany. Żadnych #znaków nie można dodawać ani usuwać.
  • Dozwolona jest dowolna ilość początkowych / końcowych białych znaków i znaków nowej linii.

Określanie pełności szkła

  • Szkło jest, fulljeśli cała jego przestrzeń wewnętrzna jest wypełniona literami.
  • Dzieje się tak, mostly fullgdy 50% lub więcej wewnętrznej przestrzeni jest wypełnione.
  • Dzieje się tak, mostly emptyjeśli mniej niż 50% przestrzeni wewnętrznej jest wypełnione.
  • To jest, emptyjeśli w szkle nie ma liter.
  • Może istnieć dowolna liczba dodatkowych znaków nowej linii i odstępów między szkłem artystycznym ASCII a wyjściem pełności.
  • Program może wyświetlać dowolne wyraźne (ale stałe!) Wartości dla 4 poziomów wypełnienia szkła, nie musi drukować dokładnych ciągów powyżej. Proszę określić, która wartość reprezentuje poziom pełności.

Przykłady we / wy

Example 1 input:

        # y    b #      i
   x   v#p  q   l#   l
  a     # a   zj # p   g
     g  #ppcg   c#
   u    #  r   n #   r
        ##########

Example 1 output:

        #        #       
        #        #    
        #        #      
        #ppcglqb #
        #yprazjnc#    
        ##########
mostly empty

Example 2 input:

   #  tz  g#
    #y abc # d
 av z#ox s #  l
   c#y abth# b
   #vg y rm#   a
    ########
 e   a  b c  d

Example 2 output:

   #       #
    #   bc #  
     #oxysa#   
    #ygabth#  
   #vgtyzrm#    
    ########
mostly full

Example 3 input:

#      #
#  g   # f
 ###ih #  d
a c #  # e
 b  ####

Example 3 output:

#      #
#      #  
 ###  g#   
    #hi#  
    ####
mostly empty

Example 4 input:

#ab# 
#cd# 
#### 

Example 4 output:

#cb# 
#da# 
#### 
full

Example 5 input:

  #        # h
   #      #
  a #    # g
   b#    #  f
 c  #    #  
     #  #  e
   d  ##

Example 5 output:

  #        #  
   #      #
    #    #  
    #    #   
    #    #  
     #  #   
      ##
empty

Example 6 input:

# b  az#
#y s ###
###### t
  l  u

Example 6 output:

#  z   #
#ybsa###
######  
mostly full

Example 7 input:

#   # g
# b #f
#  c###
#da ### i
#  e###
##### h

Example 7 output:

#   #
#   #
#   ###
#de ###
#abc###
#####
mostly empty

Misc

  • To jest golf golfowy, więc wygrywa najkrótsza odpowiedź.
  • Jeśli to możliwe, podaj link do tłumacza online, którego można użyć do uruchomienia programu na podanych przykładowych danych wejściowych, na przykład tio.run
Jonathan S.
źródło
1
Czy to ważne kubki? paste.ubuntu.com/26097168
l4m2
Mogę zasugerować: „Szklanka jest w większości pełna, jeśli więcej niż 50% przestrzeni wewnętrznej jest wypełnione”. - Jeśli następnie weźmiesz pod uwagę dokładnie 50% jako nieprawidłowe dane wejściowe (bez konieczności rozwiązania tego problemu), naprawdę nie ma czegoś takiego jak „pół pusta szklanka” (lub „pół pełna szklanka”), jeszcze bardziej dopasowując tytuł . Bez unieważnienia jakichkolwiek rozwiązań, które faktycznie zajmują się tą sprawą.
Anedar
1
@ l4m2 Zaktualizowałem wyzwanie i jeszcze bardziej ograniczyłem nakład. Pierwszy z Twoich przykładów jest nieprawidłowy, drugi jest ważny, trzeci nieważny.
Jonathan S.
@Anedar Chociaż może sprawić, że wyzwanie będzie lepiej pasowało do tytułu, moim zdaniem odebrałoby to zbyt wiele wyzwania i i tak ma już wystarczająco dużo nieprawidłowych danych wejściowych. Zostawię tam 50% sprawy.
Jonathan S.

Odpowiedzi:

12

Siatkówka , 56 bajtów

T%` l`!`^.*?#|[^#]+$
O` |\w
*`!
 
T`#!¶
*M` \w
+` \w

 +

Wypróbuj online!

Kodowanie wyjściowe jest 0\n0pełne, 0\n1puste, 1\n0głównie pełne i 1\n1prawie puste (innymi słowy, pierwszy bit wskazuje „głównie”, a drugi bit oznacza „pusty”).

Wyjaśnienie

T%` l`!`^.*?#|[^#]+$

Zaczynamy od zamiany wszystkich spacji i liter na zewnątrz szyby !. Odbywa się to poprzez dopasowanie początku linii do pierwszej #lub dopasowanie końca linii, który nie zawiera #znaku, oraz transliterację wszystkich spacji i liter w tych dopasowaniach.

O` |\w

Sortuj wszystkie spacje i litery. Ponieważ litery mają wyższe punkty kodowe niż spacje, sortuje wszystkie litery do końca, co oznacza na dole szyby. Dzieje się tak również w przypadku sortowania liter między sobą, ale kolejność liter w wyniku nie ma znaczenia.

*`!
 

Uruchomienie na sucho: wydrukuj wynik zamiany wszystkich na !spacje, ale tak naprawdę nie stosuj tej zmiany do ciągu roboczego. To drukuje ładne szkło.

T`#!¶

Odrzuć wszystkie #, !i karetki, tak że my zostajemy tylko z przestrzeni i listów wewnątrz szkła (nadal klasyfikowane).

*M` \w

Bieg próbny: wydrukuj liczbę dopasowań spacji, a następnie literę. Znajduje to co najwyżej jedno dopasowanie, i to tylko wtedy, gdy wewnątrz szyby znajdują się zarówno spacje, jak i litery, tzn. Szkło jest w większości (pełne / puste).

+` \w

Wielokrotnie usuwaj spację, a następnie literę. To „kasuje” litery i spacje, dzięki czemu uzyskujemy tylko ten rodzaj znaku, który pojawia się częściej w szybie.

 +

Policz liczbę dopasowań tego wyrażenia regularnego, co daje, 1jeśli pozostały jakieś spacje (tj. Szklanka była [przeważnie] pusta) i 0jeśli nie zostały (tj. Szklanka była dokładnie w 50% lub większa, a zatem [przeważnie] pełna ).

Martin Ender
źródło
4

C, 190 bajtów

Dzięki @ l4m2 za oszczędność 17 bajtów!

i,k,t,s;f(char*g){char*p=g,l[strlen(g)];for(s=t=0;*p;*p>35&&(t?l[i++]=*p:1)?*p=32:0,~*p++&t&&++s)t^=*p==35;for(k=i;i;t&*p==32?*p=l[--i]:0)t^=*--p==35;printf("%s\n%d",g,k?k-s?k*2<s?1:2:3:0);}

Wyjście 0 dla pustej szklanki, 1 dla większości pustej, 2 dla większości pełnej i 3 dla pełnej.

Najpierw pętle przechodzą przez łańcuch wejściowy, licząc spację wewnątrz szyby, zaznaczając litery wewnątrz szyby i zamieniając wszystkie litery na spacje. Następnie pętle przez sznurek do tyłu, umieszczając wszystkie litery, które były w szklance na dole szklanki.

Wypróbuj online!

Rozwinięty:

i,k,t,s;
f(char*g)
{
    char l[strlen(g)], *p=g;
    for (s=t=0; *p; *p>35&&(t?l[i++]=*p:1)?*p=32:0, ~*p++&t&&++s)
        t ^= *p==35;
    for (k=i; i; t&*p==32?*p=l[--i]:0)
        t ^= *--p==35;
    printf("%s\n%d", g, k?k-s?k*2<s?1:2:3:0);
}
Steadybox
źródło
zmienne globalne mają początkowo wartość 0, więc nie trzeba ponownie wprowadzać
l4m2
@ l4m2 Dzięki, ale funkcje muszą być wielokrotnego użytku , więc muszę zainicjować zmienne wewnątrz funkcji. Tyle tylko, iże wydaje się, ponieważ funkcja zawsze pozostawia swoją wartość na końcu 0.
Steadybox,
· Char * malloc (strlen (g)) · może być, char l[strlen(g)]jeśli dozwolone jest C99, ponieważ jest krótszy i nie powoduje wycieku pamięci
l4m2
t = *p-35 ? t : !t-> t ^= *p==35jeśli t jest zawsze 0 lub 1
l4m2
&&(*p=32)-> ?*p=32:0 char l[strlen(g)],*p=g->char*p=g,l[strlen(g)]
l4m2
1

Python 2 , 342 bajty

import re
def f(g):
 g=[l for l in g if'#'in l];s,w,l,W=zip(*[re.findall(r'([^#]*)(#+)'*2,l)[0] for l in g[:-1]]);a=sorted(''.join(l));R=len(a);r=a.count(' ');L=[]
 for x in l:L+=[''.join(a[:len(x)])];a=a[len(x):]
 for l in zip([' '*len(x)for x in s],w,L,W)+[re.sub('[^#]',' ',g[-1]),'mostly '*(0<r<R)+['full','empty'][r>R/2]]:print''.join(l)

Wypróbuj online!

TFeld
źródło
1

Perl 5 , 197 bajtów

map{/#([^#]+)#/;$l.=$1;y/#/ /c}@a=grep/#/,<>;$f=length$l;$_=$l=~y/ //d/$f;$a[--$i]=~s/#( +)#/'#'.(substr$l,0,($q=length$1),"").$"x($q-$p).'#'/e while$p=length$l;say for@a;say'm'x($_!=int),$_>.5?e:f

Wypróbuj online!

Wyjścia:

 e  empty
me  mostly empty
mf  mostly full
 f  full
Xcali
źródło