Berpikir di luar kotak - Apakah saya melakukannya dengan benar?


59

Saya terus mendengar bahwa berpikir di luar kotak adalah tujuan yang layak dicapai, tetapi bagaimana saya bisa tahu jika saya berhasil melakukannya?

Untuk mengatasi dilema ini saya sudah menulis -translator Brainwave-to-ASCII yang secara teori harus menghasilkan output seperti

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

atau

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

yang membuatnya cukup mudah untuk mengetahui apakah seseorang berpikir di luar kotak atau tidak. (Ini #bukan bagian dari output dan mewakili baris baru.)

Namun, karena bug terkadang hanya sebagian kecil dari output yang dikembalikan:

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

        #
       +#
       |#
inking |#

    #
    #

Tugas

Tolong bantu saya untuk secara otomatis mengklasifikasikan output -translator Brainwave-to-ASCII dengan menulis sebuah program atau fungsi yang membaca reprensentasi ascii dan mengembalikan apakah thinkingada di dalam kotak, di luarnya atau tidak dapat diketahui dari input.

Memasukkan

Satu set string dengan panjang yang sama baik sebagai daftar atau dibatasi oleh baris baru yang mengandung

  • string thinkingatau pre- atau suffix yang valid
  • karakter yang +-|membentuk kotak persegi panjang atau bagian yang valid dari itu
  • spasi
  • TIDAK# , itu hanya termasuk dalam tantangan untuk menandai ujung jalur input.

Keluaran

  • sebuah truthy nilai jika thinkingberada di luar kotak
  • sebuah falsy nilai jika thinkingdalam kotak
  • sepertiga yang berbeda mungkin bernilai jika tidak dapat ditentukan dari input apakah thinkingada di dalam kotak atau tidak

Contohnya

Benar:

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

Sebagai input string:

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

Sebagai input string:

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

Mungkin:

thinking#

g|#

think#
-----#

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

   +--#
   |  #

# (empty input)

Sebagai input string:

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

Aturan

  • Ini adalah , jadi coba gunakan sesedikit mungkin byte.
  • Nilai mungkin dapat dipilih secara bebas asalkan berbeda dari nilai true / falsy dan sama untuk semua mungkin-input. Ini juga bisa menjadi kesalahan.
  • Anda dapat mengasumsikan bahwa input selalu valid (mis. Tidak mengandung karakter lain selain +-ghiknt|, tidak lebih dari satu kotak, ...).

Gagasan untuk kasus uji kebenaran:, +\n+kotak terlalu kecil untuk satu kata
Destructible Lemon

@DestructibleWatermelon Terima kasih, saya akan menambahkan test case yang serupa.
Laikoni

Anda tidak memiliki kasus paling dasar dalam kasus uji Anda. Pikiran termasuk seluruh kotak dengan pemikiran di dalamnya, dan seluruh kotak dengan seluruh kata berpikir di luarnya?
ATaco

Apakah ada kemungkinan kata tumpang tindih kotak (berpikir pada kotak )?
Mukul Kumar

17
Ini adalah mimpi buruk batas kasus, ya ampun.
Magic Gurita Guci

Jawaban:


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

Fungsi fmengembalikan true,, falseatau -1sebagai nilainya "mungkin". Itu harus dipanggil dengan satu argumen: input. Dua parameter lainnya hanya ada untuk mempersingkat kode.

Berikut adalah versi yang tidak begitu terkenal dengan komentar:

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

Bersenang-senang dengan yang satu ini. Terima kasih!

Sunting: Disimpan 6 byte, terima kasih @L. Serné dengan memodifikasi buntuk menggunakan argumen default, menyimpan 3 byte, dan mengubah [a-z]ke \w, menyimpan 3 byte lagi. Juga menghemat 5 byte lebih dengan membuat penggantian kata non-global, menghemat 1 byte, dan mengubah "a"ke 5dan ","ke 4, menghemat 4 byte.


Mencoba dengan console.log(f("input")). Tampaknya bekerja. Pekerjaan yang bagus untuk bermain golf ini.
devRicher

Pekerjaan yang bagus pada jawabannya. Saya mencoba menjawab ini, dan saya mandek di tengah jalan. Saya perhatikan 2 byte-saver kecil: ubah b=(b,c)menjadi b=(b,c=""), dan kemudian Anda dapat menghapus argumen terakhir dari dua panggilan bdengan string kosong sebagai argumen kedua, menyimpan (2 * 3-3 =) total 3 byte. Selain itu, Anda dapat mempersingkat kata regex dari [a-z]+menjadi \w+(lakukan ini sebelum yang lain menggantikan, karena ini juga akan cocok dengan angka) menghemat 3 byte lebih.
Luke

Selamat datang di PPCG dan jawaban pertama yang bagus!
Kritixi Lithos

Hadiah yang dianugerahkan. Jawaban tersingkat. Kerja bagus, jawaban luar biasa.
devRicher

8

Python 2.7, 532 494 453 byte

Yang ini pasti punya banyak kasus khusus. Nilai-nilai kebenaran dan kepalsuan saya masing-masing adalah string "Benar" dan "Salah". Nilai mungkin saya adalah Kesalahan Indeks, karena mudah dipicu dan salah satu kasus pengujian saya memicunya jika inputnya berupa string kosong, yang merupakan kasus mungkin. Saya menggunakan ekspresi reguler sedikit.

Saya tidak sering bermain golf dengan python, jadi saya yakin ini bisa diturunkan lebih banyak lagi, tapi ini kode saya:

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]

