Multiplication de chaînes par élément

28

Inspiré par ce défi (merci @cairdcoinheringaahing pour le titre!), Votre tâche consiste à prendre deux chaînes ASCII imprimables et à les multiplier élément par élément avec les règles suivantes.

Comment ça marche?

Étant donné deux chaînes (par exemple splitet isbn), vous allez d'abord tronquer la plus longue de sorte qu'elles aient une longueur égale, puis déterminer leurs codes ASCII :

split -> spli -> [115, 112, 108, 105]
isbn  -> isbn -> [105, 115,  98, 110]

La prochaine étape consistera à les mapper à la plage [0..94]en soustrayant 32chaque code:

[115, 112, 108, 105] -> [83, 80, 76, 73]
[105, 115,  98, 110] -> [73, 83, 66, 78]

Vous allez maintenant les multiplier par élément modulo 95(pour rester dans la plage imprimable):

[83, 80, 76, 73] ⊗ [73, 83, 66, 78] -> [74, 85, 76, 89]

Ajoutez 32pour revenir à la gamme [32..126]:

[74, 85, 76, 89] -> [106, 117, 108, 121]

Et la dernière étape consiste à les mapper en caractères ASCII:

[106, 117, 108, 121] -> "july"

Règles

  • Vous allez écrire un programme / fonction qui implémente les étapes décrites sur deux chaînes et imprime ou renvoie la chaîne résultante
  • Le format d'entrée est flexible: vous pouvez prendre deux chaînes, un tuple de chaînes, une liste de chaînes, etc.
  • L'entrée peut consister en une ou deux chaînes vides
  • L'entrée sera constituée de caractères dans la plage imprimable ( [32..126])
  • La sortie est imprimée sur la console ou vous retournez une chaîne
  • La sortie peut avoir des espaces de fin

Cas de test

"isbn", "split"                  -> "july"
"", ""                           -> ""
"", "I don't matter"             -> ""
"             ", "Me neither :(" -> "             "
"but I do!", "!!!!!!!!!"         -> "but I do!"
'quotes', '""""""'               -> 'ck_iKg'
"wood", "hungry"                 -> "yarn"
"tray", "gzip"                   -> "jazz"
"industry", "bond"               -> "drop"
"public", "toll"                 -> "fall"
"roll", "dublin"                 -> "ball"
"GX!", "GX!"                     -> "!!!"
"4 lll 4", "4 lll 4"             -> "4 lll 4"
"M>>M", "M>>M"                   -> ">MM>"

Remarque : Les citations sont juste pour la lisibilité, dans le 6ème cas de test que j'ai utilisé à la 'place de ".

ბიმო
la source
Êtes-vous autorisé à avoir des espaces de fin dans votre sortie?
Erik the Outgolfer
@EriktheOutgolfer Oui. Désolé, j'ai ajouté cela après l'avoir posté.
ბიმო
Pouvons-nous prendre un tableau de tableaux de chaînes? abc, def -> [['a', 'b', 'c'], ['d', 'e', 'f']]
2017 totalement humain à 16h19
@totallyhuman Je ne dirais pas ça. Cependant, si dans votre langue les chaînes sont des tableaux de caractères et que les caractères ont le même type que les chaînes, alors ce serait valide je suppose.
ბიმო
Sommes-nous autorisés à prendre la saisie comme une liste de chaînes?
Zacharý

Réponses:

9

MATL , 12 octets

c32-p95\32+c

Essayez-le en ligne!

Explication

c      % Implicitly input cell array of 2 strings. Convert to 2-row char matrix.
       % This pads the shorter string with spaces
32-    % Subtract 32, element-wise. Each char is interpreted as its ASCII code.
       % Note that padding spaces will give 0.
p      % Product of each column. Since (padding) spaces have been mapped to 0, the
       % product effectively eliminates those colums. So the effect is the same as
       % if string length had been limited by the shorter one
95\    % Modulo 95, element-wise
32+    % Add 32, element-wise
c      % Convert to char. Implicitly display
Luis Mendo
la source
1
Une façon intelligente de gérer la différence de longueur de chaîne.
Sanchises
6

