Anonimizuj nazwy - w pewnym sensie

16

Edycja: Przy losowym maskowaniu będzie premia -20

Witam innych informatorów i nosicieli tajnej wiedzy.

Jestem z powodu wywiadu wysłanego pocztą i - oczywiście - nie mogę podać konkretnych nazwisk w pełnej długości. Ale ponieważ chcę to ujawnić w dość nieoczywisty sposób, potrzebuję twojej pomocy.

Podam te nazwy w formie

„evil_company_that_makes_me_shiver”

ale z pewnością nie chcę tego całkowicie przeliterować. Twoim zadaniem, aby pomóc mi i całemu światu, jest dostarczenie ładnego programu, który zamienia powyższe

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

lub

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

lub nawet

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

Myślę, że rozumiesz. Ale jest jedna wada: chcę ujawnić nazwę w całości, więc muszę przekazać liczbę wystąpień i samo słowo do skryptu, a on ujawni litery po kawałku. Przykładem może być

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

lub

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

lub

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

Mam nadzieję, że możesz mi pomóc, a ponieważ wiemy, że rozmiar ma znaczenie, wygrywa najkrótszy kod. Pomóż uczynić ten świat lepszym miejscem!

german_guy
źródło
1
Nie podajesz żadnych szczegółów na temat tego, jak powinno wyglądać maskowanie, więc powinieneś otrzymać jak najkrótszy kod, bez względu na twoje przykłady.
Bill Woodger,
Myślałem, że było jasne, że wygrywa najkrótszy kod? Hmmm, może muszę poprawić gramatykę angielską zgodnie z tym :( / Edycja: Naprawdę nie dbam o to, jak maskowanie zostało zrobione, powyższe to tylko przykład, ale powinno być „nieczytelne”, jeśli przeczytasz jedno uzupełnienie sam ”
german_guy,
Tak, najkrótszy kod był jasny. Ale najczęściej otrzymujesz „zwykłe” maskowanie, nie tak jak twoje próbki. Być może, skoro i tak nie masz nic przeciwko, zmień przykładowe wyniki na zwykłe. W szczególności twój drugi przykład działania, plus przykład w twoim pytaniu
Bill Woodger
1
Możesz też otrzymać bonus za losowe maskowanie.
3ıʇǝɥʇuʎs

Odpowiedzi:

12

GolfScript, 26 znaków

Ponieważ nie określono konkretnego sposobu ujawnienia, postanowiłem wybrać najkrótszy:

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

Możesz eksperymentować z tym kodem online .

Przykład:

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

Skomentowany kod:

: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
źródło
Ładny! Czy możesz wyjaśnić, co robi każda część kodu?
John Odom
9
Nie rozumiem dlaczego. GolfScript jest tak samo dokumentujący.
Evpok
@JohnOdom Niemniej jednak dodałem kilka komentarzy do kodu.
Howard
jeśli losowo zdecydujesz, czy przesunąć wszystkie * o jeden w prawo, czy to się liczy dla premii za maskowanie losowe?
Cruncher
7

PHP - 80 bajtów

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

Przykładowe użycie:

$ 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
źródło
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)

Tandetny python ( 55 35):

Nie powiedziałeś mi o wymaganej dystrybucji;)

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

Jednolity python ( 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)

Wynik:

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

daje

***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
źródło
Twój tandetny python można skrócić g=lambda a,b:[a]+["*"*len(a)]*(b-1). : P
cjfaure
@Trimsty Rozumiem, dziękuję :)
3ıʇǝɥʇuʎs
3
Myślę, ale z pewnością nie chcę tego przeliterować, całkowicie jednoznacznie unieważnia rozwiązanie, które nie zapewnia maskowania co najmniej jednego znaku w każdym wierszu wyniku.
Howard
@Howard Wiem, że to rozciąga zasady, ale disclose the letters bit by bitmoże również oznaczać first, disclose the first bit (that just happens to be the entire thing), repeat until the b is met. Może się to zdarzyć również w przypadku pierwszej odpowiedzi, więc po prostu twierdz, że użyłeś tej, a już przyniosło to wynik. (Właśnie zdałem sobie sprawę, że możesz to również napisać jako ["*"*len(a)]*(b-1)+[a], aby zacząć od ujawnienia bitów, które akurat zawierają 0 bajtów rzeczywistych informacji, aw ostatniej linii ujawniasz kolejny bit.) Zdaję sobie jednak sprawę, że to rozciąga się do maksimum.
3ıʇǝɥʇuʎs
3

