Capitalisation d'échange


35

Avec deux chaînes de lettres, transférez le modèle de capitalisation de chaque chaîne sur l’autre. Le moins d'octets gagne.

Input:   CodeGolf xxPPCGxx  
Output:  coDEGOlf XxppCgxx
  • Les deux chaînes seront de longueur égale et non vide, avec uniquement des lettres a..zet A..Z.
  • Vous pouvez sortir les deux chaînes résultantes dans l’un ou l’autre ordre par rapport aux entrées.
  • Vous pouvez représenter une paire de chaînes en tant que chaîne unique avec un séparateur à caractère unique non lettre pour entrée et / ou sortie.
  • Vous pouvez représenter une chaîne sous la forme d'une liste de caractères ou d'une chaîne à un caractère, mais pas sous la forme d'une séquence de valeurs de points de code, à moins qu'il ne s'agisse simplement de chaînes dans votre langue.
  • Votre entrée et votre sortie peuvent représenter des chaînes différemment.

Cas de test:

CodeGolf xxPPCGxx -> coDEGOlf XxppCgxx
lower UPPER -> LOWER upper
MiXeD lower -> mixed LoWeR
A A -> A A
ABcd EfGh -> AbCd EFgh

Réponses:


14

Java (JDK 10) , 66 octets

a->b->{for(int i=a.length,t;i-->0;b[i]^=t)a[i]^=t=(a[i]^b[i])&32;}

Essayez-le en ligne!

Des explications

a->b->{                           // Curried lambda
 for(int i=a.length,t;i-->0;      //  Descending loop on i,
                                  //  Declare t
     b[i]^=t                      //   Apply the case difference to b[i]
   )
  a[i]^=t=(a[i]^b[i])&32;         //   Assign the case difference of the two letters to t, and apply it to a[i].
}

9
Complètement sans lien avec votre réponse, mais c'est plus facile que de créer une discussion. ; p Avez-vous remarqué que le Java-10 TIO présentait un bogue lors de son utilisation array[i++%n]+=...;? array[t=i++%n]=array[t]+...;fonctionne bien; et array[i%n]+=...;i++;fonctionne bien aussi, mais utiliser i++ou ++iavec un modulo et +=ajouter une ligne à un tableau ne fonctionne pas. Voici un exemple de Java 10 TIO pour voir le problème. S'agit-il d'un bogue (ou d'une fonctionnalité: S) dans le JDK Java 10 ou dans le compilateur Java 10 TIO?
Kevin Cruijssen

1
@KevinCruijssen Je vois le problème, mais cela semble bizarre. Je vois que la version utilisée sur TIO est 10.0.0_46 (du 20-03-2018). La dernière version est 10.0.1. Nous devrions probablement demander à TIO de mettre à jour sa version de Java.
Olivier Grégoire

3
@KevinCruijssen Dennis a mis à jour la version 10.0.1 et le problème persiste (Java 10 n'est pas encore installé et je compte donc sur TIO, tout comme vous). J'ai demandé à Stack Overflow car je ne sais pas ce qui se passe ici ... C'est déroutant!
Olivier Grégoire

5
@KevinCruijssen Ça va, ce n'est pas comme si cette réponse attirait beaucoup de votes positifs: P En tout cas ... Le problème, c'est que vous avez réellement trouvé un bogue . Comme la spécification indique qu'elle devrait agir comme vous le pensez, continuez à écrire votre réponse de cette façon, optimisée pour Java 10 si vous en avez besoin. De cette façon, vous avez une réponse Java 10 valide, mais non testable à cause de ce bogue. Il suffit de l’écrire et de le tester sous Java 8, puis d’apporter les modifications appropriées à Java 10, comme changer Stringpour var.
Olivier Grégoire

6
Je pense que c'est vraiment bien que vous ayez trouvé un bogue dans JDK 10. Bon travail:]
Poke

13

C (gcc) , 86 58 55 53 53 octets

c(a,s,e)char*a,*s;{for(;*s++^=e=(*s^*a)&32;)*a++^=e;}

Essayez-le en ligne!



@Cowsquack Wow; Merci beaucoup.
Jonathan Frech


@ OlivierGrégoire Merci.
Jonathan Frech

8

Gelée , 9 octets

O&32^/^OỌ

Essayez-le en ligne!

Comment ça marche

O&32^/^OỌ  Main link. Argument: [s, t] (pair of strings)

O          Ordinal; replace each character with its code point.
 &32       Perform bitwise AND with 32, yielding 32 for lowercase letters, 0 for
           uppercase ones.
    ^/     Reduce by XOR, yielding 32 for letter pairs with different 
           capitalizations, 0 for letter pair with matching capitalizations.
      ^O   XOR the result with each of the code points.
        Ọ  Unordinal; replace each code point with its character.

1
... nous savions que cela allait arriver: D
Jonathan Allan

7

APL (Dyalog Classic) , 13 à 12 octets

⊖⊖819⌶¨⍨∊∘⎕a

Essayez-le en ligne!

entrée et sortie est une matrice de 2 × N caractères

⎕a est l'alphabet anglais majuscule 'ABC...Z'

∊∘⎕a retourne une matrice booléenne indiquant les lettres majuscules de l'entrée

819⌶ convertit son argument de droite en majuscule ou en minuscule en fonction de son argument de gauche booléen ("819" est leetpeak pour "BIG")

819⌶¨⍨fait cela pour chaque caractère ( ¨), swapping ( ) les arguments

signifie inverser verticalement; l'un agit comme l'argument de gauche 819⌶et l'autre est l'action finale


1
"819" is leetspeak for "BIG"... Sérieusement? C'est la véritable explication de pourquoi c'est 819? 0_o
DLosc

@DLosc oui :) voir le chat
ngn le

