Sortir des sentiers battus - Est-ce que je le fais bien?


59

Je continue à entendre que sortir des sentiers battus est un objectif à atteindre, mais comment puis-je savoir si je le fais avec succès?

Pour résoudre ce dilemme, j’ai déjà écrit un traducteur Brainwave-to-ASCII qui, en théorie, devrait produire des résultats tels que

                    #
   +------------+   #
   |   thinking |   #
   |            |   #
   +------------+   #
                    #

ou

                   #
 +------+          #
 |      | thinking #
 |      |          #
 |      |          #
 +------+          #
                   #

ce qui le rend assez facile à dire si on pense en dehors de la boîte ou pas. (Ils #ne font pas partie de la sortie et représentent de nouvelles lignes.)

Cependant, parfois à cause d’un bogue, seule une petite partie de la sortie est renvoyée:

   |         |         #
   +---------+         #
    thinking           #

        #
       +#
       |#
inking |#

    #
    #

La tâche

S'il vous plaît, aidez-moi à classer automatiquement la sortie du traducteur Brainwave-to-ASCII en écrivant un programme ou une fonction qui lit une représentation ascii et retourne si elle se thinkingtrouve dans la boîte, en dehors de celle-ci ou si elle ne pouvait pas la révéler à partir de l'entrée.

Contribution

Un ensemble de chaînes de même longueur, sous forme de liste ou délimité par des nouvelles lignes contenant

  • la chaîne thinkingou ses pré- ou suffixes valides
  • les caractères +-|formant une boîte rectangulaire ou des parties valides de celle-ci
  • les espaces
  • NON# , ceux-ci ne sont inclus que dans le défi de marquer les extrémités des lignes d'entrée.

Sortie

  • une valeur de vérité si thinkingest en dehors de la boîte
  • une valeur de fausseté si thinkingest dans la boîte
  • une troisième valeur distincte peut-être si elle ne peut pas être déterminée à partir de l'entrée si elle thinkingest dans la boîte ou non

Exemples

Vérité

                   #
 +------+          #
 |      | thinking #
 |      |          #
 |      |          #
 +------+          #
                   #

   |         |         #
   +---------+         #
    thinking           #

        #
       +#
       |#
       |#
inking |#

thinking #
-------+ #

 ++ # (thinking is not in the box, so it must be outside)
 ++ # (this is also the smallest possible box)

+ #
 t#

+----+# (The box is not wide enough to contain "thinking")

---# (The box is not high enough to contain "thinking")
---#

En entrée de chaîne:

"                   \n +------+          \n |      | thinking \n |      |          \n |      |          \n +------+          \n                   "
"   |         |         \n   +---------+         \n    thinking           "
"        \n       +\n       |\n       |\ninking |"
"thinking \n-------+ "
" ++ \n ++ "
"+ \n t"
"+----+"
"---\n---"
"g++"
"k\n+"

Fausseté:

                    #
   +------------+   #
   |   thinking |   #
   |            |   #
   +------------+   #
                    #

  +---------------#
  |               #
  |               #
  |   thinking    #

      | #
king  | #
------+ #

+---#
|thi#
+---#

-#
n#
-#

En entrée de chaîne:

"                    \n   +------------+   \n   |   thinking |   \n   |            |   \n   +------------+   \n                    "
"  +---------------\n  |               \n  |               \n  |   thinking    "
"      | \nking  | \n------+ "
"+---\n|thi\n+---"
"-\nn\n-"

Peut être:

thinking#

g|#

think#
-----#

|          |# (box large enough to possibly contain the string)
|          |#

   +--#
   |  #

# (empty input)

En entrée de chaîne:

"thinking"
"g|"
"|t"
"-\ni"
"h\n-"
"think\n-----"
"|          |\n|          |"
"   +--\n   |  "
""

Règles

  • C'est du , alors essayez d'utiliser le moins d'octets possible.
  • La peut - être la valeur peut être choisie librement tant qu'il est différent de la truthy / valeur falsy et est la même pour tous les intrants peut - être. Cela peut aussi être une erreur.
  • Vous pouvez supposer que la saisie est toujours valide (par exemple, ne contient aucun autre caractère que +-ghiknt|, pas plus d'une case, ...).

Idée de test de vérité:, +\n+boîte trop petite pour un mot
Lemon destructible

@ DestructibleWatermelon Merci, je vais ajouter un cas de test similaire.
Laikoni

Vous n'avez pas les cas les plus fondamentaux dans vos cas de test. L'esprit comprend-il la boîte entière avec la pensée en elle, et la boîte entière avec le mot entier qui pense en dehors?
ATaco

Y a-t-il une possibilité que le mot chevauche la boîte (penser sur la boîte )?
Mukul Kumar

17
Ceci est un cauchemar de cas limite, jeez.
Urne Magic Octopus

Réponses:


11

Javascript (ES6), 274 263 octets

f=(a,b=(b,c="")=>a=a.replace(b,c),c=b=>b.test(`,${a},`))=>(b(/\w+/,5),b(/\+/g,1),b(/\-/g,2),b(/\|/g,3),b(/\n/g,4),c(/[13][2 ]{0,7}[13]|[12] *4 *[12]/)||(b(/ /g),b(/43+(?=4)/g),!c(/353|24542|12+435|21453|35412|5342+1/)&&(!c(/^([^1]*|([^15]*1){1,2}[^15]*)$/)||-1)))

La fonction des frendements true, falseou -1sa valeur « peut - être ». Il devrait être appelé avec un seul argument: l'entrée. Les deux autres paramètres n'existent que pour raccourcir le code.

Voici une version moins golfée avec des commentaires:

var f = (input) => {
    var replace = (re, s) => input = input.replace(re, s);
    var test = re => re.test(input);

    /*
        Replace some "special" characters with ones that are shorter to put in a regex.
        "+" --> "1"
        "-" --> "2"
        "|" --> "3"
        "\n" --> ","
    */
    replace(/\+/g,1);
    replace(/\-/g,2);
    replace(/\|/g,3);
    replace(/\n/g,',');

    /*
        Shorten the word, if there is one, to just a single character "a".
    */
    replace(/[a-z]+/g,'a');

    /*
        Append a newline to the beginning and end of the input.
    */
    input = ','+input+',';

    /*
        Test the size of the box. These are the cases covered:
        /[13][2 ]{0,7}[13]/ : A horizontal edge or middle section has an inner width of fewer than 8 characters.
        /[12] *, *[12]/     : There are two horizontal edges in a row, with no space between.

        If either of these match, the word must be outside of the box. Return the truthy value (true).
    */
    if (test(/[13][2 ]{0,7}[13]|[12] *, *[12]/)) return true;

    /*
        Remove any spacing from the input. It it unnecessary from this point onwards.
    */
    replace(/ /g,'');

    /*
        Remove any lines with only vertical bars. These are also unnecessary.
    */
    replace(/,3+(?=,)/g,'');

    /*
        Edge / corner cases (heh). These are the cases covered:
        /3a3/    : two vertical bars with the word between.
        /2,a,2/  : two horizontal bars with the word between.
        /12+,3a/ : word inside the top left corner.
        /21,a3/  : word inside the top right corner.
        /3a,12/  : word inside the bottom left corner.
        /a3,2+1/ : word inside the bottom right corner.

        If any of these match, the word is inside the box. Return the falsy value (false).
    */
    if (test(/3a3|2,a,2|12+,3a|21,a3|3a,12|a3,2+1/)) return false;

    /*
        "Maybe" cases. These are the cases covered:
        /^[^1]*$/                : Input contains no corners, and may or may not contain a word.
        /^([^1a]*1){1,2}[^1a]*$/ : Input contains 1 or 2 corners, and no word.

        If either of these match, assuming the previous test cases have not been hit,
        we cannot tell if the word is inside or outside the box. Return the maybe value (-1).
    */
    if (test(/^([^1]*|([^1a]*1){1,2}[^1a]*)$/)) return -1;

    /*
        If none of the previous cases matched, the word must be outside of the box. Return the truthy value (true).
    */
    return true;
};

J'ai eu beaucoup de plaisir avec celui-ci. Merci!

Edit: 6 octets enregistrés grâce @L. Serné en modifiant l’ butilisation d’un argument par défaut, en sauvegardant 3 octets, et en passant [a-z]à \w, en sauvegardant 3 octets supplémentaires. Également enregistré 5 octets supplémentaires en rendant le remplacement de mot non global, en enregistrant 1 octet, et en passant "a"à 5et ","en 4, économisant 4 octets.


Essayé avec console.log(f("input")). Semble travailler. Excellent travail sur le golf cela.
devRicher

Beau travail sur la réponse. J'ai essayé d'y répondre et je me suis retrouvé coincé à mi-chemin. J'ai remarqué 2 petits économiseurs d'octets: passez b=(b,c)à b=(b,c=""), puis vous pourrez supprimer le dernier argument des deux appels bavec une chaîne vide comme second argument, en enregistrant (2 * 3-3 =) 3 octets au total. En outre, vous pouvez raccourcir le mot regex de [a-z]+à \w+(faites ceci avant que l’autre remplace, car cela correspondra également aux chiffres) en économisant 3 octets supplémentaires.
Luc

Bienvenue sur PPCG et belle première réponse!
Kritixi Lithos

Prime récompensée. Plus courte réponse. Excellent travail, réponse incroyable.
devRicher

8

Python 2.7, 532 494 453 octets

Celui-ci avait certainement beaucoup de cas particuliers. Mes valeurs de vérité et de fausseté sont les chaînes "True" et "False" respectivement. Ma valeur est peut-être une erreur d'index, car ils sont faciles à déclencher et qu'un de mes tests le déclenche si l'entrée est une chaîne vide, ce qui est peut-être un cas de toute façon. Je me suis beaucoup servi des expressions régulières.

Je ne joue pas souvent au python, alors je suis sûr que cela pourrait être plus pratique, mais voici mon code:

import re
def e(s):exit(str(s))
i=input()
T=1<2
F=2<1
a=len(i)+1
c=i.count('+')
s='[a-z]'
x=re.search
p=x(s,i)
k=x('\+.*'+s,i)
l=x(s+'.*\|',i)
r=x('\|.*'+s,i)
f=i.find('+')
g=i[f-1]=='-'and f>0
if x('\-.*\n.*\-',i):e(T)
if x('\+.{0,7}\+',i):e(T)
if c>1 and not p:i[a]
if c>3:e(not(r and l))
if c>0:
 if r and l:e(F)
 if g:
    if l:e(F)
    if p or k:e(T)
    i[a]
 if r or k:e(F)
 if p:e(T)
 i[a]
if x('-.*\s[a-z].*\s-',i):e(F)
if x('\|.*[a-z].*\|',i):e(F)
i[a]

Dans ma version jouée au golf, j'affiche la réponse vraie / fausse en appelant exit(bool as string). Voici une version commentée, dans laquelle les instructions de sortie sont remplacées par des instructions de retour, et tout a été déplacé dans une fonction:

import re
i=input()
T=True
F=False
def z():
    # some variables and shortcuts useful for testing

    # length of input +1. Used to throw an index out of bounds error on 'maybe'
    a=len(i)+1
    # c for i.Count()
    c=i.count
    # string used in regular expressions often
    s='[a-z]'
    # shorten regeX calls
    x=re.search
    # p is true is 'thinking' is Present on canvas
    p=x(s,i)
    # k is true if 'thinking' is Right of a 'Korner' (corner)
    k=x('\+.*'+s,i)
    # l is true if 'thinking' is Left of a pipe (|)
    l=x(s+'.*\|',i)
    # r is true if 'thinking' is right of a pipe
    r=x('\|.*'+s,i)
    # f is First corner (+) index
    f=i.find('+')

    # g is true if box is facing riGht (i.e. there is a dash before the first +)
    # for example, '---+' indicates the box faces right. if the + is the 0th
    # character, then the box must be facing left.
    # Note that this assignment also checks for the empty string 'maybe'
    # case, which is signalled by an IndexOutofBounds error
    # CASE 1: Empty Input
    # ex: ''
    g=i[f-1]=='-' and f>0

    # Begin testing all possible scenarios

    # CASE 2: Box is too short (vertically)
    # ex: ------
    #     ------
    if x('\-.*\n.*\-',i):return T

    # CASE 3: box is too short (horizontally)
    # ex: ||
    if x('\+.{0,7}\+',i):return T

    # CASE 4: box is not too short yet no corners (+) or text are present on canvas
    # ex:
    # |       |         --------
    # |       |   or
    # |       |         --------
    # this is a maybe case, so throw out of bounds error
    if c('+')>1 and not p:i[a]

    # CASE 5: Four corners visible (whole box visible)
    # ex: +---+
    #     | X |
    #     +---+
    # return false if text is both right of and left of pipes (i.e. in box)
    if c('+')>3:return not(r and l)

    # CASE 6: one or two corners visible
    # ex:
    # ----+        |    |          |
    #     |    or  +----+   or  ---+  etc
    # ----+
    # in this case, we idenify which way the box faces
    if c('+')>0:

        # CASE 6-A: Text is between two pipes
        # ex:
        #     |   X   |
        #     +-------+
        # if text is between pipes (box is extending from top or bottom of
        # canvas), then it is inside box
        if r and l:return F

        # CASE 6-B: Box faces right
        # if the box is riGht-facing, ex:
        # ----+
        #     |    or  ----+  etc
        # ----+            |
        if g:

            # CASE 6-B-a: Letters are left of a pipe or a + in a right facing box
            # ----+
            #  X  |   or  ----+
            # ----+         X |
            if l :return F

            # CASE 6-B-b: Letters are right of a pipe or + in a right facing box
            # ----+
            #     | X  or  ----+
            # ----+            | X
            if p or k:return T

            # CASE 6-B-c: right-facing otherwise
            # otherwise, it is a 'maybe' case
            # use an index out of bounds error to signal 'maybe'
            i[a]

        # CASE 6-C: Box faces left (or letters are on canvas yet not inside box)
        # ex:
        #   +----
        #   |        or   +---  or
        #   +----         |
        else:

            # CASE 6-C-a: Letters are right of a pipe or a + in a left facing box
            # if letters are right of pipe, they are inside box, ex:
            #   +----
            #   | X       or   +---  or X +---
            #   +----          | X        |
            if r or k:return F

            # CASE 6-C-b: Letters are left of a pipe in a left facing box
            # ex:
            #     +----
            #   X |        or     +---
            #     +----         X |

            # CASE 6-C-c: Letters are on canvas yet not left or right of
            # a pipe or a + (they must therefore be outside the box)
            # ex:
            #  |     |
            #  +-----+
            #     X
            if p:return T

            # CASE 6-C-d: text is not visible on canvas, and only part of the box is
            # ex:
            #  |     |
            #  +-----+
            #
            # this is a 'maybe' case, as text is off canvas
            # use an index out of bounds error to signal 'maybe'
            i[a]

    # CASE 7: No corners visible, nonempty input

    # CASE 7-A: No corners visible, letters sandwitched between dashes
    # ex:
    # -----
    #   X
    # -----
    # if there are no corners, yet letters are sandwitched between dashes,
    # then word is in box
    if x('-.*\s[a-z].*\s-',i):return F

    # CASE 7-B: No corners visible, letters sandwitched bewteen pipes
    # ex: |  X  |
    # in this case, word is inside box
    if x('\|.*[a-z].*\|',i):return F

    # If none of the above cases are met, it is a maybe, so throw the error
    i[a]

print z()

Ma solution suppose que l'entrée est valide, c'est-à-dire que 'Thinking' (ou ses sous-chaînes) est orthographié correctement, il n'y a qu'une seule boîte, etc.

Edit: Sauvegardé 10 octets grâce à la suggestion de @ ais523 de passer cà i.count('+')3 octets grâce à la suggestion de @ Pavel de remplacer Truepar 1<2et Falseavec 2>1, 23 octets en supprimant un bloc else inutile, et 2 octets en supprimant des espaces.

Edit 2: Sauvegardé 36 octets grâce à @Wheat Wizard qui a gentiment fait remarquer que mes "onglets" étaient en réalité de 5 espaces (D'oh!) Et a suggéré d'autres améliorations.


2
Impressionnant. Quelqu'un l'a réellement fait.
devRicher

1
Je pense ine jamais changer, non? Donc , vous pourriez probablement économiser quelques octets en stockant i.count('+')dans cplutôt que i.count, comme vous l' appelez jamais avec aucun argument , mais +.

1
Vous pouvez remplacer true et false par 1 <2 et 2 <1, n'est-ce pas?
Pavel

1
Vous n'êtes pas obligé de retourner chariot et indenter dans la définition de votre fonction. Autant que je sache, vous utilisez 4 espaces pour l'indentation. Vous pouvez mettre en retrait jusqu'à la profondeur 1 en utilisant un seul espace et la profondeur 2 avec un seul onglet.
Wheat Wizard

@WheatWizard et bien c'est embarrassant ... on dirait qu'Atom convertissait les onglets en 4 espaces. Merci pour le conseil, il a rasé 36 octets!
Ren

8

Befunge, 535 octets

Ce n’est pas beau, et n’est pas proche de concurrencer les réponses existantes, mais c’est le meilleur que je puisse obtenir à Befunge.

Retours 1si la pensée en dehors de la boîte, 0si la pensée dans la boîte, et -1pour peut - être .

p10p20p130p140p150p9-:60p70p"~":80p90pvp8p04+1:g04p03:$p9g04+g9g\<<
0$$$$"xxxx"5p041p031p$_v#!-+55:_v#`0:~<p05+1g
v01g04$_v#*`\"|"\`"-"::<>0g\8\p"0"-!!40g1-\8\p:4-!:00g0`*!:00g\6\p40g\8\p00g!*4v
>p50g20p>8%:30g88+*+:3-v4v\-1g05!!*-"3"\-"4"::p\7\g05!!-3:+*+88g8g04:p00+g00*g0<
v!*-"3"\-"5"::p\6\g04!!<!>>7\p::"C"-\"3"-*!!50g\9\p"0"-!!50g1-\9\p:5-!:40g9g48*v
>!40g1-\6\p::"S"-\"3"-*!^>0#4g#p9#\g#94#\8#g*#0-#5!#p*#\5#70#\g#-*^#84g9g04:!*`<
>80g60g-8`90g70g-1`**+!:10g80g`60g10g`20g90g`70g20g`+++!!*\!-.@
^!g01***`"}"g09`"}"g08`g070`g060<

Essayez-le en ligne!

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.