Будет ли эта строка работать как строка?


92

Напишите программу, которая принимает строку из одной строки, которая, как вы можете предположить, будет содержать только символы /\_‾. (Это прямая и обратная косая черта, подчеркивание и наложение . Вы можете использовать ~вместо наложения, если это необходимо, поскольку наложение не является удобным ASCII.)

Например, один из возможных входных данных:

__/‾‾\/\_/‾

Ваша программа должна вывести истинное или ложное значение в зависимости от того, связан ли левый край строки, так сказать, с правым краем строки через строки символов. Таким образом, если бы кернинг был немного меньше, то была бы сплошная черная (хотя и странная) линия от левого края до правого, как непрерывный кусок нити или шпагата.

Вывод для приведенного выше примера будет верным, потому что края связаны:

пример пути

Чтобы быть ясно на связи:

  • / соединяется внизу слева и сверху справа
  • \ соединяется в его верхнем левом и нижнем правом
  • _ соединяется внизу слева и справа внизу
  • (или ~) соединяется сверху слева и справа сверху

Также:

  • Не имеет значения, начинаются ли края строки сверху или снизу, важно только то, что они соединяются горизонтально по всей длине строки.

  • Вы можете предположить, что входная строка не пуста, и, конечно, только одна строка.

Вот еще несколько примеров, за которыми следует 1 (правда), если они связаны, или 0 (ложь), если нет:

__/‾‾\/\_/‾
1

_
1

\
1

/
1

‾
1

___
1

\/
1

/\/
1

/\/\
1

‾‾‾
1

\\
0

‾‾
1

_‾
0

‾_
0

\_____/
1

\/\\/\\___
0

\/\__/‾‾\
1

______/\_____
1

‾‾‾‾‾‾\\_____
0

‾‾‾‾‾‾\______
1

_____/‾‾‾‾‾
1

\___/‾‾‾\___/‾‾‾
1

\_/_\_
0

\_/\_
1

/\/\/\/\/\/\/\/\/\/\/\/
1

____________________
1

‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
1

‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾/
0

‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\
1

/\‾/\‾___/\_\/__\/\‾‾
0

Самый короткий код - победитель.


37
Добро пожаловать в PPCG! Хороший первый вызов.
AdmBorkBork

1
Являются ли символы, указанные в вашем вызове, единственными, которые появятся в строке?
Воплощение Невежества

@EmbodimentofIgnorance Да, только 4.
Дискретные игры

30
Подождите, вы могли бы сделать из этого язык
Делиот

2
@ Arnauld Нет, я действительно думаю только правдивое для связанного и ложное для несвязанного. (Если для такого рода вопросов нормальным не является обмен разрешением?)
Discrete Games

Ответы:


34

Желе , 9 байт

-1 байт благодаря @EriktheOutgolfer

Ожидайте ~вместо . Возвращает 0 или 1 .

O*Ɲ:⁽8ƇḂẠ

Попробуйте онлайн! , Набор тестов Truthy , набор тестов Falsy

Используя эту формулу (но в остальном похож на 11-байтовую версию ниже):

n=xy15145

Переход действителен, если n нечетно, или недействителен, если n четно.

комментарии

O*Ɲ:⁽8ƇḂẠ     - main link, taking a string          e.g. "\_/"
O             - get ASCII codes                     -->  [92, 95, 47]
 *Ɲ           - exponentiation on all pairs         -->  [92**95, 95**47]
   :⁽8Ƈ       - integer division by 15145           -->  [23964828…8421, 59257069…0485]
       Ḃ      - least significant bit (i.e. parity) -->  [1, 1]
        Ạ     - all values equal to 1?              -->  1

Желе ,  14 12  11 байт

Поддерживает (и ожидает) символ во входной строке. Возвращает 0 или 1 .

O*Ɲ%276%7ỊẠ

Попробуйте онлайн! , Набор тестов Truthy , набор тестов Falsy

Как?

Учитывая два последовательных символа кодов ASCII x и y , мы хотим функцию, которая проверяет, формируют ли они допустимый переход.

Нам нужна некоммутативная операция, потому что результат может измениться, когда символы поменялись местами. Например, _/действует, но /_нет.

