Найти слова бесконечности!


36

(Примечание: это ответвление моего предыдущего задания « Найди закрученные слова!» )

Определение Бесконечного Слова :

  1. Если вы соедините кривыми все символы Слова Бесконечности в алфавите (AZ), вы получите символ бесконечности ∞, как показано на диаграммах ниже.
  2. Все соединения четных должно быть вниз , все нечетные соединения должны быть вверх .
  3. Вы можете игнорировать верхний / нижний регистр или рассматривать / конвертировать все в верхний регистр или все в нижний регистр.
  4. Вводимые слова - это только символы в диапазоне алфавита AZ, без пробелов, знаков пунктуации или символов.
  5. Каждое слово должно быть ровно 5 символов. Слова> 5 или <5 недействительны.
  6. Если слово состоит из двух последовательных символов, оно недопустимо, например, «FLOOD» или «QUEEN».
  7. Все Слова Бесконечности начинаются и заканчиваются одним и тем же символом.

Вот несколько примеров:

Бесконечность Слова

Задача:

Напишите полную программу или функцию, которая возьмет слово из стандартного ввода и выведет, если это Слово Бесконечности или нет. Выход может быть true / false, 1/0, 1 / Null и т. Д.

Тестовые случаи:

Infinity Words:
ALPHA, EAGLE, HARSH, NINON, PINUP, RULER, THEFT, WIDOW

NOT Infinity Words:
CUBIC, ERASE, FLUFF, LABEL, MODEM, RADAR, RIVER, SWISS, TRUST, 
KNEES, QUEEN, GROOVE, ONLY, CHARACTER, OFF, IT, ORTHO

Правила:

  1. Самый короткий код выигрывает.

Необязательная задача:

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


Можем ли мы предположить, что вход всегда имеет длину 5? Вы определили правило 5: « Каждое слово должно быть точно 5 символов. Слова> 5 или <5 недопустимы. », Но не слова бесконечности, содержащие не более 5 символов.
Кевин Круйссен

4
Довольно забавно, что ALPHA делает этот паттерн
Fatalize

@KevinCruijssen Вы должны проверить, что слово соответствует определению, я обновил ложные случаи.
Марио

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

3
Я решил заняться Факультативным заданием: «Найти в списке как можно больше слов бесконечности в словаре английского языка ...». Я использовал этот источник и ответ Кевина Круйссена , чтобы составить список из 278 слов бесконечности .
Томас Куинн Келли

Ответы:


19

Желе , 43 41 40 25 24 23 22 21 14 13 байт

-7 байт благодаря fireflame241 ( 0ị=1ị$-> =ṚḢи использованию IIA⁼2,2для проверки 4 вращений)

-1 Благодаря Кевину Круйссену (использование ранее недоступного nilad, Ø2который дает [2,2])

=ṚḢȧOIṠIIA⁼Ø2

TryItOnline
или все контрольные примеры (плюс "ПРАВИЛА")

Как?

Слово бесконечности имеет:

  1. то же самое первое и последнее письмо;
  2. длина 5;
  3. нет одинаковых букв рядом друг с другом;
  4. сумма его четырех алфавитных дельт равна нулю;
  5. сумма его четырех алфавитных дельт-знаков равна нулю;
  6. две положительные дельты алфавита или две отрицательные дельты алфавита подряд.

Все, кроме (1) и (эквивалентно) (4), могут быть сведены к условию, что дельта-знаки алфавита являются некоторым вращением [1,1,-1,-1](где знак 0является 0)

fireflame241 отметил, что тогда это эквивалентно дельтам дельт алфавитных дельта-знаков, в [[2,2],[2,-2],[-2,2],[-2,-2]]которых могут быть проверены абсолютные значения, равные [2,2]!

Как?

=ṚḢȧOIṠIIA⁼Ø2 - Main link: word
 Ṛ            - reverse word
=             - equals? (vectorises)
  Ḣ           - head (is the first character equal to the last?)
   ȧ          - and
    O         - cast word to ordinals
     I        - increments - the alphabet deltas (or just [] if 1st != last)
      Ṡ       - sign (vectorises)
       I      - increments - deltas of those signs
        I     - increments - deltas of those
         A    - absolute value (vectorises)
           Ø2 - literal [2,2]
          ⁼   - equals? (non-vectorising version)

