Moltiplicazione delle stringhe per elemento


28

Ispirato da questa sfida (grazie a @cairdcoinheringaahing per il titolo!), Il tuo compito è quello di prendere due stringhe ASCII stampabili e moltiplicarle in base agli elementi con le seguenti regole.

Come funziona?

Date due stringhe (ad esempio splite isbn), per prima cosa, troncare la più lunga in modo che abbiano la stessa lunghezza e quindi determinare i loro codici ASCII :

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

Il prossimo passo sarà mapparli all'intervallo [0..94]sottraendo 32ogni codice:

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

Ora li moltiplichi per modulo 95(per rimanere nell'intervallo stampabile):

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

Aggiungi 32per tornare all'intervallo [32..126]:

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

E il passaggio finale è mapparli di nuovo ai caratteri ASCII:

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

Regole

  • Scriverai un programma / funzione che implementa i passaggi descritti su due stringhe e stampa o restituisce la stringa risultante
  • Il formato di input è flessibile: puoi prendere due stringhe, una tupla di stringhe, un elenco di stringhe ecc.
  • L'input può essere costituito da una o due stringhe vuote
  • L'input sarà costituito da caratteri nell'intervallo stampabile ( [32..126])
  • L'output viene stampato sulla console o si restituisce una stringa
  • L'output può contenere spazi bianchi finali

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

Nota : le virgolette sono solo per leggibilità, nel sesto caso di test che ho usato al 'posto di ".


È consentito avere spazi finali nell'output?
Erik the Outgolfer,

@EriktheOutgolfer Sì. Mi dispiace, l'ho aggiunto dopo averlo pubblicato.
ბიმო

Possiamo prendere una serie di matrici di stringhe? abc, def -> [['a', 'b', 'c'], ['d', 'e', 'f']]
totalmente umano il

@totallyhuman Non direi così. Tuttavia, se nella tua lingua le stringhe sono matrici di caratteri e i caratteri hanno lo stesso tipo di stringhe, allora sarebbe valido immagino.
ბიმო

Siamo autorizzati a prendere input come un elenco di stringhe?
Zacharý,

Risposte:


9

MATL , 12 byte

c32-p95\32+c

Provalo online!

Spiegazione

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
Modo intelligente di gestire la differenza di lunghezza della stringa.
Sanchises,

6

Gelatina , 15 12 byte

z⁶O_32P€‘ịØṖ

Provalo online!

-3 grazie a Jonathan Allan .


Abuso subdolo di spazi bianchi finali. ;)
Dennis il

@Dennis Beh, è ​​nelle regole, perché non abusarne?
Erik the Outgolfer,

Credo che puoi salvare 3 byte usando l'atomo niladico per i caratteri stampabili ØṖ, con z⁶O_32P€‘ịØṖ- faresti meglio a ricontrollare che l'aritmetica funzioni comunque.
Jonathan Allan,

@JonathanAllan Certo.
Erik the Outgolfer,

5

Python 3 , 80 74 71 byte

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

Grazie a @shooqie per giocare a golf con 3 byte!

Provalo online!


1
71 se prendi (s, t)come tupla:lambda t:''.join(map(lambda x,y:chr((ord(x)-32)*(ord(y)-32)%95+32),*t))
shooqie,

5

Python 2 , 75 70 byte

-3 byte grazie al suggerimento di Dennis del suggerimento di shooqie. -2 byte grazie al suggerimento di Zacharý.

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

Provalo online!


2
Lo stesso trucco suggerito nella mia risposta:lambda*t:''.join(chr(((ord(i)-32)*(ord(j)-32))%95+32)for i,j in zip(*t))
Dennis,

2
E lo stesso che ho suggerito molto: ((ord(i)-32)*(ord(j)-32))%95+32=> (ord(i)-32)*(ord(j)-32)%95+32...
Zacharý

o_o battere Dennis. +1
Zacharý,

1
Eh, non proprio, ho appena cambiato in una comprensione della lista invece di usare map. Ero solo leggermente in ritardo.
totalmente umano il

5

Haskell , 60 57 byte

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

Provalo online!

La prima riga è una funzione anonima che accetta due argomenti.

Questa è un'implementazione diretta dell'algoritmo: zipWithaccetta entrambe le stringhe e applica una determinata funzione alle coppie di caratteri. Gestisce il troncamento e funziona anche per stringhe vuote. fromEnume toEnumsono alternative alla orde chrper passare tra personaggi e le loro valori ASCII, che non hanno bisogno di un lungo di importazione.

Modifica: -3 byte grazie a Bruce Forte.


Puoi salvare i 3byte estraendo -32e salvando quelle parentesi, vedi qui .
ბიმო

5

C ++, 331 291 282 270 268 byte, Versione 2 = 178 176 150 148 byte

Versione 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 byte grazie a Bruce Forte
-39 byte grazie a Zacharý

Versione 2, ispirata alle risposte degli altri

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

Se la prima versione utilizza un lambda, è perché volevo testare la funzione std :: async C ++ 11 che avevo appena imparato prima, quindi l'ho tenuto per nessun motivo ...

Versione più leggibile:

#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
Benvenuti in PPCG!
Martin Ender,

