String.prototype.isПовторюється


41

ОНОВЛЕННЯ : подання isaacg Pyth є переможцем!


Багато з вас, напевно, чули, що в місті є більш крута версія JavaScript (читайте ES6), яка має метод, String.prototype.repeatщоб ви могли це робити

"Hello, World!".repeat(3)

і дістати

"Hello, World!Hello, World!Hello, World!"

як вихід.

Ваше завдання полягає в тому, щоб написати функцію або програму на обраній вами мові, яка визначає, чи не було рядок під таким перетворенням.

тобто рядок введення може бути представлений у вигляді точного nповторення меншої строки в часі. Вихід (як оператор повернення функції або STDOUT) повинен бути правдивим, якщо рядок може бути фальшивим, якщо рядок не може бути представлена ​​як повторення меншого рядка.

Деякі приклади введення:

"asdfasdfasdf"  // true
"asdfasdfa"     // false
"ĴĴĴĴĴĴĴĴĴ"     // true
"ĴĴĴ123ĴĴĴ123"  // true
"abcdefgh"      // false

Зауважте, що останній ввід помилковий, тому nмає бути більше, ніж1

Повні правила

  • Напишіть функцію / програму будь-якою мовою, щоб ввести рядок (через аргумент функції / аргументи командного рядка / STDIN)
  • Повернення / друк тритидної величини, якщо заданий рядок формується за допомогою точного повторення меншого рядка, повторюючи принаймні двічі.
  • Максимальний розмір вхідного рядка в ідеалі - Нескінченність
  • Рядок може містити всі можливі символи ASCII
  • Це тому найменший код в символах виграє.

Що має повернути порожній рядок? (Він містить нескінченну кількість примірників порожнього рядка.)
billpg

Значення фальшивого @billpg
оптимізатор

Ви перериваєте голоси? Я вважаю, що звичайна практика - це подання на ранніх термінах (ну, перше, що отримало гольф до рівня зав'язування). Але я не впевнений, що це записується як автоматичний вимикач за замовчуванням де завгодно, тому в кінцевому підсумку це залежить від вас.
Мартін Ендер

Час між їх публікацією - всього 30 хвилин. Я не вважатиму це досить для перемоги :). Оскільки цей час зараз не зміниться, але голоси можуть, я пішов з голосами
Optimizer

Це питання слід перейменувати на xnor :) Він - людина!
Сільвіу Бурча

Відповіді:


16

Піта , 9

/:+zz1_1z

Або

}z:+zz1_1

Це обидва тісні переклади відповіді python @ xnor, за винятком того, що вони беруть вхід зі STDIN і друкують його. Перший еквівалентний:

z = input()
print((z+z)[1:-1].count(z))

0 - Неправдиво, 1 - Правда.

Другий рядок еквівалентний:

z = input()
print(z in (z+z)[1:-1])

Неправдивий за хибний, правдивий для правдивого.

Офіційний компілятор Pyth мав помилку, пов’язану з другою, яку я просто виправляв, тому перше - це моє офіційне подання.


Я просто шукав спосіб повідомити вам про цю помилку (булева інформація не надрукується). Не думав про перше, а використовувати xбуло занадто довго ...
Денніс

Так, помилка виправлена ​​зараз. Крім того, якщо ви хочете повідомити про помилки, хорошим способом може бути відкриття проблеми на сайті github, тут: github.com/isaacg1/pyth/isissue
isaacg

О, ось воно. Я не знаю свого шляху навколо GitHub, і я ніколи не помічав панелі навігації праворуч ...
Денніс,

81

Пітон (24)

lambda s:s in(s+s)[1:-1]

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


8
Тривіальний переклад на Гольфскрипт дає 10 символів:..+);(;\?)
Джастін

3
Я не зовсім розумію, як це працює. Чи можете ви навести пояснений вручну приклад того, як це оброблятиме рядок?
Nzall

