Anonimize nomes - mais ou menos

16

Edit: Haverá um bônus de -20 para mascaramento aleatório

Olá colegas denunciantes e portadores de conhecimento secreto.

Devo-me a uma entrevista por correio e, é claro, não posso dizer nomes específicos em toda a extensão. Mas, como quero divulgá-lo de uma maneira não tão óbvia, preciso de sua ajuda.

Fornecerei esses nomes na forma de

"evil_company_that_makes_me_shiver"

mas certamente não quero explicá-lo completamente. Sua tarefa para me ajudar e ao mundo inteiro é que você forneça um bom programa que transforme o que foi dito acima em

"ev**************************"

ou

"**il************************"

ou mesmo

"****_c**********************"

Eu acho que você entendeu. Mas há uma falha: quero divulgar o nome no total, por isso preciso passar o número de ocorrências e a palavra em si para o script, revelando as letras pouco a pouco. Um exemplo pode ser

~$ ./whistle NSA 3
> "N**"
> "**A"
> "*S*"

ou

~$ ./whistle nuclear 3
> "nu*****"
> "***lea*"
> "**c***r"

ou

~$ ./whistle nuclear 2
> "nuc****"
> "***lear"

Espero que você possa me ajudar e, como sabemos que esse tamanho importa, o menor código vence. Ajude a tornar este mundo um lugar melhor!

