Чи працює цей рядок як рядок?


92

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

Наприклад, одним із можливих входів є:

__/‾‾\/\_/‾

Вашій програмі потрібно вивести значення "химерне" або "хибне" залежно від того, "лівий край" рядка "з'єднаний", так би мовити, з правим краєм рядка за допомогою рядків символів. Отже, якби кернінг був трохи меншим, то була б суцільна чорна (хоч і химерна) лінія з усієї сторони від лівого краю до правого, як нерозривний шматок струни чи шпагату.

Вихід для наведеного вище прикладу буде істинним, оскільки краї з'єднані:

Приклад шляху

Щоб зрозуміти з'єднання:

  • / з’єднується в нижній лівій і верхній правій частині
  • \ з'єднується вгорі ліворуч і праворуч знизу
  • _ з’єднується в нижній лівій і нижній правій частині
  • (або ~) з'єднується вгорі ліворуч і вгорі праворуч

Також:

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

  • Ви можете припустити, що рядок введення не порожній, і звичайно, лише один рядок.

Ось ще кілька прикладів, за якими слідує 1 (truthy), якщо вони підключені, або 0 (Falsy), якщо ні:

__/‾‾\/\_/‾
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
Зачекайте, що ви можете зробити мову з цього
Delioth

2
@Arnauld Ні, я дійсно думаю, що тільки триут для підключених і фальшивий для непоєднаних. (Якщо дозволити заміни не є нормальним для подібного роду питань?)
Дискретні ігри

Відповіді:


34

Желе , 9 байт

-1 байт завдяки @EriktheOutgolfer

Очікуйте ~замість . Повертає або .01

O*Ɲ:⁽8ƇḂẠ

Спробуйте в Інтернеті! , Truthy набір тестів , тест Falsy люкс

Використовуючи цю формулу (але в іншому випадку схожа на 11-байтну версію нижче):

n=xy15145

Перехід дійсний, якщо непарне, або недійсне, якщо парне.nn

Прокоментував

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 байт

Підтримує (і очікує) символ у рядку введення. Повертає або .01

O*Ɲ%276%7ỊẠ

Спробуйте в Інтернеті! , Truthy набір тестів , тест Falsy люкс

Як?

Враховуючи два послідовних символи коду ASCII і , ми хочемо функцію, яка перевіряє, чи утворюють вони дійсний перехід.xy

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

Можлива формула 1, використовуючи експоненцію :

n=(xymod276)mod7

Перехід дійсний, якщо або недійсний, якщо .n1n>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.
Ерік Аутгольфер

@EriktheOutgolfer Дякую :) Можливо, сценарій, наданий у цій підказці, має бути оновлений для підтримки цього формату (коли це доречно).
Арнольд

1
@Arnauld Власне, Джонатан Аллан зробив це .
Ерік Аутгольфер

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 байт завдяки @Nick Kennedy

-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

Пітон , 46 байт

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

Спробуйте в Інтернеті!

Підтверджує, що кожна сусідня пара символів з'єднується, перевіряючи, чи вони відображаються послідовно в __/~~\/\_. Цей рядок може розглядатися як De_Bruijn_sequence на трійках високих / низьких позицій.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

Відповідь Порту @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, BTW.)
Арнольд,

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

Спробуйте в Інтернеті!

Безголовки:

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 байт

Це те саме зворотнє вираження, яке використовують інші відповіді, але адаптоване для Р.

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

Спробуйте в Інтернеті!

І обов’язковий xkcd .


1
ви можете використовувати ~замість того, щоб дістатися до 43 байт, 43 символів.
Джузеппе

2
Щоправда, але із забарвленням веселіше. :)
Зал КТ

4

Четвертий (gforth) , 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 з лічильника, якщо вони не збігаються. Зрештою, якщо лічильник змінився, то рядок не є рядком.

Кінцеве положення є високим, якщо знак char /(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 байт

Я не дуже багато гольфів пітонного коду, але я подумав, що спробувати

  • -2 байти: реалізований 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

Хаскелл, 42 байти

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

це рішення використовує ~, а функція викликати h (тобто h stringдає відповідь)

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

Тоді ми використовуємо g для створення списку дозволених сусідів (в 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, або перший і шостий біти. (Це дійсно приємний трюк, BTW, молодець. c&32Це справедливо для знаків, які закінчуються високо, тоді як c&1це справедливо лише для символів, які починаються низькими.)
Пітер Кордес,

Я знаю, що правила вимагають, щоб він працював принаймні на одній реалізації, але все ж варто зазначити, що *_ ^ *++_це не визначена поведінка: ^це не точка послідовності, тому немає жодних послідовних відносин, що гарантували б отримання різних символів. Звичайно, йому також не вистачає а 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

Вугілля деревне , 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 байт, не обробляючи односимвольні рядки, які є тривіально строгими.)

Використовує перевірку позиції бітів з відповіді C @ attinat

Цей же машинний код працює в 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);у системі V86 x86-64. Не boolтому, що випадок переходів = 0 повертає ASCII-код, а не 1.

RCX = len = strlen(s) - 1. тобто кількість символьних меж = переходи для перевірки в рядку явної довжини.

Для цього transitions > 0повертає 0 (невідповідність) або 1 (підключено) і залишає ZF встановленим відповідно. Бо transitions == 0повертає єдиний байт рядка (який не є нульовим і, таким чином, також truthy). Якби не цей особливий випадок, ми могли б скинути 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, остерігайтеся U-точки послідовності C у цій C-функції). Спробуйте в Інтернеті! . Ця функція є правильною для всіх 30 випадків. (У тому числі випадки з одним символом, коли значення, що повертається, не збігаються: обидва є правдоподібними з різними ненульовими значеннями в цьому випадку.)


1

Excel, 79 байт

Комірка A1як вхідна

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




0

Регекс, 34 байти

Не вдалося знайти правила використання Regex як мови. Будь ласка, дайте мені знати, чи потрібно мені це коригувати.

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

Спробуйте тут: https://regex101.com/r/s9kyPm/1/tests


2
Це 34 байти, а не 24, правда?
Сара Дж

Ну, справді 42 байти, але ви можете змінитись на~
Jo King

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.