Perkalian string elemen-bijaksana


28

Terinspirasi oleh tantangan ini (terima kasih @cairdcoinheringaahing untuk judulnya!), Tugas Anda adalah mengambil dua string ASCII yang dapat dicetak dan melipatgandakannya berdasarkan elemen dengan aturan berikut.

Bagaimana cara kerjanya?

Diberikan dua string (misalnya splitdan isbn) Anda akan pertama-tama, memotong yang lebih panjang sehingga mereka memiliki panjang yang sama dan kemudian menentukan kode ASCII mereka :

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

Langkah selanjutnya adalah memetakannya ke kisaran [0..94]dengan mengurangi 32masing-masing kode:

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

Sekarang Anda akan melipatgandakan modulo elemen-bijaksana mereka 95(untuk tetap dalam kisaran yang dapat dicetak):

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

Tambahkan 32untuk kembali ke rentang [32..126]:

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

Dan langkah terakhir adalah memetakannya kembali ke karakter ASCII:

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

Aturan

  • Anda akan menulis program / fungsi yang mengimplementasikan langkah-langkah yang dijelaskan pada dua string dan mencetak atau mengembalikan string yang dihasilkan
  • Format input fleksibel: Anda dapat mengambil dua string, tupel string, daftar string, dll.
  • Input dapat terdiri dari satu atau dua string kosong
  • Input akan berupa karakter dalam rentang yang dapat dicetak ( [32..126])
  • Outputnya dicetak ke konsol atau Anda mengembalikan string
  • Outputnya dibolehkan memiliki spasi spasi tambahan

Uji kasus

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

Catatan : Kutipan hanya untuk keterbacaan, dalam test case ke-6 saya menggunakan 'sebagai ganti ".


Apakah Anda diizinkan memiliki spasi tambahan di output Anda?
Erik the Outgolfer

@EriktheOutgolfer Ya. Maaf, saya menambahkannya setelah mempostingnya.
ბიმო

Bisakah kita mengambil array array string? abc, def -> [['a', 'b', 'c'], ['d', 'e', 'f']]
totallyhuman

@ sebenarnya manusia saya tidak akan mengatakan begitu. Padahal, jika dalam bahasa Anda, string adalah array chars dan chars memiliki tipe yang sama dengan string, maka itu akan menjadi valid kurasa.
ბიმო

Apakah kami diizinkan mengambil input sebagai daftar string?
Zacharý

Jawaban:


9

MATL , 12 byte

c32-p95\32+c

Cobalah online!

Penjelasan

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
Cara pintar mengelola perbedaan panjang string.
Sanchises

6

Jelly , 15 12 byte

z⁶O_32P€‘ịØṖ

Cobalah online!

Terima kasih kepada Jonathan Allan .


Penyalahgunaan licik dari trailing space. ;)
Dennis

@ Dennis Yah itu ada dalam aturan, mengapa tidak menyalahgunakannya?
Erik the Outgolfer

Saya percaya Anda dapat menyimpan 3 byte dengan menggunakan atom niladic untuk karakter yang dapat dicetak ØṖ,, dengan z⁶O_32P€‘ịØṖ- Anda sebaiknya mengecek apakah aritmatika berfungsi.
Jonathan Allan

@ Jonathan Allan Tentu saja.
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))

Terima kasih kepada @shooqie untuk bermain golf 3 byte!

Cobalah online!


1
71 jika Anda menganggap (s, t)sebagai tuple: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 berkat saran Dennis tentang saran shooqie. -2 byte berkat saran Zacharý.

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

Cobalah online!


2
Trik yang sama yang disarankan pada jawaban saya:lambda*t:''.join(chr(((ord(i)-32)*(ord(j)-32))%95+32)for i,j in zip(*t))
Dennis

2
Dan yang sama yang saya sarankan banyak: ((ord(i)-32)*(ord(j)-32))%95+32=> (ord(i)-32)*(ord(j)-32)%95+32...
Zacharý

o_o mengalahkan Dennis. +1
Zacharý

1
Eh, tidak juga, saya hanya berubah ke daftar pemahaman daripada menggunakan map. Saya sedikit terlambat.
totallyhuman

5

Haskell , 60 57 byte

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

Cobalah online!

Baris pertama adalah fungsi anonim mengambil dua argumen.

Ini merupakan implementasi langsung dari algoritma: zipWithmengambil kedua string dan menerapkan fungsi yang diberikan ke pasangan karakter. Ini menangani pemotongan dan juga berfungsi untuk string kosong. fromEnumdan toEnummerupakan alternatif untuk orddan chruntuk beralih antara karakter dan nilai ASCII mereka yang tidak memerlukan impor yang panjang.

Sunting: -3 bytes terima kasih kepada Bruce Forte.


Anda dapat menyimpan 3byte dengan menarik -32dan menyimpan tanda kurung itu, lihat di sini .
ბიმო

5

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

Versi asli :

#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 terima kasih kepada Bruce Forte
-39 byte terima kasih kepada Zacharý

Versi 2, terinspirasi oleh jawaban orang lain

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

Jika versi pertama menggunakan lambda, itu karena saya ingin menguji fungsi C ++ 11 std :: async yang baru saya pelajari sebelumnya, jadi saya menyimpannya tanpa alasan ...

Versi yang lebih mudah dibaca:

#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
Selamat datang di PPCG!
Martin Ender

Selamat datang di situs ini! Terima kasih atas jawaban Anda, saya menghargainya. Saya tidak punya pengalaman dalam bermain golf dengan C ++, tetapi di sini Anda akan menemukan beberapa tips. Nikmati waktu Anda di sini!
ბიმო

