Ce qui est entouré


18

J'ai toujours voulu entourer un texte de #s, mais j'ai du mal à comprendre ce que j'ai entouré, donc dans ce défi, vous allez écrire un programme pour faire exactement cela

Exemples

Les entrées / sorties sont séparées par une nouvelle ligne.

###
#a#
###

a
 #
#a#
 #

a
  ###  
 # a #
# b c #
#######

  a 
 b c 
ABCDHIJ
E####GK
F# M #L
#   N#O
P####

  M 
   N
###A###
#C#B#o#
#d###e#
 # go#
  ###

C   o
d   e
  go

Spec

  • #s ce qui "entoure" un bloc de texte
  • # sera toujours adjacent (y compris en diagonale)
  • # formera toujours une forme fermée
  • Il n'y aura qu'une seule #forme
  • En cas de forme concave, les trous doivent être remplis d'espaces.
  • Les espaces doivent être préservés dans la sortie

au début, j'étais comme ... il suffit de retirer les #s et c'est parti ... et puis c'est devenu difficile.
Bald Bantha

J'ai du mal à obtenir des entrées en javascript et à les séparer par des retours à la ligne ... comment dois-je obtenir des entrées? pourrait-il être formaté avec un \naprès chaque ligne d'entrée et passé en tant que paramètre de fonction à mon programme ou quoi?
Bald Bantha

1
Quel est l'ensemble des caractères d'entrée valides?
Ton Hospel

Y a-t-il une erreur sur la sortie de l' exemple MN ? Sa sortie se compose uniquement du texte entouré _M_\n___N(en utilisant des traits de soulignement au lieu d'espaces en raison de problèmes de formatage), tandis que dans les exemples abc et Codego , la sortie comprend également des espaces où #s étaient dans l'entrée. Si seul le texte entouré de # doit être imprimé, la sortie de l' exemple abc doit être _a_\n_b_c_(au lieu de __a_\n_b_c) et la sortie de l' exemple Codego doit être Co\nde\n_go(au lieu de C___o\nd___e\n__go).
épidémie

@epidemian ah, belle prise. J'ai corrigé l' MNexemple. car il ne devrait pas y avoir d'espace supplémentaire après M.
Downgoat

Réponses:


6

Perl, 144 138 132 132 129 128 127 126 126 124 octets

Comprend +2 pour -p0

