Искажай эту строку!

20

Задав строку в качестве входных данных, выведите один или несколько вариантов строки так, чтобы:

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

Вы можете предположить, что это всегда будет возможно для данной строки и будет содержать только единичные буквенные символы ( [a-z]или, [A-Z]если вы предпочитаете)

Обратите внимание, что дубликаты одного и того же символа не считаются уникальными.

Например, учитывая ввод programming, вывод не может содержать m7-й или 8-й символ и не может содержать g4-й или 11-й символ (1 проиндексирован)

Пример:

Возьми струну abcdef

Следующее будет правильным выводом: daecfb

Однако следующее будет недопустимым: fdbcaeкак в этом примере cи bвсе еще рядом.

Смежность также окутывает, а это значит, что вы не можете делать, fdbecaкак fи aвсе еще рядом.

Testcases:

Обратите внимание, что это не единственные действительные выходы для данных входов

Написано как input -> output:

helowi -> ioewhl
mayube -> euabmy
stephens -> nhseespt
aabcdeffghij -> dbfhjfigaeca

Подсчет очков:

Это поэтому побеждает меньшее количество байтов на каждом языке !

Skidsdev
источник
No character is adjacent to a character that it was originally adjacent to, Разве порядок не имеет значения для смежности? Таким образом, ввод «abcd» не может иметь «ab» нигде, и также не может иметь «ba» нигде?
DrZ214
@ DrZ214 это правильно
Скидсдев

Ответы:

5

Желе , 24 23 байта

ẋ2ṡ2Ṣ€
dzǤœ&¬ɓ³=Sȯ
ẊÇ¿

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

Чрезвычайно долго из-за того, что я ужасен в Джелли, но это наконец работает, по крайней мере ... все еще в процессе игры в гольф.

link that generates a list of sorted adjacent pairs:
ẋ2            duplicate argument ("abc" -> "abcabc")
  ṡ2          slices of 2 (-> "ab","bc","ca","ab","bc")
    Ṣ€        sort each

link that tests for invalid permutations:
Ç             get sorted adjacent pairs of argument
 ³Ç¤          do the same for the original input
    œ&        set intersection, then...
      ¬       ...inverse; i.e. do they have no elements in common
       ɓ   ȯ  logical OR the result of that with...
        ³=    elementwise equality with original input, and...
          S   ...sum; i.e. are some characters in the same position

main link:
Ẋ             shuffle the input list
  ¿           while
 Ç            the result of the previous link is truthy
Дверная ручка
источник
Протестировано со всеми тестами в OP, работает для всех из них
Skidsdev
Это может быть очень длинным для Желе, но чрезвычайно коротким для всего остального (за возможным исключением 05AB1E и нескольких других безумных языков игры в гольф).
Грифон - Восстановить Монику
да, это безумно мало, я не ожидал, что даже Джелли сделает это в гольфе, даже неправильное решение 05AB1E, которое не проверяло исходную позицию символа, было 45 байтов
Skidsdev
Там идет еще один мод, испорченный Jelly. Как грустно.
Caird Coneheringaahing
3

Python 2 , 185 байт

from itertools import*
x=input()
g=lambda m:set(zip(m*2,(m*2)[1:]))
for l in permutations(x):
 if not((g(l)|g(l[::-1]))&(g(x)|g(x[::-1]))or any(a==b for a,b in zip(x,l))):print`l`[2::5]

Попробуйте онлайн!
Печатает все допустимые строки

прут
источник
проверено на mayube, stephensи helowi, похоже, работает для всех 3. Мне нужно сделать выходной валидатор, чтобы провести более интенсивное тестирование
Skidsdev
Время истекло aabcdeffghij, но это не значит, что оно не работает, просто для этого требуется больше минуты
Skidsdev
Чтобы запустить «aabcdeffghij» на моей машине, нужно ДЛИННОЕ время. Пока> 2мин. Также похоже, что это печатает более одной перестановки, что не соответствует спецификации.
Не то чтобы Чарльз
Род - Вы можете сэкономить несколько байтов сprint next(l for l in permutations(x) if not((g(l)|g(l[::-1]))&(g(x)|g(x[::-1]))or any(a==b for a,b in zip(x,l))))
Не то, чтобы Чарльз
@NotthatCharles вы забыли `l`[2::5]= /
Род
3