Gelée , 15 12 octets

z⁶O_32P€‘ịØṖ

Essayez-le en ligne!

-3 merci à Jonathan Allan .

Erik le Outgolfer
la source
Abus sournois d'espaces de fuite. ;)
Dennis
@ Dennis Eh bien, c'est dans les règles, pourquoi ne pas en abuser?
Erik the Outgolfer
Je crois que vous pouvez économiser 3 octets en utilisant l'atome niladique pour les caractères imprimables ØṖ, avec z⁶O_32P€‘ịØṖ- vous feriez mieux de vérifier que l'arithmétique fonctionne bien.
Jonathan Allan
@JonathanAllan Bien sûr.
Erik the Outgolfer
5

Python 3 , 80 74 71 octets

lambda*t:''.join(map(lambda x,y:chr((ord(x)-32)*(ord(y)-32)%95+32),*t))

Merci à @shooqie d'avoir joué au golf sur 3 octets!

Essayez-le en ligne!

Dennis
la source
1
71 si vous prenez (s, t)comme tuple:lambda t:''.join(map(lambda x,y:chr((ord(x)-32)*(ord(y)-32)%95+32),*t))
shooqie
5

Python 2 , 75 70 octets

-3 octets grâce à la suggestion de Dennis de la suggestion de shooqie. -2 octets grâce à la suggestion de Zacharý.

lambda*l:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(*l))

Essayez-le en ligne!

totalement humain
la source
2
Même astuce qui a été suggérée sur ma réponse:lambda*t:''.join(chr(((ord(i)-32)*(ord(j)-32))%95+32)for i,j in zip(*t))
Dennis
2
Et le même que j'ai beaucoup suggéré: ((ord(i)-32)*(ord(j)-32))%95+32=> (ord(i)-32)*(ord(j)-32)%95+32...
Zacharý
o_o battre Dennis. +1
Zacharý
1
Eh, pas vraiment, je viens de passer à une compréhension de liste au lieu de l'utiliser map. J'étais juste un peu en retard.
2017 totalement humain
5

Haskell , 60 57 octets

zipWith(\a b->toEnum$f a*f b`mod`95+32)
f=(-32+).fromEnum

Essayez-le en ligne!

La première ligne est une fonction anonyme prenant deux arguments.

Il s'agit d'une implémentation simple de l'algorithme: zipWithprend les deux chaînes et applique une fonction donnée aux paires de caractères. Il gère la troncature et fonctionne également pour les chaînes vides. fromEnumet toEnumsont des alternatives à ordet chrpour basculer entre les caractères et leurs valeurs ASCII qui n'ont pas besoin d'une importation longue.

Edit: -3 octets grâce à Bruce Forte.

Laikoni
la source
Vous pouvez enregistrer des 3octets en extrayant -32et en enregistrant ces parenthèses, voir ici .
ბიმო
5

C ++, 331 291 282 270 268 octets, version 2 = 178 176 150 150 148 octets

Version originale :

#include<string>
#include<algorithm>
#define L length()
#define S std::string
S m(S a,S b){S c;int m=a.L<b.L?a.L:b.L;auto l=[m](S&s){s=s.substr(0,m);std::for_each(s.begin(),s.end(),[](char&c){c-=32;});};l(a);l(b);for(int i=0;i<m;++i){c+=a[i]*b[i]%95+32;}return c;}

-40 octets grâce à Bruce Forte
-39 octets grâce à Zacharý

Version 2, inspirée des réponses des autres

#include<string>
#define L length()
using S=std::string;S m(S a,S b){S c;for(int i=0;i<(a.L<b.L?a.L:b.L);++i)c+=(a[i]-32)*(b[i]-32)%95+32;return c;}

Si la première version utilise un lambda, c'est parce que je voulais tester la fonction std :: async C ++ 11 que je viens d'apprendre, donc je l'ai gardée sans raison ...

Version plus lisible:

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

#define L length()
#define S string