Как это работает?
Оливер Ни

входящее объяснение.
Джонатан Аллан

2
@PascalvKooten Это в основном для развлечения и соревнования в Code Golf - я довольно новичок и в Code Golf, и в Jelly, так что собирать программу Jelly - это почти маленькая головоломка почти каждый раз; Я нахожу это удовлетворяющим. Если кто-то хочет извлечь что-то осязаемое из этой игры, он должен использовать это, чтобы отточить свои навыки на языке, который более часто используется в реальном мире, хотя, или, конечно, создать собственный язык игры в гольф!
Джонатан Аллан

1
@ lois6b :). Вы начинаете с уроком , а затем использовать страницы с Atom определениями , определениями Quicks и просматривать исходный код .
Джонатан Аллан

1
14 байтов Основной гольф здесь используется IIдля проверки на равенство вращения 1,1, -1, -1.
fireflame241

11

Ява 8, 231 193 185 122 103 78 байт

s->s.length==5&&(s[1]-s[0])*(s[3]-s[2])<0&(s[2]-s[1])*(s[4]-s[3])<0&s[4]==s[0]

Попробуй это здесь.

-38 байт, спасибо @ dpa97 за напоминание о необходимости использовать char[]вместо String.
-63 байта благодаря полученной формуле @KarlNapf .
-25 байт путем преобразования его из Java 7 в Java 8 (и теперь возвращает логическое значение вместо целого числа).

Ответ 193 байта:

int c(char[]s){if(s.length!=5)return 0;int a=s[0],b=s[1],c=s[2],d=s[3],e=s[4],z=b-a,y=c-b,x=d-c,w=e-d;return e!=a?0:(z>0&y>0&x<0&w<0)|(z<0&y>0&x>0&w<0)|(z>0&y<0&x<0&w>0)|(z<0&y<0&x>0&w>0)?1:0;}

Объяснение:

  • Если длина строки не 5, мы возвращаем false
  • Если первый символ не равен последнему символу, мы возвращаем false
  • Затем мы проверяем четыре действительных случая один за другим (давайте обозначим пять символов от 1 до 5) и возвращаем, trueесли он соответствует любому из них (и в falseпротивном случае):
    1. Если пять символов распределены как: 1<2<3>4>5(т.е. ALPHA)
    2. Если пять символов распределены так: 1>2<3<4>5(т.е. EAGLE, HARSH, NINON, PINUP)
    3. Если пять символов распределены как: 1<2>3>4<5(т.е. RULER)
    4. Если пять символов распределены как: 1>2>3<4<5(то есть THEFT, WIDOW)

Эти четыре правила могут быть упрощены 1*3<0 and 2*4<0(благодаря ответу @KarlNapf на Python 2 ).


2
+1, чтобы компенсировать необъяснимое понижение голосов ... Насколько я могу судить, это совершенно функциональное решение.
Арно

1
Я получил его до 215, преобразовывающего s в тип char [] char [] c = s.toCharArray (); int z = c [1] -c [0], y = c [2] -c [1] ,. ..
dpa97

@ dpa97 Спасибо за напоминание, чтобы использовать в char[]качестве ввода вместо String. -38 байт благодаря вам.
Кевин Круйссен

1
Ваши булевы могут быть оптимизированы: z,xи w,yдолжны иметь переменный знак, поэтому достаточно проверить , z*x<0иw*y<0
Карл NAPF

@KarlNapf Ах, я неправильно истолковал ваш комментарий несколько часов назад. Я реализовал вашу производную формулу для колоссальных -63 байта. :) Благодарность.
Кевин Круйссен

4

JavaScript (ES6), 91 89 87 байт

Сохранено 2 байта благодаря Исмаилу Мигелю

s=>(k=0,[...s].reduce((p,c,i)=>(k+=p>c?1<<i:0/(p<c),c)),k?!(k%3)&&!s[5]&&s[0]==s[4]:!1)

Как это работает

Мы создаем 4-битную битовую маску, kпредставляющую 4 перехода между 5 символами строки:

