Il n'y a pas de «verre à moitié vide»


15

Vous connaissez probablement la question rhétorique de savoir si un verre est à moitié plein ou à moitié vide . Je suis un peu fatigué de la phrase, j'ai donc décidé qu'il était temps d'éliminer cette confusion sur la plénitude ou la vacuité du verre par programme.

Votre tâche consiste à écrire un programme qui prend une représentation artistique ASCII d'un verre laid et génère un art ASCII d'un joli verre correspondant . Il doit également décider si le verre est full, mostly full, mostly emptyou emptyet de sortie ainsi ce (toutes les valeurs de sortie distinctes, 4 constantes font).

TL; DR

L'entrée est un art ASCII d'un verre ( #caractères) et liquide ( a-z) répartis de manière aléatoire à l'intérieur et à l'extérieur du verre. Le liquide à l'intérieur du verre tombe et s'accumule à son fond, le liquide à l'extérieur est jeté. Sortez un art ASCII du verre après que le liquide se soit déposé au fond. Déterminez le niveau de remplissage du verre et imprimez-le également.

Lunettes laides et agréables

Un verre en général est un récipient composé de #personnages avec un fond, deux parois latérales et pas de dessus.

  • Les lunettes valides n'ont pas de trous. (Tous les #personnages doivent être connectés.)
  • Il y aura soit au moins deux #caractères dans chaque ligne de l'art ASCII d'entrée, soit aucun. Il n'y aura pas de ligne avec exactement un #.
  • La ligne supérieure de l'art ASCII en entrée aura toujours exactement deux #.
  • Les lunettes valides ont exactement un minimum local dans leur mur de délimitation de #caractères. Cela signifie que le liquide ne peut pas être piégé quelque part.
  • La paroi de délimitation d'un verre n'aura pas de maxima locaux.
  • Il n'y en aura pas #sous le fond du verre.
  • L'intérieur du verre sera toujours un espace connecté .
  • Il peut y avoir des espaces en début / fin et des retours à la ligne dans l'entrée.

Exemples de lunettes valides et invalides:

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

Un verre laid est un verre avec du liquide qui flotte juste à l'intérieur.

  • Le liquide est représenté par les lettres minuscules a-z.
  • Il n'y aura pas de liquide au-dessus de la première ligne de #caractères. Cela signifie qu'il n'est pas nécessaire de permettre au liquide de tomber dans le verre.
  • Il peut y avoir du liquide à l' extérieur du verre . Ce liquide sera jeté lors de la conversion du verre laid en un beau verre.

Exemples de verres laids :

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

Un beau verre est un verre où tout le liquide s'est accumulé au fond.

  • De bas en haut, l'intérieur d'un joli verre se compose d'un certain nombre de lignes entièrement remplies de lettres, suivies d'au plus une ligne qui n'est pas complètement remplie de lettres, puis d'un certain nombre de lignes vides.
  • Il ne doit pas y avoir de liquide à l'extérieur de l'intérieur d'un joli verre.

Conversion d'un verre laid en un joli verre

  • Le liquide à l'intérieur du verre tombe et s'accumule au fond.
  • Le liquide à l'extérieur du verre est jeté.
  • Lors de la conversion d'un verre laid en un beau verre, les lettres exactes doivent être conservées. Par exemple, si le vilain verre en a trois a, le beau verre doit aussi en avoir trois a. (Le soda ne se transforme pas soudainement en eau.)
  • Les lettres dans le joli verre ne doivent pas être commandées.
  • La forme du verre doit être préservée. Aucun #caractère ne peut être ajouté ou supprimé.
  • Toute quantité d'espaces blancs de début / de fin et de nouvelles lignes est autorisée.

Déterminer la plénitude du verre

  • Un verre est fullsi tout son espace intérieur est rempli de lettres.
  • C'est mostly fullsi 50% ou plus de l'espace intérieur est rempli.
  • Ses mostly empty si moins de 50% de l'espace intérieur est rempli.
  • C'est emptys'il n'y a pas de lettres dans le verre.
  • Il peut y avoir un certain nombre de nouvelles lignes et d'espaces supplémentaires entre le verre d'art ASCII et la sortie de plénitude.
  • Le programme peut produire des valeurs distinctes (mais constantes!) Pour les 4 niveaux de plénitude du verre, il n'a pas à imprimer les chaînes exactes ci-dessus. Veuillez spécifier quelle valeur représente quel niveau de plénitude.

Exemples d'E / S

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

Divers

  • C'est le golf de code, donc la réponse la plus courte l'emporte.
  • Si possible, veuillez fournir un lien vers un interpréteur en ligne qui peut être utilisé pour exécuter votre programme sur les exemples d'entrées fournis, par exemple tio.run

1
Ces tasses sont-elles valables? paste.ubuntu.com/26097168
l4m2

Puis-je suggérer: "Un verre est généralement plein si plus de 50% de l'espace intérieur est rempli." - Si vous considérez alors exactement 50% comme une entrée invalide (sans nécessiter les solutions pour gérer ce cas), il n'y a vraiment plus rien de tel qu'un "verre à moitié vide" (ou un "verre à moitié plein"), correspondant encore mieux au titre . Sans invalider les solutions qui gèrent réellement ce cas.
Anedar

1
@ l4m2 Mise à jour du défi et restriction encore plus importante de la saisie. Le premier de vos exemples n'est pas valide, le second est valide, le troisième n'est pas valide.
Jonathan S.

@Anedar Bien que cela puisse améliorer le défi pour le titre, cela enlèverait trop du défi à mon avis et il a déjà suffisamment d'entrées invalides de toute façon. Je vais laisser le cas de 50% là-dedans.
Jonathan S.

Réponses:


12

Rétine , 56 octets

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

 +

Essayez-le en ligne!

Le codage de sortie est 0\n0pour plein, 0\n1pour vide, 1\n0pour la plupart plein et 1\n1pour la plupart vide (en d'autres termes, le premier bit indique "principalement" et le second bit indique "vide").

Explication

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

Nous commençons par transformer tous les espaces et lettres en dehors du verre en !. Cela se fait en faisant correspondre soit un début de ligne au premier, #soit en faisant correspondre une fin de ligne qui ne contient pas de a #et en translittérant tous les espaces et toutes les lettres dans ces correspondances.

O` |\w

Triez tous les espaces et toutes les lettres. Étant donné que les lettres ont des points de code plus élevés que les espaces, cela trie toutes les lettres à la fin, ce qui signifie au fond de la vitre. Cela se produit également pour trier les lettres entre elles, mais l'ordre des lettres dans le résultat n'est pas pertinent.

*`!
 

Dry run: affiche le résultat du remplacement de tous !par des espaces, mais n'applique pas réellement cette modification à la chaîne de travail. Cela imprime le joli verre.

T`#!¶

Jetez tous les #, !et linefeeds, de sorte que nous ne retrouvons avec les espaces et les lettres à l' intérieur du verre (encore triés).

*M` \w

Dry run: imprime le nombre de correspondances d'un espace suivi d'une lettre. Cela trouvera au plus une correspondance, et cela seulement s'il y avait à la fois des espaces et des lettres à l'intérieur du verre, c'est-à-dire que le verre est principalement (plein / vide).

+` \w

Supprimez à plusieurs reprises un espace suivi d'une lettre. Cela "annule" les lettres et les espaces, de sorte que nous ne nous retrouvons qu'avec ce type de personnage qui apparaît plus souvent à l'intérieur du verre.

 +

Comptez le nombre de correspondances de cette expression régulière, ce qui donne 1s'il reste des espaces (c'est-à-dire que le verre était [principalement] vide) et 0s'il n'y en a pas (c'est-à-dire que le verre était exactement à 50% ou plus et donc [principalement] plein) ).


4

C, 190 octets

Merci à @ l4m2 pour avoir économisé 17 octets!

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);}

Sorties 0 pour le verre vide, 1 pour la plupart vide, 2 pour la plupart pleine et 3 pour la pleine.

Tout d'abord, parcourez la chaîne d'entrée en comptant l'espace à l'intérieur du verre, en marquant les lettres qui sont à l'intérieur du verre et en changeant toutes les lettres en espaces. Boucle ensuite à travers la chaîne vers l'arrière en plaçant toutes les lettres qui étaient dans le verre au fond du verre.

Essayez-le en ligne!

Déroulé:

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);
}

les variables globales sont initialement 0, donc pas besoin de les réinitialiser
l4m2

@ l4m2 Merci, mais les fonctions doivent être réutilisables , j'ai donc besoin d'initialiser les variables à l'intérieur de la fonction. Sauf iqu'il semble, car la fonction laisse toujours sa valeur à 0 à la fin.
Steadybox

· Char * malloc (strlen (g)) · peut l'être char l[strlen(g)]si C99 est autorisé, car il est plus court et ne fait pas de fuite de mémoire
l4m2

t = *p-35 ? t : !t-> t ^= *p==35si t est toujours 0 ou 1
l4m2

&&(*p=32) -> ?*p=32:0 char l[strlen(g)],*p=g ->char*p=g,l[strlen(g)]
l4m2

1

Python 2 , 342 octets

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)

Essayez-le en ligne!


1

Perl 5 , 197 octets

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

Essayez-le en ligne!

Les sorties:

 e  empty
me  mostly empty
mf  mostly full
 f  full
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.