Myślenie nieszablonowe - czy robię to dobrze?

59

Ciągle słyszę, że nieszablonowe myślenie jest celem, który warto osiągnąć, ale skąd mam wiedzieć, czy mi się to udaje?

Aby rozwiązać ten dylemat, napisałem już tłumacz Brainwave-to-ASCII -translator, który teoretycznie powinien dawać wyniki takie jak

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

lub

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

co sprawia, że ​​dość łatwo jest stwierdzić, czy ktoś myśli nieszablonowo, czy nie. (Nie #są częścią wyniku i reprezentują nowe wiersze.)

Jednak z powodu błędu czasami zwracana jest tylko mniejsza część wyniku:

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

        #
       +#
       |#
inking |#

    #
    #

Zadanie

Proszę, pomóż mi automatycznie sklasyfikować wyjście Brainwave-to-ASCII -translator, pisząc program lub funkcję, która czyta ascii-representation i zwraca, czy thinkingjest w pudełku, poza nim, czy nie może tego stwierdzić na podstawie danych wejściowych.

Wejście

Zestaw ciągów o tej samej długości albo jako listę, albo ograniczony znakami nowej linii zawierającymi

  • ciąg thinkinglub jego poprawne przedrostki lub sufiksy
  • znaki +-|tworzące prostokątne pudełko lub jego prawidłowe części
  • spacje
  • NIE# , są one uwzględnione tylko w wyzwaniu oznaczenia końców linii wejściowych.

Wynik

  • truthy wartość, jeśli thinkingjest poza pole
  • falsy wartość, jeśli thinkingjest w polu
  • wyraźna trzecia wartość może być, jeśli nie można ustalić z danych wejściowych, czy thinkingjest w polu, czy nie

Przykłady

Prawda:

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

Jako ciąg wejściowy:

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

Falsy:

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

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

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

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

-#
n#
-#

Jako ciąg wejściowy:

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

Może:

thinking#

g|#

think#
-----#

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

   +--#
   |  #

# (empty input)

Jako ciąg wejściowy:

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

Zasady

  • To jest , więc spróbuj użyć jak najmniej bajtów.
  • Może wartość może być wybrana dowolnie, o ile różnią się od truthy / wartość falsy i jest taka sama dla wszystkich być może na dane wejściowe. Może to być także błąd.
  • Możesz założyć, że dane wejściowe są zawsze poprawne (np. Nie zawiera innych znaków, niż +-ghiknt|nie więcej niż jedno pole, ...).
Laikoni
źródło
Pomysł na prawdziwy przypadek testowy:, +\n+pudełko za małe na słowo
Destructible Lemon
@DestructibleWatermelon Dzięki, dodam podobny przypadek testowy.
Laikoni,
Nie masz najbardziej podstawowych przypadków w przypadkach testowych. Zastanawiasz się nad włączeniem całego pudełka z myśleniem i całego pudełka z całym słowem myślenia poza nim?
ATaco,
Czy istnieje możliwość, że słowo zachodzi na pole (myślenie o polu )?
Mukul Kumar,
17
To koszmar graniczny, Jezu.
Magic Octopus Urn

Odpowiedzi:

11

JavaScript (ES6), 274 263 bajtów

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

Funkcja fzwraca true, falselub -1jako wartość „być może”. Powinien zostać wywołany z jednym argumentem: wejściem. Pozostałe dwa parametry istnieją tylko w celu skrócenia kodu.

Oto mniej golfowa wersja z komentarzami:

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

Świetnie się bawiłem z tym. Dzięki!

Edycja: Zapisano 6 bajtów dzięki @L. Serné, zmieniając bużycie domyślnego argumentu, oszczędzając 3 bajty i przechodząc [a-z]do \w, oszczędzając 3 kolejne bajty. Również zapisywane 5 więcej bajtów poprzez zastąpienie słowa non-global, oszczędzając 1 bajt, a zmienia "a"się 5i ","na 4zapisanie 4 bajty.

kyle1320
źródło
Próbowałem z console.log(f("input")). Wydaje się działać. Świetna robota w golfa.
devRicher
Dobra robota na odpowiedź. Próbowałem odpowiedzieć na to pytanie i utknąłem w połowie drogi. Zauważyłem 2 małe wygaszacze bajtów: zmień b=(b,c)na b=(b,c=""), a następnie możesz usunąć ostatni argument dwóch wywołań bz pustym ciągiem jako drugim argumentem, oszczędzając (2 * 3-3 =) 3 bajty łącznie. Możesz także skrócić słowo regex od [a-z]+do \w+(zrób to, zanim inne zastąpią, ponieważ to również dopasuje cyfry), oszczędzając 3 kolejne bajty.
Łukasz
Witamy w PPCG i fajna pierwsza odpowiedź!
Kritixi Lithos
Przyznana nagroda. Najkrótsza odpowiedź. Świetna robota, niesamowita odpowiedź.
devRicher
8

Python 2.7, 532 494 453 bajtów

Ten z pewnością miał wiele specjalnych przypadków. Moje prawdziwe i fałszywe wartości to odpowiednio ciąg „Prawda” i „Fałsz”. Moja wartość może być błędem indeksu, ponieważ jest łatwy do wyzwolenia, a jeden z moich przypadków testowych wyzwala go, jeśli dane wejściowe są pustym ciągiem, co i tak może być przypadkiem. Dość często korzystałem z wyrażeń regularnych.

Często nie gram w golfa w pythonie, więc jestem pewien, że można by grać w golfa bardziej, ale oto mój kod:

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]

