İsimleri anonimleştirme - bir çeşit


16

Düzenleme: Rasgele maskeleme için -20 bonus olacak

Merhaba dostum Whistleblowers ve gizli bilgi taşıyıcıları.

Posta ile yapılan bir röportajdan kaynaklandım ve - tabii ki - tam uzunlukta belirli isimler söyleyemem. Ama bunu oldukça açık olmayan bir şekilde açıklamak istediğim için yardımına ihtiyacım var.

Bu isimleri şu şekilde vereceğim

"Evil_company_that_makes_me_shiver"

ama kesinlikle bunu hecelemek istemiyorum. Bana ve tüm dünyaya yardım etme göreviniz, yukarıdakilere dönüşen güzel bir program sağlamanızdır.

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

veya

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

ya da

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

Sanırım anladın. Ama bir kusur var: Toplamda adı açıklamak istiyorum, bu yüzden olayların sayısını ve kelimenin kendisini betiğe geçirmem gerekiyor ve harfleri yavaş yavaş açıklayacağım. Bir örnek olabilir

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

veya

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

veya

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

Umarım bana yardımcı olabilirsiniz ve bildiğimiz gibi boyutun en kısa kod kazanması önemlidir. Bu dünyayı daha iyi bir yer haline getirmeye yardımcı olun!


1
Maskelemenin nasıl olması gerektiği hakkında hiçbir ayrıntı vermezsiniz, bu nedenle örnekleriniz ne olursa olsun en kısa kodu almalısınız.
Bill Woodger

En kısa kodun kazanıldığını açıkça düşündüm. Hmmm, belki de İngilizce gramerimi buna göre geliştirmeliyim :( / Edit: Maskelemenin nasıl yapıldığını gerçekten umursamıyorum, yukarıdaki sadece bir örnektir, ancak bir akordeon okursanız "okunamaz" olmalıdır yalnız "
german_guy

Evet, en kısa kod açıktı. Ama çoğunlukla "normal" maskeleme alacaksınız, örnekleriniz gibi değil. Belki de umursamadığınız için örnek çıktılarınızı düzenli olarak değiştirin. Özellikle ikinci örneğiniz, artı sorunuzdaki örnek
Bill Woodger

1
Veya rastgele maskeleme için bir bonus olabilir.
ɐɔıʇǝɥʇuʎs

Yanıtlar:


12

GolfScript, 26 karakter

Belirli bir açıklama yolu belirtilmediğinden en kısa yol için gitmeye karar verdim:

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

Bu kodu çevrimiçi olarak deneyebilirsiniz .

Misal:

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

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

Güzel! Kodun her bölümünün ne yaptığını açıklayabilir misiniz?
John Odom

9
Nedenini göremiyorum. GolfScript çok kendi kendini belgeliyor.
Evpok

@JohnOdom Yine de koda bazı yorumlar ekledim.
Howard

tüm * 'leri birer sağa kaydırıp kaydırmayacağınıza rastgele karar verirseniz, bu rastgele maskeleme bonusu için geçerli midir?
Cruncher

7

PHP - 80 bayt

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

Örnek kullanım:

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

Peynirli piton ( 55 35):

Bana gerekli dağıtımı söylemedin;)

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

Üniforma piton ( 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)

Çıktı:

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

verir

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

Sevimsiz pitonunuz kısaltılabilir g=lambda a,b:[a]+["*"*len(a)]*(b-1). : P
cjfaure

@Trimsty Anlıyorum, teşekkürler :)
ɐɔıʇǝɥʇuʎs

3
Bence ama kesinlikle açık bir şekilde hecelemek istemiyorum , her çıktı satırında en az bir karakterin maskelenmesini sağlamayan bir çözümü geçersiz kılıyor.
Howard

@ Kuralların gerildiğini biliyorum, ama disclose the letters bit by bitaynı zamanda anlamına da gelebilir first, disclose the first bit (that just happens to be the entire thing), repeat until the b is met. Bu, ilk cevap için de olabilir, bu yüzden bunu kullandığınızı iddia edin ve bu sonucu üretmesi yeterlidir. (Sadece ["*"*len(a)]*(b-1)+[a]0 bayt gerçek bilgi içeren bitleri açıklayarak başlayabileceğinizi fark ettim ve son satırda başka bir bit ifşa edersiniz.) Bununla birlikte, bunun Maks.
Aprıʇǝɥʇuʎs

3

Bash, 80 bayt

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

Eylemde:

$ ./anon.sh stackoverflow.com 6
st ***************
** ack ************
***** ove *********
******** RFL ******
*********** ow. ***
************** com
$ 

2

C #, 226

Rastgele şeyleri daha basit bir dağılımla (düşünme modülü) değiştirirseniz, ancak rastgele ilgimi çeken şey budur. =)

Her neyse, her şeyi tek bir satıra koyarak 226 karakter kazanıyorum. Okunabilir kodda şöyle görünür:

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

Örnek çıktı:

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*

Her zaman girişten gelen en azından karakteri garanti ediyor mu?
Bill Woodger

Hmm .. hayır, muhtemelen hayır; İyi yakalama. Kısa dizeler ve düşük değerler için imuhtemelen sonuçlanabilir ***/test.
deroby

2

Perl, 24

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

-pİki bayttan oluşan anahtarı gerektirir . STDIN'den okur.