k += p > c ? 1<<i : 0 / (p < c)
  • если предыдущий символ выше следующего, бит установлен
  • если предыдущий символ ниже, чем следующий, бит не установлен
  • если предыдущий символ идентичен следующему, вся битовая маска принудительно NaNустанавливается так, что слово отбрасывается (в соответствии с правилом № 6)

Действительными битовыми масками являются те, которые имеют ровно два последовательных 1перехода (первый и последний биты также рассматриваются как последовательные ):

Binary | Decimal
-------+--------
0011   | 3
0110   | 6
1100   | 12
1001   | 9

Другими словами, это комбинации, которые:

  • k? : больше 0
  • !(k%3): соответствует 0 по модулю 3
  • ниже 15

Другие условия:

  • !s[5] : не более 5 символов
  • s[0]==s[4] : 1-й и 5-й символы идентичны

NB : Мы не проверяем явно, k != 15потому что любое слово, следующее за таким шаблоном, будет отклонено этим последним условием.

Контрольные примеры

Первоначальный вариант

Для записи, моя первоначальная версия была 63 байта. Он успешно проходит все тестовые случаи, но не может обнаружить последовательные идентичные символы.

([a,b,c,d,e,f])=>!f&&a==e&&!(((a>b)+2*(b>c)+4*(c>d)+8*(d>e))%3)

Ниже приведена 53-байтовая версия, предложенная Нилом в комментариях, которая работает (и не работает) одинаково хорошо:

([a,b,c,d,e,f])=>!f&&a==e&&!((a>b)-(b>c)+(c>d)-(d>e))

Редактировать: См . Ответ Нейла для фиксированной / завершенной версии приведенного выше кода.


0000также соответствует 0 по модулю 3, но опять же вы не можете иметь первые и последние буквы одинаковыми, поэтому, подобно 15, вам не нужно явно проверять это.
Нил

Для этой начальной версии вы можете использовать !((a>b)-(b>c)+(c>d)-(d>e))?
Нил

p<c?0:NaNможно записать как 0/(p<c), что экономит 2 байта.
Исмаэль Мигель

@Neil Что касается теста против 0: вы совершенно правы. (Однако мне нужен k?тест из-за возможного NaN.) Что касается вашей альтернативной версии: это должно сработать.
Арно

@IsmaelMiguel - Хороший звонок! Спасибо.
Арно

4

JavaScript (ES6), 78 байт

([a,b,c,d,e,f])=>a==e&&!(f||/(.)\1/.test(a+b+c+d+e)||(a>b)-(b>c)+(c>d)-(d>e))

Основано на неверном коде @ Arnauld, но исправлено и исправлено. Работает, сначала проверив, что первый символ совпадает с пятым (таким образом гарантируя 5 символов) и что длина строки не более 5. После проверки последовательных повторяющихся символов остается проверить волнообразность строки, который должен иметь один пик и одну впадину с двумя буквами.

  • Если пик и впадина - это средняя и первая / последняя буквы, то первые два сравнения и два последних сравнения отменяются
  • Если вершина и впадина - вторая и четвертая буквы, то средние два сравнения и внешние два сравнения отменяют
  • В противном случае что-то не может быть отменено, и общее выражение возвращает false

Изменить: Альтернативное 78-байтовое решение, основанное на ответе @ KarlNapf:

([a,b,c,d,e,f],g=(a,b)=>(a<b)-(a>b))=>a==e&&!f&&g(a,b)*g(c,d)+g(b,c)*g(d,e)<-1

3

Код выхода Python 2, 56 байт

s=input()
v,w,x,y,z=map(cmp,s,s[1:]+s[0])
v*x+w*y|z>-2>_

Выходы через код выхода: Ошибка для False и успешный запуск для True.

Принимает строку sс символами abcde, поворачивает ее bcdea, выполняет поэлементное сравнение соответствующих символов и присваивает их пяти переменным v,w,x,y,z. Неправильная длина дает ошибку.

Слова бесконечности у всех есть

v*x == -1
w*y == -1
z == 0

которые могут быть проверены совместно как v*x+w*y|z == -2. Цепочка сравнения v*x+w*y|z>-2>_цепей замыкается в этом случае, и в противном случае выполняется оценка, -2>_которая выдает ошибку имени.


Ах, как хорошо, что вы играли в гольф больше!
Карл Напф

