Tidak ada yang namanya "gelas setengah kosong"

15

Anda mungkin tahu pertanyaan retoris tentang apakah gelas setengah penuh atau setengah kosong . Saya mulai bosan dengan kalimat itu, jadi saya memutuskan bahwa sudah waktunya untuk menghilangkan kebingungan tentang kepenuhan atau kekosongan gelas ini secara terprogram.

Tugas Anda adalah menulis sebuah program yang mengambil representasi seni ASCII dari kaca yang jelek dan menghasilkan seni ASCII dari gelas yang sesuai . Hal ini juga harus memutuskan apakah kaca adalah full, mostly full, mostly emptyatau emptydan output ini juga (setiap 4 konstan, nilai output yang berbeda lakukan).

TL; DR

Input adalah seni ASCII dari gelas ( #karakter) dan cairan ( a-z) didistribusikan secara acak di dalam dan di luar kaca. Cairan di dalam gelas jatuh dan menumpuk di bagian bawahnya, cairan di luar itu akan dibuang. Keluarkan seni ASCII dari gelas setelah cairan mengendap di bagian bawah. Tentukan seberapa penuh gelas itu dan hasilkan juga.

Kacamata jelek dan bagus

Sebuah kaca pada umumnya adalah wadah yang terbuat dari #karakter dengan bawah, dua dinding samping dan tidak ada atas.

  • Kacamata yang valid tidak memiliki lubang di dalamnya. (Semua #karakter harus terhubung.)
  • Akan ada setidaknya dua #karakter di setiap baris input ASCII art, atau tidak ada. Tidak akan ada garis dengan tepat satu #.
  • Baris teratas dari seni ASCII input akan selalu memiliki tepat dua #.
  • Kacamata yang valid memiliki tepat satu minimum lokal di dinding #karakter pembatasnya . Ini berarti cairan tidak bisa terjebak di suatu tempat.
  • Dinding pembatas gelas tidak akan memiliki maxima lokal.
  • Tidak akan ada apapun di #bawah bagian bawah gelas.
  • Interior kaca akan selalu menjadi ruang yang terhubung .
  • Mungkin ada spasi / baris terdepan dan baru pada input.

Contoh kacamata yang valid dan tidak valid:

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

Sebuah kaca jelek adalah kaca dengan cairan hanya melayang-layang di interior.

  • Liquid diwakili oleh huruf kecil a-z.
  • Tidak akan ada cairan di atas #karakter baris pertama . Ini berarti bahwa itu tidak diperlukan untuk memungkinkan cairan jatuh ke gelas.
  • Mungkin ada cairan di luar gelas . Cairan ini akan dibuang ketika mengubah gelas jelek menjadi gelas yang bagus.

Contoh-contoh kacamata jelek :

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

Sebuah kaca bagus adalah kaca di mana semua cairan menumpuk di bagian bawah.

  • Dari bawah ke atas, bagian dalam gelas yang bagus terdiri dari sejumlah garis yang sepenuhnya diisi dengan huruf, diikuti oleh paling banyak satu baris yang tidak sepenuhnya diisi dengan huruf, dan kemudian sejumlah garis yang kosong.
  • Mungkin tidak ada cairan di luar bagian dalam gelas yang bagus.

Konversi gelas jelek menjadi gelas bagus

  • Cairan di dalam gelas jatuh dan menumpuk di bagian bawah.
  • Cairan di luar kaca akan dibuang.
  • Saat mengubah gelas jelek menjadi gelas bagus, huruf-huruf yang tepat di dalamnya harus dilestarikan. Misalnya, jika kaca jelek memiliki tiga adi dalamnya, kaca yang bagus harus memiliki tiga ajuga. (Soda tidak tiba-tiba berubah menjadi air.)
  • Surat-surat di dalam gelas yang bagus tidak harus dipesan.
  • Bentuk gelas harus dilestarikan. Tidak ada #karakter yang dapat ditambahkan atau dihapus.
  • Jumlah spasi spasial dan baris baru terkemuka / trailing diizinkan.

Menentukan kepenuhan gelas

  • Gelas adalah fulljika seluruh ruang interiornya diisi dengan huruf.
  • Itu mostly fulljika 50% atau lebih dari ruang interior diisi.
  • Itu mostly emptyjika kurang dari 50% dari ruang interior diisi.
  • Itu emptyjika tidak ada huruf di gelas.
  • Mungkin ada sejumlah baris dan ruang tambahan baru antara kaca seni ASCII dan output kepenuhan.
  • Program ini dapat menampilkan nilai yang berbeda (tetapi konstan!) Untuk 4 level kepenuhan gelas, tidak harus mencetak string yang tepat di atas. Silakan tentukan nilai mana yang mewakili tingkat kepenuhan mana.

Contoh I / O

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

Lain-lain

  • Ini adalah kode golf sehingga jawaban terpendek menang.
  • Jika memungkinkan, harap berikan tautan ke juru bahasa online yang dapat digunakan untuk menjalankan program Anda pada contoh input yang disediakan, misalnya tio.run
Jonathan S.
sumber
1
Apakah ini cangkir yang valid? paste.ubuntu.com/26097168
l4m2
Bolehkah saya menyarankan: "Sebagian besar gelas penuh jika lebih dari 50% ruang interior diisi." - Jika Anda kemudian mempertimbangkan tepat 50% sebagai input tidak valid (tanpa memerlukan solusi untuk menangani kasus ini) benar-benar tidak ada lagi yang disebut "setengah gelas kosong" (atau "setengah gelas penuh"), cocok dengan judul yang lebih baik . Tanpa membatalkan solusi apa pun yang benar-benar menangani kasus ini.
Anedar
1
@ l4m2 Memperbarui tantangan dan membatasi input lebih jauh. Pertama salah satu contoh Anda tidak valid, yang kedua valid, yang ketiga tidak valid.
Jonathan S.
@Aardar Meskipun mungkin membuat tantangan cocok dengan judul yang lebih baik, ini akan mengambil terlalu banyak dari tantangan menurut saya dan itu sudah memiliki input yang tidak valid cukup pula. Saya akan meninggalkan case 50% di sana.
Jonathan S.

Jawaban:

12

Retina , 56 byte

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

 +

Cobalah online!

Pengkodean keluaran adalah 0\n0untuk penuh, 0\n1untuk kosong, 1\n0untuk sebagian besar penuh dan 1\n1sebagian besar kosong (dengan kata lain, bit pertama menunjukkan "sebagian besar" dan bit kedua menunjukkan "kosong").

Penjelasan

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

Kita mulai dengan mengubah semua ruang dan huruf di luar kaca menjadi !. Ini dilakukan dengan mencocokkan baris-awal hingga yang pertama #atau dengan mencocokkan akhir-baris yang tidak mengandung a #dan menerjemahkan semua spasi dan huruf dalam pertandingan tersebut.

O` |\w

Sortir semua spasi dan huruf. Karena huruf memiliki titik kode yang lebih tinggi daripada spasi, ini mengurutkan semua huruf hingga akhir, yang berarti bagian bawah kaca. Ini juga terjadi untuk mengurutkan surat-surat di antara mereka sendiri, tetapi urutan surat-surat dalam hasilnya tidak relevan.

*`!
 

Dry run: cetak hasil penggantian semua !dengan spasi, tetapi tidak benar-benar menerapkan perubahan ini ke string yang berfungsi. Ini mencetak gelas yang bagus.

T`#!¶

Buang semua #, !dan umpan garis, sehingga kita hanya memiliki spasi dan huruf di dalam gelas (masih diurutkan).

*M` \w

Dry run: mencetak jumlah kecocokan ruang diikuti oleh huruf. Ini akan menemukan paling banyak satu kecocokan, dan hanya jika ada spasi dan huruf di dalam gelas, yaitu gelas sebagian besar (penuh / kosong).

+` \w

Hapus ruang yang berulang kali diikuti oleh surat. Ini "membatalkan" huruf dan spasi, sehingga kita berakhir hanya dengan tipe karakter yang lebih sering muncul di dalam kaca.

 +

Hitung jumlah korek api dari regex ini, yang memberi 1jika ada ruang yang tersisa (mis. Gelas itu [sebagian besar] kosong) dan 0jika ada yang tidak tersisa (yaitu gelas itu tepat 50% atau lebih dan karenanya [kebanyakan] penuh ).

Martin Ender
sumber
4

C, 190 byte

Berkat @ l4m2 untuk menghemat 17 byte!

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

Output 0 untuk gelas kosong, 1 untuk sebagian besar kosong, 2 untuk sebagian besar penuh, dan 3 untuk penuh.

Pertama loop melalui string input menghitung ruang di dalam kaca, menandai huruf yang ada di dalam kaca, dan mengubah semua huruf menjadi spasi. Kemudian loop melalui string ke belakang menempatkan semua huruf yang ada di gelas di bagian bawah kaca.

Cobalah online!

Belum dibuka:

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
sumber
variabel global awalnya 0, jadi tidak perlu untuk menginstal ulang
l4m2
@ l4m2 Terima kasih, tetapi fungsi harus dapat digunakan kembali , jadi saya perlu menginisialisasi variabel di dalam fungsi. Kecuali itampaknya, karena fungsi selalu meninggalkan nilainya pada 0 pada akhirnya.
Steadybox
· Char * malloc (strlen (g)) · bisa jadi char l[strlen(g)]jika C99 diperbolehkan, karena lebih pendek dan tidak membuat memori bocor
l4m2
t = *p-35 ? t : !t-> t ^= *p==35jika t selalu 0 atau 1
l4m2
&&(*p=32)-> ?*p=32:0 char l[strlen(g)],*p=g->char*p=g,l[strlen(g)]
l4m2
1

Python 2 , 342 byte

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)

Cobalah online!

TFeld
sumber
1

Perl 5 , 197 byte

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

Cobalah online!

Output:

 e  empty
me  mostly empty
mf  mostly full
 f  full
Xcali
sumber