Über den Tellerrand hinausdenken - mache ich es richtig?


59

Ich höre immer wieder, dass es sich lohnt, über den Tellerrand hinaus zu denken, aber wie kann ich feststellen, ob ich es erfolgreich mache?

Um dieses Dilemma zu lösen, habe ich bereits einen Brainwave-to-ASCII- Übersetzer geschrieben, der theoretisch Ausgaben wie erzeugen sollte

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

oder

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

was es ziemlich einfach macht zu sagen, ob man über den Tellerrand hinaus denkt oder nicht. (Sie #sind nicht Teil der Ausgabe und stellen neue Zeilen dar.)

Aufgrund eines Fehlers wird jedoch manchmal nur ein kleinerer Teil der Ausgabe zurückgegeben:

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

        #
       +#
       |#
inking |#

    #
    #

Die Aufgabe

Bitte helfen Sie mir, die Brainwave-zu-ASCII- Übersetzer-Ausgabe automatisch zu klassifizieren, indem Sie ein Programm oder eine Funktion schreiben, die eine ASCII- Repräsentation liest und zurückgibt, ob sie thinkingsich in der Box befindet, sich außerhalb davon befindet oder nicht von der Eingabe unterscheiden konnte.

Eingang

Eine Reihe von Zeichenfolgen gleicher Länge, die entweder als Liste oder durch Zeilenumbrüche begrenzt sind

  • die Zeichenfolge thinkingoder gültige Vor- oder Nachsetzzeichen davon
  • die Zeichen, +-|die ein rechteckiges Kästchen oder gültige Teile davon bilden
  • Leerzeichen
  • NEIN# , diese sind nur in der Abfrage enthalten, um die Enden der Eingabezeilen zu markieren.

Ausgabe

  • Ein wahrer Wert, wenn er thinkingaußerhalb des Rahmens liegt
  • ein falscher Wert, wenn thinkingin der Box ist
  • ein deutlicher dritte vielleicht Wert , wenn sie nicht von dem Eingang bestimmt werden können , ob thinkingin der Box oder nicht

Beispiele

Wahrheit:

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

Als Stringeingabe:

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

Falsch:

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

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

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

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

-#
n#
-#

Als Stringeingabe:

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

Vielleicht:

thinking#

g|#

think#
-----#

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

   +--#
   |  #

# (empty input)

Als Stringeingabe:

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

Regeln

  • Das ist , also versuchen Sie, so wenig Bytes wie möglich zu verwenden.
  • Der Wert für " Vielleicht" kann frei gewählt werden, solange er sich vom Wert für "Wahr" / "Falsch" unterscheidet und für alle "Vielleicht" -Eingaben gleich ist. Es kann auch ein Fehler sein.
  • Sie können davon ausgehen, dass die Eingabe immer gültig ist (z. B. enthält keine anderen Zeichen als +-ghiknt|, nicht mehr als ein Kästchen, ...).

Idee für wahrheitsgemäßen Testfall:, +\n+Box zu klein für ein Wort
Destructible Lemon

@DestructibleWatermelon Danke, ich werde einen ähnlichen Testfall hinzufügen.
Laikoni

Sie haben nicht die grundlegendsten Fälle in Ihren Testfällen. Stört es dich, die ganze Kiste mit dem Denken darin einzuschließen und die ganze Kiste mit dem ganzen Wort, das außerhalb davon denkt?
ATaco

Gibt es eine Möglichkeit, dass sich das Wort mit dem Kästchen überschneidet ( über das Kästchen nachdenken )?
Mukul Kumar

17
Dies ist ein Grenzfall-Albtraum, Herrgott.
Magic Octopus Urn

Antworten:


11

Javascript (ES6), 274 263 Bytes

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

Die Funktion fgibt true, falseoder -1als "Vielleicht" -Wert zurück. Es sollte mit einem Argument aufgerufen werden: der Eingabe. Die anderen beiden Parameter dienen nur zur Kürzung des Codes.

Hier ist eine weniger golfene Version mit Kommentaren:

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

Hatte viel Spaß mit diesem. Vielen Dank!

Bearbeiten: 6 Bytes gespeichert dank @L. Serné durch Ändern b, um ein Standardargument zu verwenden, Sparen von 3 Bytes und Ändern , um 3 weitere Bytes [a-z]zu \wsparen. Außerdem wurden 5 weitere Bytes gespart, indem die Wortersetzung als nicht global definiert, 1 Byte gespart und "a"zu 5und ","zu 4geändert wurde, wodurch 4 Bytes gespart wurden.


Versucht mit console.log(f("input")). Scheint zu funktionieren. Toller Job beim Golfen.
devRicher

Gute Arbeit bei der Antwort. Ich habe versucht, darauf zu antworten, und bin auf halbem Weg festgefahren. Ich habe 2 kleine Bytespeicher bemerkt: ändere b=(b,c)auf b=(b,c=""), und dann kannst du das letzte Argument der beiden Aufrufe auf bmit einer leeren Zeichenfolge als zweites Argument entfernen und insgesamt 3 Bytes (2 * 3-3 =) sparen. Sie können auch das Wort "Regex" von " [a-z]+bis" kürzen \w+(dies tun, bevor das andere Wort ersetzt wird, da dies auch mit den Ziffern übereinstimmt) und so 3 weitere Bytes einsparen.
Luke

Willkommen bei PPCG und schöne erste Antwort!
Kritixi Lithos

Kopfgeld zuerkannt. Kürzeste Antwort. Tolle Arbeit, tolle Antwort.
devRicher

8

Python 2.7, 532 494 453 Bytes

Dieser hatte sicher viele Sonderfälle. Meine wahren und falschen Werte sind die Zeichenfolgen "True" und "False". Mein "Vielleicht" -Wert ist ein Indexfehler, da er leicht auszulösen ist und einer meiner Testfälle ihn auslöst, wenn die Eingabe eine leere Zeichenfolge ist, was ohnehin ein "Vielleicht" -Fall ist. Ich habe ziemlich viel mit regulären Ausdrücken gearbeitet.

Ich spiele nicht oft in Python, daher bin ich sicher, dass ich hier mehr Golf spielen kann, aber hier ist mein 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]