german_guy
fonte
11
Você não fornece detalhes sobre como a máscara deve acontecer, portanto, você deve obter o código mais curto, independentemente dos seus exemplos.
precisa saber é o seguinte
Eu pensei que estava claro que o código mais curto vence? Hmmm, talvez eu precise melhorar minha gramática inglesa de acordo com o seguinte :( / Edit: Eu realmente não me importo com o modo como a máscara é feita, o acima é apenas um exemplo, mas deve ser "ilegível" se você ler uma frase sozinho "
german_guy 03/04
Sim, o código mais curto estava claro. Mas você geralmente obtém mascaramento "regular", não como suas amostras. Talvez, já que você não se importa, mude as saídas de amostra para as normais. Especificamente seu segundo exemplo de que marcha mais a exemplo na sua pergunta
Bill Woodger
11
Ou você pode receber um bônus por mascaramento aleatório.
ɐɔıʇǝɥʇuʎs

Respostas:

12

GolfScript, 26 caracteres

Como nenhuma forma específica de divulgação foi especificada, decidi ir pelo mais curto possível:

:f,\`{{\)f%.!@42if}%\;n}+%

Você pode experimentar esse código online .

Exemplo:

> "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 7
******G******N******U*****
*****F******M******T******
****E******L******S******Z
***D******K******R******Y*
**C******J******Q******X**
*B******I******P******W***
A******H******O******V****

Código comentado:

:f           # Save the second input to variable f
,            # Makes the array [0 1 2 .... f-1]
\`{          # \´{}+% builds a code block where
             # first the input string is pushed (done
             # via the + operator and afterwards the whole
             # block is applied to above array, i.e.
             # For each line 0, 1, ...                                                
             #   Here, the stack contains the line number (counter)
             #   and the string
  {          #   {}% -> map to each character of the string
             #     Stack contains counter and current character
    \)f%     #     Increase the counter by one and calculate modulo f
    .        #     Duplicate counter (will be used for the if below)
    !        #     and test for zero 
             #     I.e. if counter==0
    @        #       Then Current character
    42       #       Else 42 (which is '*')
    if       #     
  }%         #   The mapping operation masked most of the characters
  \;         #   Discard the counter
  n          #   Add newline
}+%      
Howard
fonte
Agradável! Você poderia explicar o que cada parte do código faz?
John Odom
9
Não consigo ver o porquê. O GolfScript é tão auto-documentado.
Evpok
@ JohnOdom No entanto, adicionei alguns comentários ao código.
Howard
se você decidir aleatoriamente se vai mudar todos os * por um para a direita, isso conta para o bônus de mascaramento aleatório?
Cruncher
7

PHP - 80 bytes

<?for(;($c=$argv[1][~-$i+=1])?:$k^++$j;)echo$c?$i%$k=&$argv[2]^$j?'*':$c:$i='
';

Uso da amostra:

$ php whistle-blower.php ABCDEFGHIJKLMNOPQRSTUVWXYZ 7
******G******N******U*****
A******H******O******V****
*B******I******P******W***
**C******J******Q******X**
***D******K******R******Y*
****E******L******S******Z
*****F******M******T******
primo
fonte
7

Python ( 157 149 139 138-20 = 118):

def f(a,b):
 from random import*;c=[["*"]*len(a) for i in range(b)]
 for d in range(len(a)):choice(c)[d]=a[d]
 for e in c:print "".join(e)

Pitão de queijo ( 55 35):

Você não me disse a distribuição necessária;)

g=lambda a,b:["*"*len(a)]*(b-1)+[a]

Pitão uniforme ( 129 123 122):

def h(a,b):
 c=[["*"]*len(a)for i in range(b)]
 for d in range(len(a)):c=c[1:]+c[:1];c[0][d]=a[d]
 for e in c:print"".join(e)

Resultado:

a="Synthetica 'Evil' the Second"
b=7
f(a,b)
print
for i in g(a,b): print i
print
h(a,b)

***t***i***'***** *********d
******************t** ******
******t*** ***********Se**n*
S**************l****e*******
*y******c***E************o**
**n*h****a**************c***
*****e*******vi*'**h********

****************************
****************************
****************************
****************************
****************************
****************************
Synthetica 'Evil' the Second

******t******v******e******d
S******i******i****** ******
*y******c******l******S*****
**n******a******'******e****
***t****** ****** ******c***
****h******'******t******o**
*****e******E******h******n*
ɐɔıʇǝɥʇuʎs
fonte
Seu python de queijo pode ser reduzido para g=lambda a,b:[a]+["*"*len(a)]*(b-1). : P
cjfaure 03/04
@Trimsty vejo, graças :)
ɐɔıʇǝɥʇuʎs
3
Penso, mas certamente não quero explicitar completamente , invalida claramente uma solução que não garante que pelo menos um caractere seja mascarado em cada linha de saída.
Howard
@ Howard Eu sei que está esticando as regras, mas disclose the letters bit by bittambém pode significar first, disclose the first bit (that just happens to be the entire thing), repeat until the b is met. Isso também pode acontecer para a primeira resposta, então apenas afirme que você usou essa, e que aconteceu muito bem para produzir esse resultado. (Acabei de perceber que você também pode escrevê-lo como ["*"*len(a)]*(b-1)+[a], para começar a divulgar bits que contêm 0 bytes de informações reais e, na última linha, você divulga outro bit.) No entanto, percebo que isso está se estendendo ao máximo.
ɐɔıʇǝɥʇuʎs
3

Bash, 80 bytes

m=${1//?/*}
for((i=1;d=i*${#1}/$2,i++<=$2;c=d)){
echo "${m:0:c}${1:c:d-c}${m:d}"
}

Em ação:

$ ./anon.sh stackoverflow.com 6
st ***************
** ack ************
***** ove *********
******** rfl ******
*********** ow. ***
************** com
$ 
Trauma Digital
fonte
2

C #, 226

Isso pode ser reduzido se você substituir o material aleatório por uma distribuição mais simples (pense no módulo), mas a aleatoriedade é o que me interessou. =)

Enfim, colocando tudo em apenas uma linha, recebo 226 caracteres. No código legível, fica assim:

private void F(string n, int i)
{
    var l = n.Length;
    var r = new Random();
    var a = new string[i];

    for (var p = 0; p < l; p++)
    {
        var x = r.Next(0, i);
        for (var j = 0; j < i; j++)
        {
            a[j] += j == x ? n.Substring(p, 1) : "*";
        }
    }

    for (var j = 0; j < i; j++)
    {
        Console.WriteLine(a[j]);
    }
}

Saída de amostra:

Anonymize.exe ABCDEFGHIJKLMNOPQRSTUVWXYZ 7
*****F**I**********T**W***
A*****************S****X**
**CDE**H*JKL**************
*************N************
**************O*****U****Z
*B****G*****M***QR********
***************P*****V**Y*
deroby
fonte
Isso garante pelo menos sempre o caractere da entrada?
precisa saber é o seguinte
Hmm .. não, provavelmente não; boa pegada. Para cadeias curtas e valores baixos, ivocê provavelmente pode acabar com ***/test.
deroby
2

Perl, 24

$_ x=<>;s/(.|
)./\1*/g

Requer a -popção, que responde por dois dos bytes. Lê de STDIN.

Como funciona

  • Por causa dessa -popção, o Perl lê a primeira mentira de entrada e armazena seu conteúdo $_.

  • O comando $_ x=<>;duplica a primeira linha de entrada o número de vezes que a segunda linha de entrada ( <>) especifica.

  • O comando s/(.|\n)./\1*/g;consome dois caracteres e substitui o segundo (que não pode ser uma nova linha) por um asterisco. Faz isso até consumir todo o conteúdo de $_.

    Como as novas linhas contam como o primeiro caractere, isso ofuscará todos os caracteres pares na primeira linha e todos os caracteres ímpares nas linhas restantes.

  • Por causa da -popção, Perl imprime o conteúdo de $_.

Exemplo de entrada

codegolf
4

Saída de exemplo

c*d*g*l*
*o*e*o*f
*o*e*o*f
*o*e*o*f
Dennis
fonte
cordas duplicados, não muito limpo ...
CSᵠ
O que fez você pensar que poderia mexer com a entrada para tê-la em duas linhas?
Bill Woodger
@ BillWoodger: A pergunta não especifica nenhuma forma de entrada.
Dennis
Justo. couldpermite através :-)
Bill Woodger
Since newlines count as the first character, this will obfuscate all even characters on the first line and all odd characters on the remaining lines.Soa como ele irá falhar paracodegolf\n1
Cruncher
1

Java - 490

Sim, não é realmente um jogador de golfe ou algo assim. Oh bem, aqui está:

import java.util.ArrayList;public class Anonymise {public static void  main(String[] args){ArrayList[] c=new ArrayList[Integer.parseInt(args[1])];for(int i=0;i<c.length;i++)c[i]=new ArrayList();for(char a:args[0].toCharArray()){int f=new java.util.Random().nextInt(c.length);c[f].add(a);for(int i=0;i<c.length;i++)if(i!=f)c[i].add('*');}ArrayList<String> b = new ArrayList<String>();for(ArrayList a:c){String s = "";for(Object o : a)s += o;b.add(s);}for(String s : b)System.out.println(s);}}

Em um formato agradável e legível:

import java.util.ArrayList;

public class Anonymise {

public static void main(String[] args){
    ArrayList[] c = new ArrayList[Integer.parseInt(args[1])];
    for(int i=0;i<c.length;i++)
        c[i]=new ArrayList();
    for(char a:args[0].toCharArray()){
        int f = new java.util.Random().nextInt(c.length);
        c[f].add(a);
        for(int i=0;i<c.length;i++)
            if(i!=f)c[i].add('*');
    }
    ArrayList<String> b = new ArrayList<String>();
    for(ArrayList a:c){
        String s = "";
        for(Object o : a)
            s += o;b.add(s);
    }
    for(String s : b)
        System.out.println(s);
}
}

Uso de amostra (quando executado a partir da classe compilada)

> java Anonymise OnlinePerson 3
*n****P***o*
O*li***e****
****ne**rs*n
Isaac
fonte
Você está executando isso ou digitando? Como P chega a ser p?
precisa saber é o seguinte
Sem problemas. Apenas arrumar afastado os comentários usados agora
Bill Woodger
Apenas import java.util.*também, ArrayList<String> = new ArrayList<>();vai funcionar. Você também pode remover muitos espaços. E na maioria das vezes, você pode usar em Listvez de ArrayList.
Ypnypn
1

Python 3-187 (-20 = 167)

Levei um tempo para escrever, provavelmente poderia ser mais jogado.

import sys,random as a
b=sys.argv
x=[""for i in' '*int(b[2])]
for i in range(len(b[1])):n=a.randrange(len(x));x=[c+["*",b[1][len(c)]][j==n]for j,c in enumerate(x)]
for i in x:print(i)

Uso da amostra:

$ python tx.py super_anonymous_user 3
s******n**y*ou****e*
**p***a**n*m**s_us*r
*u*er_**o***********

Em função - 161 (-20 = 141)

from random import*
def f(c,n):
    x=[""for i in' '*n]
    for i in range(len(c)):n=randrange(len(x));x=[v+["*",c[len(v)]][j==n]for j,v in enumerate(x)]
    return x
cjfaure
fonte
Isso garante pelo menos sempre o caractere da entrada?
precisa saber é o seguinte
@BillWoodger No.
cjfaure
2
Desculpe, pessoalmente eu considero que não está funcionando então. então.
precisa saber é o seguinte
Algumas maneiras simples de encurtar as coisas: Descompacte sys.argvna tarefa e inicialize xcomo x=['']*int(b[2])(com b[2]substituído por qualquer que seja o nome da variável que você usa na descompactação).
User2357112 suporta Monica
2
Penso, mas certamente não quero explicitar completamente , invalida claramente uma solução que não garante que pelo menos um caractere seja mascarado em cada linha de saída.
Howard
1

C # 184

namespace System.Linq{class P{static void Main(string[] a){int n=int.Parse(a[1]);for(int i=0;i<n;i++)Console.WriteLine(new String(a[0].Select((c,x)=>(i+x)%n==0?c:'*').ToArray()));}}}

Não-golfe

namespace System.Linq
{
    class P
    {
        static void Main(string[] a)
        {
            int n = int.Parse(a[1]);
            for (int i = 0; i < n; i++)
                Console.WriteLine(new String(a[0].Select((c, x) => (i + x) % n == 0 ? c : '*').ToArray()));
        }
    }
}

Amostra:

> Anonymize.exe "qwertyuio" 4
q***t***o
***r***i*
**e***u**
*w***y***
Rik
fonte
1

Perl 6 (77 bytes)

Isso pode ser considerado trapaça, mas resolve o problema (não imprime completamente a string).

($_,$!)=@*ARGS;.say for .chop~"*","*"x.chars-1~.substr(*-1),"*"x.chars xx$!-2

E a saída da amostra.

> ./script.p6 ultimately_awesome 6
ultimately_awesom*
*****************e
******************
******************
******************
******************
Konrad Borowski
fonte
1

JavaScript - 170

function s(a,e){o="",b=a.length,x=b/e|0,y=b-x*e;for(c=1;c<=e;c++){r="*";o+=Array((c-1)*x+1).join(r)+a.substr(c*x-x,c==e?x+y:x)+Array(c<e?b-c*x+1:0).join(r)+"\n"}return o}

Uma rápida, quebra se você fornecer um nome e pedir mais peças do que personagens, mas vai até esse ponto e até 1. Poderia jogar mais, presumo, por isso, pode revisar ou seguir conselhos, pois é uma bagunça.

Edit: Golfe mais (de 187) com remoção de suportes (@Synthetica) e substituição de Math.floor de @toothbrush. Para a mudança de loop, conforme sugerido, resulta em erros na saída.

Matt
fonte
function s(d,a){o="";b=d.length;x=Math.floor(b/a);y=b-x*a;for(c=1;c<=a;c++)r="*",o+=Array((c-1)*x+1).join(r)+d.substr(c*x-x,c==a?x+y:x)+Array(c<a?b-c*x+1:0).join(r)+"\n";return o}; encerramento-compiler.appspot.com/home foi capaz de raspar 8 caracteres;)
#
Você está dizendo se o texto tem cinco caracteres e pede seis substituições que ele quebra?
precisa saber é o seguinte
@ BillWoodger Ele disse que, usando o compilador de fechamento, raspou 8 caracteres do comprimento total do código.
Eduard Florinescu 03/04
@EduardFlorinescu, desculpe, eu não estava claro, eu quis dizer isso poucobreaks if you supply a name and ask for more pieces than characters
Bill Woodger
11
Use em x=b/e|0vez de x=Math.floor(b/e). Além disso, for(c=1;c<=e;c++)pode ser reduzido para for(c=1;c++<=e;).
Escova de dentes
1

R, (120-20) = 100 bytes (2 soluções diferentes do mesmo comprimento)

Além da concisão, o R com certeza apresenta o melhor gerador de números aleatórios! :) Aqui a primeira solução de comprimento 120:

function(s,n){
  c=strsplit(s,"")[[1]]
  e=sample(n,nchar(s),T)
  sapply(1:n,function(i)paste(ifelse(e==i,c,"*"),collapse=""))
}

Se a função for nomeada como f , a saída será semelhante a:

> f("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 7)
"******GH*****************Z" 
"ABCD*********N************" 
"***********L**O***********"
"*********J**M**P*RS*U**X**" 
"**********K***********W***" 
"*****F**I*******Q*********"
"****E**************T*V**Y*"

E aqui a segunda solução, novamente com mascaramento aleatório e novamente com 120 bytes de comprimento:

function(s,n){
  x=matrix("*",n,(m=nchar(s)))
  x[cbind(sample(n,m,T),1:m)]=strsplit(s,"")[[1]]
  apply(x,1,paste,collapse="")
}
lambruscoAcido
fonte
0

Scala (1) 177 bytes

Depois que a solução no RI também encontrou uma em Scala, aqui está:

def f(s:String, n:Int)={
  def c=s map (z=>z.toString)
  def r=(1 to s.length) map (v=>v%n+1)
  (for (i<-1 to n) yield s zip r map (t=>if(t._2==i) t._1 else "*") mkString "") map println
}

Scala (2) 129 bytes

Após uma breve pesquisa, encontrei o método zipWithIndex . Maravilhoso :)

def f(s:String, n:Int)={
  (for (i<-0 until n) yield s.zipWithIndex.map (t=>if(t._2 % n==i) t._1 else "*") mkString "") map println
}

Aqui a solução:

f("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 4)
***D***H***L***P***T***X**
A***E***I***M***Q***U***Y*
*B***F***J***N***R***V***Z
**C***G***K***O***S***W***
lambruscoAcido
fonte
0

Javascript - 166

function s(b,a){o="";k=Array(a).join("*");t=k+b+k;for(i=a;0<i;i--)o+=t.replace(RegExp(".{"+(a-1)+"}(.)","g"),k+"$1").substr(i-1,b.length)+"\n",t=t.substr(1);return o}

Usando regex.

Amostra

> s("four",5)                      
f***                            
*o**                             
**u*                             
***r                             
****                             

> s("evil_company_that_makes_me_shiver",3)
e**l**o**a**_**a**m**e**m**s**v**
*v**_**m**n**t**t**a**s**e**h**e*
**i**c**p**y**h**_**k**_**_**i**r
zoro
fonte
0

k [50-20 = 30 caracteres]

{.{@[y#"*";z;:;x z]}[x;c]'=_d*y%#d:<<(-d)?!d:c:#x}

Explicação

  1. Entrada: x = String que precisa ser mascarada, y = número de linhas
  2. Conte o número de caracteres c na string e crie y buckets.
  3. Coloque caracteres modificados em cada bloco.
  4. Para cada balde, imprima "*" para os números restantes que não estão nesse balde.

Exemplo

{.{@[y#"*";z;:;x z]}[x;c]'=_d*y%#d:<<(-d)?!d:c:#x}["abcdefghijklmnopqrstuvwxyz";4]

Resultado

"ab*d*f***j**********u*w***"
"**c*e*gh**k*****q*s*******"
"********i***mn*****t*v**y*"
"***********l**op*r*****x*z"
Nyi
fonte
0

JavaScript - 139-20 = 119

function e(s,c){r=[];for(i=c;i--;)r[i]='';for(i=0;i<s.length*c;i++)x=i%c,n=(x<1?Math.random()*c|0:n),r[x]+=(n!=x?'*':s[(i/c)|0]);return r}

Uso e saída da amostra:

console.log(e("evil_company_that_makes_me_shiver", 3));

["**i*_**mp*****h**_ma**********v**", 
 "*****co**a***t*a******s*me_*hi*e*", 
 "ev*l******ny_***t***ke*_***s****r"]

Como o mascaramento é aleatório, a saída também pode ser assim:

console.log(e("evil_company_that_makes_me_shiver", 2));

["evil_company_that_makes_me_shiver", 
 "*********************************"]
codeporn
fonte
0

Julia 56-20 = 36 (funciona frequentemente)

f(s,n)=[join([rand()<1.9/n?c:"*" for c in s]) for r=1:n]

julia> f("evilcompany!!!",4)
4-element Array{Union(UTF8String,ASCIIString),1}:
 "e**l**mp*ny*!*"
 "***lco********"
 "e*il**m*a*y!*!"
 "evil**m*an***!"

Tentando buscar uma solução aleatória mais curta, decidi sacrificar o funcionamento garantido por uma solução mais curta. Realmente não é uma solução muito boa.

gggg
fonte
0

F # - 81 80 75

Isso é bastante semelhante aos outros que foram oferecidos:

let a s n=[for i in 0..n-1->String.mapi(fun j c->[c;'*'].[min((j+i)%n)1])s]

Amostra:

a "evil_company_that_makes_me_shiver" 7

e******m******h******e******h**** 
******o******t******k******s***** 
*****c******_******a******_****** 
****_******y******m******e******r 
***l******n******_******m******e* 
**i******a******t******_******v** 
*v******p******a******s******i*** 

Como um aplicativo completo e independente, ele possui 160 155 156 caracteres:

[<EntryPoint>]let m (a:string array)=
 let n=System.Int32.Parse a.[1]
 for i in 0..n-1 do printfn"%s"(String.mapi(fun j c->[c;'*'].[min((j+i)%n)1])a.[0])
 0
pswg
fonte