String.prototype.isRepeated


41

ОБНОВЛЕНИЕ : подчинение Исаака 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 минут. Я не буду считать, что этого достаточно для победы :). Поскольку это время сейчас не изменится, но голоса могут, я пошел с голосами
Оптимизатор

Этот вопрос должен быть переименован в xnor :) Он человек!
Сильвиу Бурча

Ответы:


16

Пиф , 9

/:+zz1_1z

Или

}z:+zz1_1

Оба являются близкими переводами ответа Python @ xnor, за исключением того, что они принимают ввод из STDIN и распечатывают его. Первый эквивалентен:

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

0 для False, 1 для True.

Вторая строка эквивалентна:

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

Ложь за ложь, правда за правда.

У официального компилятора Pyth была ошибка, связанная со второй, которую я только что исправил, поэтому первая - это официальное представление.


Я просто искал способ сообщить вам об этой ошибке (логическое значение не печатается). Не думал о первом и использовать xбыло слишком долго ...
Деннис

Да, ошибка исправлена. Кроме того, если вы хотите сообщить об ошибках, хорошим способом может быть открытие проблемы на сайте github, здесь: github.com/isaacg1/pyth/issues
isaacg

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

81

Python (24)

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

Проверяет, является ли строка собственной подстрокой, конкатенированной дважды, удаляя первый и последний символы, чтобы избежать тривиальных совпадений. Если это так, это должна быть нетривиальная циклическая перестановка сама по себе и, следовательно, сумма повторяющихся сегментов.


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

3
Я не совсем понимаю, как это работает. Можете ли вы привести объясненный вручную пример того, как это будет обрабатывать строку?
Nzall

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

6
Вы рубите его после того, как удвоите его. abстановится ababстановится ba, поэтому он возвращает ложь, а aaстановится aaaaстановится aa, что возвращает истину.
гистократ

1
@SargeBorsch Это работает точно так же: qweqweqweв weqweqweqweqweqwтом True.
xnor

30

Regex (на ECMAScript), 11 байт

Похоже, работа для регулярных выражений!

^([^]+)\1+$

Проверьте это здесь.

Я выбрал ECMAScript, потому что это единственный вариант (я знаю), который [^]соответствует любому символу. Во всех остальных случаях мне понадобится флаг для изменения поведения .или использование на [\s\S]три символа длиннее.

В зависимости от того, как мы рассчитываем флаг, который мог бы , конечно , быть байт короче. Например, если мы посчитаем pattern + flags (например, игнорируя разделители), эквивалент PCRE / Perl будет

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

Что составляет 10 байт, игнорируя разделители.

Проверьте это здесь.

Это соответствует только строкам, которые состоят как минимум из двух повторений некоторой подстроки.

Вот полная 26-байтовая функция ES6, но я утверждаю, что регулярные выражения в общем случае допустимы:

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

^(.+)\1+$у меня работает, что составляет 9 байт. Это не работает для вас?
Оптимизатор

@Optimizer Попробуйте строку с разрывом строки.
Мартин Эндер

Я попробовал asd\nasd\nasd\n. Это работает
Оптимизатор

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00, кажется, не работает для меня (и не должно)
Мартин Эндер

Да, это не работает. Может быть, это ускользает от того, \ когда я пишу \nвручную
Оптимизатор

12

CJam, 9

q__+)@+#)

Похоже на идею Кснора.

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 означает ИСТИНА
Цифровая травма

@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
Деннис


3

Чистый bash, 30 байтов

Простой порт умного ответа @ xnor :

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

Код выхода 0 для ИСТИНА и 1 для ЛОЖЬ:

$ 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, и длину повторяемой строки, если true.

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

Я знаю, я просто пытался быть
умником

2

ECMAScript 6 (34 36 )

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

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

Должен запускаться в консоли браузера с поддержкой ES6, такого как Firefox.


2

С 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. просто чтобы быть оригинальным ... я переписал ту же идею в с.

объяснение:

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).
Роб Вт


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.