W mojej wersji golfowej wyświetlam odpowiedź Prawda / Fałsz, dzwoniąc exit(bool as string). Oto skomentowana wersja, w której instrukcje wyjścia są zastępowane instrukcjami powrotu, a wszystko zostało przeniesione do funkcji:

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

Moje rozwiązanie zakłada, że ​​dane wejściowe są prawidłowe, tzn. „Myślenie” (lub jego podciągi) są poprawnie zapisane, jest tylko jedno pole itp.

Edit: Zapisane 10 bajtów dzięki sugestii @ ais523 do zmiany cdo i.count('+'), 3 bajty dzięki @ sugestią Pavel za zastąpienia Truez 1<2i Falsez 2>123 bajtów przez usunięcie niepotrzebnych innego bloku i 2 bajty usuwając niektóre przestrzenie.

Edycja 2: Zapisano 36 bajtów dzięki @Wheat Wizard, który uprzejmie zauważył, że moje „tabulatory” to tak naprawdę 5 spacji (D'oh!) I zasugerował kilka innych ulepszeń.

ren
źródło
2
Imponujący. Ktoś to zrobił.
devRicher
1
Myślę, że inigdy się nie zmienia, prawda? Więc prawdopodobnie można zaoszczędzić kilka bajtów przez przechowywanie i.count('+')w czamiast i.count, jak nigdy go nie nazywać, ale z żadnym argumentem +.
1
Możesz zamienić true i false na 1 <2 i 2 <1, prawda?
Pavel
1
Nie musisz przewozić znaku powrotu i wcięcia w definicji funkcji. O ile mogę powiedzieć, używasz 4 spacji do wcięcia. Możesz wciąć do głębokości jeden za pomocą pojedynczej spacji i głębokości 2 za pomocą jednej tabulacji.
Wheat Wizard
@ WheatWizard dobrze to krępujące ... wygląda na to, że Atom konwertuje tabulatory na 4 spacje. Dzięki za radę, straciło 36 bajtów!
ren
8

Befunge, 535 bajtów

To nie jest ładne i nie jest blisko konkurowania z istniejącymi odpowiedziami, ale to najlepsze, co mogłem osiągnąć w Befunge.

Zwraca 1jeśli nieszablonowego myślenia, 0jeśli myśli się wewnątrz pudełka, a -1na może .

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<

Wypróbuj online!

James Holderness
źródło