Идея нового пароля: Word-walker


23

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

Взяв строку слов, пароль генерируется так:

  • Выберите n-й символ в n-м слове
  • Если n больше, чем слово, продолжайте считать в обратном направлении

Пример:

This is a fun task!
T     s a  u      !

T - первый символ,
s - второй,
а - первый, но если идти вперед и назад, он также является третьим,
u - вторым, но из-за обратного отсчета это также четвертое
'!' является пятым персонажем в «задании!» и, таким образом, будет включен в окончательный пароль,Tsau!

правила

  • На входе будет строка
  • Разделяйте строку пробелами, все остальные символы должны быть включены
  • Прописные буквы должны оставаться в верхнем регистре, то же самое с строчными
  • Вы делаете n шагов в каждом слове, где n - количество слов, которые предшествовали плюс один
  • Если n больше, чем слово, вы должны шагнуть назад через слово, если вы нажмете начало, вы идете вперед, пока не пройдете n раз
  • Первый и последний символы вводятся только один раз, поэтому в качестве примера «веселье» на седьмой позиции идет «funufun» и заканчивается на n, а не «funnuff» и заканчивается на f
  • Выход должен быть строкой

Примеры:

Input              Output
Once Upon A Time   OpAe
There was a man    Taaa
Who made a task    Waak
That was neat!     Taa
This is a long string to display how the generator is supposed to work  Tsagnoyotoipto

Самый короткий код в байтах побеждает!


3
to12-е слово (0-индексированное) в длинной строке, и поэтому буква кода должна быть t, а не o.
Нил

@Neil <s> последовательность индексируется 1, иначе вы не можете начать с первой буквы в первом слове </ s> (я пытался), мой плохой, я вижу это сейчас
Troels MB Jensen

14
Tsau!это китайский дляFuck!
sergiol

1
Также ваш пошаговый план по выбору funufun вместо funnuff увеличит процент гласных в выходных данных. Криптографически, это не надежный генератор паролей.
Criggie

1
@Criggie Я никогда не собирался его использовать, но, как я уже сказал, это доставило бы удовольствие, и, похоже, игроки в гольф согласны
Troels MB Jensen

Ответы:





4

Java 10, 148 117 114 110 байт

s->{int i=-1,j;for(var a:s.split(" "))System.out.print(a.charAt((j=a.length()-1)>0*i++?i/j%2<1?i%j:j-i%j:0));}

-31 байт благодаря @SamYonnou , создав порт ответа JavaScript @ user71546 .
-4 байта, спасибо @SamYonnou снова, оптимизируя алгоритм для Java.

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

Объяснение:

s->{                            // Method with String parameter and no return-type
  int i=-1,                     // Step integer, starting at -1
      j;                        // Temp integer
  for(var a:s.split(" "))       // Loop over the parts split by spaces
    System.out.print(           // Print:
     a.charAt((j=a.length()-1)  //  Set `j` to the the length of the part minus 1
               >0               //  If the length of the part is larger than 1 (`j` > 0)
                 *i++?          //  (and increase `i` by 1 in the process with `i++`)
                i/j%2<1?        //   If `i` integer-divided by `j` is even:
                 i%j            //    Print the character at index `i` modulo-`j`
                :               //   Else:
                 j-i%j          //    Print the character at index `j` minus `i` modulo-`j`
               :                //  Else:
                0));}           //   Print the first (and only) character
                                //   (the >0 check is added to prevent divided-by-0 errors)

Не работает для тестовых случаев 0, 2 и 5
TFeld

1
Гольф до 117 "используя более арифметический подход", аналогично тому, что делает версия s->{int i=-1,j;for(var a:s.split(" ")){System.out.print(a.charAt(++i>(j=a.length()-1)?j>0?i/j%2==0?i%j:j-i%j:0:i));}}
user71546

1
@ SamYonnou Спасибо! И я смог сыграть еще три байта, сняв скобки и изменив ==0на <1.
Кевин Круйссен

1
гольф до 110, избавившись от ++i>(j=a.length()-1)условия, так как математика работает одинаково, независимо от результата этого условия:s->{int i=-1,j;for(var a:s.split(" "))System.out.print(a.charAt(0<(j=a.length()+i-++i)?i/j%2<1?i%j:j-i%j:0));}
SamYonnou