3

Python 2, 110 87 60 байт

Сохранение 1 байта благодаря Нейлу

Требуется ввод в кавычках, например 'KNEES'

Trueесли это бесконечное слово, Falseесли нет, оно имеет длину 5 и печатает сообщение об ошибке, если неправильная длина

s=input()
a,b,c,d,e=map(cmp,s,s[1:]+s[0])
print a*c+b*d|e<-1

Вдохновленный ответом xnor используяmap(cmp...

s=input()
e=map(cmp,s,s[1:]+s[0])
print e[4]==0and e[0]*e[2]+e[1]*e[3]==-2and 5==len(s)

предыдущее решение:

s=input()
d=[ord(x)-ord(y)for x,y in zip(s,s[1:])]
print s[0]==s[4]and d[0]*d[2]<0and d[1]*d[3]<0and 4==len(d)

Используя оптимизированную логику Кевина Круйссена


Почему нет a*c+b*d+2==0==e?
Нил

@ Нил да, почему бы и нет, но у Кснора a*c+b*d|eеще меньше.
Карл Напф

Я думаю, что <-1может работать, так как оба -2|1и -2|-1равны -1.
Нил


2

Python 2, 71 байт

lambda s:map(cmp,s,s[1:]+s[0])in[[m,n,-m,-n,0]for m in-1,1for n in-1,1]

Берет строку sс символами abcde, поворачивает ее bcdeaи выполняет поэлементное сравнение соответствующих символов.

a  b   cmp(a,b)
b  c   cmp(b,c)
c  d   cmp(c,d)
d  e   cmp(d,e)
e  a   cmp(e,a)

Результатом является список -1, 0, 1. Затем проверяет, является ли результат одной из действительных последовательностей взлетов и падений:

[-1, -1, 1, 1, 0]
[-1, 1, 1, -1, 0]
[1, -1, -1, 1, 0]
[1, 1, -1, -1, 0]

как сгенерировано из шаблона [m,n,-m,-n,0]с m,n=±1. Последние 0проверяют, чтобы первая и последняя буквы были равны, а длина гарантирует, что длина входной строки равна 5.


Альтернатива 71. Проверяет условия сравнения при обеспечении правильной длины.

def f(s):a,b,c,d,e=map(cmp,s,s[1:]+s*9)[:5];print a*c<0==e>b*d>len(s)-7

1

R, 144 байта

Ответ основан на логике @Jonathan Allan. Это, вероятно, может быть в гольф, хотя.

s=strsplit(scan(,""),"")[[1]];d=diff(match(s,LETTERS));s[1]==tail(s,1)&length(s)==5&all(!rle(s)$l-1)&!sum(d)&!sum(sign(d))&any(rle(sign(d))$l>1)

Тестовые сценарии R-fiddle (векторизованный пример, но та же логика)


Поскольку у вас уже есть проверка length(s)==5, вы можете заменить s[1]==tail(s,1)на s[1]==s[5]. Один байт короче метод , чтобы проверить длину является is.na(s[6]). Вместе эти два изменения возвращаются TRUEдля sдлины 5 точно и FALSEиначе, как TRUE&NAесть, NAно FALSE&NAесть FALSE. Вы также можете сохранить несколько байтов, заменив !sum(sign(d))&any(rle(sign(d))$l>1)на !sum(a<-sign(d))&any(rle(a)$l>1).
rturnbull

1

GNU Prolog, 47 байт

i([A,B,C,D,A]):-A>B,B>C,C<D,D<A;i([B,C,D,A,B]).

Определяет предикат, iкоторый успешно (на самом деле бесконечно много раз) для бесконечного слова, таким образом, выводит «да» при запуске из интерпретатора (как обычно для Пролога); не подходит для слова-кандидата, чьи первая и последняя буквы не совпадают или не имеют длины 5 букв, таким образом, выводя «нет» при запуске из интерпретатора; и вылетает с переполнением стека, если дано слово-кандидат, которое не является словом бесконечности, но состоит из пяти букв с первым и последним совпадением. (Я не уверен почемуон падает; рекурсивный вызов должен восприниматься как ответный вызов. По-видимому, оптимизатор GNU Prolog не очень хорош.) Успех - это эквивалент Пролога для Пролога, а неудачный эквивалент для Falsey; сбой определенно более ложный, чем правдивый, и его исправление сделает решение значительно более длительным, поэтому я надеюсь, что это считается правильным решением.

Алгоритм довольно прост (и действительно, программа довольно читабельна); проверьте, составляют ли буквы один из четырех шаблонов, составляющих бесконечное слово, и, если нет, циклически переставьте и попробуйте снова. Нам не нужно явно проверить для двойных букв , как <и >операторы позволяют нам неявно проверить , что в то же самое время , что мы проверяем , что дельты совпадают.


1

На самом деле , 38 27 байтов

Этот ответ был в значительной степени вдохновлен превосходным ответом Джонатана Аллана . Вероятно, есть несколько мест, где можно сыграть в гольф, поэтому предложения по игре в гольф приветствуются! Попробуйте онлайн!

O;\♀-dY@♂s4R`0~;11({k`Míub*

Ungolfing

     Implicit input s.
O    Push the ordinals of s. Call this ords.
;    Duplicate ords.
\    Rotate one duplicate of ords left by 1.
♀-   Vectorized subtraction. This effectively gets the first differences of ords.
d    Pop ord_diff[-1] onto the stack. This is ords[0] - ords[-1].
Y    Logical negate ord_diff[-1], which returns 1 if s[0] == s[-1], else 0.
@    Swap (s[0] == s[-1]) with the rest of ord_diff.

♂s       Vectorized sgn() of ord_diff. This gets the signs of the first differences.
4R       Push the range [1..4] onto the stack.
`...`M   Map the following function over the range [1..4]. Variable x.
  0~;      Push -1 onto the stack twice.
  11       Push 1 onto the stack twice.
  (        Rotate x to TOS.
  {        Rotate the stack x times, effectively rotating the list [1, 1, -1, -1].
  k        Wrap it all up in a list.

     Stack: list of rotations of [1, 1, -1, -1], sgn(*ord_diff)
í    Get the 0-based index of sgn(*ord_diff) from the list of rotations. -1 if not found.
ub   This returns 1 only if sgn(*ord_diff) was found, else 0.
     This checks if the word loops like an infinity word.

*    Multiply the result of checking if the word s loops and the result of s[0] == s[-1].
     Implicit return.


1

TI-BASIC, 81 байт

Строка для передачи в программу находится в Ans. Возвращает (и неявно отображает) 1, если введенное слово является Бесконечным Словом, и 0 (или выходит с сообщением об ошибке), если это не так.

seq(inString("ABCDEFGHIJKLMNOPQRSTUVWXYZ",sub(Ans,A,1)),A,1,length(Ans
min(Ans(1)=Ans(5) and {2,2}=abs(deltaList(deltaList(deltaList(Ans)/abs(deltaList(Ans

Ошибки любых повторяющихся символов или не 5-буквенных слов.


1

05AB1E , 16 байтов

Ç¥DO_s.±¥¥Ä2DиQ*

Порт @JonathanAllan 's Jelly ответа .

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

Объяснение:

Ç             # Convert the (implicit) input string to a list of unicode values
              #  i.e. "RULES" → [82,85,76,69,82]
 ¥            # Take the deltas
              #  i.e. [82,85,76,69,82] → [3,-9,-7,13]
  DO          # Duplicate and take the sum
              #  i.e. [3,-9,-7,13] → 0
    _         # Check if that sum is exactly 0
              # (which means the first and last characters are equal)
              #  i.e. 0 and 0 → 1 (truthy)
 s            # Swap so the deltas are at the top of the stack again
            # Get the sign of each
              #  i.e. [3,-9,-7,13] → [1,-1,-1,1]
    ¥         # Get the deltas of those signs
              #  i.e. [1,-1,-1,1] → [-2,0,2]
     ¥        # And then get the deltas of those
              #  i.e. [-2,0,2] → [2,2]
      Ä       # Convert them to their absolute values
       2Dи    # Repeat the 2 two times as list: [2,2]
          Q   # Check if they are equal
              #  i.e. [2,2] and [2,2] → 1 (truthy)
 *            # Check if both are truthy (and output implicitly)
              #  i.e. 1 and 1 → 1 (truthy)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.