Multiplicación de cuerdas por elementos


28

Inspirado en este desafío (¡gracias @cairdcoinheringaahing por el título!), Su tarea es tomar dos cadenas ASCII imprimibles y multiplicarlas por elementos con las siguientes reglas.

¿Como funciona?

Dadas dos cadenas (por ejemplo, splity isbn) primero, truncará la más larga para que tengan la misma longitud y luego determine sus códigos ASCII :

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

El siguiente paso será asignarlos al rango [0..94]restando 32cada código:

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

Ahora los multiplicará por módulo en cuanto a elementos 95(para permanecer en el rango de impresión):

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

Agregar 32para volver al rango [32..126]:

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

Y el paso final es asignarlos de nuevo a los caracteres ASCII:

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

Reglas

  • Escribirás un programa / función que implemente los pasos descritos en dos cadenas e imprima o devuelva la cadena resultante
  • El formato de entrada es flexible: puede tomar dos cadenas, una tupla de cadenas, una lista de cadenas, etc.
  • La entrada puede consistir en una o dos cadenas vacías
  • La entrada será caracteres en el rango imprimible ( [32..126])
  • El resultado se imprime en la consola o devuelve una cadena
  • La salida puede tener espacios en blanco al final

Casos de prueba

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

Nota : Las citas son solo para facilitar la lectura, en el sexto caso de prueba que utilicé en 'lugar de ".


¿Se le permite tener espacios finales en su salida?
Erik the Outgolfer

@EriktheOutgolfer Sí. Lo siento, lo agregué después de publicarlo.
ბიმო

¿Podemos tomar una serie de matrices de cadenas? abc, def -> [['a', 'b', 'c'], ['d', 'e', 'f']]
totalmente humano

@totallyhuman no lo diría. Sin embargo, si en su idioma las cadenas son matrices de caracteres y los caracteres tienen el mismo tipo que las cadenas, entonces sería válido, supongo.
ბიმო

¿Se nos permite tomar la entrada como una lista de cadenas?
Zacharý

Respuestas:


9

MATL , 12 bytes

c32-p95\32+c

Pruébalo en línea!

Explicación

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

1
Manera inteligente de gestionar la diferencia de longitud de cadena.
Sanchises

6

Jalea , 15 12 bytes

z⁶O_32P€‘ịØṖ

Pruébalo en línea!

-3 gracias a Jonathan Allan .


Abuso disimulado del espacio en blanco al final. ;)
Dennis

@ Dennis Bueno, está en las reglas, ¿por qué no abusar de él?
Erik the Outgolfer

Creo que puede ahorrar 3 bytes usando el átomo niládico para caracteres imprimibles ØṖ, con z⁶O_32P€‘ịØṖ- es mejor que verifique que la aritmética funcione.
Jonathan Allan

@ JonathanAllan Por supuesto.
Erik the Outgolfer

5

Python 3 , 80 74 71 bytes

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

¡Gracias a @shooqie por jugar 3 bytes!

Pruébalo en línea!


1
71 si lo tomas (s, t)como una tupla:lambda t:''.join(map(lambda x,y:chr((ord(x)-32)*(ord(y)-32)%95+32),*t))
shooqie

5

Python 2 , 75 70 bytes

-3 bytes gracias a la sugerencia de Dennis de la sugerencia de shooqie. -2 bytes gracias a la sugerencia de Zacharý.

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

Pruébalo en línea!


2
Mismo truco que se sugirió en mi respuesta:lambda*t:''.join(chr(((ord(i)-32)*(ord(j)-32))%95+32)for i,j in zip(*t))
Dennis

2
Y el mismo que sugerí mucho: ((ord(i)-32)*(ord(j)-32))%95+32=> (ord(i)-32)*(ord(j)-32)%95+32...
Zacharý

o_o golpeando a Dennis. +1
Zacharý

1
Eh, en realidad no, simplemente cambié a una lista de comprensión en lugar de usar map. Llegué un poco tarde.
totalmente humano

5

Haskell , 60 57 bytes

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

Pruébalo en línea!

La primera línea es una función anónima que toma dos argumentos.

Esta es una implementación directa del algoritmo: zipWithtoma ambas cadenas y aplica una función determinada a los pares de caracteres. Maneja el truncamiento y también funciona para cadenas vacías. fromEnumy toEnumson alternativas a ordy chrpara cambiar entre los personajes y sus valores ASCII que no necesitan una larga importación.

Editar: -3 bytes gracias a Bruce Forte.


Puede guardar 3bytes extrayendo -32y guardando esos paréntesis, consulte aquí .
ბიმო

5

C ++, 331 291 282 270 268 bytes, Versión 2 = 178 176 150 148 bytes

Versión original :

#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 bytes gracias a Bruce Forte
-39 bytes gracias a Zacharý

Versión 2, inspirada en las respuestas de otras personas.

#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 primera versión usa una lambda, es porque quería probar C ++ 11 std :: función asíncrona que acabo de aprender, así que la guardé sin ningún motivo ...

Versión más legible:

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

1
Bienvenido a PPCG!
Martin Ender

Bienvenido al sitio! Gracias por tu respuesta, te lo agradezco. No tengo experiencia en golf con C ++, pero aquí encontrarás algunos consejos. ¡Disfruta tu tiempo aquí!
ბიმო