Используя возведение в степень, возможная формула 1 :

n=(xymod276)mod7

Переход действителен, если n1 , или недействителен, если n>1 .

 chars |    x |    y | (x**y)%276 | %7 | valid
-------+------+------+------------+----+-------
   __  |   95 |   95 |      71    |  1 |  yes
   _/  |   95 |   47 |     119    |  0 |  yes
   _‾  |   95 | 8254 |     265    |  6 |   no
   _\  |   95 |   92 |     265    |  6 |   no
   /_  |   47 |   95 |      47    |  5 |   no
   //  |   47 |   47 |      47    |  5 |   no
   /‾  |   47 | 8254 |       1    |  1 |  yes
   /\  |   47 |   92 |       1    |  1 |  yes
   ‾_  | 8254 |   95 |     136    |  3 |   no
   ‾/  | 8254 |   47 |      88    |  4 |   no
   ‾‾  | 8254 | 8254 |     196    |  0 |  yes
   ‾\  | 8254 |   92 |     196    |  0 |  yes
   \_  |   92 |   95 |      92    |  1 |  yes
   \/  |   92 |   47 |      92    |  1 |  yes
   \‾  |   92 | 8254 |     184    |  2 |   no
   \\  |   92 |   92 |     184    |  2 |   no

1. Найден с помощью перебора в Node.js (с помощью BigInts).

комментарии

O*Ɲ%276%7ỊẠ   - main link, taking a string          e.g. "\_/"
O             - get ASCII codes                     -->  [92, 95, 47]
 *Ɲ           - exponentiation on all pairs         -->  [92**95, 95**47]
   %276       - modulo 276                          -->  [92, 119]
       %7     - modulo 7                            -->  [1, 0]
         Ị    - ≤1?                                 -->  [1, 1]
          Ạ   - all values equal to 1?              -->  1

2
метод справочной таблицы принес много проблем
qwr

9 байт : так ⁽"Oже, как 9580.
Эрик Outgolfer

@EriktheOutgolfer Спасибо. :) Может быть, скрипт, представленный в этом совете, должен быть обновлен для поддержки этого формата (когда это актуально).
Арно

1
@Arnauld На самом деле, Джонатан Аллан сделал это .
Эрик Outgolfer

16

Ruby -n , 30 байтов

p !/[_\\][\\‾]|[\/‾][_\/]/

Попробуйте онлайн!

Сокращает все последовательности, прерывающие строки, до двух случаев, используя классы символов Regex.


5
Вы можете сохранить 4 байта, используя ~вместо . Я не уверен, имеет ли это значение для этого испытания, так как количество символов одинаково.
iamnotmaynard

Вам нужно избегать /s, даже если они находятся в квадратных скобках?
Соломон Уко

14

JavaScript (ES6), 45 байт

Наивный путь.

s=>!/\/\/|\\\\|_~|~_|~\/|_\\|\/_|\\~/.test(s)

Попробуйте онлайн!


1
Так что это проверяет все недопустимые пары, чтобы убедиться, что они не существуют в строке? Умная.
Дискретные игры

@DiscreteGames Да, именно так. (За исключением того, что я забыл 2 из них. Теперь исправлено.)
Арно

35 байт: s=>!/[~\/][\/_]|[_\\][\\~]/.test(s). Он проверяет, если \/или в ~конце \/или _. И затем, он проверяет, если \\или _конец \\или ~.
Исмаэль Мигель

@IsmaelMiguel Это может быть опубликовано в качестве отдельного ответа, но я бы лучше оставить его без изменений для справки, так как оно показывает простейшее (как в «наименее сложном») регулярное выражение, решающее проблему.
Арно

Вы можете опубликовать его как альтернативный, но не окончательный ответ.
Исмаэль Мигель

10

R , 89 87 81 78 байт

-2 байта благодаря @Giuseppe

-6 байт благодаря @ Ник Кеннеди

-3 байта с заменой 1:length(y)на seq(a=y), где aкороткоalong.with

y=utf8ToInt(scan(,''));all(!diff(cumprod(c(1,y>93)*2-1)[seq(a=y)]*(y%%2*2-1)))

использует \ / _ ~. Это, вероятно, не так коротко, как решение на основе регулярных выражений, но мне хотелось сделать что-то немного другое для всех остальных.