1
@SamYonnou Еще раз спасибо! Я немного изменил 0<(j=a.length()+i-++i)?это, (j=a.length()-1)>0*i++?поэтому объяснение было немного легче набрать (однако при этом не было сохранено ни одного байта).
Кевин Круйссен,

3

Древесный уголь , 16 байт

⭆⪪S §⁺ι✂ι±²¦⁰±¹κ

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

  S                 Input string
 ⪪                  Split on spaces
⭆                   Map over words and join
      ι ι           Current word
       ✂ ±²¦⁰±¹     Slice backwards from 2nd last character to start exclusive
     ⁺              Concatenate
    §          κ    Cyclically index on current word index
                    Implicitly print

Я не часто использую последний параметр Slice.


Мне нравится, что Древесный уголь использует глиф ножниц
Иона

3

JavaScript (Node.js) , 78 70 69 68 байт

-1 байт @Arnauld

x=>x.split` `.map((y,i)=>y[a=i%(l=y.length-1)|0,i/l&1?l-a:a]).join``

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

объяснение

x=>
 x.split` `                    // Split the words by spaces
 .map((y,i)=>                  // For each word:
  y[                           //  Get the character at index:
                               //   A walk has cycle of length (2 * y.length - 2)
   a=i%(l=y.length-1)|0,       //   Calculate index a = i % (y.length - 1)
   i/l&1                       //   Check in which half the index i in
   ?l-a                        //   If in the second half of cycle, use y.length - 1 - a
   :a                          //   If in the first half of cycle, use a                  
  ]
 ).join``                      // Join back the letters




1

Pyth , 12 байт

s.e@+b_Ptbkc

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

s.e@+b_PtbkcQ   Final Q (input) implicit

           cQ   Split on spaces
 .e             Map the above with b=element, k=index
       Ptb        Remove 1st and last character
      _           Reverse
    +b            Prepend the unaltered element ('abcd' -> 'abcdcb')
   @      k       Get the kth character (0 indexed, wrapping)
s               Join on empty string, implicit output

1

Japt -P, 11 байт

¸Ëê ŪD gEÉ

Попытайся

¸Ë+s1J w)gE

Попытайся


Пояснения

¸Ëê ŪD gEÉ
¸               :Split on spaces
 Ë              :Map over each element D at index E
  ê             :  Palindromise
    Å           :  Slice off the first character
     ªD         :  Logical OR with the original element (the above will return an empty string for single character words)
        g       :  Get the character at index
         EÉ     :  E-1
¸Ë+s1J w)gE
¸               :Split on spaces
 Ë              :Map over each element D at index E
   s1J          :  Slice off the first and last characters
       w        :  Reverse
  +     )       :  Append to D
         gE     :  Get the character at index E

1

C (gcc) , 148 байтов (строковая версия), 114 байтов (печатная версия)

Если я должен вернуть строку (длинная версия):

char c[99]={0};char*f(s,t,u,i,j,k)char*s,*t,*u;{for(u=c,i=0;t=strtok(s," ");s=0,i++)*u++=t[j=strlen(t),k=2*j-(j>1)-1,(i%k<j?i%k:k-i%k)%j];return c;}

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

В противном случае я просто печатаю и не беспокоюсь о буфере (короткая версия):

f(s,t,i,j,k)char*s,*t;{for(i=0;t=strtok(s," ");s=0,i++)putchar(t[j=strlen(t),k=2*j-(j>1)-1,(i%k<j?i%k:k-i%k)%j]);}

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


-(j>1)-1можно заменить на +~(j>1)1 байт меньше, я думаю.
Шиеру Асакото

106 символов: putchar( t[ j=strlen(t)-1, k = i++ % (j ? j*2 : 1), k<j ? k : j+j-k ]); попробуйте онлайн!
user5329483

Буферизованная версия: глобальные переменные неявно обнуляются. Заменить *u++на c[i]и удалить.
user5329483

Опираясь на @ user5329483 105 байт
потолок cat

1

AWK, 79 байт

Главным образом потому, что мне любопытно увидеть какие-нибудь лучшие решения awk или bash!

{for(i=1;i<=NF;i++){l=length($i);k=int(i/l)%2?l-i%l:k%l;printf substr($i,k,1)}}

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



1

Haskell, 65 62 61 байт

zipWith(\i->(!!i).cycle.(id<>reverse.drop 1.init))[0..].words

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

Требуется последняя версия, Preludeкоторая имеет <>функцию.

                   words    -- split the input string into a list of words