Saya juga cukup yakin Anda bisa mengirimkan fungsi, seperti ini .
ბიმო

Tidak bisakah Anda menghapus spasi di sini: #include <string>=> #include<string>dan #include <algorithm>=> #include<algorithm>?
Zacharý

Selain itu, Anda harus dapat membuat setara makro stringdan menggunakannya sesuai.
Zacharý

3

Dyalog APL, 36 34 33 25 24 byte

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

Coba online (TryAPL)!

Coba online (TIO)!

Input adalah daftar string, dan memiliki spasi spasi.

Begini cara kerjanya:

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

Saya tidak mendapatkan antarmuka tryapl.org, jadi inilah TIO untuk mereka yang ingin mencobanya.
ბიმო

Di sana, saya menempatkan keduanya di sana.
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));}

Cobalah online!

-4 byte terima kasih kepada @ Zacharý

-1 byte dengan menggerakkan kenaikan

Menggunakan lambda dan menyalahgunakan fakta bahwa karakter pada dasarnya int.


Dapatkah Anda menggunakan (l[i]-32)*(n[i]-32)%95+32?
Zacharý

Kenapa ya, saya bisa. Terima kasih!
jkelm

1
Anda harus memenuhi syarat sepenuhnya Consoledan Anda dapat menggunakan kari untuk menyimpan byte. Kompilasi ke Action<string, Action<string>>like l=>n=>dan panggil seperti("word")("string")
TheLethalCoder

2

Mathematica, 114 byte

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


memasukkan

["publik", "tol"]


Apakah ada cara untuk mencobanya secara online?
ბიმო

tentu saja, buka sandbox.open.wolframcloud.com/app/objects tempel kode, tempel input di akhir, tekan shift + enter
J42161217

apa "8 karakter"?
J42161217

Maaf bila membingungkan! Pesan "Terima kasih!" akan terlalu pendek untuk memposting seperti ini, dibutuhkan 8 karakter lebih.
ბიმო

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

2

Ditumpuk , 52 byte

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

Cobalah online!

Fungsi yang mengambil dua argumen dari stack.

Penjelasan

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

Mari kita lihat bagian pertama, dengan asumsi dua item teratas adalah 'split'dan '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'))

Bagian ini melakukan pemangkasan.

Kemudian:

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

Lalu, bagian terakhir:

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

fungsi anonim; mengambil input sebagai dua string; Argumen ketiga hanya untuk memastikan ini adalah fungsi satu baris dan menyimpan beberapa byte.

TIO link di bawah ini mengembalikan array dengan entri bernama dengan input pertama.

Coba semua test case!




2

05AB1E , 16 15 byte

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

Cobalah online!

-1 untuk Emigna yang menunjukkan dorongan 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

adalah yang lain.


menghemat satu byte. Sayang sekali tentang input string kosong. Kalau tidak, øakan menghemat beberapa lagi.
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));}

Penjelasan:

Coba di sini.

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

Saya yakin ada banyak golf yang harus dilakukan tetapi saya tidak punya waktu sekarang.

Cobalah online!

Versi Lengkap / Diformat:

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

Saya pikir (((c-32)*(t.Substring(0,l)[i]-32))%95)+32)bisa ((c-32)*(t.Substring(0,l)[i]-32)%95+32)(mungkin mengacaukan parens di sana ... itu tampak seperti cadel!)
Zacharý

1

Gangguan Umum, 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))

Cobalah online!


1

Japt , 24 byte

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

Mengembalikan string dengan mengekor null-chars ( \u0000) saat input pertama lebih panjang dari yang kedua.

Cobalah online! dengan -Qflag untuk menampilkan output yang diformat, termasuk null-chars.

Jalankan semua test case menggunakan WIP CodePen saya.


1

Python 2 , 95 73 byte

  • Terima kasih @ Zacharý untuk 4 byte: tanda kurung yang tidak diinginkan dihapus
lambda x,y:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(x,y))

Cobalah online!


3
Astaga ... belajar menggunakan urutan operasi! (((ord(x[i])-32)*(ord(y[i])-32))%95)+32=>(ord(x[i])-32)*(ord(y[i])-32)%95+32
Zacharý

1

Arang , 30 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Saya benar-benar menulis perhitungan (32 - ord(q)) * (32 - ord(h))karena itu menghindari literal angka berturut-turut tapi saya kira saya bisa saja menulis (ord(q) - ord(" ")) * (ord(h) - ord(" "))saja.


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

Cobalah online!

Penjelasan:

@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
Saya pikir Anda tidak memotong hasil dengan benar dengan panjang string yang lebih kecil (lihat di sini ).
Dada

Kamu benar. Memperbaikinya dengan biaya banyak byte
Xcali

1

Pip , 19 byte

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

Mengambil string sebagai argumen baris perintah. Cobalah online!

Penjelasan

(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

Faktor , 45

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

Ini kutipan (lambda), calldengan dua string di stack, meninggalkan string baru di stack.

Sebagai sebuah kata:

: 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

Larutan:

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

Cobalah online!

Contoh:

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

Penjelasan:

Evaluasi dilakukan dari kanan ke kiri:

`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); Juga, saya tidak sepenuhnya yakin apakah mengganti &&dengan &mungkin juga dimungkinkan dalam PHP, menguranginya dengan byte lain menjadi 108 .
Kevin Cruijssen

0

JavaScript (ES6), 89 byte

Javascript dan kutukan dari nama fungsi yang panjang ...

Menggunakan currying dan fakta yang charCodeAtkembali NaNketika dipanggil dengan posisi yang tidak valid. Mungkin ada trailing nulls di output.

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

Uji

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.