5

Pyth , 10 octets

rVV_mmrIk1

Essayez-le ici!

Explications et astuces Pyth utilisées

  • rVV_mmrIk1- Programme complet. L'entrée provient de STDIN sous forme de liste de deux chaînes et la sortie est écrite dans STDOUT sous forme de liste de deux listes de caractères.

  • mm - Pour chaque caractère dans chacune des chaînes:

    • Ik - Vérifiez si elle est invariante sous ...
    • r...1- ... Conversion en majuscule. Rend Vrai pour les majuscules et Faux pour les minuscules.
  • _ - Inverser cette liste.

  • VV - Et double-vectoriser la fonction suivante sur les deux listes:

    • r- Convertir en majuscule si la valeur est True(aka 1), sinon convertir en minuscule.

Cette soumission abuse du fait que r0et r1sont les fonctions minuscules et majuscules dans Pyth, et nous utilisons des valeurs de vérité (les valeurs obtenues en vérifiant si chaque caractère est majuscule, inversé) donnant Truepour des majuscules et Falsedes minuscules. Le fait que les booléens soient des sous-classes d'entiers en Python est très pratique pour l'approche utilisée par cette réponse. Le portage des approches de Dennis et Jelly de Jonathan a abouti à plus de 18 octets. Je suis donc assez satisfait des astuces spécifiques à Pyth utilisées ici.


4

MATL , 11 octets

kG91<P32*-c

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

k      % Implicit input: 2-row char matrix. Convert to lower-case
G      % Push input again 
91<    % Less than 91?, element-wise. Gives 1 for upper-case
P      % Flip vertically
32*    % Multiply by 32, element-wise
-      % Subtract, element-wise
c      % Convert to char. Implicit display


3

J , 36 31 27 octets

-9 octets grâce à FrownyFrog!

(XOR"$32*[:~:/97>])&.(3&u:)

Essayez-le en ligne!

La solution précédente était:

J , 36 31 octets

-5 octets grâce à FrownyFrog!

|:@(XOR 32*0~:/@|:97>])&.(3&u:)

Essayez-le en ligne!

Comment ça marche:

                          (3&u:)  converts the strings to code points
   (                    )&.       then do the following and convert back to chars
                    97>]          check if they are uppercase letters 
             0~:/@|:              transpose and check if the two values are different
          32*                     multiply by 32 (32 if different, 0 otherwise)
      XOR                         xor the code point values with 32 or 0
 |:@                              and transpose