8
@NateKerkhofs беруть abcabc. s+sперетворює це в abcabcabcabc. на [1:-1]відбивні двома кінцями , щоб дати bcabcabcabcab. а потім s in ...намагається знайти abcabcяк підрядку цього. Цю підрядку не можна знайти ні в одній із початкових половин, оскільки вони обидві були скорочені, тому вона повинна охоплювати обидві половинки. Зокрема, він повинен мати власний кінець перед початком, що означає, що він повинен складатися з однакових (повторних) підрядків.
Мартін Ендер

6
Ви рубаєте його після того, як подвоїте. abстає ababстає ba, тому він повертається помилковим, тоді як aaстає aaaaстає aa, що повертається істинним.
гістократ

1
@SargeBorsch Це працює так само: qweqweqwein weqweqweqweqweqwis True.
xnor

30

Регекс (аромат ECMAScript), 11 байт

Здається, що робота для регулярного виразу!

^([^]+)\1+$

Тестуйте це тут.

Я вибрав ECMAScript, тому що це єдиний аромат (я знаю), в якому [^]відповідає будь-який символ. У всіх інших, мені або потрібен прапор, щоб змінити поведінку, .або використовувати [\s\S]його на три символи довше.

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

/^(.+)\1+$/s

Що становить 10 байт, ігноруючи роздільники.

Тестуйте це тут.

Це відповідає лише рядкам, що складаються з щонайменше двох повторень деякої підрядки.

Ось повна 26-байтна функція ES6, але я стверджую, що регулярні подання виразів, як правило, дійсні:

f=s->/^([^]+)\1+$/.test(s)

^(.+)\1+$працює для мене, що становить 9 байт. Це не працює для вас?
Оптимізатор

@Optimizer Спробуйте рядок із розривами рядків.
Мартін Ендер

Я спробував asd\nasd\nasd\n. Працює
оптимізатор

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00 , здається, не працює для мене (і не повинно)
Martin Ender

Так, це не працює. Можливо, це уникне, \ коли я пишу \nвручну
Optimizer

12

CJam, 9

q__+)@+#)

Схожа на ідею xnor.

q      " Read input. ";
__+    " Duplicate twice and concatenate them together. ";
)      " Remove the last character of the longer string. ";
@+     " Insert that character at the beginning of the shorter string. ";
#)     " Find the shorter string in the longer string, and increase by one. ";

+1 зобов’язався підтвердити це перед моєю власною відповіддю CJam
Digital Trauma

Чому необхідність у фіналі )? Я думаю, що розумно мати -1 середній ЛЖ, а> = 0 означати ІСТИНА
Digital Trauma

@DigitalTrauma Я думаю, що 0 є хибною в CJam ... для операторів, як gі ?.
jimmy23013

@DigitalTrauma: чи це потрібно в кінцевому рахунку, залежить від ОП, але строго кажучи, лише нуль вважається помилковим в CJam.
Денніс

@ user23013 @Dennis А як щодо #оператора пошуку? Зрозуміло, результат цього також є "правдою" з точки зору успіху проти невдач?
Цифрова травма

7

APL, 11

2<+/x⍷,⍨x←⍞

Пояснення
вимагає введення рядка з екрана,
x←присвоює змінній x
,⍨конкатенацію рядка з самим
x⍷пошуком xв отриманій рядку. Повертає масив, що складається з знаків "1" у вихідному положенні відповідності та 0 - в іншому місці.
+/підсумовує
2<перевірку масиву, якщо сума більша за 2 (оскільки буде 2 тривіальних збігу)


7

CJam, 10 байт

Я спіймав помилку CJam. Моя перша відповідь, тому, ймовірно, можна пограти ще трохи:

q__+(;);\#

Виходи -1 для FALSE і число> = 0 для TRUE


5
Ласкаво просимо в клуб!
Денніс

5

GolfScript, 10 байт

..+(;);\?)

Ще одна реалізація розумної ідеї xnor.


Хахаха, я просто розмістив цю хвилину назад: codegolf.stackexchange.com/questions/37851 / ... . Я думав про те, щоб опублікувати це як відповідь, але подумав, що тривіальні переклади нецікаві.
Джастін