utf8ToInt('\\/_~')
# [1]  92  47  95 126

Символы меньше 93 переключают состояние сверху вниз (или наоборот) и, таким образом, ведут себя так, -1как другие ничего не делают, и ведут себя как 1, cumprod отслеживает состояние относительно начала. Чётные числа находятся в северной части штата (представлены с помощью -1), нечетные числа находятся в нерабочем состоянии ( 1). Если строка не сломана, отслеживаемое состояние, умноженное на положение вверх / вниз, не должно изменяться, оно всегда будет начальным условием ( -1или 1)

Попробуйте онлайн


2
это довольно умный и уникальный R способ делать вещи! Я полагаю, что вы можете удалить ()округление, y%%2чтобы сэкономить 2 байта, поскольку специальные операторы %(any)%имеют довольно высокий приоритет.
Джузеппе

3
Как насчет tio для 83 байтов? Использует неявное принуждение к логическим путем!
Ник Кеннеди

9

Python , 46 байт

f=lambda s:s==''or s[:2]in"__/~~\/\_"*f(s[1:])

Попробуйте онлайн!

__/~~\/\_23знак равно8

Я пробовал другие, менее смешные методы, чтобы проверить пары символов, но все они были дольше, чем жестко кодировать все допустимые пары, подобные этой.



6

Чип -z , 17 байт

FZ!C~aS
A}^]--^~t

Попробуйте онлайн! (TIO включает, -vчтобы облегчить понимание результатов.)

Ожидает _/~\множество. Возвращает либо \x00(ложь), либо \x01(правда).

Стратегия для моего ответа использует следующую информацию:

Symbol  Binary
   _    0101 1111
   /    0010 1111
   ~    0111 1110
   \    0101 1100
          ^   ^ ^
        HGFE DCBA

A: Эта битовая позиция бывает, 1когда левая сторона символа низкая, и 0когда она высокая
F: эта битовая позиция бывает, 0когда правая сторона символа низкая, и 1когда она высокая
C: эта битовая позиция всегда быть1

Используя эту информацию, мне просто нужно проверить, соответствует ли Fкаждый символ not Aследующему. xorЗатвора является удобным способом для достижения этой цели .

Следующий код делает это, но выдает выходные данные для каждой пары (плюс дополнительный 1в начале) (7 байт):

FZ!
A}a

Мы хотим остановить при первом сбое, а также распечатать, остановились ли мы в пределах строки или в нулевом терминаторе (мы также добавляем, -zчтобы дать нам нулевой терминатор). Мы можем использовать, not Cчтобы указать, где мы остановились, и это дает нам эту программу (13 байт):

FZ!C~a
A}^]~t

Но у нас все еще есть «ведущие нули» (например, \_/\дает 00 00 00 00 01), так что это преобразуется в ответ, данный в верхней части.


Хорошо, я заметил этот шаблон, но не знал хорошего языка, чтобы использовать его.
гистократ

6

05AB1E , 29 14 9 байт

ÇümŽb‘÷ÈP

Port of @Arnauld 's Jelly ответ , так что не забудьте также поддержать его!

Ввод с .

Попробуйте онлайн или проверьте все контрольные примеры .


Оригинальный 29- байтовый ответ:

