Pensare fuori dagli schemi - Lo sto facendo bene?


59

Continuo a sentire che pensare fuori dagli schemi è un obiettivo che vale la pena raggiungere, ma come posso sapere se lo sto facendo con successo?

Per risolvere questo dilemma ho già scritto un traduttore da Brainwave-to-ASCII che in teoria dovrebbe produrre output come

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

o

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

il che rende abbastanza facile dire se si sta pensando fuori dagli schemi o no. (Non #fanno parte dell'output e rappresentano nuove righe.)

Tuttavia, a causa di un bug a volte viene restituita solo una sezione più piccola dell'output:

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

        #
       +#
       |#
inking |#

    #
    #

L'obiettivo

Aiutatemi a classificare automaticamente l' output del traduttore da Brainwave-a-ASCII scrivendo un programma o una funzione che legge una ripensazione ascii e restituisce se si thinkingtrova nella casella, al di fuori di essa o non è in grado di distinguere dall'input.

Ingresso

Un set di stringhe della stessa lunghezza o come elenco o delimitato da newline contenenti

  • la stringa thinkingo pre o suffissi validi
  • i personaggi che +-|formano una scatola rettangolare o parti valide di essa
  • spazi
  • No# , quelli sono inclusi solo nella sfida per contrassegnare le estremità delle righe di input.

Produzione

  • un valore veritiero se thinkingè fuori dagli schemi
  • un valore errato se thinkingè nella casella
  • un distinto terzo forse valore se non può essere determinato dall'input se thinkingè nella scatola o no

Esempi

Truthy:

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

Come input di stringa:

"                   \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#
-#

Come input di stringa:

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

Può essere:

thinking#

g|#

think#
-----#

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

   +--#
   |  #

# (empty input)

Come input di stringa:

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

Regole

  • Questo è , quindi prova a usare il minor numero di byte possibile.
  • Il valore forse può essere scelto liberamente fintanto che è diverso dal valore verità / falsa ed è lo stesso per tutti gli ingressi forse. Può anche essere un errore.
  • Si può presumere che l'input sia sempre valido (es. Non contiene altri caratteri di +-ghiknt|, non più di una casella, ...).

Idea per un test di verità: +\n+scatola troppo piccola per una parola
Destructible Lemon

@DestructibleWatermelon Grazie, aggiungerò un caso di test simile.
Laikoni,

Non hai i casi più elementari nei casi di test. Ti dispiace includere l'intera scatola con il pensare in essa e l'intera scatola con l'intera parola che pensa al di fuori di essa?
ATaco,

Esiste la possibilità che la parola si sovrapponga alla scatola (pensando sulla scatola )?
Mukul Kumar il

17
Questo è un incubo di caso limite, cavolo.
Magic Octopus Urn

Risposte:


11

Javascript (ES6), 274 263 byte

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 funzione frestituisce true, falseo -1come valore "forse". Dovrebbe essere chiamato con un argomento: l'input. Gli altri due parametri esistono solo per abbreviare il codice.

Ecco una versione meno giocata a golf con commenti:

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

Mi sono divertito molto con questo. Grazie!

Modifica: 6 byte salvati grazie a @L. Serné modificando bper utilizzare un argomento predefinito, salvando 3 byte e cambiando [a-z]in \w, salvando altri 3 byte. Inoltre, ho salvato altri 5 byte rendendo la parola sostitutiva non globale, salvando 1 byte e cambiando "a"in 5e ","in 4, salvando 4 byte.


Provato con console.log(f("input")). Sembra funzionare. Ottimo lavoro sul golf questo.
devRicher

Bel lavoro sulla risposta. Ho provato a rispondere a questa domanda e mi sono bloccato a metà strada. Ho notato 2 piccoli risparmiatori di byte: passare b=(b,c)a b=(b,c=""), quindi è possibile rimuovere l'ultimo argomento delle due chiamate bcon una stringa vuota come secondo argomento, salvando (2 * 3-3 =) 3 byte in totale. Inoltre, puoi abbreviare la parola regex da [a-z]+a \w+(fallo prima che l'altro sostituisca, perché corrisponderà anche alle cifre) salvando altri 3 byte.
Luca

Benvenuti in PPCG e bella prima risposta!
Kritixi Lithos

Premio assegnato. Risposta più breve Ottimo lavoro, risposta incredibile.
devRicher

8

Python 2.7, 532 494 453 byte

Questo sicuramente ha avuto molti casi speciali. I miei valori di verità e falsità sono rispettivamente le stringhe "Vero" e "Falso". Il mio valore forse è un errore indice, in quanto sono facili da attivare e uno dei miei casi di test lo innesca se l'input è una stringa vuota, il che è comunque un caso forse. Ho usato un po 'le espressioni regolari.

Non gioco spesso a golf in Python, quindi sono sicuro che questo potrebbe essere golfato di più, ma ecco il mio codice:

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]

Nella mia versione golfata, visualizzo la risposta Vero / Falso chiamando exit(bool as string). Ecco una versione commentata, in cui le istruzioni di uscita vengono sostituite con le dichiarazioni di ritorno e tutto è stato spostato in una funzione:

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

La mia soluzione presuppone che l'input sia valido, ovvero che "Thinking" (o le sue sottostringhe) siano scritte correttamente, c'è solo una casella, ecc.

Modifica: salvato 10 byte grazie al suggerimento di @ ais523 di passare ca i.count('+'), 3 byte grazie al suggerimento di @ Pavel di sostituire Truecon 1<2e Falsecon 2>1, 23 byte rimuovendo un blocco else non necessario e 2 byte rimuovendo alcuni spazi.

Modifica 2: salvato 36 byte grazie alla procedura guidata @Wheat che ha gentilmente sottolineato che le mie 'schede' erano in realtà 5 spazi (D'oh!) E mi hanno suggerito altri miglioramenti.


2
Degno di nota. Qualcuno l'ha effettivamente fatto.
devRicher

1
Penso che inon cambi mai, giusto? Così si potrebbe probabilmente risparmiare qualche byte per la memorizzazione i.count('+')in cpiù che i.count, come si chiama mai con qualsiasi argomento, ma +.

1
Puoi sostituire vero e falso con 1 <2 e 2 <1, giusto?
Pavel

1
Non è necessario inserire il ritorno a capo e il rientro nella definizione della funzione. Per quanto ne so, stai usando 4 spazi per il rientro. È possibile rientrare nella profondità uno utilizzando un singolo spazio e la profondità 2 con una singola scheda.
Wheat Wizard

@WheatWizard questo è imbarazzante ... sembra che Atom stia convertendo le schede in 4 spazi. Grazie per il consiglio, si è rasato 36 byte!
ren

8

Befunge, 535 byte

Questo non è carino e non si avvicina alla concorrenza con le risposte esistenti, ma è il massimo che potrei ottenere in Befunge.

Restituisce 1se il pensiero fuori della scatola, 0se pensare all'interno della scatola, e -1per forse .

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<

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.