También estoy bastante seguro de que puede enviar una función, como esta .
ბიმო

¿No puedes eliminar los espacios aquí: #include <string>=> #include<string>y #include <algorithm>=> #include<algorithm>?
Zacharý

Además, debería poder crear una macro equivalente stringy utilizarla en consecuencia.
Zacharý

3

Dyalog APL, 36 34 33 25 24 bytes

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

¡Pruébelo en línea (TryAPL)!

¡Pruébelo en línea (TIO)!

La entrada es una lista de cadenas y tiene espacios en blanco al final.

Así es como funciona:

{⎕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

No obtuve la interfaz tryapl.org, así que aquí hay un TIO para aquellos que quieran probarlo.
ბიმო

Allí, puse los dos allí.
Zacharý



2

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

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

Pruébalo en línea!

-4 bytes gracias a @ Zacharý

-1 byte moviendo el incremento

Utiliza una lambda y abusa del hecho de que los personajes son básicamente ints.


Puedes usar (l[i]-32)*(n[i]-32)%95+32?
Zacharý

¿Por qué sí puedo? ¡Gracias!
jkelm

1
Debe calificar completamente el Consoley puede usar curry para guardar un byte. Compilar a un me Action<string, Action<string>>gusta l=>n=>y llamar como("word")("string")
TheLethalCoder

2

Mathematica, 114 bytes

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


entrada

["público", "peaje"]


¿Hay alguna forma de probarlo en línea?
ბიმო

por supuesto, vaya a sandbox.open.wolframcloud.com/app/objects pegue el código, pegue la entrada al final, presione shift + enter
J42161217

¿Qué "8 caracteres"?
J42161217

¡Perdón por la confusion! El mensaje "¡Gracias!" hubiera sido demasiado corto para publicar así, necesitaba 8 caracteres más.
ბიმო

3
ok ....................................
J42161217

2

Apilado , 52 bytes

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

Pruébalo en línea!

Función que toma dos argumentos de la pila.

Explicación

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

Veamos la primera parte, suponiendo que los dos elementos principales son 'split'y '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'))

Esta parte realiza el recorte.

Luego:

[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 `()`

Entonces, la última parte:

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

2

R , 88 bytes

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

función anónima; toma la entrada como dos cadenas; El tercer argumento es solo para garantizar que se trata de una función de una línea y guardar algunos bytes.

El siguiente enlace TIO devuelve una matriz con entradas nombradas con la primera entrada.

¡Pruebe todos los casos de prueba!




2

05AB1E , 16 15 bytes

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

Pruébalo en línea!

-1 para Emigna señalando empujones 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

es otro.


Guarda un byte. Lástima lo de la entrada de cadena vacía. De ølo contrario , ahorraría algunos más.
Emigna

2

Java 8, 127 115 97 95 bytes

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

Explicación:

Pruébalo aquí

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

1

C #, 166 bytes

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

Estoy seguro de que hay mucho golf por hacer, pero no tengo tiempo en este momento.

Pruébalo en línea!

Versión completa / formateada:

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

Creo que (((c-32)*(t.Substring(0,l)[i]-32))%95)+32)puede ser ((c-32)*(t.Substring(0,l)[i]-32)%95+32)(podría haber jodido a los padres allí ... ¡parece lisp!)
Zacharý



1

Python 2 , 95 73 bytes

  • Gracias @ Zacharý por 4 bytes: se eliminaron los corchetes no deseados
lambda x,y:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(x,y))

Pruébalo en línea!


3
¡Dios mío ... aprende a usar el orden de las operaciones! (((ord(x[i])-32)*(ord(y[i])-32))%95)+32=>(ord(x[i])-32)*(ord(y[i])-32)%95+32
Zacharý

1

Carbón , 30 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. De hecho, escribí el cálculo como (32 - ord(q)) * (32 - ord(h))porque evita literales numéricos consecutivos, pero supongo que podría haber escrito en su (ord(q) - ord(" ")) * (ord(h) - ord(" "))lugar.


1

Perl 5 , 95 bytes

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

Pruébalo en línea!

Explicación:

@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

1
Creo que no estás truncando correctamente el resultado a la longitud de la cadena más pequeña (ver aquí ).
Dada

Tienes razón. Se arregló a un costo de muchos bytes
Xcali

1

Pip , 19 bytes

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

Toma las cadenas como argumentos de línea de comandos. Pruébalo en línea!

Explicación

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

1

Factor , 45

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

Es una cita (lambda), callcon dos cadenas en la pila, deja la nueva cadena en la pila.

Como una palabra:

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

"M>>M" "M>>M" s*      ! => ">MM>"
dup s*                ! => "M>>M"
dup s*                ! => ">MM>"
...

1

K (oK) , 26 bytes

Solución:

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

Pruébalo en línea!

Ejemplo:

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

Explicación:

La evaluación se realiza de derecha a izquierda:

`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

0

PHP, 112 bytes

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

109 bytes: 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); Además, no estoy completamente seguro de si también es posible reemplazarlo &&con &PHP, reduciéndolo en otro byte a 108 .
Kevin Cruijssen

0

JavaScript (ES6), 89 bytes

Javascript y la maldición de los nombres largos de funciones ...

Usar curry y el hecho de que charCodeAtvuelve NaNcuando se llama con una posición no válida Puede haber nulos finales en la salida.

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

Prueba

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.