Anonimizar nombres - una especie de


16

Editar: Habrá una bonificación de -20 por enmascaramiento aleatorio

Hola compañeros denunciantes y portadores de conocimiento secreto.

Tengo una entrevista por correo y, por supuesto, no puedo decir nombres específicos en toda su extensión. Pero como quiero revelarlo de una manera no tan obvia, necesito su ayuda.

Proporcionaré estos nombres en forma de

"evil_company_that_makes_me_shiver"

pero seguramente no quiero explicarlo completamente. Tu tarea para ayudarme a mí y al mundo entero es que proporciones un buen programa que convierta lo anterior en

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

o

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

o incluso

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

Creo que lo tienes. Pero hay una falla: quiero revelar el nombre en total, por lo que necesito pasar el número de apariciones y la palabra en sí al script y revelará las letras poco a poco. Un ejemplo podría ser

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

o

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

o

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

Espero que me puedan ayudar y como sabemos que el tamaño importa, el código más corto gana. ¡Ayuda a hacer de este mundo un lugar mejor!


1
No proporciona detalles sobre cómo debe ocurrir el enmascaramiento, por lo que debe obtener el código más corto, sin importar sus ejemplos.
Bill Woodger

¿Pensé que estaba claro que gana el código más corto? Hmmm, tal vez necesito mejorar mi gramática inglesa de acuerdo con esto :( / Edit: Realmente no me importa cómo se hace el enmascaramiento, lo anterior es solo un ejemplo, pero debería ser "ilegible" si lees una frase solo "
german_guy 03 de

Sí, el código más corto fue claro. Pero en su mayoría obtendrá enmascaramiento "regular", no como sus muestras. Quizás, dado que no le importa, cambie sus salidas de muestra a las normales. Específicamente su segundo ejemplo de ejecución, más el ejemplo en su pregunta
Bill Woodger

1
O podría obtener una bonificación por enmascaramiento aleatorio.
Aprıʇǝɥʇuʎs

Respuestas:


12

GolfScript, 26 caracteres

Como no se especificó ninguna forma específica de divulgación, decidí ir por el más corto:

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

Puede experimentar con este código en línea .

Ejemplo:

> "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
}+%      

¡Agradable! ¿Podría explicar qué hace cada parte del código?
John Odom

99
No puedo ver por qué. GolfScript es tan autodocumentado.
Evpok

@JohnOdom Sin embargo, agregué algunos comentarios al código.
Howard

si decide al azar si va a cambiar todos los * por uno a la derecha, ¿eso cuenta para el bono de enmascaramiento aleatorio?
Cruncher

7

PHP - 80 bytes

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

Uso de la muestra:

$ 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******

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ón con queso ( 55 35):

No me dijiste la distribución requerida;)

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

Pitón 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)

Salida:

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

da

***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*

Su pitón cursi se puede acortar a g=lambda a,b:[a]+["*"*len(a)]*(b-1). : P
cjfaure

@Trimsty Ya veo, gracias :)
ɐɔıʇǝɥʇuʎs

3
Creo, pero seguramente no quiero explicarlo completamente , invalida claramente una solución que no garantiza que al menos un personaje esté enmascarado en cada línea de salida.
Howard

@Howard Sé que está estirando las reglas, pero disclose the letters bit by bittambién puede significar first, disclose the first bit (that just happens to be the entire thing), repeat until the b is met. Esto también puede suceder para la primera respuesta, así que simplemente afirme que usó esa, y simplemente sucedió para producir este resultado. (Me acabo de dar cuenta de que también puedes escribirlo como ["*"*len(a)]*(b-1)+[a], para que comiences revelando bits que solo contienen 0 bytes de información real, y en la última línea, revelas otro bit). Sin embargo, me doy cuenta de que esto se estira al máximo
Aprıʇǝɥʇ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}"
}

En acción:

$ ./anon.sh stackoverflow.com 6
S t***************
** ack ************
***** ove *********
******** rfl ******
***********Ay.***
************** com
PS 

2

C #, 226

Esto se puede recortar si reemplaza las cosas aleatorias con una distribución más simple (módulo de pensamiento) pero la aleatoriedad es lo que me interesó. =)

De todos modos, poniendo todo en una sola línea, obtengo 226 caracteres. En código legible se ve así:

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]);
    }
}

Salida de muestra:

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*

¿Garantiza al menos el carácter de la entrada siempre?
Bill Woodger

Hmm .. no, probablemente no; buena atrapada. Para cadenas cortas y valores bajos de iusted probablemente podría terminar con ***/test.
deroby

2

Perl, 24

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

Requiere el -pconmutador, que representa dos de los bytes. Lecturas de STDIN.

Cómo funciona

  • Debido al -pcambio, Perl lee la primera mentira de entrada y almacena su contenido $_.

  • El comando $_ x=<>;duplica la primera línea de entrada la cantidad de veces que <>especifica la segunda línea de entrada ( ).

  • El comando s/(.|\n)./\1*/g;consume dos caracteres y reemplaza el segundo (que no puede ser una nueva línea) con un asterisco. Hace esto hasta que haya consumido todo el contenido de $_.

    Como las nuevas líneas cuentan como el primer carácter, esto ofuscará todos los caracteres pares en la primera línea y todos los caracteres impares en las líneas restantes.

  • Debido al -pcambio, Perl imprime el contenido de $_.