//Function code for the original version
S m(S a,S b) {
    S c;
    int m = a.L < b.L ? a.L : b.L;

    auto l=[m](S&s){
        s = s.substr(0, m);
        for_each(s.begin(),s.end(),[](char&c){
            c -= 32;
        });
    };
    l(a);
    l(b);
    for(int i=0;i<m;++i) {
        c += a[i] * b[i] % 95 + 32;
    }
    return c;
}

//Code for the version 2
S m2(S a,S b) {
    S c;
    for(int i = 0; i < (a.L < b.L ? a.L : b.L); ++i) {
        c += (a[i] - 32) * (b[i] - 32) % 95 + 32;
    }
    return c;
}

int main() {
    string a, b, c;
    getline(cin, a);
    getline(cin, b);
    c = m(a, b);
    cout << c;
}
HatsuPointerKun
la source
1
Bienvenue chez PPCG!
Martin Ender
Bienvenue sur le site! Merci pour votre réponse, je l'apprécie. Je n'ai pas d' expérience dans le golf avec C ++, mais ici vous trouverez quelques conseils. Profitez de votre temps ici!
ბიმო
Je suis également sûr que vous pouvez simplement soumettre une fonction, comme celle-ci .
ბიმო
Vous ne pouvez pas supprimer les espaces ici: #include <string>=> #include<string>et #include <algorithm>=> #include<algorithm>?
Zacharý
De plus, vous devriez pouvoir créer une macro équivalente à stringet l'utiliser en conséquence.
Zacharý
3

Dyalog APL, 36 34 33 25 24 octets

{⎕UCS 32+95|×⌿32-⎕UCS↑⍵}

Essayez-le en ligne (TryAPL)!

Essayez-le en ligne (TIO)!

L'entrée est une liste de chaînes et possède un espace de fin.

Voici comment cela fonctionne:

{⎕UCS 32+95|×⌿32-⎕UCS↑⍵}
                     ↑⍵ - the input as a 2d array
                 ⎕UCS   - codepoints
              32-       - subtract 32
            ×⌿          - element wise product reduction ([a,b]=>a×b)
         95|            - Modulo 95
      32+               - Add 32
 ⎕UCS                   - Unicode characters
Zacharý
la source
Je n'ai pas eu l'interface de tryapl.org, voici donc un TIO pour ceux qui veulent l'essayer.
ბიმო
Là, je mets les deux là-dedans.
Zacharý
3

FSharp 275 octets

let f (p : string, q : string) =     
let l = if p.Length < q.Length then p.Length else q.Length
p.Substring(0,l).ToCharArray() |> Array.mapi (fun i x -> (((int(x) - 32) * (int(q.[i]) - 32)) % 95) + 32) |> Array.map (fun x -> char(x).ToString()) |> Array.fold(+) ""
Laco
la source
Bienvenue chez PPCG!
Martin Ender
169 octets
ASCII uniquement
127 octets
ASCII uniquement
126 octets
ASCII uniquement
124 octets
ASCII uniquement
2

C # (.NET Core) , 100 96 95 octets

(l,n)=>{for(int i=0;i<l.Length&i<n.Length;)Console.Write((char)((l[i]-32)*(n[i++]-32)%95+32));}

Essayez-le en ligne!

-4 octets grâce à @ Zacharý

-1 octet en déplaçant l'incrément

Utilise un lambda et abuse du fait que les personnages sont essentiellement des ints.

jkelm
la source
Pouvez-vous utiliser (l[i]-32)*(n[i]-32)%95+32?
Zacharý
Pourquoi oui, je peux. Merci!
jkelm
1
Vous devez entièrement qualifier le Consoleet vous pouvez utiliser le curry pour enregistrer un octet. Compiler vers un Action<string, Action<string>>semblable l=>n=>et appeler comme("word")("string")
TheLethalCoder
2

Mathematica, 114 octets