PHP> = 7.1, 147 байт

for($a=$argn,$r="^$a[-1].*$a[0]$",$k=0;$v=$a[$k];)$r.="|^.{{$k}}$v|$v".($l=$a[$k++-1])."|$l$v";for(;preg_match("#$r#",$s=str_shuffle($a)););echo$s;

PHP Sandbox Online

PHP> = 7.1, 184 байта

Используйте расстояние Левенштейна вместо способа Regex

for($a=$argn;$v=$a[$k];$r[]=$l.$v)$r[]=$v.($l=$a[$k++-1]);for(;!$t&&$s=str_shuffle($a);)for($t=1,$i=0;$v=$s[$i];$t*=$v!=$a[$i++])foreach($r as$x)$t*=levenshtein($x,$s[$i-1].$v);echo$s;

PHP Sandbox Online

PHP , 217 байт

Версия под 7.1

for($l=strlen($a=$argn),$r=$a[$k=0].$a[$l-1]."|".$a[$l-1]."$a[0]|^{$a[$l-1]}.*$a[0]$";$v=$a[$k];!$k?:$r.="|$v".$a[$k-1],++$k<$l?$r.="|$v".$a[$k]:0)$r.="|^.{{$k}}$v";for(;preg_match("#$r#",$s=str_shuffle($a)););echo$s;

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

Йорг Хюльсерманн
источник
Боже мой, это работает
Skidsdev
Почему это не должно работать? Я делаю все возможное регулярное выражение. Если он совпадает, перетасуйте строку, пока она не
совпадет
ждать, не будет работать на helowi, выходы ioewlh, iи hпримыкают
Skidsdev
@Mayube Хорошо, теперь нужно сделать последний случай безопасным
Йорг Хюльсерманн
Да, проверено со всеми тестами в OP, все они работают
Skidsdev
3

Брахилог , 21 байт

p.jP;?z≠ᵐ&j¬{s₂p~s}P∧

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

объяснение

Я действительно хотел p.;?z≠ᵐ&j¬{s₂p~s~j}бы работать на 2 байта меньше, но, кажется ~j, не достаточно умен ...

p.jP;?z≠ᵐ&j¬{s₂p~s}P∧  Input is a string, say ? = "asdfgha"
p                      Take a permutation of ?, say "sfagadh".
 .                     It is the output.
  j                    Concatenate it to itself: "sfagadhsfagadh"
   P                   Call that string P.
    ;?                 Pair P with the input: ["sfagadhsfagadh","asdfgha"]
      z                Zip, repeating elements of the longer string:
                        [["s","a"],["f","s"],["a","d"],...,["a","g"],["d","h"],["h","a"]]
       ≠ᵐ              Each pair must have different elements.
         &             Start new predicate
          j            Concatenate ? to itself: "asdfghaasdfgha"
           ¬{     }    The following cannot be satisfied:
             s₂        Take a substring of length 2
               p       and permute it.
                ~s     It is a substring of
                   P   P.
                    ∧  Do not unify P with the output.
Zgarb
источник
2

PHP 7.1, 136 131 байт

вдохновленный решением Jörg :

for($a=$argn;$c=$a[$k];)$r.="|$c".($d=$a[$k-1])."|$d$c|^.{".+$k++."}$c";while(preg_match("#$a$r#",($s=str_shuffle($a)).$s));echo$s;

Запустите как трубу с -rили проверьте это онлайн . (Убедитесь, что выбрана версия PHP 7.1 или выше)

Требуется PHP 7.1; добавить 14 байт для старого PHP: заменить $k-1на ($k?:strlen($a))-1;
(еще два байта для PHP <5.3: $k?$k-1:strlen($a)-1)

сломать

# A: loop through input to collect sub-expressions
for($a=$argn;$c=$a[$k];)
    $r.="|$c".($d=$a[$k-1])     # 1. pair of characters
        ."|$d$c"                # 2. reversed pair
        ."|^.{".+$k++."}$c";    # 3. $c is at k-th position