Le [:peut être 0 et le (22 b.)peut être XOR. &.(3&u:)enregistre 1 octet.
FrownyFrog le

@FrownyFrog Très beaux golfs, merci! Tu es très bon!
Galen Ivanov


@FrownyFrog Wow! Pouvez-vous expliquer l'utilisation de "et $? Merci!
Galen Ivanov

La saisie est faite avec ,:, il y a 2 rangées sur le côté gauche. Nous avons besoin de "(1)mais "$travaille aussi, parce que cela représente "1 _. $ b.0donne le rang de $ (monadique, gauche dyadique, droite dyadique).
FrownyFrog le

3

R , 118 94 75 72 octets

m=sapply(scan(,""),utf8ToInt);w=m>96;apply(m-32*(w-w[,2:1]),2,intToUtf8)

Essayez-le en ligne!

Il doit y avoir une manière beaucoup plus golfeuse. -43 octets grâce à Giuseppe qui m'a indiqué la solution MATL de Luis Mendo. Le lien TIO contient une solution de fonction pour le même nombre d'octets.

m=sapply(a<-scan(,""),utf8ToInt)    # Turns input into a matrix of bytecode (2 columns)
w=m>96                              # Predicate : which chars are lower?
apply(m-32*(w-w[,2:1]),2,intToUtf8) # -32*w turns the string to UPPER
                                    # +32*w[,2:1] swaps capitalization
                                    # intToUtf8 turns bytecode to strings

Bonus: La sortie est un vecteur nommé dont les noms sont les chaînes d'entrée d'origine!


Vous devriez pouvoir laisser tomber a<-puisque vous n'utilisez anulle part ailleurs.
Giuseppe

@ Giuseppe lisiez-vous mes pensées? ;)
JayCe

3

code machine x86-64, 14 octets