Dalam versi golf saya, saya menampilkan jawaban Benar / Salah dengan menelepon exit(bool as string). Inilah versi yang dikomentari, di mana pernyataan keluar diganti dengan pernyataan pengembalian, dan semuanya telah dipindahkan ke fungsi:

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

Solusi saya mengasumsikan bahwa input tersebut valid, yaitu 'Berpikir' (atau substringnya) dieja dengan benar, hanya ada satu kotak, dll.

Sunting: Disimpan 10 byte berkat saran @ ais523 untuk diubah cmenjadi i.count('+'), 3 byte berkat saran @ Pavel untuk mengganti Truedengan 1<2dan Falsedengan 2>1, 23 byte dengan menghapus blok orang lain yang tidak dibutuhkan, dan 2 byte dengan menghapus beberapa spasi.

Sunting 2: Disimpan 36 byte berkat @Wheat Wizard yang dengan ramah menunjukkan bahwa 'tab' saya sebenarnya 5 spasi (D'oh!) Dan menyarankan beberapa peningkatan lainnya.


2
Impresif. Seseorang benar-benar melakukannya.
devRicher

1
Saya pikir itidak pernah berubah, kan? Jadi Anda mungkin bisa menghemat byte dengan menyimpan i.count('+')di cbukan i.count, karena Anda tidak pernah menyebutnya dengan argumen tapi +.

1
Anda dapat mengganti benar dan salah dengan 1 <2 dan 2 <1, kan?
Pavel

1
Anda tidak perlu kembali dan indentasi dalam definisi fungsi Anda. Sejauh yang saya tahu Anda menggunakan 4 spasi untuk indentasi. Anda dapat indentasi ke kedalaman satu menggunakan spasi tunggal dan kedalaman 2 dengan satu tab.
Wheat Wizard

@WheatWizard nah ini memalukan ... sepertinya Atom mengonversi tab menjadi 4 spasi. Terima kasih atas sarannya, ini mencukur 36 byte!
ren

8

Befunge, 535 byte

Ini tidak cantik, dan hampir tidak bersaing dengan jawaban yang ada, tapi itu yang terbaik yang bisa saya capai di Befunge.

Pengembalian 1jika berpikir di luar kotak, 0jika berpikir di dalam kotak, dan -1untuk mungkin .

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<

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.