Цього разу я навіть перевірив на нові відповіді, але не на нові коментарі ... )Однак у вашому коді відсутній ; коли не збігається, воно надрукується -1. Якщо ви збираєтесь опублікувати це як відповідь, я з радістю видаляю свою.
Денніс

Я додав )лише до того, як ви опублікували свою відповідь (я відредагував коментар)
Джастін

1
Поліпшена версія (в CJam) q__+)@+#). Він не працює в GolfScript.
jimmy23013

1
@ user23013: Не знову. Я просто збирався це повідомлення! На сьогоднішній день там занадто багато CJammers ...: P
Dennis


3

Чистий баш, 30 байт

Простий порт розумної відповіді @ xnor :

[[ ${1:1}${1:0: -1} =~ "$1" ]]

Вихідний код 0 для TRUE і 1 для FALSE:

$ for s in 'Hello, World!Hello, World!Hello, World!' 'asdfasdfasdf' 'asdfasdfa' 'ĴĴĴĴĴĴĴĴĴ' 'ĴĴĴ123ĴĴĴ123' 'abcdefgh'; do echo "./isrepeated.sh "\"$s\"" returns $(./isrepeated.sh "$s"; echo $?)"; done
./isrepeated.sh "Hello, World!Hello, World!Hello, World!" returns 0
./isrepeated.sh "asdfasdfasdf" returns 0
./isrepeated.sh "asdfasdfa" returns 1
./isrepeated.sh "ĴĴĴĴĴĴĴĴĴ" returns 0
./isrepeated.sh "ĴĴĴ123ĴĴĴ123" returns 0
./isrepeated.sh "abcdefgh" returns 1
$ 

Примітка =~в [[ ... ]]це регулярний вираз оператора в Баш . Однак "Будь-яка частина шаблону може бути процитована, щоб змусити його відповідати як рядок" . Отже, як це часто буває з bash, правильне цитування є дуже важливим - тут ми просто хочемо перевірити наявність рядкового підматчу, а не збігу регулярних виразів.


3

TI-BASIC - 32

Я думав, що спробую токенізовану мову. Виконати з рядком в Ans, повертає 0 якщо false, а довжину повторюваного рядка - якщо це правда.

inString(sub(Ans+Ans,1,2length(Ans)-1),sub(Ans,length(Ans),1)+Ans

Дивно, як це однолінійний.


Але ... але ... я збирався використовувати TI-BASIC: P +1
Timtech

@Timtech. Зверніть увагу, хто намагається обробляти рядкові маніпуляції в TI-BASIC. Не намагайтеся використовувати маніпуляції з рядком у TI-BASIC. : P Це було важко зробити та оптимізувати.
Джосія Уінслоу

Гарна ідея. Струнна маніпуляція - одна з найважчих речей. Однак я опублікував кілька подібних відповідей, тому, мабуть, зараз у вас є конкурент;)
Timtech

Принесіть це! : P
Джосія Уінслоу

3

ECMAScript 6 (189)

(function(){var S=String.prototype,r=S.repeat;S.isRepeated=function(){return!1};S.repeat=function(c){var s=new String(r.call(this,c));if(c>1)s.isRepeated=function(){return!0};return s}}());

 

< console.log("abc".isRepeated(),"abc".repeat(10).isRepeated());
> false true

Напевно, це єдино вірне рішення? Наприклад, слово (рядок) nanaне обов'язково створюється з"na".repeat(2)


"nana"ні, але питання не в тестуванні, .repeatвикористовувались чи ні. Вірніше, чи є рядок повторюваним чи ні
Optimizer

Я знаю, я просто намагався бути спритним: P
Mardoxx,

2

ECMAScript 6 (34 36 )

Інший ES6 відповідь, але без використання repeatі з використанням трюку XNOR в :

f=i=>(i+i).slice(1,-1).contains(i)

Потрібно запустити в консолі браузера з підтримкою ES6, такого як Firefox.