Le code suppose que ce \0n'est pas un caractère d'entrée valide (au moins à l'intérieur de #).

Exécutez avec l'entrée sur STDIN:

surround.pl < surround.txt

surround.pl:

#!/usr/bin/perl -p0
/^#[^#\0]/m&&s/^|[^#\n\0]\0/\0\0/mg,s%.%s/.(.*)/$+\0/g;/#/&&reverse"\n",/^./mg%seg until$?++<$$_++;y/\0/#/;s/^#*\n|#+$|^#//mg;y;#; 

Le code fonctionne tel quel, mais remplace le \0et \npar leurs versions littérales pour le score revendiqué. Notez qu'il y a un espace à la fin de la ligne. Le code boucle beaucoup trop de fois, vous devrez donc peut-être attendre environ 30 secondes pour la sortie.

Explication

Je vais faire un remblai avec \0arrêté #de l'extérieur dans les directions orthogonales. Après cela, je couperai les #côtés et remplacerai tout ce qui reste des espaces. Pour éviter d'avoir à gérer toutes les directions dans le remblai, je ferai tourner à plusieurs reprises la zone cible et ne remuerai que de droite à gauche

/^#[^#\0]/m                   The rotation is written such that it slices
                              off the first column. That is ok unless the
                              first column contains a # that is followed by
                              something that could be the inside. There is
                              no newline inside the [] because short lines
                              will get extended during the rotation and 
                              the character following the # will end
                              up as a \0 and match in a later round
    &&s/^|[^#\n\0]\0/\0\0/mg  In case the # could be an interior border I
                              will add two columns of \0's in front. One 
                              will be a sacrifice for the rotation, the
                              other column will end up at the end of the area
                              after two rotations and function as seed for the
                              floodfill. This regex also does one step of
                              the floodfill from the back to the front.
                              After a certain number of loops we are certain
                              to get to a first column that must not be 
                              dropped so at some point the last column is 
                              guaranteed to consist of only \0. And we only need
                              to fill backward since the rotations will make
                              any direction backward at some point

s%.%  process column  %seg    I will replace each character (including \n)
                              in the string by the next column in reversed
                              order or an empty string if there are no more
                              interesting columns. This is therefore a right
                              rotation. There are less columns than
                              characters so this loop is long enough

    s%.%s/.(.*)/$+\0/g        Remove the next (now first) character from each
                              row (so remove the column). Because the
                              original area is not necessarily a rectangle
                              add a \0 at the end of the row so we won't run
                              out out of columns (this would cause shorter
                              rows to have no entry in the new rotated row)
                              This will not do anything for empty lines so
                              they DO get squeezed out. But that is not a 
                              problem since the problem statement says there
                              will be only one # shape so any empty lines
                              are can be safely dropped (this would not be
                              so if there could be multiple # shapes because
                              that could create a new surrounded area

    /#/                       Check if any of the remaining columns still 
                              has a #. If not all remaining columns are on 
                              the outside and can be dropped
       &&reverse"\n",/^./mg   Collect the column and add a \n to its reverse

 until$?++<$$_++              Keep doing this until we get to a multiple of
                              65536 rotations when $? waraps back around to 0
                              (this is a multiple of 4 so the area is left
                              unrotated) and an area we have seen before
                              ($$_ >= 1)
                              (so all slicing and flood filling is finished)
                              $_ having been seen in a previous rotations is
                              not a problem (though rather tricky to prove)

À ce stade, par exemple

AB##J
E####GK
F# M #L
#   N#O
P####

aura été remplacé par:

0000000
0####00
0# M #0
#   N#0
0####00

Fondamentalement, toutes les colonnes et lignes qui ne bordent pas directement l'intérieur ont été coupées. Tout caractère extérieur restant a été remplacé par \ 0. En haut et à droite, il y a une couche supplémentaire de \ 0. Il ne reste donc plus qu'à nettoyer:

y/\0/#/                       Replace any outside that is left by #
s/^#*\n|#+$|^#//mg            Removes the first two and last line (the only 
                              lines that can consist of purely #)
                              Removes any trailing #
                              Removes the first column of #
y;#; \n;                      Replace any remaining # by space since they 
                              are needed to fill the concave parts
                              The final \n; is not written since it is implicit
                              in the -p loop

Vos remblais inondent-ils les coins intérieurs, le cas échéant?
mbomb007

@ mbomb007: Oui, étant donné que la zone subit plusieurs rotations, elle peut donc suivre tous les couloirs sinueux. La boucle s'arrêtant trop tôt avant de réduire les murs très épais est le seul défaut à ma connaissance
Ton Hospel

@ mbomb007: Aaaa et le défaut de paroi épaisse est maintenant résolu
Ton Hospel

copier-coller votre solution telle quelle (sans remplacer les caractères échappés), la sortie est simplement l'entrée avec tous les éléments #supprimés. veuillez vérifier ma session bash: codepad.org/YbCzB4O4
ardnew

@ardnew: Oups, désolé. Pour la dernière mise à jour, je n'ai pas repassé la solution complète, et j'aurais dû remplacer le tout par un jusqu'à. Réparé maintenant, veuillez réessayer
Ton Hospel

4

Javascript, 485 464 427 417 396 390 octets

s='indexOf';k='lastIndexOf';h="#";t=b=>b[0].map((x,i)=>b.map(x=>x[i]));i=>{m=i.split`
`;for(h of m){m[m[s](h)]=h.split``;}for(y=0;y<m.length;y++){for(z=x=0;x<m[y].length;x++){if(m[y][x]==h)break;if(m[y][s](h)<x&&m[y][k](h)>x)z++;q=t(m);if(q[y][s]h)<x&&m[y][k](h)>x)z++;if(z>2)m[y][x]=h}}for(p of m){v=p.join``.match(/\S/);e=v?p.join``:'';m[m[s](p)]=e;}m=m.join`
`;return m.replace(#/g," ")}

Oui. J'ai essayé. Et, bien que je sois à 485 octets, je gagne parce que personne d'autre n'avait envie de répondre à cette question. Alors, hah!
Et aussi, je suis bien conscient que je pouvais jouer au golf avec autant de charges, je suis juste fatigué en ce moment ... eh bien maintenant je suis à 396 Merci à Conor pour la plupart du golf ...: D


1
Déclarez les variables à l'intérieur des boucles for à l'extérieur avecy=z=0
Bálint
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.