Entrada de ejemplo

codegolf
4

Salida de ejemplo

c*d*g*l*
*o*e*o*f
*o*e*o*f
*o*e*o*f

cadenas duplicadas, no muy limpias ...
CSᵠ

¿Qué te hizo pensar que podrías perder el tiempo con la entrada para tenerla en dos líneas?
Bill Woodger

@BillWoodger: la pregunta no especifica ninguna forma de entrada.
Dennis

Lo suficientemente justo. couldte deja pasar :-)
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.Parece que va a fallarcodegolf\n1
Cruncher

1

Java - 490

Sí, realmente no jugaba golf ni nada. Oh bueno, aquí 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);}}

En un formato agradable y legible:

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 muestra (cuando se ejecuta desde la clase compilada)

> java Anonymise OnlinePerson 3
*n****P***o*
O*li***e****
****ne**rs*n

¿Estás ejecutando eso o escribiendo? ¿Cómo llega a ser P?
Bill Woodger

No hay problema. Solo ordena los comentarios usados ​​ahora
Bill Woodger

Simplemente import java.util.*también, ArrayList<String> = new ArrayList<>();funcionará. También puedes eliminar muchos espacios. Y la mayoría de las veces, puede usar en Listlugar de ArrayList.
Ypnypn

1

Python 3 - 187 (-20 = 167)

Me tomó un tiempo escribir, probablemente podría jugar más golf.

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 de la muestra:

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

Como una función - 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

¿Garantiza al menos el carácter de la entrada siempre?
Bill Woodger

@BillWoodger No.
cjfaure

2
Lo siento, personalmente considero que no funciona entonces. luego.
Bill Woodger

Algunas formas simples de acortar las cosas: desempaquetar sys.argven la asignación e inicializar xcomo x=['']*int(b[2])(con b[2]reemplazado por lo que nombre la variable que utiliza en el desempaquetado).
user2357112 es compatible con Monica el

2
Creo, pero seguramente no quiero explicarlo completamente , invalida claramente una solución que no garantiza que al menos un personaje esté enmascarado en cada línea de salida.
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()));}}}

No golf

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()));
        }
    }
}

Muestra:

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

1

Perl 6 (77 bytes)

Esto puede contar como trampa, pero resuelve el problema (no imprime la cadena por completo).

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

Y la salida de muestra.

> ./script.p6 ultimately_awesome 6
ultimately_awesom*
*****************e
******************
******************
******************
******************

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}

Uno rápido, se rompe si proporciona un nombre y pide más piezas que caracteres, pero funciona hasta ese punto y baja a 1. Supongo que podría jugar más golf, así que puede revisar o tomar consejos, ya que es un poco desordenado.

Editar: Golf más lejos (desde 187) con la eliminación de los soportes (@Synthetica) y el reemplazo de Math.floor de @toothbrush. Para el cambio de bucle como se sugiere, se producen errores en la salida.


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}; clos-compiler.appspot.com/home fue capaz de eliminar 8 caracteres;)
3ıʇǝɥʇuʎs

¿Estás diciendo que si el texto es de cinco caracteres y se le pide seis reemplazos se rompe?
Bill Woodger

@BillWoodger Él dijo que al usar el compilador de cierre depiló 8 caracteres de la longitud total del código.
Eduard Florinescu

@EduardFlorinescu, lo siento, no estaba claro, quise decir esto breaks if you supply a name and ask for more pieces than characters
Bill Woodger

1
Usar en x=b/e|0lugar de x=Math.floor(b/e). Además, for(c=1;c<=e;c++)se puede acortar a for(c=1;c++<=e;).
Cepillo de dientes

1

R, (120-20) = 100 bytes (2 soluciones diferentes de la misma longitud)

¡Además de la concisión, R con seguridad presenta el mejor generador de números aleatorios! :) Aquí la primera solución de longitud 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=""))
}

Si la función se nombra como f , la salida se ve así:

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

Y aquí la segunda solución, nuevamente con enmascaramiento aleatorio, y nuevamente 120 bytes de longitud:

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="")
}

0

Scala (1) 177 bytes

Después de que la solución en RI también encontró una en Scala, aquí 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

Después de una breve investigación encontré el método zipWithIndex . Maravilloso :)

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
}

Aquí la solución:

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***

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.

Muestra

> 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

0

k [50-20 = 30 caracteres]

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

Explicación

  1. Entrada: x = cadena que necesita ser enmascarada, y = número de líneas
  2. Cuente el número de caracteres c en cadena y cree cubos y.
  3. Coloque caracteres c mod y en cada cubo.
  4. Para cada depósito, imprima "*" para los números restantes que no están en ese depósito.

Ejemplo

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

Salida

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

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 y salida de muestra:

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 el enmascaramiento es aleatorio, la salida también puede verse así:

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

["evil_company_that_makes_me_shiver", 
 "*********************************"]

0

Julia 56-20 = 36 (trabaja a menudo)

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***!"

Intentando buscar una solución aleatoria más corta, decidí sacrificar el funcionamiento garantizado por una solución más corta. Realmente no es una muy buena solución.


0

F # - 81 80 75

Esto es bastante similar a otros que se han ofrecido:

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

Muestra:

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 una aplicación completa e independiente, tiene 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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.