# B: shuffle input until regex does not match the result
while(preg_match("#$a$r#",($s=str_shuffle($a)).$s));    # (input as dummy sub-expression)
# C: print result
echo$s;
Titus
источник
@ JörgHülsermann намного больше;)
Тит
@ JörgHülsermann Случай переноса обрабатывается в первой итерации ( $c=$a[$k=0], $d=$a[$k-1]) с помощью $s.$s.
Тит
Хорошо, хороший трюк
Йорг Хюльсерманн
1

PHP 7.1, 187 185 172 178 143 байта

do for($r=str_shuffle($s=$argn),$p=$i=0;$c=$s[$i];$p+=($c==$z)+preg_match("#$a|$b#",$s.$s))$b=strrev($a=$r[$i-1].$z=$r[$i++]);while($p);echo$r;

Запустите как трубу с -rили проверьте это онлайн . (Убедитесь, что выбрана версия PHP 7.1.0 или выше!)

сломать

do
    for($r=str_shuffle($s=$argn),   # 2. shuffle input
        $p=$i=0;$c=$s[$i];          # 3. loop through input
        $p+=($c==$z)                        # 2. set $p if char is at old position
            +preg_match("#$a|$b#",$s.$s)    #    or if adjacency occurs in input
    )
        $b=strrev($a=$r[$i-1].$z=$r[$i++]); # 1. concat current with previous character
while($p);                          # 1. loop until $p is falsy
echo$r;                             # 4. print
Titus
источник
Сбой на входе mayube, выходов yeuamb, mи aявляются смежными
Skidsdev
1
Кроме того, ваш онлайн-тестер, похоже, не очень хорош, каждый тестовый пример, который я пробовал, просто перерыв через 3 секунды
Skidsdev
@Mayube Я забыл упомянуть: используйте PHP версии 7.1
Титус
1

Рубин, 110 97 102 байт

->s{x=s.chars
t=s*2
x.shuffle!while s.size.times.any?{|i|a,b=(x*2)[i,2];a==s[i]||t[a+b]||t[b+a]}
x*''}

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

daniero
источник
Это не следует правилу «смежности»; например, я получил 3594817062в качестве вывода по вашей ссылке TIO.
Ручка
@ Doorknob исправлено!
Даниеро
1

JavaScript 6, 116 байт

f=x=>(h=[...x].sort(_=>Math.random(z=0)-.5)).some(y=>y==x[z]||(x+x).match(y+(q=h[++z]||h[0])+'|'+q+y))?f(x):h.join``

f=x=>(h=[...x].sort(_=>Math.random(z=0)-.5)).some(y=>y==x[z]||(x+x).match(y+(q=h[++z]||h[0])+'|'+q+y))?f(x):h.join``

console.log (f('abcdef'));

l4m2
источник
1

Stax , 23 21 байт

å╘┤‼¬½P¥ë└w↕⌐î◘E{╟u!Ö

Запускать и отлаживать онлайн!

Спасибо за @recursive за сохранение 2 байта.

Занимает очень много времени, чтобы бежать. Более разумная / выполнимая версия (всего 2 байта длиннее)

Ç≡╨áiS║çdèû.#-Gî☺└╨◙σφ+

Запускать и отлаживать онлайн!

объяснение

Использует распакованную версию для объяснения.

w|Nc_:=nGyG|*{E-!f+}ch+2B
w                            Loop anything before `}` while
 |N                          Next permutation (starting from the input)
   c_:=                      Index where the current array has the same element as the input (*)
                   }ch+2B    Define a block that finds all contiguous pairs in current string, including the pair `[last element, first element]`
       nG                    Apply the defined block to current string                         
         yG                  Do the same for the input
           |*                Outer product, contains pairs (which themselves are pairs) constructed from the last two array.
             {   f           Only keep pairs
              E-!            whose two elements have the same set of characters
                  +          Prepend the array at step (*).
                             This is used as the condition for the while loop
Вейцзюнь Чжоу
источник
Ницца. Есть улучшение, которое вы можете сделать, используя G. Вы делаете, {...}X!...x!чтобы выполнить один и тот же блок дважды. В общем, вы можете переписать это как G...G с }... в конце программы, как это .
рекурсивный
Спасибо. Я видел, как вы использовали Gв другом посте, чтобы сохранить один байт, заменив {...}*на D.... Я думаю, я все еще не совсем привык к этому ...
Вейцзюнь Чжоу