„_~SD2×s:Çü-т+•6_üê{↕ƵΔвåO_

Ввод с ~вместо .

Это звучало короче в моей голове .. Попробую сыграть в гольф отсюда.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение: "

_~S                          # Push the characters ["_","~"]
    D2×                       # Duplicate it, and increase each to size 2: ["__","~~"]
       s:                     # Swap and replace all "__" with "_" and all "~~" with "~"
                              #  in the (implicit) input-string
         Ç                    # Convert the remaining characters to unicode values
          ü-                  # Calculate the difference between each pair
            т+                # Add 100 to each
              6_üê{↕       # Push compressed integer 1781179816800959
                       ƵΔ     # Push compressed integer 180
                         в    # Convert the larger integer to Base-180 as list: 
                              #  [52,66,69,100,103,131,179]
                          å   # Check for each if it's in the difference-list
                              # (1 if present; 0 if not)
                           O  # Sum the truthy values
                            _ # Check if this sum is exactly 0 (1 if 0; 0 otherwise)
                              # (and output this result implicitly)

См. Этот мой совет 05AB1E (разделы Как понять большие целые числа? И Как сжать списки целых чисел? ), Чтобы понять, почему •6_üê{↕есть 1781179816800959, ƵΔесть 180и •6_üê{↕ƵΔвесть [52,66,69,100,103,131,179].

Дополнительное объяснение:

24["/_", 52]["\~", 66]["_~", 69]["//", 100]["\\", 100]["_\", 103]["~_", 131]["~/", 179]
__~~//\\0100~и _ во входной строке, перед вычислением и проверкой парных различий.


1
Теперь 9 байтов .
Арно

@ Arnauld О, хорошо!
Кевин Круйссен

Это объяснение будет работать как строка.
connectyourcharger

@connectyourcharger Что ты имеешь в виду?
Кевин Круйссен

6

Python 3 , 79 70 63 байта

Спасено 16 байтов благодаря Арно и Джо Кингу, спасибо!

p=lambda s:len(s)<2or((ord(s[-2])%13>5)^ord(s[-1])%2)&p(s[:-1])

Попробуйте онлайн!

Python 3 , 67 60 байт с ~ вместо ‾

p=lambda s:len(s)<2or(~(ord(s[-2])//7^ord(s[-1]))&p(s[:-1]))

Попробуйте онлайн!


2
Хороший первый ответ! Вы можете сохранить 6 байтов , удалив пробелы. (Вы можете добавить ссылку TIO, кстати.)
Арно

1
Спасибо! Я наслаждаюсь изучением всех этих уловок
Иоахим Уортингтон

4

Python 3, 126 байт

lambda s,d={'‾':'\‾','_':'/_','/':'\‾','\\':'/_'}:len(s)<2or all([s[i+1] in d[s[i]]for i in range(len(s)-1)if s[i]in d])

4

Haskell , 70 байт

Этот вариант использует ~вместо подчеркивания. Он принимает все восемь допустимых пар и проверяет, содержит ли строка только те:

f(a:b:x)=[a,b]`elem`words"__ _/ /~ ~~ ~\\ \\_ \\/ /\\"&&f(b:x)
f _=1>0

Попробуйте онлайн!

Ungolfed:

validate :: String -> Bool
validate xs = all valid $ zip xs (tail xs)
  where
    valid (a,b) = [a,b] `elem` starts
    starts      = words "__ _/ /~ ~~ ~\\ \\_ \\/ /\\"

4

Perl 6 , 32 байта

{!/< \\\ \~ ~/ // _~ ~_ _\ /_>/}

Попробуйте онлайн!

Решение регулярного выражения, которое просто проверяет, что строка не содержит недопустимых последовательностей.

Объяснение:

{                              }   # Anonymous code block
  /<                         >/    # Find the longest sequence from
     \\\                           # \\
         \~                        # \‾
            ~/                     # ‾/
               //                  # //
                  _~               # _‾
                     ~_            # ‾_
                        _\         # _\
                           /_      # /_
 !                                 # And logically negate the match

4

R , 43 символа, 47 байтов

Это то же выражение, которое используют другие ответы, но адаптированное для R.

!grepl('[/‾][/_]|[\\\\_][\\\\‾]',scan(,''))

Попробуйте онлайн!

И обязательно xkcd .


1
Вы можете использовать ~вместо, чтобы получить до 43 байтов, 43 символа.
Джузеппе

2
Правда, но с овербаром веселее. :)
CT Hall

4

Далее , 100 98 байтов

: x = swap '~ = + ;
: f 1 tuck ?do over i + >r i 1- c@ r> c@ dup 92 x swap dup 47 x <> + loop 0> ;

Попробуйте онлайн!

объяснение

Просмотрите строку и определите, начинается ли каждый символ с той же позиции (сверху или снизу), что и предыдущий. Вычтите 1 из счетчика, если они не совпадают. В конце концов, если счетчик изменился, то строка не является строкой.

Конечная позиция высока, если символ / (47) или ~(126). В противном случае это низко

Стартовая позиция высока, если символ \ (92) или ~(126). В противном случае это низко

Код Объяснение

\ x is basically just extracting some common logic out into a function to save a few bytes
\ it checks if the first number is equal to the second number
\ or the third number is equal to 126   
: x                \ start a new word definition
  = swap           \ check if the first two numbers are equal then swap with the third
  '~ =             \ checks if the third number is equal to 126
  +                \ adds results together (cheaper version of or)
;                  \ end the word definition

: f                \ start a new word definition
  1 tuck           \ set up parameters for a loop (and create a bool/counter)
  ?do              \ start counted loop from 1 to string-length -1, 
                   \ ?do will skip if loop start and end are the same
    over i +       \ copy the string address and add the loop index to get the char address
    >r i           \ place char address on return stack and place a copy back on the stack
    1- c@          \ subtract 1 to get previous char address and grab ascii from memory
    r> c@          \ move char address back from return stack, then grab from memory
    dup 92 x       \ get the "output" position of the prev character
    swap dup 47 x  \ get the input position of the current character
    <> +           \ check if they aren't equal and add the result to the counter
                   \ the counter won't change if they're equal
  loop             \ end the loop
  0>               \ check if counter is less than 1 (any of the "links" was not valid)
;                  \ end word definition

3

Python 3 , 80 78 байт

Я не очень много играю в гольф с кодом Python, но я подумал, что могу попробовать

  • -2 байта: реализовано not (any ()) совпадает со всеми (not ()) и может переместить not в строку r
def f(x):*l,=map(r'_/\~'.find,x);return 1-any((i^j//2)%2for i,j in zip(l,l[1:]))

Попробуйте онлайн!

Python 3.8 (предварительная версия) , 71 байт

Я хотел попробовать новое :=назначение выражения

lambda x:all((i^j//2)%2for i,j in zip(l:=[*map(r'\~_/'.find,x)],l[1:]))

Попробуйте онлайн!


3

Желе ,  13 12  11 байт

O*Ɲ%⁽wḃ%5ỊẠ

Монадическая ссылка, принимающая список символов, использует ~вместо опции.

Попробуйте онлайн! Или посмотрите тестовый набор (... где я переупорядочил, чтобы поместить 8 ложных в конце)

Эта формула была найдена путем возни с рукой: p (как и те, что ниже)

Для этого я тоже все 16 пар ординалов персонажа рассматривал как возведение в степень и искал большое по модулю, которое уместится в три байта, за которыми следует однобайтовое по модулю (1,2,3,4,5,6,7,8). , 9,10,16,256), который разделил 16 так, что все приемлемые результаты были либо 1, либо 0 («незначительный»), поскольку я знаю, что он короче, чем <5в моем предыдущем решении, где все приемлемые результаты были меньше все недопустимые.

O*Ɲ%⁽wḃ%5ỊẠ - Link: list of characters
O           - ordinals
  Ɲ         - for each pair of neighbours:
 *          -   exponentiate
    ⁽wḃ     - 30982
   %        - modulo (vectorises)
        5   - five
       %    - modulo (vectorises)
         Ị  - insignificant? (abs(x) <=1) (vectorises)
          Ạ - all truthy?

Возможные соседние персонажи и их внутренние оценки:

(Ɲ)         (O)            (*%⁽wḃ)        (%5)      (Ị)
pair   a,b=ordinals   c=exp(a,b)%30982   d=c%5   abs(d)<=1
__       95,  95         28471             1         1
_/       95,  47         29591             1         1
/~       47, 126         19335             0         1
/\       47,  92          9755             0         1
~~      126, 126         28000             0         1
~\      126,  92         26740             0         1
\_       92,  95          9220             0         1
\/       92,  47         13280             0         1
~_      126,  95          3024             4         0
~/      126,  47         12698             3         0
\~       92, 126         27084             4         0
\\       92,  92         17088             3         0
_~       95, 126         28169             4         0
_\       95,  92          4993             3         0
/_       47,  95         22767             2         0
//       47,  47          7857             2         0

Предыдущая @ 12:

O*Ɲ%⁽?K%⁴<8Ạ

Попробуйте онлайн!


Предыдущая @ 13:

O%7ḅ6$Ɲ%⁵%8ỊẠ

Попробуйте онлайн!


Почему-то я думал, что это тестирование, abs(x)<1а не abs(x)≤1. Это предлагает довольно много дополнительных возможностей. :) (хотя я пока застрял на 11 байтах.)
Арно

Я нахожу это очень полезным.
Джонатан Аллан


3

Excel, 150 байт

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"_\",),"_‾",),"‾_",),"‾/",),"/_",),"//",),"\‾",),"\\",)=A1

Удаляет все недопустимые пары, а затем возвращает, trueесли это приводит к исходной строке.


3

Haskell, 42 байта

g=tail>>=zip
h=all(`elem`g"__/~~\\/\\_").g

это решение использует ~, и функция для вызова является ч (т. е. h stringдает ответ)

Решение использует функцию g, которая дает список, возвращает все кортежи смежных значений в списке.

Затем мы используем g, чтобы сгенерировать список разрешенных соседей (in g"__/~~\\/\\_"), а также список всех соседних пар во входном списке. Затем мы проверяем, что каждая соседняя пара является разрешенной парой.


3

C (gcc) , 41 36 байт

f(char*_){_=!_[1]||*_/32+*++_&f(_);}

Попробуйте онлайн!

-5 исключен &1старт с идеи от Питера Кордеса ; изменены операторы (приоритет) для удаления скобок


Использует ~. Проверяет первый и шестой бит двоичных представлений первых двух символов:

_ 1011111
\ 1011100
/  101111
~ 1111110
   ^    ^

и обходит строку рекурсивно.

(*_ / 32) & 1верно только для символов с *_ & 1низким уровнем. (x&1) ^ (y&1) == (x+y)&1, XOR является надстройкой без переноса, и перенос не нарушает младший бит. 1Происходит от f(_)возвращаемого значения, если остальная часть строки была тягучей.


Сдвиг вправо на 5 оставляет 6-й бит внизу. Итак, вы проверяете биты 0 и 5 или первый и шестой биты. (Это действительно хороший трюк, кстати, хорошо сделано. c&32Это верно для символов, которые заканчиваются высокими, в то время c&1как справедливо только для символов, начинающихся с низких.)
Питер Кордес

Я знаю, что правила требуют, чтобы он работал по крайней мере в одной реализации, но все же стоит отметить, что *_ ^ *++_это неопределенное поведение: ^это не точка последовательности, поэтому нет никаких последовательных отношений перед тем, чтобы гарантировать получение разных символов. Конечно, он также пропускает a return, поэтому он работает только gcc -O0там, где тело функции является выражением-оператором.
Питер Кордес

Ой, ты прав насчет битов. Спасибо, что
поймали

1
Делать &1дважды излишне. (x^y)&1 == (x&1) ^ (y&1), Но учитывая приоритет оператора C, где &приоритет выше, чем ^(в отличие от арифметических операторов, где + и - имеют одинаковый приоритет), нам нужно добавить ()2 байта, чтобы удалить &12 байта, потому что (x&1) ^ yэто не эквивалентно. Но, возможно, использование паренов открывает возможности для какой-то другой экономии. К счастью, это не проблема для машинного кода x86, где битовая манипуляция очень компактна ...
Питер Кордес

Закончил мой машинный код ответа x86 , 13 байт используя этот алгоритм.
Питер Кордес

2

Баш, 30 байт

grep -E '//|\\\\|_~|~_|~/|_\\|/_|\\~'

Ввод STDIN. Код выхода равен 1, если он действителен, и 0, если он недействителен.


1

SNOBOL4 (CSNOBOL4) , 58 байт

	INPUT '/_' | '_\' | '\\' | '//' | '~/' | '\~' @OUTPUT
END

Попробуйте онлайн!

Ничего не выводит для истины и положительное целое число (указывающее на позицию первого разрыва в строке) для фальсификации.


1

Древесный уголь , 32 18 байт

⌊⭆θ∨¬κ⁼№_/ι№\_§θ⊖κ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

  θ                 Input string
 ⭆                  Map over characters and convert to string
     κ              Current index
    ¬               Logical Not (i.e. is zero)
   ∨                Logical Or
          ι         Current character
       №            Count (i.e. contained in)
        _/          Literal _/ (i.e. begins at bottom)
      ⁼             Equals
               θ    Input string
              §     Indexed by
                 κ  Current index
                ⊖   Decremented (i.e. previous character)
           №        Count (i.e. contained in)
            \_      Literal \_ (i.e. ended at bottom)
⌊                   Minimum (i.e. if all true)
                    Implicitly print

1

машинный код x86, 13 байт.

(Или 11 байтов без обработки односимвольных строк, которые являются тривиальными.)

Использует проверку битовой позиции из ответа @ attinat's C

Тот же машинный код работает в 16, 32 и 64-битных режимах. Источник - NASM для 64-битного режима.

nasm -felf64 -l/dev/stdout  listing
    17   addr                  global string_connected
    18           code          string_connected:
    19           bytes         ;;; input: char *RSI, transitions to check=RCX
    20                         ;;; output: AL=non-zero => connected.  AL=zero disconnected
    21                         .loop:                      ; do {
    22 00000000 AC                 lodsb                   ;   al = *p++
    23 00000001 E309               jrcxz  .early_exit        ; transitions=0 special case.  Checking before the loop would require extra code to set AL.
    24 00000003 C0E805             shr    al, 5
    25 00000006 3206               xor    al, [rsi]          ; compare with next char
    26 00000008 2401               and    al, 1
    27 0000000A E0F4               loopne .loop            ; }while(--rcx && al&1);
    28                         .early_exit:
    29 0000000C C3                 ret

Вызывается из C, как unsigned char string_connected(int dummy_rdi, const char *s, int dummy_rdx, size_t transitions);в соглашении о вызовах System V. Не boolпотому, что в случае переходов = 0 возвращается код ASCII, а не 1.

RCX = len = strlen(s) - 1, т.е. число символьных границ = переходов для проверки в строке с явной длиной.

For transitions > 0возвращает 0 (несоответствие) или 1 (подключено) и оставляет ZF установленным соответствующим образом. For transitions == 0, возвращает единственный байт строки (который не равен нулю и, следовательно, также истинен). Если бы не этот особый случай, мы могли бы отказаться от JRCXZ с ранним выходом. Он внутри цикла только потому, что там AL ненулевой.


Логика битовой позиции основана на наблюдении, что бит 0 кода ASCII сообщает вам начальную высоту, а бит 5 сообщает вам конечную высоту.

;;;  _ 1011111
;;;  \ 1011100
;;;  /  101111
;;;  ~ 1111110
;;;     ^    ^

    ; end condition (c>>5) & 1 =>  0 = low
    ; start cond: c&1 => 0 = high
    ; (prev>>5)&1 == curr&1  means we have a discontinuity
    ; ((prev>>5) ^ curr) & 1 == 0  means we have a discontinuity

Испытательный жгут (изменен из ссылки TIO от attinat, остерегайтесь UB точки последовательности C в этой эталонной функции C). Попробуйте онлайн! , Эта функция верна для всех 30 случаев. (Включая односимвольные случаи, когда возвращаемое значение не совпадает: оба являются достоверными с разными ненулевыми значениями в этом случае.)


1

Excel, 79 байт

Ячейка A1как вход

=1---SUMPRODUCT(--ISNUMBER(FIND({"//","/_","\~","\\","~/","~_","_\","_~"},A1)))


0

C ++, 132 110 байт

-22 байта благодаря ASCII-только

int f(char*s){int t[128];t[95]=0;t[47]=1;t[92]=2;t[126]=3;for(;*++s;)if(t[s[-1]]%2^t[*s]/2)return 0;return 1;}

Использует битовую маску, чтобы знать, когда начало и конец вверх или вниз


хмм. не будет ли портировать версию C игрой в гольф: P
только ASCII




0

Регулярное выражение, 34 байта

Я не мог найти правила использования Regex в качестве языка. Пожалуйста, дайте мне знать, если мне нужно настроить это.

^(‾+|(‾*\\)?(_*\/‾*\\)*_*(\/‾*)?)$

Попробуйте это здесь: https://regex101.com/r/s9kyPm/1/tests


2
Это 34 байта, а не 24, верно?
Сара Джей

Ну, на самом деле 42 байта, но вы можете изменить на~
Джо Кинг

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.