(a=Min@StringLength[x={##}];FromCharacterCode[Mod[Times@@(#-32&/@ToCharacterCode/@(StringTake[#,a]&/@x)),95]+32])&


contribution

["public", "péage"]

J42161217
la source
Existe-t-il un moyen de l'essayer en ligne?
2017
bien sûr, allez sur sandbox.open.wolframcloud.com/app/objects collez le code, collez l'entrée à la fin, appuyez sur Maj + Entrée
J42161217
qu'est-ce que "8 caractères"?
J42161217
Désolé pour la confusion! Le message "Merci!" aurait été trop court pour publier comme ça, il avait besoin de 8 caractères de plus.
ბიმო
3
ok ....................................
J42161217
2

Empilé , 52 octets

[,:$#'"!MIN$take"![CS#.toarr]"!32-prod 95%32+#:''#`]

Essayez-le en ligne!

Fonction qui prend deux arguments de la pile.

Explication

[,:$#'"!MIN$take"![CS#.toarr]"!32-prod 95%32+#:''#`]

Regardons la première partie, en supposant que les deux premiers éléments sont 'split'et 'isbn':

,:$#'"!MIN$take"!      stack:                      ('split' 'isbn')
,                      pair top two:               (('split' 'isbn'))
 :                     duplicate:                  (('split' 'isbn') ('split' 'isbn'))
  $#'                  length function literal:    (('split' 'isbn') ('split' 'isbn') $#')
    "!                 execute on each:            (('split' 'isbn') (5 4))
      MIN              obtain the minimum:         (('split' 'isbn') 4)
         $take         "take" function literal:    (('split' 'isbn') 4 $take)
                       (e.g. `'asdf' 2 take` is `'as'`)
              "!       vectorized binary each:     (('spli' 'isbn'))

Cette partie effectue le recadrage.

Ensuite:

[CS#.toarr]"!     stack: (('spli' 'isbn'))
[         ]"!     perform the inside on each string
                  string `'spli'`:
 CS               convert to a character string:    $'spli'
   #.             vectorized "ord":                 (115 112 108 105)
     toarr        convert to array:                 (115 112 108 105)
                  (needed for empty string, since `$'' #.` == `$''` not `()`

Ensuite, la dernière partie:

32-prod 95%32+#:''#`  stack: (((115 112 108 105) (105 115  98 110)))
32-                   subtract 32 from each character code:   (((83 80 76 73) (73 83 66 78)))
   prod               reduce multiplication over the array:   ((6059 6640 5016 5694))
        95%           modulus 95:                             ((74 85 76 89))
           32+        add 32:                                 ((106 117 108 121))
              #:      convert to characters:                  (('j' 'u' 'l' 'y'))
                ''#`  join:                                   ('july')
Conor O'Brien
la source
2

R , 88 octets

function(r,s,u=utf8ToInt)intToUtf8((((u(r)-32)*(u(s)-32))%%95+32)[0:min(nchar(c(r,s)))])

fonction anonyme; prend l'entrée comme deux chaînes; le troisième argument est juste de s'assurer qu'il s'agit d'une fonction d'une ligne et d'économiser quelques octets.

Le lien TIO ci-dessous renvoie un tableau avec des entrées nommées avec la première entrée.

Essayez tous les cas de test!

Giuseppe
la source
2

Perl 5 , 65 octets

64 octets de code + -pindicateur.

$n=reverse<>;s/./($_=chop$n)&&chr 32+(-32+ord$&)*(-32+ord)%95/ge

Essayez-le en ligne!

Dada
la source
2

05AB1E , 16 15 octets

.BÇ32-`*₃%32+çJ

Essayez-le en ligne!

-1 pour Emigna soulignant les poussées 95.


                 # ['hi', 'you']
.B               # [['hi ', 'you']]
  Ç              # [[[104, 105, 32], [121, 111, 117]]]
   32-           # [[[72, 73, 0], [89, 79, 85]]]
      `          # [[72, 73, 0], [89, 79, 85]]
       *         # [[6408, 5767, 0]]
        ₃%       # [[43, 67, 0]]
          32+    # [[75, 99, 32]]
             ç   # [['K', 'c', ' ']]
              J  # ['Kc ']

.BÇ32-`*95%žQsèJ

en est un autre.

Urne de poulpe magique
la source
enregistre un octet. Dommage pour l'entrée de chaîne vide. Sinon, øj'en économiserais quelques autres.
Emigna
2

Java 8, 127 115 97 95 octets

a->b->{for(int i=0;i<a.length&i<b.length;System.out.printf("%c",(a[i]-32)*(b[i++]-32)%95+32));}

Explication:

Essayez-le ici.

a->b->{                       // Method with 2 char-array parameters and no return-type
  for(int i=0;                //  Index-integer, starting at 0
      i<a.length&i<b.length;  //  Loop over both arrays up to the smallest of the two
    System.out.printf("%c",   //   Print, as character:
      (a[i]-32)               //    Current char of `a` minus 32
      *(b[i++]-32)            //    multiplied with current char of `b` minus 32
      %95                     //    Take modulo-95 of that multiplied result
      +32));}                 //    And add 32 again
Kevin Cruijssen
la source
1

C #, 166 octets

using System.Linq;s=>t=>{int e=s.Length,n=t.Length,l=e>n?n:e;return string.Concat(s.Substring(0,l).Select((c,i)=>(char)((((c-32)*(t.Substring(0,l)[i]-32))%95)+32)));}

Je suis sûr qu'il y a beaucoup de golf à faire mais je n'ai pas le temps pour l'instant.

Essayez-le en ligne!

Version complète / formatée:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<string, Func<string, string>> f = s => t =>
        {
            int e = s.Length, n = t.Length, l = e > n ? n : e;

            return string.Concat(s.Substring(0, l).Select((c, i) => (char)((((c - 32) * (t.Substring(0, l)[i] - 32)) % 95) + 32)));
        };

        Console.WriteLine(string.Concat(f("split")("isbn")));

        Console.ReadLine();
    }
}
TheLethalCoder
la source
Je pense que ça (((c-32)*(t.Substring(0,l)[i]-32))%95)+32)peut être ((c-32)*(t.Substring(0,l)[i]-32)%95+32)( ça a peut-être
foiré
1

Lisp commun, 99 octets

(lambda(a b)(map'string(lambda(x y)(code-char(+(mod(*(-(#1=char-code x)32)(-(#1#y)32))95)32)))a b))

Essayez-le en ligne!

Renzo
la source
1

Japt , 24 octets

¬íVq)®®©c -HÃ×u95 +H dÃq

Renvoie une chaîne avec des caractères nuls de fin (\u0000 ) lorsque la première entrée est plus longue que la seconde.

Essayez-le en ligne! avec le-Q indicateur pour afficher la sortie formatée, y compris les caractères nuls.

Exécutez tous les cas de test à l' aide de mon WIP CodePen.

Justin Mariner
la source
1

Python 2 , 95 73 octets

  • Merci @ Zacharý pour 4 octets: les crochets indésirables supprimés
lambda x,y:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(x,y))

Essayez-le en ligne!

officialaimm
la source
3
Bonté gracieuse ... apprenez à utiliser l'ordre des opérations! (((ord(x[i])-32)*(ord(y[i])-32))%95)+32=>(ord(x[i])-32)*(ord(y[i])-32)%95+32
Zacharý
1

Fusain , 30 octets

F⌊⟦LθLη⟧℅⁺³²﹪×⁻³²℅§θι⁻³²℅§ηι⁹⁵

Essayez-le en ligne! Le lien est vers la version détaillée du code. J'ai en fait écrit le calcul (32 - ord(q)) * (32 - ord(h))car il évite les littéraux numériques consécutifs mais je suppose que j'aurais pu simplement écrire à la (ord(q) - ord(" ")) * (ord(h) - ord(" "))place.

Neil
la source
1

Perl 5 , 95 octets

@a=<>=~/(.)/g;@b=<>=~/(.)/g;$#a=$#b if@a>@b;print chr 32+(-32+ord$_)*(-32+ord$b[$i++])%95 for@a

Essayez-le en ligne!

Explication:

@a=<>=~/(.)/g;@b=<>=~/(.)/g;  # Split the strings into 2 arrays
$#a=$#b if@a>@b;              # Truncate the first if longer than the second
print chr 32+(-32+ord$_)*(-32+ord$b[$i++])%95 for@a  # Multiply each character
Xcali
la source
1
Je pense que vous ne tronquez pas correctement le résultat à la longueur de la plus petite chaîne (voir ici ).
Dada
Tu as raison. Correction d'un coût de plusieurs octets
Xcali
1

Pip , 19 octets

(PA$* *(PA@?Zg)%95)

Prend les chaînes comme arguments de ligne de commande. Essayez-le en ligne!

Explication

(PA$* *(PA@?Zg)%95)
                     g is list of args; PA is string of all printable ASCII characters
            Zg       Zip items of g together: result is list of pairs of characters
        PA@?         Find index of each character in PA
       (      )      (Parentheses to get correct operator precedence)
   $* *              Map (fold on *) to the list: multiplies each pair of numbers
               %95   Take list items mod 95
(PA               )  Use those numbers to index into PA again
                     Print the resulting list of chars, concatenated together (implicit)
DLosc
la source
1

Facteur , 45

[ [ [ 32 - ] bi@ * 95 mod 32 + ] "" 2map-as ]

C'est une citation (lambda), callelle avec deux chaînes sur la pile, laisse la nouvelle chaîne sur la pile.

En un mot:

: s* ( s1 s2 -- ps ) [ [ 32 - ] bi@ * 95 mod 32 + ] "" 2map-as ;

"M>>M" "M>>M" s*      ! => ">MM>"
dup s*                ! => "M>>M"
dup s*                ! => ">MM>"
...
fede s.
la source
1

K (oK) , 26 octets

Solution:

`c$32+95!*/-32+(&/#:'x)$x:

Essayez-le en ligne!

Exemple:

`c$32+95!*/-32+(&/#:'x)$x:("split";"isbn")
"july"

Explication:

L'évaluation s'effectue de droite à gauche:

`c$32+95!*/-32+(&/#:'x)$x: / the solution
                        x: / assign input to variable x
                       $   / pad right to length on left
               (  #:'x)    / count each x (return length of each char list in list)
                &/         / min-over, get the minimum of these counts
           -32+            / subtract 32, this automagically converts chars -> ints
         */                / multiply-over, product of the two lists
      95!                  / modulo 95
   32+                     / add 32 back again
`c$                        / convert to character array
streetster
la source
0

PHP, 112 octets

for($i=0;$i<min(strlen($a=$argv[1]),strlen($b=$argv[2]));$i++)echo chr((ord($a[$i])-32)*(ord($b[$i])-32)%95+32);
jstnthms
la source
109 octets: for($i=0;$i<strlen($a=$argv[1])&&$i<strlen($b=$argv[2]);)echo chr((ord($a[$i])-32)*(ord($b[$i++])-32)%95+32); De plus, je ne suis pas tout à fait sûr si le remplacement &&par &pourrait également être possible en PHP, en le réduisant d'un autre octet à 108 .
Kevin Cruijssen
0

JavaScript (ES6), 89 octets

Javascript et la malédiction des longs noms de fonctions ...

Utiliser le curry et le fait qu'il charCodeAtrevient NaNlorsqu'il est appelé avec une position invalide. Il peut y avoir des valeurs nulles de fin dans la sortie.

a=>b=>a.replace(/./g,(c,i)=>String.fromCharCode((z=x=>x.charCodeAt(i)-32)(a)*z(b)%95+32))

Tester

var f=
a=>b=>a.replace(/./g,(c,i)=>String.fromCharCode((z=x=>x.charCodeAt(i)-32)(a)*z(b)%95+32))

q=x=>'['+x+']'

;[["isbn", "split"],["", ""],["", "I don't matter"],["             ", "Me neither :("],
["but I do!", "!!!!!!!!!"],['quotes', '""""""'],["wood", "hungry"],["tray", "gzip"],
["industry", "bond"],["public", "toll"],["roll", "dublin"],["GX!", "GX!"],
["4 lll 4", "4 lll 4"],["M>>M", "M>>M"]]
.forEach(([a,b])=>console.log(q(a)+' x '+q(b)+' --> '+q(f(a)(b))))

edc65
la source