zipWith(\i->     )[0..]     -- zip the elements i of [0..] and the words pairwise
                            -- with the function      
      ... <> ...            --   call the functions with a word and concatenate
                            --   the results. The functions are
        id                  --     id: do nothing
        reverse.drop 1.init --     drop last and first element and reverse
    cycle                   --   repeat infinitely
(!!i)                       -- take the ith elemnt of  

Изменить: -3 байта благодаря @ user28667, -1 байт благодаря @B. Мехта


Похоже, zipWith(\i w->(cycle$id<>reverse.drop 1.init$w)!!i)[0..].wordsтоже работает.
user28667

1
Вы можете сохранить другой байт, изменив лямбду на \i->(!!i).cycle.(id<>reverse.drop 1.init)фактическое wупоминание (TIO)
Б. Мехта


1

PHP , 77 байт

while(ord($w=$argv[++$i]))echo($w.=strrev(substr($w,1,-1)))[~-$i%strlen($w)];

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

  • -3 байта благодаря Кевину
  • -10 байт благодаря Титу

1
Хороший ответ! Одна маленькая вещь для гольфа: вы можете избавиться от скобок и еще одного третьего байта, изменив foreach(...){$c=...;echo$c[...];}на foreach(...)echo($c=...)[...];. Попробуйте онлайн: 87 байтов
Кевин Круйссен,

Вы можете использовать список аргументов для автоматического разбиения на слова (-8 байт) и .=сохранения двух байтов: while(ord($w=$argv[++$i]))echo($w.=strrev(substr($w,1,-1)))[~-$i%strlen($w)]; попробуйте онлайн
Тит

Ницца! Один вопрос: ~ - $ i делает то же самое, что и ($ i-1), верно?
user2803033

0

Powershell 208 186 170 байт

$args|%{$i=0;-join($_.Split()|%{$l=($b=($a=$_)).Length;if($l-gt2){$b=($a|%{-join$a[($l-2)..1]})}for($j=0;$a.Length-le$i;$j++){$a+=($b,$_)[$j%2]}$a.Substring($i,1);$i++})}

Ungolfed:

$args|%{
   $i=0;
    -join($_.Split()|%{
        $l=($b=($a=$_)).Length;
        if($l-gt2){
            $b=($a|%{-join$a[($l-2)..1]})
        }
        for($j=0;$a.Length-le$i;$j++){
            $a+=($b,$_)[$j%2]
        }
        $a.Substring($i,1);
        $i++
    })
}

Тестовые случаи ниже или попробуйте онлайн

@(
    "This is a fun task!",
    "Once Upon A Time",
    "There was a man",
    "Who made a task",
    "That was neat",
    "This is a long string to display how the generator is supposed to work"
)|%{$i=0;-join($_.Split()|%{$l=($b=($a=$_)).Length;if($l-gt2){$b=($a|%{-join$a[($l-2)..1]})}for($j=0;$a.Length-le$i;$j++){$a+=($b,$_)[$j%2]}$a.Substring($i,1);$i++})}

1
Здесь можно многое сделать короче. Вы видели советы по игре в гольф в PowerShell ?
briantist

Благодарность! Я думал об использовании switch сразу после публикации, но остальное мне еще не пришло в голову.
Питер Вандивье

Также одна актуальная проблема заключается в том, что вы не принимаете входные данные в этом фрагменте. Мы довольно гибки в том, что можем написать программу или функцию, но у вас есть неявный вклад. В качестве первого шага вы можете просто заменить ваш ""|%{с $args|%{, но я думаю , что вы можете играть в гольф это более эффективно тоже;)
briantist

1
Вот демонстрация в TIO, которая также показывает, как использовать функцию аргументов для тестовых случаев . Сохраняя блок кода только для своего кода, мы также можем использовать простые ссылки TIO и количество байтов для своего поста!
briantist

0

J, 43 байта

[:(>{~"_1#@>|i.@#)[:(,}.@}:)&.>[:<;._1' '&,

ungolfed

[: (> {~"_1 #@> | i.@#) [: (, }.@}:)&.> [: <;._1 ' '&,
  • <;._1 ' '&, разделить на пробелы
  • (, }.@}:)&.> за каждое слово убей первого и последнего вяза и добавь к слову
  • #@> | i.@# взять остаток от длины каждого слова, разделенный на его индекс
  • > {~"_1 возьми этот результат и вырви его из каждого слова.

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.