XOR trie un tableau

15

Étant donné une clé et un tableau de chaînes, mélangez le tableau afin qu'il soit trié lorsque chaque élément est XOR avec la clé.

XOR'ing deux cordes

Pour XOR une chaîne par une clé, XOR chacune des valeurs de caractère de la chaîne par sa paire dans la clé, en supposant que la clé se répète pour toujours. Par exemple, abcde^123ressemble à:

       a        b        c        d        e
       1        2        3        1        2
--------------------------------------------
01100001 01100010 01100011 01100100 01100101
00110001 00110010 00110011 00110001 00110010
--------------------------------------------
01010000 01010000 01010000 01010101 01010111
--------------------------------------------
       P        P        P        U        W

Tri

Le tri doit toujours être fait lexicographiquement des chaînes XOR. C'est,1 < A < a < ~ (en supposant un codage ASCII)

Exemple

"912", ["abcde", "hello", "test", "honk"]

-- XOR'd
["XSQ]T", "QT^U^", "MTAM", "Q^\R"]
-- Sorted
["MTAM", "QT^U^", "Q^\R", "XSQ]T"]
-- Converted back
["test", "hello", "honk", "abcde"]

Remarques

  • La clé aura toujours au moins 1 caractère
  • La clé et l'entrée ne seront constituées que d'ASCII imprimables.
  • Les chaînes XOR peuvent contenir des caractères non imprimables.
  • L'entrée et la sortie peuvent être effectuées à l'aide des méthodes raisonnables
  • Failles standard sont interdites.
  • Vous pouvez prendre la clé et l'entrée dans n'importe quel ordre.

Cas de test

key, input -> output
--------------------
"912", ["abcde", "hello", "test", "honk"] -> ["test", "hello", "honk", "abcde"]
"taco", ["this", "is", "a", "taco", "test"] -> ["taco", "test", "this", "a", "is"]
"thisisalongkey", ["who", "what", "when"] -> ["who", "what", "when"]
"3", ["who", "what", "when"] -> ["what", "when", "who"]

Il s'agit de , donc le moins d'octets gagne!

ATaco
la source
Lié loin d'un dupe cependant
MD XF
Les chaînes sont-elles garanties différentes?
Neil
@Neil Bien que je ne puisse pas imaginer une situation où leur identique causerait des problèmes, vous pouvez supposer que toutes les chaînes seront uniques.
ATaco
@ATaco Cela peut certainement être important si vous n'utilisez pas la comparaison de chaînes intégrée.
Dennis

Réponses:

7

Gelée , 9 7 octets

⁹ṁO^OµÞ

Merci à @EriktheOutgolfer pour une suggestion qui a permis d'économiser 2 octets!

Essayez-le en ligne!

Comment ça fonctionne

⁹ṁO^OµÞ  Dyadic link.
         Left argument: A (string array). Right argument: k (key string).

     µ   Combine the code to the left into a chain.
         Begin a new, monadic chain with argument A.
      Þ  Sort A, using the chain to the left as key.
         Since this chain is monadic, the key chain will be called monadically,
         once for each string s in A.
⁹            Set the return value to the right argument of the link (k).
 ṁ           Mold k like s, i.e., repeat its characters as many times as necessary
             to match the length of s.
  O          Ordinal; cast characters in the resulting string to their code points.
    O        Do the same for the chain's argument (s).
   ^         Perform bitwise XOR.
Dennis
la source
10

Python 3 , 75 73 octets

lambda k,x:x.sort(key=lambda s:[ord(x)^ord(y)for x,y in zip(s,k*len(s))])

Cela trie la liste x sur place.

Merci à @mercator pour avoir joué au golf sur 2 octets!

Essayez-le en ligne!

Version alternative, 62 octets

Cela prend l'entrée sous forme de chaînes d'octets, ce qui peut ne pas être autorisé.

lambda k,x:x.sort(key=lambda s:[*map(int.__xor__,s,k*len(s))])

Essayez-le en ligne!