Nasıl çalışır

  • -pAnahtar nedeniyle , Perl ilk giriş yalanını okur ve içeriğini saklar $_.

  • Komut $_ x=<>;, ilk giriş satırını ikinci giriş satırının ( <>) belirtme sayısını çoğaltır .

  • Komut s/(.|\n)./\1*/g;iki karakter tüketir ve ikinciyi (yeni satır olamaz) bir yıldız işareti ile değiştirir. Tüm içeriğini tüketene kadar bunu yapar $_.

    Yeni satırlar ilk karakter olarak sayıldığından, bu ilk satırdaki tüm çift karakterleri ve kalan satırlardaki tüm tek karakterleri gizleyecektir.

  • -pAnahtar nedeniyle , Perl içeriğini yazdırır $_.

Örnek giriş

codegolf
4

Örnek çıktı

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

dizeleri, çok temiz değil yinelenen ...
CSᵠ

Sizi iki satırda tutmak için girdi ile uğraşabileceğinizi düşündüren nedir?
Bill Woodger

@BillWoodger: Soru hiçbir girdi biçimini belirtmiyor.
Dennis

Yeterince adil. could:-)
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.Kulağa başarısız olacak gibi geliyorcodegolf\n1
Cruncher

1

Java - 490

Evet, golf oynamamış falan değil. Ah, işte burada:

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

Güzel, okunaklı bir biçimde:

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

Örnek kullanım (Derlenmiş sınıftan çalıştırıldığında)

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

Bunu çalıştırıyor musunuz yoksa yazıyor musunuz? P nasıl p olur?
Bill Woodger

Sorun değil. Şimdi kullanılan yorumları derli toplu
Bill Woodger

Just import java.util.*Also, ArrayList<String> = new ArrayList<>();işe yarayacak. Ayrıca çok fazla alan kaldırabilirsiniz. Ve çoğu zaman, Listyerine kullanabilirsiniz ArrayList.
Ypnypn

1

Python 3-188 (-20 = 167)

Bana yazmak için biraz zaman aldı, muhtemelen daha fazla golf olabilir.

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)

Örnek kullanım:

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

Fonksiyon olarak - 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

Her zaman girişten gelen en azından karakteri garanti ediyor mu?
Bill Woodger

@BillWoodger No
cjfaure

2
Üzgünüm, şahsen ben o zaman çalışmıyor olarak görüyorum. sonra.
Bill Woodger

Paketini açın: Bazı basit yolları şeyleri kısaltmak sys.argvödevi ve initialize xolarak x=['']*int(b[2])(ile b[2]size açma kullandığımız değişkeni isim olanlarla değiştirilir).
user2357112 Monica

2
Bence ama kesinlikle açık bir şekilde hecelemek istemiyorum , her çıktı satırında en az bir karakterin maskelenmesini sağlamayan bir çözümü geçersiz kılıyor.
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()));}}}

Sigara golfed

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

Örneklem:

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

1

Perl 6 (77 bayt)

Bu hile olarak sayılabilir, ancak sorunu çözer (dizeyi tamamen yazdırmaz).

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

Ve örnek çıktı.

> ./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}

Hızlı bir, bir isim sağlarsanız ve karakterlerden daha fazla parça sorarsanız kırılır, ancak o noktaya kadar ve 1'e kadar çalışır.

Düzenleme: Köşeli parantezler (@Synthetica) ve @ diş fırçası yerine Math.floor değiştirilmesi ile (187'den itibaren) Golf. Döngü değişikliği için önerilen çıktıda hatalara neden olur.


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 8 karakter kapalı tıraş yeteneğine sahip olduğunu;)
ɐɔıʇǝɥʇuʎs

Metnin beş karakter olup olmadığını ve kırıldığı altı değişiklik olup olmadığını mı söylüyorsunuz?
Bill Woodger

@BillWoodger Kapatma derleyicisini kullanarak kodun toplam uzunluğundan 8 karakter tıraş ettiğini söylüyor.
Eduard Florinescu

@EduardFlorinescu, üzgünüm, belirsizdim, bu bit demek breaks if you supply a name and ask for more pieces than characters
istedim

1
Yerine x=b/e|0kullanın x=Math.floor(b/e). Ayrıca, for(c=1;c<=e;c++)kısaltılabilir for(c=1;c++<=e;).
diş fırçası

1

R, (120-20) = 100 bayt (aynı uzunlukta 2 farklı çözüm)

Kısaca, R kesinlikle en iyi rastgele sayı üreteci özellikleri! :) Burada uzunluk 120'nin ilk çözümü:

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

İşlev f olarak adlandırılırsa , çıktı şöyle görünür:

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

Ve yine rasgele maskeleme ile ve yine 120 bayt uzunluğunda 2. çözüm:

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 bayt

RI'daki çözüm de Scala'da bir tane bulduktan sonra, burada:

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 bayt

Kısa bir araştırmadan sonra zipWithIndex yöntemini buldum . Olağanüstü :)

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
}

İşte çözüm:

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}

Normal ifade kullanma.

Örneklem

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

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

açıklama

  1. Girdi: x = Maskelenmesi gereken dize, y = satır sayısı
  2. Dizedeki c karakter sayısını sayın ve y bölümleri oluşturun.
  3. Her gruba c mod y karakterleri yerleştirin.
  4. Her grup için, o grupta olmayan kalan numaralar için "*" yazdırın.

Misal

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

Çıktı

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

Kullanım ve örnek çıkışı:

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

Maskeleme rastgele olduğundan, çıktı da şöyle görünebilir:

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

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

0

Julia 56-20 = 36 (sıklıkla çalışır)

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

Daha kısa rastgele bir çözüm bulmaya çalışarak daha kısa bir çözüm için garantili çalışmayı feda etmeye karar verdim. Gerçekten çok iyi bir çözüm değil.


0

F # - 81 80 75

Bu, teklif edilenlere oldukça benzer:

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

Örneklem:

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

Tam, bağımsız bir uygulama olarak, çıkar 160 155 156 karakterden:

[<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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.