In meiner Golfversion zeige ich die Richtig / Falsch-Antwort an, indem ich anrufe exit(bool as string). Hier ist eine kommentierte Version, in der die exit-Anweisungen durch return-Anweisungen ersetzt werden und alles in eine Funktion verschoben wurde:

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

Meine Lösung geht davon aus, dass die Eingabe gültig ist, dh "Denken" (oder seine Teilzeichenfolgen) sind richtig geschrieben, es gibt nur ein einziges Kästchen usw.

Bearbeiten: 10 Bytes gespart dank des Vorschlags von @ ais523, cauf i.count('+'), 3 Bytes dank des Vorschlags von @ Pavel, Truedurch 1<2und Falsemit zu ersetzen 2>1, 23 Bytes durch Entfernen eines nicht benötigten else-Blocks und 2 Bytes durch Entfernen einiger Leerzeichen.

Edit 2: 36 Bytes gespart dank @Wheat Wizard, der freundlicherweise darauf hinwies, dass meine "Tabs" tatsächlich 5 Leerzeichen (D'oh!) Enthielten und einige andere Verbesserungen vorschlug.


2
Beeindruckend. Jemand hat es tatsächlich getan.
devRicher

1
Ich denke, iändert sich nie, oder? Sie könnten also wahrscheinlich ein paar Bytes einsparen, indem Sie i.count('+')in canstatt speichern i.count, da Sie es nie mit einem anderen Argument aufrufen +.

1
Sie können true und false durch 1 <2 und 2 <1 ersetzen, richtig?
Pavel

1
Sie müssen in Ihrer Funktionsdefinition keinen Wagenrücklauf und keine Einrückung durchführen. Soweit ich das beurteilen kann, werden 4 Leerzeichen zum Einrücken verwendet. Sie können die Tiefe 1 mit einem einzelnen Leerzeichen und die Tiefe 2 mit einer einzelnen Registerkarte einrücken.
Weizen-Zauberer

@ WheatWizard Nun, das ist peinlich ... sieht aus, als würde Atom Tabs in 4 Leerzeichen konvertieren. Danke für den Rat, es hat 36 Bytes abgeschnitten!
Ren

8

Befunge, 535 Bytes

Das ist nicht schön und kann mit den vorhandenen Antworten nicht mithalten, aber es ist das Beste, was ich in Befunge erreichen konnte.

Gibt 1wenn Denken außerhalb der Box, 0wenn in der Box zu denken, und -1für vielleicht .

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<

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.