Appelable à partir de C (convention d'appel SysV x86-64) avec ce prototype:

void casexchg(char *rdi, char *rsi);  // modify both strings in place

Une version de longueur explicite dont la longueur rcxest égale à la même taille. void casexchg(char *rdi, char *rsi, int dummy, size_t len);


Cela utilise le même algorithme d'échange de bits que les réponses C et Java: si les deux lettres sont identiques, aucune des deux ne doit être modifiée. S'ils sont dans le cas contraire, ils doivent tous les deux changer.

Utilisez XOR pour différencier le bit de casse des deux chaînes. mask = (a XOR b) AND 0x20est 0 pour identique ou 0x20 pour différer. a ^= mask; b ^= maskcaseflip les deux lettres ssi elles étaient des cas opposés. (Parce que les codes de lettres ASCII pour les lettres supérieure et inférieure ne diffèrent que par le bit 5.)

Liste NASM (de nasm -felf64 -l/dev/stdout). Utilisez-le cut -b 26- <casexchg.lst >casexchg.lstpour transformer cela en quelque chose que vous pouvez assembler.

   addr    machine
 6         code          global casexchg
 7         bytes         casexchg:
 8                       .loop:
 9 00000000 AC               lodsb                ; al=[rsi] ; rsi++
10 00000001 3207             xor   al, [rdi]
11 00000003 2420             and   al, 0x20       ; 0 if their cases were the same: no flipping needed
12                       
13 00000005 3007             xor   [rdi], al      ; caseflip both iff their cases were opposite
14 00000007 3046FF           xor   [rsi-1], al
15                       
16 0000000A AE               scasb                ; cmp al,[rdi] / inc rdi
17                           ; AL=0 or 0x20.
18                           ; At the terminating 0 in both strings, AL will be 0 so JNE will fall through.
19                           ; 0x20 is ASCII space, which isn't allowed, so AL=0x20 won't cause early exit
20 0000000B 75F3             jne  .loop
21                       ;    loop  .loop            ; caller passes explict length in RCX
22                       
23 0000000D C3               ret

  size = 0xe bytes = 14
24 0000000E 0E           db $ - casexchg_bitdiff

L' loopinstruction lente est également 2 octets, identique à un court jcc. scasbreste le meilleur moyen d’incrémenter rdiavec une instruction à un octet. Je suppose que nous pourrions xor al, [rdi]/ stosb. Ce serait la même taille mais probablement plus rapide pour le loopcas (la mémoire src + store est moins chère que la mémoire dst + reload). Et définirait toujours ZF de manière appropriée pour le cas de longueur implicite!

Essayez-le en ligne! avec un _start qui l'appelle sur argv [1], argv [2] et utilise sys_write sur le résultat





2

QBasic, 133 octets

INPUT a$,b$
FOR i=1TO LEN(a$)
c=ASC(MID$(a$,i,1))
d=ASC(MID$(b$,i,1))
s=32AND(c XOR d)
?CHR$(c XOR s);
r$=r$+CHR$(d XOR s)
NEXT
?
?r$

Prend les deux chaînes séparées par des virgules et génère les résultats séparés par une nouvelle ligne. Utilise l'algorithme bidouiller de la réponse de Dennis's Jelly . En dehors de cela, l'astuce principale du golf ici est que la première chaîne de résultat est imprimée directement, un caractère à la fois, ce qui est un peu plus court que d'enregistrer les deux chaînes de résultat dans des variables et de les imprimer en dehors de la boucle.


2

JavaScript, 77 74 73 octets

W=>W.map((w,x)=>w.map((c,i)=>W[+!x][i][`to${c>{}?'Low':'Upp'}erCase`]()))

Prend un tableau de tableaux de caractères, génère un tableau de tableaux de caractères.

-1 octet ( @Arnauld ): c>'Z'c>{}


1
Vous pouvez enregistrer un octet avec c>{}.
Arnauld

1

Retina , 75 octets

^
¶
+`¶(([A-Z])|(.))(.*)¶(([A-Z])|(.))
$#6*$u$1$#7*$l$1¶$4$#2*$u$5$#3*$l$5¶

Essayez-le en ligne! Explication: Les nouvelles lignes sont utilisées comme marqueurs pour déterminer la quantité de chaîne traitée. La regex essaie de faire correspondre les lettres avec des lettres majuscules ou échoue avec n'importe quel caractère. Si une lettre majuscule était appariée, l'autre caractère est mis en majuscule, sinon il est mis en minuscule et vice-versa, tandis que les nouvelles lignes sont passées au caractère suivant.



1

Assembly (nasm, x64, Linux) , 25 octets (source de 123 octets)

Hex octets:

0x88, 0xE6, 0x30, 0xC6, 0x80, 0xE6, 0x20, 0x88
0xF2, 0x66, 0x31, 0xD0, 0x88, 0x26, 0xAA, 0xAC
0x8A, 0x26, 0x8A, 0x07, 0x08, 0xE4, 0x75, 0xE8, 0xC3

Le point d'entrée de la fonction est à a, avec les chaînes passées à l'aide de RDIet RSI.

b:MOV DH,AH
XOR DH,AL
AND DH,32
MOV DL,DH
XOR AX,DX
MOV [RSI],AH
STOSB
LODSB
a:MOV AH,[RSI]
MOV AL,[RDI]
OR AH,AH
JNZ b
RET

Essayez-le en ligne!


Je viens de me rendre compte que vous gérez la source asm, pas la taille du code machine. C'est généralement plus amusant, car c'est parfois utile dans la vie réelle. (Toutes choses étant égales par ailleurs, plus petit est généralement préférable pour la densité du cache frontal et du cache uop.) Astuces pour jouer au golf en code machine x86 / x64 .
Peter Cordes

@PeterCordes Merci pour le tuyau. J'ai ajouté les octets hexadécimaux. Mon assemblage est un peu rouillé (il me fallait pour la dernière fois écrire un petit pilote de périphérique pour DOS 3.3!), Mais je pense avoir obtenu la plupart des optimisations.
ErikF

Ouais, ça a l'air bien. Des hacks de registre partiel intéressants. and al,32est seulement 2 octets, en utilisant le codage spécial AL, imm8 que la plupart des instructions ALU ont. Vous pourriez avoir besoin de la longueur de chaîne dans RCX et l'utiliser loop. J'allais dire que tu devrais test ah,ahparce que que c'est plus efficace que d'or avoir la même longueur, mais c'est plus long dans la source asm, donc le vieil idiot croustillant a en fait du mérite pour le golf avec le code source asm: P
Peter Cordes

En utilisant le xor de destination mémoire et une structure de boucle plus étroite, ma version utilisait 14 octets de code machine x86-64 . Idem pour count chaînes de longueur implicite ou explicite. Sa source NASM pourrait probablement aussi être jouée plus courte que 123 octets. Je ne sais pas ce qui fonctionnerait plus rapidement sur un processeur moderne comme Skylake ou Ryzen (Ryzen n'aurait aucun coût supplémentaire pour la fusion DH lorsque DX est lu, mais SKL aurait besoin d'un cycle supplémentaire pour insérer un uop de fusion.)
Peter Cordes


0

charbon , 17 octets

Eθ⭆ι⎇№α§§θ¬κμ↥λ↧λ

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Prend l'entrée comme un tableau de deux chaînes. Explication:

 θ                  Input array
E                   Map over strings
   ι                Current string
  ⭆                 Map over characters
         θ          Input array
           κ        Outer loop index
          ¬         Logical Not
        §           Index into array
            μ       Inner loop index
       §            Index into array
      α             Uppercase characters
     №              Count number of matches
              λ λ   Current character
             ↥      Uppercase
               ↧    Lowercase
    ⎇               Ternary
                    Implicitly print

0

F #, 120 octets

Bugger.

open System
let g=Seq.fold2(fun a x y->a+string(x|>if y>'Z'then Char.ToLower else Char.ToUpper))""
let b f s=g f s,g s f

Essayez-le en ligne!

La fonction gprend les deux chaînes en tant que paramètres. Seq.fold2applique une fonction avec un accumulateur ( a) à chaque élément ( xet y) dans les chaînes. Initialement, il as'agit d'une chaîne vide, qui y ajoute le caractère converti à chaque itération.

best la fonction principale. Il convertit d'abord fpar rapport à s, puis convertit spar rapport à f. Il retourne ensuite un tuple avec les deux valeurs.



0

Ruby , 74 69 octets

->a,b{a.zip(b).map{|x|x.one?{|y|y>?_}?x.map(&:swapcase):x}.transpose}

Essayez-le en ligne!

L'entrée et la sortie sont des tableaux de caractères, de sorte que le pied de page effectue des transformations en arrière à partir de chaînes.

Je ne sais pas encore s'il s'agit d'une bonne approche du problème, mais ce défi ressemble certainement à un bon scénario d'utilisation pour la swapcaseméthode.


0

PHP 4.1.2 , 40 octets

Remplacez la paire de guillemets par l'octet A0 (dans ISO-8859-1 ou Windows-1252, il s'agit de NBSP) pour obtenir le nombre d'octets affiché, puis exécutez-la à partir d'un navigateur Web (ou de la ligne de commande), en fournissant les chaînes suivantes: les arguments de la chaîne de requête (ou les variables d'environnement) aet b.

<?=$a^$c=($a^$b)&str_pad("",2e5),_,$b^$c;

Dans cette version de PHP, register_globals est activé par défaut, les chaînes seront automatiquement affectées aux variables $aet $b. Augmentez la valeur 2e5(200000) si nécessaire.

PHP 7.1+, 58 octets

Exécuter sur la ligne de commande, en utilisant php -r 'code here' string1 string2:

[,$a,$b]=$argv;echo("$b $a"^$a.=" $b")&str_pad("",3e5)^$a;

La valeur 3e5 (300000) est choisie pour dépasser (MAX_ARG_STRLEN * 2 + 1) sur la plupart des systèmes Linux (en particulier, x86 et les autres architectures pour lesquelles PAGE_SIZE est 4096 et MAX_ARG_STRLEN est donc 131072), afin d'éviter tout problème avec une chaîne d'entrée possible. Augmenter si nécessaire.

Essayez-le en ligne!


0

Stax , 10 octets

▌Ö↑o╓→ì]yç

Exécuter et déboguer

Voici une représentation non golfée du même programme pour montrer comment cela fonctionne.

        Example
        ["Ab", "cd"]                    
:)      [["Ab", "cd"], ["cd", "Ab"]]    Get all rotations of input
m       ["cd", "Ab"]                    For each, run the rest of program; print result
  M     ["cA", "db"]                    Transpose matrix
  {     "cA"                            Begin block for mapping to result
    B   "A" 99                          "Pop" first element from string array; leave the rest
    96> "A" 1                           Is the character code > 96?
    :c  "a"                             Set case of string; 0 -> upper,  1 -> lower
  m     "ab"                            Perform the map using the block

Exécuter celui-ci


0

Crystal , 108 octets

def f(a,b)r=s=""
a.zip(b){|x,y|r+="`"<x<"{"?y.downcase: y.upcase
s+="`"<y<"{"?x.downcase: x.upcase}
{s,r}end

Essayez-le en ligne!

Comment ça marche?

def f(a, b)                       # Strings as list of characters
r = s = ""                        # Strings buffers initialization
a.zip(b) do |x, y|                # Join two arrays to paired tuples and iterate
r+="`"<x<"{"?y.downcase: y.upcase # Check if character is downcase using triple
s+="`"<y<"{"?x.downcase: x.upcase # comparison and ascii table. Then apply it to
end                               # the other character using String methods
{s, r}                            # Return two new strings using a tuple
end                               # PS: Tuples are inmutable structures in Crystal
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.