Dennis
la source
Tri en place permet d' économiser 2 octets: x.sort(key=...).
mercator
3

Haskell, 77 octets

import Data.Bits
import Data.List
t=fromEnum
sortOn.zipWith((.t).xor.t).cycle

Trop d'importations.

Essayez-le en ligne!

nimi
la source
2

Rubis , 61 octets

->k,w{w.sort_by{|x|x.bytes.zip(k.bytes.cycle).map{|x,y|x^y}}}

Essayez-le en ligne!

Unihedron
la source
2

Clean , 101 100 94 octets

-6 octets grâce à Ourous!

import StdEnv
? =toInt
s k=let%s=[b bitxor?a\\a<-s&b<-[?c\\_<-s,c<-k]];@a b= %b> %a in sortBy@

Essayez-le en ligne! Exemple d' utilisation: s ['3'] [['who'], ['what'], ['when']].

Non golfé:

import StdEnv
sort key list = 
   let
      f string = [(toInt a) bitxor (toInt b) \\ a<-string & b<-flatten(repeat key)]
      comp a b = f a <= f b
   in sortBy comp list
Laikoni
la source
? =toIntet l'utilisation à la ?place économise 2 octets, et l'utilisation d'un inversé supérieur à au lieu de inférieur ou égal en enregistre un autre.
Decurous
Encore mieux, enregistre 6 octets: TIO
2017
1

En fait , 24 octets

O╗⌠;O;l;╜@αH♀^♂cΣ@k⌡MS♂N

Essayez-le en ligne!

Explication:

O╗⌠;O;l;╜@αH♀^♂cΣ@k⌡MS♂N
O╗                        store ordinals of key in register 0
  ⌠;O;l;╜@αH♀^♂cΣ@k⌡M     for each string in array:
   ;O                       make a copy, ordinals
     ;l;                    make a copy of ordinals, length, copy length
        ╜@αH                list from register 0, cycled to length of string
            ♀^              pairwise XOR
              ♂cΣ           convert from ordinals and concatenate
                 @k         swap and nest (output: [[a XOR key, a] for a in array])
                     S♂N  sort, take last element (original string)
Mego
la source
@ATaco Non, ce n'est pas le cas. Essayez-le avec ["who", "what", "when"]et"thisisalongkey"
caird coinheringaahing
1
@cairdcoinheringaahing Cela a été publié avant un patch pour Actually sur TIO.
ATaco
1

Perl 6 , 37 octets

{@^b.sort(*.comb Z~^(|$^a.comb xx*))}

Essayez-le en ligne!

$^aet @^bsont respectivement les arguments clé et tableau de la fonction. @^b.sort(...)trie simplement le tableau d'entrée en fonction de la fonction de prédicat qui lui est donnée. Cette fonction prend un seul argument, doncsort elle lui transmettra donc chaque élément à tour de rôle et traitera la valeur de retour comme une clé pour cet élément, en triant la liste en fonction des clés des éléments.

La fonction de tri est *.comb Z~^ (|$^a.comb xx *). *est l'argument chaîne unique de la fonction. *.combest une liste des caractères individuels de la chaîne. |$^a.comb xx *est une liste des caractères de la clé de tri xor, répliqués à l'infini. Ces deux listes sont zippées ensemble ( Z) à l'aide de l'opérateur xor en chaîne ( ~^). Puisque le prédicat de tri renvoie une clé de tri qui est une liste, sortordonne deux éléments en comparant les premiers éléments des listes renvoyées, puis les seconds si les premiers éléments sont les mêmes, et cetera.

Sean
la source
{sort *.comb »~^»$^a.comb,@^b}
Brad Gilbert b2gills
1

C (gcc) , 132 128 126 octets

char*k;g(a,b,i,r)char**a,**b;{r=k[i%strlen(k)];(r^(i[*a]?:-1))-(r^(i[*b]?:-2))?:g(a,b,i+1);}f(c,v)int*v;{k=*v;qsort(v,c,8,g);}

