Munge minha senha

17

Palavras comuns ainda devem ser evitadas para serem usadas como senhas. Este desafio é sobre a codificação de um programa muito simples que munges uma determinada palavra-passe ( M odify UN ot G uessed E asily).

Entrada

Uma palavra, que é uma string escrita no alfabeto abcdefghijklmnopqrstuvwxyz. Não importa se as letras são minúsculas ou maiúsculas.

Munging

  1. Alterar qualquer sequência repetida de uma mesma letra para si mesma precedida pelo número de vezes que a letra foi repetida ( LLLLcom 4L)
  2. Mude o primeiro acom@
  3. Mude o primeiro bcom8
  4. Mude o primeiro ccom(
  5. Mude o primeiro dcom6
  6. Mude o primeiro ecom3
  7. Mude o primeiro fcom#
  8. Mude o primeiro gcom9
  9. Mude o primeiro hcom#
  10. Mude o primeiro icom1
  11. Mude o segundo icom!
  12. Mude o primeiro kcom<
  13. Mude o primeiro lcom1
  14. Mude o segundo lcomi
  15. Mude o primeiro ocom0
  16. Mude o primeiro qcom9
  17. Mude o primeiro scom5
  18. Mude o segundo scom$
  19. Mude o primeiro tcom+
  20. Mude o primeiro vcom>
  21. Mude o segundo vcom<
  22. Mude o primeiro wcomuu
  23. Mude o segundo wcom2u
  24. Mude o primeiro xcom%
  25. Mude o primeiro ycom?

A regra 1 deve ser aplicada o número necessário de vezes até que não seja possível aplicá-la mais. Depois disso, o restante das regras é aplicado.

Saída A palavra munged

Exemplos

  • codegolf -> (0639o1#
  • programming -> pr09r@2m1ng
  • puzzles -> pu2z135
  • passwords -> p@25uu0r6$
  • wwww -> 4uu
  • aaaaaaaaaaa -> 11a
  • lllolllolll -> 3103io3l
  • jjjmjjjj -> 3jm4j

Isso é , então faça seu programa o mais curto possível!

Nada nesta postagem deve ser usado como idéias de senha ou como parte das práticas de senha.

mdahmoune
fonte
18
O simples fato de que programas como esse são possíveis significa que o invasor pode gravá-los e mover a senha (e experimentar as várias opções) com a mesma facilidade (ainda mais fácil, porque geralmente têm acesso a um hardware melhor). Portanto, apenas por uma questão de segurança, direi: nada neste post deve ser usado como idéias de senha ou como parte das práticas de senha.
NH.
1
Eu recomendo tornar esse aviso em negrito e duplicá-lo na parte superior. Você nunca pode ser muito cuidadoso ...
wizzwizz4

Respostas:

11

Java 8, 237 321 319 280 247 241 240 237 bytes

s->{for(int a[]=new int[26],i=0,l=s.length,t,x;i<l;i+=t){for(t=0;++t+i<l&&s[i]==s[t+i];);System.out.print((t>1?t+"":"")+(++a[x=s[i]-65]>2?s[i]:"@8(63#9#1J<1MN0P9R5+U>u%?ZABCDEFGH!JKiMNOPQR$TU<2XYZ".charAt(x+26*~-a[x])+(x==22?"u":"")));}}

+84 bytes porque as regras sofreram alterações. ( EDIT: Finalmente, de volta aos meus 237 bytes iniciais. ) É fácil substituir WWWWpor 222WJava em Java, mas 4Wnão por ... Se apenas Java tivesse uma maneira de usar o grupo de captura regex para alguma coisa. Obter o comprimento "$1".length(), substituir a correspondência em si "$1".replace(...), converter a correspondência em um número inteiro com new Integer("$1")ou usar algo semelhante a Retina (por exemplo s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1")) ou JavaScript (por exemplo s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) seria minha coisa número 1 que eu gostaria de ver em Java no futuro para beneficiar o codegolfing ..>.> Acho que é a décima vez que odeio que o Java não possa fazer nada com a correspondência do grupo de captura ..
-78 bytes graças a @ OlivierGrégoire .

E / S está em maiúsculas.

Explicação:

Experimente aqui.

s->{                           // Method with String parameter and no return-type
  for(int a[]=new int[26],     //  Array with 26x 0
          i=0,                 //  Index-integer, starting at 0
          l=s.length,          //  Length
          t,x;                 //  Temp integers
      i<l;                     //  Loop (1) over the characters of the input
      i+=t){                   //    After every iteration: Increase `i` by `t`
    for(t=0;++                 //   Reset `t` to 1
        t+i<l                  //   Inner loop (2) from `t+i` to `l` (exclusive)
        &&s[i]==s[t+i];        //   as long as the `i`'th and `t+i`'th characters are equal
    );                         //   End of inner loop (2)
    System.out.print(          //   Print:
     (t>1?t+"":"")             //    If `t` is larger than 1: print `t`
     +(++a[x=s[i]-65]>2?       //    +If the current character occurs for the third time:
       s[i]                    //      Simply print the character
      :                        //     Else:
       "@8(63#9#1J<1MN0P9R5+U>u%?ZABCDEFGH!JKiMNOPQR$TU<2XYZ".charAt(x
                               //      Print the converted character at position `x`
        +26*~-a[x])            //       + 26 if it's the second time occurring
       +(x==22?"u":"")));      //      And also print an additional "u" if it's 'W'
  }                            //  End of loop (1)
}                              // End of method
Kevin Cruijssen
fonte
10

JavaScript (ES6), 147 bytes

s=>[[/(.)\1+/g,m=>m.length+m[0]],..."a@b8c(d6e3f#g9h#i1k<l1o0q9s5t+v>x%y?i!lis$v<".match(/../g),["w","uu"],["w","2u"]].map(r=>s=s.replace(...r))&&s

Casos de teste

Explicação

Executa uma série de substituições na sequência de entrada s, na ordem especificada pelo desafio. Cada item da série é uma matriz ou sequência, com dois itens, que é então espalhada ( ...r) e passada para s.replace().

s=>[
    [/(.)\1+/g, m=>m.length + m[0]],// first replacement: transform repeated letters
                                    // into run-length encoding

                                    // string split into length-2 partitions and
                                    // spread into the main array
    ..."a@b8c(d6e3f#g9h#i1k<l1o0q9s5t+v>x%y?i!lis$v<".match(/../g),
                                    // next replacements: all single-char replacements.
                                    // "second" versions are placed at the end so they
                                    //    replace the second instance of that char

    ["w","uu"],["w","2u"]           // last replacements: the two "w" replacements
]
.map(r=> s = s.replace(...r))       // run all replacements, updating s as we go
&& s                                // and return the final string
Justin Mariner
fonte
Resposta muito boa
mdahmoune
6

05AB1E , 69 bytes

-9 bytes graças a Emigna

γvygD≠×yÙ}J.•k®zĀÒĀ+ÎÍ=ëµι
•"@8(63#9#1<1095+>%?!i$<"ø'w„uu„2u‚â«vy`.;

Experimente online!

Okx
fonte
Você pode usar'w„uu„2u‚â
Emigna
Plz você pode verificar o resultado para wwww como entrada?
mdahmoune
@mdahmoune It outputs4uu
Okx
@Emigna Cartesian product, good idea.
Okx 19/10/17
A primeira parte pode serγvygD≠×yÙ}J
Emigna 19/10/19
6

Perl 5 , 152 + 1 ( -p) = 153 bytes

s/(.)\1+/(length$&).$1/ge;%k='a@b8c(d6e3f#g9h#i1j!k<l1mio0q9r5s$t+u>v<x%y?'=~/./g;for$i(sort keys%k){$r=$k{$i};$i=~y/jmru/ilsv/;s/$i/$r/}s/w/uu/;s/w/2u/

Experimente online!

Xcali
fonte
Plz, o que você quer dizer com (-p)?
mdahmoune
1
@mdahmoune -pé usado como argumento para perlna linha de comando que lê automaticamente as entradas STDINe printos conteúdos $_no final do script. O TIO permite essa opção e, uma vez que perl -pe<code>é 1 byte a mais do perl -e<code>que é contado como um byte adicional.
Dom Hastings
Eu acho que você cometeu um erro de digitação, o ~intervalo não deveria j~kser um !? Atualmente, substituiu a segunda ocorrência de icom a em ~vez de a !.
Kevin Cruijssen 19/10/19
@Xcali #testingonproduction
NieDzejkob
2
@NieDzejkob Não há lugar melhor. Essa é a única maneira que você sabe que funcionará na produção.
Xcali #
4

Provavelmente não é o mais jogado de golfe, mas funciona.

-6 bytes graças a ovs

-77 bytes graças a NieDzejkob e Jonathan French

Python 3 , 329 323 bytes 246 bytes

import re;n=input()
for a in re.finditer('(\w)\\1+',n):b=a.group();n=n.replace(b,str(len(b))+b[0],1)
for A,B,C in[('abcdefghikloqstvxyw','@8(63#9#1<1095+>%?','uu'),('ilsvw','!i$<','2u')]:
	for a,b in zip(A,list(B)+[C]):n=n.replace(a,b,1)
print(n)

Experimente online!

reffu
fonte
1
Eu acho que você pode cair.lower()
mdahmoune
Isso faz sentido, eu não tinha certeza se precisava lidar com maiúsculas ou não.
Reffu
321 bytes .
Jonathan Frech
1
320 bytes .
Jonathan Frech
2
Na verdade, sua resposta não funciona. jjjmjjjjdeve sair, 3jm4jmas saídas 3jm3jj. Edit: 258 bytes com este problema corrigido
NieDzejkob 21/10
3

Retina , 166 124 bytes

(.)\1+
$.&$1
([a-y])(?<!\1.+)
¶$&
¶w
uu
T`l¶`@8(63#9#1j<\1mn0\p9r5+u>\w%?_`¶.
([ilsvw])(?<!\1.+)
¶$&
¶w
2u
T`i\lsv¶`!i$<_`¶.

Experimente online! Explicação:

(.)\1+
$.&$1

Substitua uma sequência de letras repetidas pelo comprimento e pela letra.

([a-y])(?<!\1.+)
¶$&

Combinar a primeira ocorrência das letras apara ye marcá-los com um espaço reservado.

¶w
uu

Corrija a primeira ocorrência de w.

T`l¶`@8(63#9#1j<\1mn0\p9r5+u>\w%?_`¶.

Fixar a primeira ocorrência de todas as outras cartas de apara ye excluir os espaços reservados.

([ilsvw])(?<!\1.+)
¶$&

Marcar o (originalmente) segunda ocorrência das cartas i, l, s, v, ou wcom um marcador de posição.

¶w
2u

Corrija a segunda ocorrência de w.

T`i\lsv¶`!i$<_`¶.

Corrija a segunda ocorrência das outras quatro letras.

Neil
fonte
Você acha que é possível jogar golfe ainda mais?
Mdahmoune 19/10/19
@mdahmoune Sim, acho que posso salvar 33 bytes.
Neil
I-se-votou a sua resposta :) vai ser ótimo se o seu salvar os 33 bytes;)
mdahmoune
@mdahmoune Boas notícias, eu realmente salvei 42 bytes!
Neil
Grande, seu código é o segundo mais curto;)
mdahmoune
3

Haskell , 221 218 213 bytes

($(f<$>words"w2u li i! s$ v< a@ b8 c( d6 e3 f# g9 h# i1 k< l1 o0 q9 s5 t+ v> wuu x% y?")++[r]).foldr($)
f(a:b)(h:t)|a==h=b++t|1>0=h:f(a:b)t
f _ s=s
r(a:b)|(p,q)<-span(==a)b=[c|c<-show$1+length p,p>[]]++a:r q
r s=s

Experimente online!

Abusa foldrde executar a cadeia de caracteres através de uma sequência de transformações de cadeia de trás para a frente. A sequência "começa" com a rqual a repetição conta a substituição usando spanpara quebrar a cauda da corda quando ela deixa de ser igual à cabeça. Se a primeira parte não estiver vazia, é uma repetição, por isso imprimimos o comprimento +1. Em seguida, adicionamos um argumento fpara cada substituição de caracteres na ordem (reversa). As substituições são codificadas como uma única sequência de caracteres, com o primeiro caractere sendo o caractere a ser substituído e o restante como a sequência (já que as substituições w são vários caracteres) que devem ser substituídas. Coloquei essas cadeias codificadas em uma grande cadeia separada por espaços, para que wordspossam ser divididas em uma lista para mim.

EDIT: Obrigado @Laikoni por me salvar 5 bytes! Esse foi um uso inteligente do $qual não pensei. Eu também não conhecia esse <-truque.

user1472751
fonte
Thanx para explicação detalhada;)
mdahmoune
1
Você pode usar em (p,q)<-span(==a)bvez de let(p,q)=span(==a)be em p>[] vez de p/=[].
Laikoni
2
Economize mais dois bytes criando mpointfree: ($(f<$>words"w2u ... y?")++[r]).foldr($) Experimente online!
Laikoni 19/10/19
2

Lua , 173 bytes

s=...for c,r in("uua@b8c(d6e3f#g9h#i1i!jjk<l1limmnno0ppq9rrs5s$t+v>v<wuuw2ux%y?zz"):gmatch"(.)(.u?)"do s=s:gsub(c..c.."+",function(p)return#p..c end):gsub(c,r,1)end print(s)

Experimente online!

Ungolfed e explicou:

s = ...


--This string contains every character to replace, followed by
--the character(s) it should be replaced with.
--
--It also contains all characters for which repeated sequences
--of them should be replaced by "<number><character>". That is,
--all letters in the alphabet. This way, a single loop can do
--both the "replace repeated characters" and "encode characters"
--operations, saving a for loop iterating over the alphabet.
--
--Characters that shouldn't be replaced will be replaced with
--themselves.
--
--In order to avoid matching half of the "replace u with u"
--command as the replace part of another command, "uu" is placed
--at the beginning of the string. This ensures that only the
--2-character replacements for "w" get an extra "u".

cmdstring = "uua@b8c(d6e3f#g9h#i1i!jjk<l1limmnno0ppq9rrs5s$t+v>v<wuuw2ux%y?zz"


--Iterate over all the search/replace commands.
--The character to replace is in the "c" variable, the string to
--replace it with is in "r".
--
--Due to the dummy search/replace commands (i.e. "mm") placed
--in the string, this loop will also iterate over all letters
--of the alphabet.

for c,r in cmdstring:gmatch("(.)(.u?)") do
	
	--First, replace any occurences of the current letter
	--multiple times in a row with "<number><letter>".
	s = s:gsub(c..c.."+", function(p)
		return #p .. c
	end)
	
	--Then, replace the first occurence of the letter
	--with the replacement from the command string.
	s = s:gsub(c, r, 1)
end

print(s)
Jonathan S.
fonte
Lol lua :) bom trabalho
mdahmoune
2

C # (.NET Core), 317 , 289 , 279 bytes

p=>{string r="",l=r,h=r,c="a@b8c(d6e3f#g9h#i1i!k<l1lio0q9s5s$t+v>v<wuw2x%y?";int i=0,n=p.Length,d,a=1;for(;i<n;i++){h=p[i]+"";if(h==p[(i==n-1?i:i+1)]+""&&i!=n-1)a++;else{d=c.IndexOf(h);if(d>=0&&d%2<1){l=c[d+1]+"";h=l=="u"?"uu":l;c=c.Remove(d,2);}r+=a>1?a+""+h:h;a=1;}}return r;};

Experimente Online!

Espero que seja bom receber uma matriz de caracteres como uma entrada e não uma string.

Ungolfed :

string result = "", casesCharReplacement = result, currentChar = result, cases = "a@b8c(d6e3f#g9h#i1i!k<l1lio0q9s5s$t+v>v<wuw2x%y?";
int i = 0, n = pas.Length, casesIndex, charAmounts = 1;

// For every char in the pass.
for (; i < n; i++)
{
    currentChar = pas[i] + "";
    // if the next char is equal to the current and its not the end of the string then add a +1 to the repeated letter.
    if (currentChar == (pas[(i == n - 1 ? i : i + 1)] + "") && i != n - 1)
        charAmounts++;
    else
    {
        // Finished reading repeated chars (N+Char).
        casesIndex = cases.IndexOf(currentChar);
        // Look for the replacement character: only if the index is an even position, otherwise I could mess up with letters like 'i'.
        if (casesIndex >= 0 && casesIndex % 2 < 1)
        {
            casesCharReplacement = cases[casesIndex + 1]+"";
            // Add the **** +u
            currentChar = casesCharReplacement == "u"?"uu": casesCharReplacement;
            // Remove the 2 replacement characters (ex: a@) as I won't need them anymore.
            cases = cases.Remove(casesIndex, 2);
        }
        // if the amount of letters founded is =1 then only the letter, otherwise number and the letter already replaced with the cases.
        result += charAmounts > 1 ? charAmounts + ""+currentChar : currentChar;
        charAmounts = 1;
    }
}
return result;
Emiliano
fonte
1
Sim, é ok :) para a entrada
mdahmoune
2

C ++, 571 495 478 444 bytes

-127 bytes graças a Zacharý

#include<string>
#define F r.find(
#define U(S,n)p=F s(S)+b[i]);if(p-size_t(-1)){b.replace(i,1,r.substr(p+n+1,F'/',n+p)-p-2));r.replace(p+1,F'/',p+1)-p,"");}
#define V(A)i<A.size();++i,c
using s=std::string;s m(s a){s b,r="/a@/b8/c(/d6/e3/f#/g9/h#/i1//i!/k</l1//li/o0/q9/s5//s$/t+/v>/wuu//w2u/x%/y?/";int c=1,i=0;for(;V(a)=1){for(;a[i]==a[i+1]&&1+V(a)++);b+=(c-1?std::to_string(c):"")+a[i];}for(i=0;V(b)){auto U("/",1)else{U("//",2)}}return b;}

a "/a@/b8/c(/d6/e3/f#/g9/h#/i1//i!/k</l1//li/o0/q9/s5//s$/t+/v>/wuu//w2u/x%/y?/"cadeia é usada para transformar de um caractere para outro. 1 /significa que o primeiro "próximo caractere" deve ser substituído pelo seguinte /, 2 significa que o segundo "próximo caractere" deve ser substituído pelo seguinte.

Experimente online

HatsuPointerKun
fonte
Ótimo, você poderia adicionar um link tio.run?
Mdahmoune 21/10
ligação @mdahmoune TIO é adicionado, com o código de teste para seus casos de teste :)
HatsuPointerKun
494 bytes e atualize o link TIO adequadamente, se você o alterar.
Zacharý 22/10
@ Zacharý Você precisa colocar um espaço entre o nome da macro e o conteúdo da macro; caso contrário, ele gera um erro ao compilar com o C ++ 17. Além disso, você sabe como excluir um link TIO? (Uma vez que o antigo é inútil)
HatsuPointerKun
1
444 bytes
Zacharý
2

R , 224 219 bytes

function(s,K=function(x)el(strsplit(x,"")),u=rle(K(s)))
Reduce(function(x,y)sub(K('abcdefghiiklloqsstvvwwxy')[y],c(K('@8(63#9#1!<1i095$+><'),'uu','2u',K('%?'))[y],x),1:24,paste0(gsub("1","",paste(u$l)),u$v,collapse=""))

Experimente online!

Desagradável, mas a parte principal é a substituição iterativa no Reduce. subaltera apenas a primeira ocorrência da partida.

Agradecemos a JayCe por apontar um bom golfe!

Giuseppe
fonte
Bom trabalho :)))))
mdahmoune
economize 1 byte reorganizando args. Não fazer uma enorme diferença Eu sei;)
Jayce
@JayCe eu achei mais alguns bytes :-)
Giuseppe
1

Perl 5 , 123 bytes

Código de 122 bytes + 1 para -p.

Desenvolvido independentemente de @ Xcali 's resposta , mas usando um processo muito similar.

s/(.)\1+/$&=~y!!!c.$1/ge;eval"s/$1/$2/"while'a@b8c(d6e3f#g9h#i1i!k<l1lio0q9s5t+v>v<x%y?'=~/(.)(.)/g;s/s/\$/;s/w/uu/;s;w;2u

Experimente online!

Dom Hastings
fonte
1

Python 2 , 220 216 194 190 188 bytes

import re
S=re.sub(r'(.)\1+',lambda m:`len(m.group(0))`+m.group(1),input())
for a,b in zip('abcdefghiiklloqsstvvxyww',list('@8(63#9#1!<1i095$+><%?')+['uu','2u']):S=S.replace(a,b,1)
print S

Experimente online!

Python 3 , 187 bytes

import re
S=re.sub(r'(.)\1+',lambda m:str(len(m.group(0)))+m.group(1),input())
for a,b in zip('abcdefghiiklloqsstvvxyww',[*'@8(63#9#1!<1i095$+><%?','uu','2u']):S=S.replace(a,b,1)
print(S)

Experimente online!

TFeld
fonte
Thanx Tfeld 192 bytes tio.run/…
mdahmoune 20/17
Grande golfe;)
mdahmoune
186 bytes . Você também pode portar isso facilmente para Python 3 em 192 bytes , mas não acho que deva ser uma resposta separada.
precisa saber é o seguinte
@NieDzejkob Parece que sua versão Python 2 para golfe produz uma saída diferente da versão atual do OP ou da versão Python 3.
Jonathan Frech
@JomathanFrech desculpe, como sempre testando na produção. 188 bytes
NieDzejkob 21/10
1

Pip , 103 102 bytes

aR:`(.)\1+`#_.B
Fm"abcdefghiiklloqsstvvwwxy"Z"@8(63#9#1!<1i095$+><WU%?"I#Ya@?@maRA:ym@1aR'W"uu"R'U"2u"

Experimente online!

Explicação

O código executa três etapas de transformação:

aR:`(.)\1+`#_.B  Process runs of identical letters

a                1st cmdline argument
 R:              Do this replacement and assign back to a:
   `(.)\1+`       This regex (matches 2 or more of same character in a row)
           #_.B   Replace with callback function: concatenate (length of full match) and
                  (first capture group)
                  Note: #_.B is a shortcut form for {#a.b}

Fm"..."Z"..."I#Ya@?@maRA:ym@1  Do the bulk of rules 2-25

  "..."                        String of letters to replace
       Z"..."                  Zip with string of characters to replace with
Fm                             For each m in the zipped list:
                   @m           First item of m is letter to replace
                a@?             Find its index in a, or nil if it isn't in a
               Y                Yank that into y
             I#                 If len of that is truthy:*
                     aRA:        Replace character in a at...
                         y        index y...
                          m@1     with second item of m

aR'W"uu"R'U"2u"  Clean up substitution
                 In the previous step, the replacements each had to be a single character.
                 This doesn't work for uu and 2u, so we use W and U instead (safe, since
                 uppercase letters won't be in the input) and replace them here with the
                 correct substitutions.
aR'W"uu"         In a, replace W with uu
        R'U"2u"  and U with 2u
                 and print the result (implicit)

* Precisamos testar se a@?m@0é nulo. Não basta testar se é verdade, pois 0 é um índice legítimo que é falsey. O Pip não tem uma maneira curta e interna de testar se um valor é nulo, mas testar seu comprimento funciona bem o suficiente neste caso: qualquer número terá comprimento pelo menos 1 (verdade) e nulo terá comprimento nulo (falsey).

DLosc
fonte