Benvenuti nel sito! Grazie per la tua risposta, lo apprezzo molto. Non ho esperienza nel golf con C ++, ma qui troverai alcuni suggerimenti. Goditi il ​​tuo tempo qui!
ბიმო

Inoltre sono abbastanza sicuro che puoi semplicemente inviare una funzione, come questa .
ბიმო

Non puoi rimuovere gli spazi qui: #include <string>=> #include<string>e #include <algorithm>=> #include<algorithm>?
Zacharý,

Inoltre, dovresti essere in grado di creare una macro equivalente stringe utilizzarla di conseguenza.
Zacharý,

3

Dyalog APL, 36 34 33 25 24 byte

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

Provalo online (TryAPL)!

Provalo online (TIO)!

L'input è un elenco di stringhe e presenta spazi vuoti finali.

Ecco come funziona:

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

Non ho avuto l'interfaccia di tryapl.org, quindi ecco un TIO per coloro che vogliono provarlo.
ბიმო

Lì, ho inserito entrambi.
Zacharý,



2

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

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

Provalo online!

-4 byte grazie a @ Zacharý

-1 byte spostando l'incremento

Usa un lambda e abusa del fatto che i personaggi sono fondamentalmente ints.


Puoi usare (l[i]-32)*(n[i]-32)%95+32?
Zacharý,

Perché sì, posso. Grazie!
jkelm,

1
Devi qualificare completamente il Consolee puoi usare il curry per salvare un byte. Compilare un Action<string, Action<string>>like l=>n=>e chiamare like("word")("string")
TheLethalCoder

2

Mathematica, 114 byte

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


ingresso

[ "Pubblico", "pedaggio"]


C'è un modo per provarlo online?
ბიმო

ovviamente, vai su sandbox.open.wolframcloud.com/app/objects incolla il codice, incolla input alla fine, premi
maiusc

quali "8 caratteri"?
J42161217

Dispiace per la confusione! Il messaggio "Grazie!" sarebbe stato troppo breve per pubblicare in questo modo, aveva bisogno di 8 caratteri in più.
ბიმო

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

2

Impilato , 52 byte

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

Provalo online!

Funzione che accetta due argomenti dallo stack.

Spiegazione

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

Diamo un'occhiata alla prima parte, supponendo che i primi due elementi siano 'split'e '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'))

Questa parte esegue il ritaglio.

Poi:

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

Quindi, l'ultima 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 byte

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

funzione anonima; accetta input come due stringhe; il terzo argomento è solo per garantire che questa sia una funzione a una riga e salvare alcuni byte.

Il collegamento TIO di seguito restituisce un array con voci denominate con il primo input.

Prova tutti i casi di test!




2

05AB1E , 16 15 byte

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

Provalo online!

-1 per Emigna sottolineando le spinte 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

è un altro.


salva un byte. Peccato per l'input di stringa vuota. Altrimenti øne risparmierebbe qualche altro.
Emigna,

2

Java 8, 127 115 97 95 byte

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

Spiegazione:

Provalo qui.

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 byte

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

Sono sicuro che c'è molto da giocare a golf, ma non ho tempo in questo momento.

Provalo online!

Versione completa / formattata:

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

Penso che (((c-32)*(t.Substring(0,l)[i]-32))%95)+32)possa essere ((c-32)*(t.Substring(0,l)[i]-32)%95+32)(potrebbe aver
rovinato i genitori

1

Lisp comune, 99 byte

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

Provalo online!



1

Python 2 , 95 73 byte

  • Grazie @ Zacharý per 4 byte: parentesi indesiderate rimosse
lambda x,y:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(x,y))

Provalo online!


3
Bontà gentile ... impara a usare l'ordine delle operazioni! (((ord(x[i])-32)*(ord(y[i])-32))%95)+32=>(ord(x[i])-32)*(ord(y[i])-32)%95+32
Zacharý,

1

Carbone , 30 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. In realtà ho scritto il calcolo come (32 - ord(q)) * (32 - ord(h))perché evita letterali numerici consecutivi, ma suppongo che avrei potuto semplicemente scrivere (ord(q) - ord(" ")) * (ord(h) - ord(" "))invece.


1

Perl 5 , 95 byte

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

Provalo online!

Spiegazione:

@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
Penso che tu non stia troncando correttamente il risultato alla lunghezza della stringa più piccola (vedi qui ).
Dada,

Hai ragione. Risolto il problema con un costo di molti byte
Xcali,

1

Pip , 19 byte

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

Prende le stringhe come argomenti della riga di comando. Provalo online!

Spiegazione

(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

Fattore , 45

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

È una citazione (lambda), callcon due stringhe nello stack, lascia la nuova stringa nello stack.

Come una parola:

: 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 byte

Soluzione:

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

Provalo online!

Esempio:

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

Spiegazione:

La valutazione viene eseguita da destra a sinistra:

`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 byte

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 byte: 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); Inoltre, non sono del tutto sicuro se la sostituzione &&con &potrebbe essere possibile anche in PHP, riducendolo di un altro byte a 108 .
Kevin Cruijssen,

0

JavaScript (ES6), 89 byte

Javascript e la maledizione dei lunghi nomi di funzioni ...

Utilizzo del curry e del fatto che charCodeAtritorna NaNquando viene chiamato con una posizione non valida. Possono esserci nulli finali nell'output.

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

Test

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.