Prend un nombre d'arguments et un pointeur vers un tableau de chaînes (la clé, suivie des chaînes à trier) et modifie le tableau de chaînes sur place.

Le code est hautement non portable et nécessite des pointeurs 64 bits, gcc et glibc.

Merci à @ceilingcat d'avoir joué au golf sur 2 octets!

Essayez-le en ligne!

Dennis
la source
1

Python 2,  204 140 134 134  126 octets

Merci à @Mr. Xcoder pour avoir économisé 64 octets, grâce à @ovs pour avoir économisé six octets, et merci à @Dennis pour avoir économisé huit octets!

lambda k,l:[x(k,s)for s in sorted(x(k,s)for s in l)]
x=lambda k,s:''.join(chr(ord(v)^ord(k[i%len(k)]))for i,v in enumerate(s))

Essayez-le en ligne!

Steadybox
la source
1

Opcode x86, 57 octets

0100  60 89 CD 4D 8B 74 8A FC-8B 3C AA 53 F6 03 FF 75
0110  02 5B 53 8A 23 AC 08 C0-74 0A 30 E0 32 27 47 43
0120  38 E0 74 E8 77 0A 8B 04-AA 87 44 8A FC 89 04 AA
0130  85 ED 5B 75 CE E2 CA 61-C3

    ;input ecx(length), edx(array), ebx(xor-d)
F:  pushad
L1: mov ebp, ecx
L2: dec ebp
    mov esi, [edx+ecx*4-4]
    mov edi, [edx+ebp*4]
    push ebx
L6: test [ebx], byte -1 ; t1b
    jnz L4
    pop ebx
    push ebx
L4: mov ah, [ebx]
    lodsb
    or  al, al
    jz  L7
    xor al, ah
    xor ah, [edi]
    inc edi
    inc ebx
    cmp al, ah
    jz  L6
L7: ja  L8
    mov eax, dword[edx+ebp*4]
    xchg eax, dword[edx+ecx*4-4]
    mov dword[edx+ebp*4], eax
L8: ;call debug
    test ebp, ebp
    pop ebx
    jnz L2
    loop L1
    popad
    ret            

Code de test:

if 1
    use32
else
    org $0100
    mov ecx, (Qn-Q0)/4
    mov edx, Q0
    mov ebx, S
    call F
    call debug
    ret

debug:pushad
    mov ecx, (Qn-Q0)/4
    mov edx, Q0
    mov ebx, S
E3:   mov esi, [edx]
    push dx
    mov ah, 2
E4:   lodsb
    cmp al, 0
    jz E5
    mov dl, al
    int $21
    jmp E4
E5:   mov dl, $0A
    int $21
    mov dl, $0D
    int $21
    pop dx
    add edx, 4
    loop E3
    ;mov ah, 1
    ;int $21
    int1
    popad
    ret
    align 128
Q0:
    dd str1, str2, str3, str4
Qn:
S     db '912', 0
str1  db 'abcde', 0
str2  db 'hello', 0
str3  db 'test', 0
str4  db 'honk', 0
    align 128
end if
    ;input ecx(length), edx(array), ebx(xor-d)
F:  pushad
L1: mov ebp, ecx
L2: dec ebp
    mov esi, [edx+ecx*4-4]
    mov edi, [edx+ebp*4]
    push ebx
L6: test [ebx], byte -1 ; t1b
    jnz L4
    pop ebx
    push ebx
L4: mov ah, [ebx]
    lodsb
    or  al, al
    jz  L7
    xor al, ah
    xor ah, [edi]
    inc edi
    inc ebx
    cmp al, ah
    jz  L6
L7: ja  L8
    mov eax, dword[edx+ebp*4]
    xchg eax, dword[edx+ecx*4-4]
    mov dword[edx+ebp*4], eax
L8: ;call debug
    test ebp, ebp
    pop ebx
    jnz L2
    loop L1
    popad
    ret
l4m2
la source
1

JavaScript ES 6, 113 97 95 octets