Bash, 80 bajtów

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

W akcji:

$ ./anon.sh stackoverflow.com 6
st ***************
** ack ************
***** ove *********
******** rfl ******
*********** ow. ***
************** com
$ 
Cyfrowa trauma
źródło
2

C #, 226

Można to zredukować, jeśli zastąpisz losowe rzeczy prostszym rozkładem (pomyśl moduł), ale losowość mnie zainteresowała. =)

W każdym razie, umieszczając wszystko w jednym wierszu, otrzymuję 226 znaków. W czytelnym kodzie wygląda to tak:

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

Przykładowe dane wyjściowe:

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
źródło
Czy zawsze gwarantuje przynajmniej charakter od wejścia?
Bill Woodger,
Hmm .. nie, prawdopodobnie nie; dobry chwyt. W przypadku krótkich ciągów znaków i niskich wartości iprawdopodobnie może się to skończyć ***/test.
deroby
2

Perl, 24

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

Wymaga -pprzełącznika, który odpowiada za dwa bajty. Czyta ze STDIN.

Jak to działa

  • Z powodu -pprzełącznika Perl odczytuje pierwsze kłamstwo wejściowe i zapisuje jego zawartość $_.

  • Polecenie $_ x=<>;powiela pierwszy wiersz wejściowy tyle razy, ile określa drugi wiersz wejściowy ( <>).

  • Polecenie s/(.|\n)./\1*/g;zużywa dwa znaki i zastępuje drugi (który nie może być znakiem nowej linii) gwiazdką. Robi to, dopóki nie zużyje całej zawartości $_.

    Ponieważ znaki nowej linii liczą się jako pierwszy znak, spowoduje to zaciemnienie wszystkich znaków parzystych w pierwszym wierszu i wszystkich znaków nieparzystych w pozostałych wierszach.

  • Z powodu -pprzełącznika Perl drukuje zawartość $_.

Przykładowe dane wejściowe

codegolf
4

Przykładowe dane wyjściowe

c*d*g*l*
*o*e*o*f
*o*e*o*f
*o*e*o*f
Dennis
źródło
zduplikowane ciągi, niezbyt czyste ...
CSᵠ
Co sprawiło, że pomyślałeś, że możesz zadzierać z danymi wejściowymi, aby mieć je w dwóch wierszach?
Bill Woodger
@BillWoodger: Pytanie nie określa formy wprowadzania danych.
Dennis
Słusznie. couldprzepuszcza :-)
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.Wygląda na to, że zawiedziecodegolf\n1
Cruncher
1

Java - 490

Tak, naprawdę nie grał w golfa ani nic takiego. No cóż, oto jest:

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

W ładnym, czytelnym formacie:

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

Przykładowe użycie (po uruchomieniu z skompilowanej klasy)

> java Anonymise OnlinePerson 3
*n****P***o*
O*li***e****
****ne**rs*n
Izaak
źródło
Prowadzisz to lub piszesz? Jak P może być p?
Bill Woodger,
Nie ma problemu. Po prostu posprzątaj używane komentarze teraz
Bill Woodger
Po prostu import java.util.*też ArrayList<String> = new ArrayList<>();będzie działać. Możesz także usunąć wiele spacji. I przez większość czasu możesz użyć Listzamiast ArrayList.
Ypnypn,
1

Python 3-187 (-20 = 167)

Zajęło mi to trochę czasu, by napisać, prawdopodobnie można by grać w golfa więcej.

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)

Przykładowe użycie:

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

W funkcji - 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
źródło
Czy zawsze gwarantuje przynajmniej charakter od wejścia?
Bill Woodger,
@BillWoodger No.
cjfaure
2
Przepraszam, osobiście uważam, że wtedy nie działa. następnie.
Bill Woodger,
Kilka prostych sposobów na skrócenie rzeczy: Rozpakuj sys.argvw przydziale i zainicjuj xjako x=['']*int(b[2])(z b[2]zastąpioną dowolną nazwą zmiennej używanej podczas rozpakowywania).
user2357112 obsługuje Monikę
2
Myślę, ale z pewnością nie chcę tego przeliterować, całkowicie jednoznacznie unieważnia rozwiązanie, które nie zapewnia maskowania co najmniej jednego znaku w każdym wierszu wyniku.
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()));}}}