2

C 85

l,d;f(s){return l=strlen(s),strstr(d,strcpy(strcpy(d=alloca(l*2+1),s)+l,s)-1)-d-l+1;}

Це виявилося досить довгим, але зовнішні функції завжди такі. Мені прийшло в голову, що я можу переписати кожну струнну функцію, замінивши її циклом або рекурсивною. Але на моєму досвіді це виявиться довше, і відверто кажучи, я не хочу це намагатися.

Після деяких досліджень я побачив рішення з високою продуктивністю, але не настільки розумними (і короткими), як у xnor. просто щоб бути оригінальним ... я переписав ту саму ідею в c.

пояснення:

int length, 
    duplicate;
int is_repetition(char *input)
{
    // length = "abc" -> 3
    length = strlen(input);
    // alloca because the function name is as long as "malloc" 
    // but you don't have to call free() because it uses the stack
    // to allocate memory
    // duplicate = x x x x x x + x
    duplicate = alloca(length*2 + 1);
    // duplicate = a b c 0 x x + x
    strcpy(duplicate, input);
    // duplicate = a b c a b c + 0
    strcpy(duplicate + length, input);
    if (strstr(duplicate,duplicate + length - 1) != duplicate + length - 1)
        // repetition
        // e.g. abab -> abababab -> aba[babab]
        // -> first occurence of [babab] is not aba[babab]
        // but a[babab]ab -> this is a repetition
        return 1;
    else
        // not repetition
        // e.g. abc -> abcabc -> ab[cabc]
        // -> first occurence of [cabc] is ab[cabc]
        // it matches the last "cabc"
        return 0;
}

1

ECMAScript 6 (59 62 67 73 )

Не є переможцем, але здається, що у ES6 на це запитання, яке фактично використовує repeatфункцію, має бути принаймні одна відповідь :

f=i=>[...i].some((_,j)=>i.slice(0,j).repeat(i.length/j)==i)

Потрібно запустити в консолі браузера з підтримкою ES6, такого як Firefox.

Це робить багато непотрібних ітерацій, але навіщо робити це довше, щоб уникнути цього, правда?

  • Редагувати №1: збережено кілька байт, перетворивши його у функцію. Дякуємо Оптимізатору!
  • Редагувати №2: Завдяки hsl за хитрість оператора розповсюдження, щоб заощадити більше байтів!
  • Редагувати №3: І завдяки Робу В. за ще 3 байти!

Ви можете просто перетворити його у функцію, щоб зберегти там більше байтів
Optimizer

@Optimizer Щоправда, я думаю, це не повинно бути "stdin". Ваша реалізація свого імені :)
Ingo Bürk

Я не перевіряв це, але ви повинні бути в змозі використати оператор спреда для [...i]замістьi.split('')
NinjaBearMonkey

1
@hsl Божевільний, це працює. Я не знав, що оператор розповсюдження працює так. Спочатку я відчайдушно намагався використовувати його для створення масиву з діапазоном 0..N. Дякую!
Інго Бюрк

1
.slice(0,j)на один символ коротший за .substr(0,j). Крім того, перетворення на ціле число здається непотрібним, |0його можна видалити (використання |0фактично знижує корисність методу, оскільки воно не вдасться для повторів, що перевищують 2 ^ 31).
Rob W


0

Java 8, 28 байт

s->s.matches("(?s)(.+)\\1+")

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

Пояснення:

Перевіряє, чи відповідає input-String регексу, де String#matchesнеявно додається, ^...$щоб відповідати всій String.
Пояснення самого регулярного виразу:

^(s?)(.+)\1+$
^                Begin of the string
 (s?)            Enable DOTALL-mode, where `.` also matches new-lines
     (           Open capture group 1
      .+          One or more characters
        )        Close capture group 1
         \1+     Plus the match of the capture group 1, one or more times
            $    End of the string

Таким чином, він в основному перевіряє, чи повторюється підрядок два чи більше разів (підтримуючи нові рядки).

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