k=>p=>p.sort((a,b,F=x=>[...x].map((y,i)=>1e9|y.charCodeAt()^(p=k+p).charCodeAt(i)))=>F(a)>F(b))

JavaScript est long à coder ...

Pour [0,65536) + 1e4 tous les 5 chiffres peuvent donc être comparés comme une chaîne

Q=
k=>p=>p.sort((a,b,F=x=>[...x].map((y,i)=>1e9|y.charCodeAt()^(p=k+p).charCodeAt(i)))=>F(a)>F(b))
;
console.log(Q("912")(["abcde", "hello", "test", "honk"]));
console.log(Q("taco")(["this", "is", "a", "taco", "test"]));
console.log(Q("thisisalongkey")(["who", "what", "when"]));
console.log(Q("3")(["who", "what", "when"]));

l4m2
la source
Threoiy je peux utiliser k+=kau lieu de p=k+pmais trop de mémoire en utilisant avec le petit cas de test
l4m2
0

Perl 5, 88 octets

sub{[map@$_[0],sort{@$a[1]cmp@$b[1]}map[$_,substr$_^($_[0]x length),0,length],@{$_[1]}]}

Essayez-le en ligne .

Denis Ibaev
la source
0

Clojure, 80 octets

#(sort-by(fn[s](apply str(apply map bit-xor(for[i[(cycle %)s]](map int i)))))%2)
NikoNyrh
la source
0

Perl 5, 80 + 3 ( anl) = 83 , 67 octets

sub{$,=shift;sub X{$_^substr$,x y///c,0,y///c};map X,sort map X,@_}

essayez-le en ligne

Nahuel Fouilleul
la source
Cela répète la clé 9 fois, ce qui n'est pas suffisant en général. Par exemple, la sortie sera incorrecte pour 9; abcdeabcde abcdeabcdz(devrait donner abcdeabcdz abcdeabcde)
Lynn
@Lynn, correction de l'ajout de 3 octets
Nahuel Fouilleul
pourrait économiser 16 octets en utilisant des sous
Nahuel Fouilleul
0

AWK , 285 284 octets

{for(;z++<128;){o[sprintf("%c",z)]=z}split(substr($0,0,index($0,FS)),k,"");$1="";split($0,w);for(q in w){split(w[q],l,"");d="";for(;i++<length(l);){d=d sprintf("%c",xor(o[k[(i-1)%(length(k)-1)+1]],o[l[i]]))}a[q]=d;i=0}asort(a,b);for(j in b){for(i in a){printf(a[i]==b[j])?w[i]FS:""}}}

Essayez-le en ligne!

Accepte les entrées sous la forme, key word word ...par exemple,912 abcde hello test honk

Produit des mots triés séparés par des espaces

Légèrement plus lisible

{
  for (; z++ < 128;) {
    o[sprintf("%c", z)] = z
  }
  split(substr($0, 0, index($0, FS)), k, "");
  $1 = "";
  split($0, w);
  for (q in w) {
    split(w[q], l, "");
    d = "";
    for (; i++ < length(l);) {
      d = d sprintf("%c", xor(o[k[(i - 1) % (length(k) - 1) + 1]], o[l[i]]))
    }
    a[q] = d;
    i = 0;
  }
  asort(a, b);
  for (j in b) {
    for (i in a) {
      printf(a[i] == b[j]) ? w[i] FS : ""
    }
  }
}  
Noskcaj
la source
0

Facteur, 85

[ [ dup length rot <array> concat [ bitxor ] 2map ] with
[ dup bi* <=> ] curry sort ]

Essayez d'abord, je vais voir si je peux jouer au golf demain.

J'accepte les suggestions;)

fede s.
la source
0

Dyalog APL, 34 octets

Dfn, utilise ⎕ml 3

{⍵[⍋⊃82⎕dr¨⊃≠/11⎕dr¨¨⍵((⍴¨⍵)⍴⊂⍺)]}
Lobachevsky
la source