Nie golfa

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

Próba:

> Anonymize.exe "qwertyuio" 4
q***t***o
***r***i*
**e***u**
*w***y***
Rik
źródło
1

Perl 6 (77 bajtów)

Może to być traktowane jako oszustwo, ale rozwiązuje problem (nie drukuje całego łańcucha).

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

I próbka wyjściowa.

> ./script.p6 ultimately_awesome 6
ultimately_awesom*
*****************e
******************
******************
******************
******************
Konrad Borowski
źródło
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}

Szybka, łamie się, jeśli podasz imię i poprosisz o więcej elementów niż postaci, ale działa do tego momentu i do 1. Mogę grać w golfa więcej, jak sądzę, więc może zmienić lub zasięgnąć porady, ponieważ jest to trochę bałagan.

Edycja: Dalsza gra w golfa (od 187) z usunięciem wsporników (@Synthetica) i wymianą Math.floor z @toothbrush. Sugerowana zmiana pętli powoduje błędy w danych wyjściowych.

Matt
źródło
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}; closure-compiler.appspot.com/home był w stanie zgolić 8 znaków;)
3ıʇǝɥʇuʎs
Czy mówisz, że jeśli tekst ma pięć znaków i jest proszony o sześć zamienników, łamie się?
Bill Woodger
@BillWoodger Mówi, że za pomocą kompilatora zamykającego zgolił 8 znaków z całkowitej długości kodu.
Eduard Florinescu,
@EduardFlorinescu, przepraszam, byłem niejasny, miałem na myśli tobreaks if you supply a name and ask for more pieces than characters
Bill Woodger
1
Użyj x=b/e|0zamiast x=Math.floor(b/e). Ponadto, for(c=1;c<=e;c++)może być skrócony do for(c=1;c++<=e;).
Szczoteczka do zębów
1

R, (120-20) = 100 bajtów (2 różne rozwiązania o tej samej długości)

Oprócz zwięzłości, R na pewno oferuje najlepszy generator liczb losowych! :) Oto pierwsze rozwiązanie o długości 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=""))
}

Jeśli funkcja ma nazwę f , dane wyjściowe wyglądają następująco:

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

I tutaj drugie rozwiązanie, znowu z losowym maskowaniem i znowu 120 bajtów długości:

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
źródło
0

Scala (1) 177 bajtów

Po znalezieniu rozwiązania w RI również w Scali, oto ono:

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 bajtów

Po krótkim badaniu znalazłem metodę zipWithIndex . Wspaniale :)

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
}

Oto rozwiązanie:

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
źródło
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}

Używanie wyrażenia regularnego.

Próba

> 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
źródło
0

k [50-20 = 30 znaków]

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

Wyjaśnienie

  1. Dane wejściowe: x = ciąg znaków, który należy zamaskować, y = liczba wierszy
  2. Policz liczbę znaków cw ciągu i utwórz y wiadra.
  3. Umieść c mod y znaków w każdym wiadrze.
  4. Dla każdego segmentu wydrukuj „*” dla pozostałych liczb nie w tym segmencie.

Przykład

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

Wynik

"ab*d*f***j**********u*w***"
"**c*e*gh**k*****q*s*******"
"********i***mn*****t*v**y*"
"***********l**op*r*****x*z"
nyi
źródło
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}

Wykorzystanie i przykładowe wyjście:

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"]

Ponieważ maskowanie jest losowe, dane wyjściowe mogą również wyglądać następująco:

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

["evil_company_that_makes_me_shiver", 
 "*********************************"]
codeporn
źródło
0

Julia 56-20 = 36 (działa często)

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

Próbując wybrać krótsze rozwiązanie losowe, postanowiłem poświęcić gwarantowane funkcjonowanie dla krótszego rozwiązania. To naprawdę niezbyt dobre rozwiązanie.

gggg
źródło
0

F # - 81 80 75

Jest to dość podobne do innych, które zostały zaoferowane:

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

Próba:

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

Jako pełna, samodzielna aplikacja ma 160 155 156 znaków:

[<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
źródło