Phép nhân chuỗi phần tử


28

Lấy cảm hứng từ thử thách này (cảm ơn @cairdcoinheringaahing cho tiêu đề!), Nhiệm vụ của bạn là lấy hai chuỗi ASCII có thể in và nhân chúng thành phần tử thông minh với các quy tắc sau.

Làm thế nào nó hoạt động?

Đưa ra hai chuỗi (ví dụ splitisbn) trước tiên bạn sẽ cắt ngắn chuỗi dài hơn sao cho chúng có độ dài bằng nhau và sau đó xác định mã ASCII của chúng :

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

Bước tiếp theo sẽ là ánh xạ chúng đến phạm vi [0..94]bằng cách trừ 32từng mã:

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

Bây giờ bạn sẽ nhân chúng theo modulo phần tử khôn ngoan 95(để ở trong phạm vi có thể in):

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

Thêm 32để quay lại phạm vi [32..126]:

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

Và bước cuối cùng là ánh xạ chúng trở lại các ký tự ASCII:

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

Quy tắc

  • Bạn sẽ viết một chương trình / hàm thực hiện các bước được mô tả trên hai chuỗi và in hoặc trả về chuỗi kết quả
  • Định dạng đầu vào rất linh hoạt: bạn có thể lấy hai chuỗi, một chuỗi các chuỗi, danh sách các chuỗi, v.v.
  • Đầu vào có thể bao gồm một hoặc hai chuỗi trống
  • Đầu vào sẽ là các ký tự trong phạm vi có thể in ([32..126] )
  • Đầu ra được in ra bàn điều khiển hoặc bạn trả về một chuỗi
  • Đầu ra được phép có khoảng trắng ở cuối

Các trường hợp thử nghiệm

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

Lưu ý : Các trích dẫn chỉ dành cho khả năng đọc, trong trường hợp thử nghiệm thứ 6 tôi đã sử dụng 'thay vì ".


Bạn có được phép có dấu cách ở đầu ra không?
Erik the Outgolfer 21/07/17

@EriktheOutgolfer Có. Xin lỗi, tôi đã thêm rằng sau khi đăng nó.
ბიმო

Chúng ta có thể lấy một mảng các chuỗi của chuỗi không? abc, def -> [['a', 'b', 'c'], ['d', 'e', 'f']]
hoàn toàn là

@totallyhuman Tôi sẽ không nói như vậy. Mặc dù, nếu trong ngôn ngữ của bạn là các chuỗi ký tự và ký tự có cùng loại với chuỗi, thì tôi đoán nó sẽ hợp lệ.
ბიმო

Chúng ta có được phép lấy đầu vào làm danh sách các chuỗi không?
Zacharý

Câu trả lời:


9

MATL , 12 byte

c32-p95\32+c

Hãy thử trực tuyến!

Giải trình

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
Cách thông minh để quản lý sự khác biệt chiều dài chuỗi.
Sanchise

6

Thạch , 15 12 byte

z⁶O_32P€‘ịØṖ

Hãy thử trực tuyến!

-3 cảm ơn Jonathan Allan .


Lén lút lạm dụng khoảng trắng dấu. ;)
Dennis

@Dennis Vâng, đó là trong các quy tắc, tại sao không lạm dụng nó?
Erik the Outgolfer 21/07/17

Tôi tin rằng bạn có thể tiết kiệm 3 byte bằng cách sử dụng nguyên tử niladic cho các ký tự có thể in được ØṖ, với z⁶O_32P€‘ịØṖ- bạn nên kiểm tra kỹ nhất xem số học có hoạt động hay không.
Jonathan Allan

@Jonathan Allan Tất nhiên rồi.
Erik the Outgolfer 21/07/17

5

Python 3 , 80 74 71 byte

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

Cảm ơn @shooqie vì đã chơi golf 3 byte!

Hãy thử trực tuyến!


1
71 nếu bạn xem (s, t)như một 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 nhờ đề xuất của Dennis về đề xuất của shooqie. -2 byte nhờ đề xuất của Zacharý.

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

Hãy thử trực tuyến!


2
Một mẹo tương tự đã được đề xuất cho câu trả lời của tôi:lambda*t:''.join(chr(((ord(i)-32)*(ord(j)-32))%95+32)for i,j in zip(*t))
Dennis

2
Và cũng chính là điều mà tôi đã gợi ý rất nhiều: ((ord(i)-32)*(ord(j)-32))%95+32=> (ord(i)-32)*(ord(j)-32)%95+32...
Zacharý

o_o đánh Dennis. +1
Zacharý

1
Eh, không thực sự, tôi chỉ thay đổi để hiểu danh sách thay vì sử dụng map. Tôi chỉ hơi muộn.
hoàn toàn là

5

Haskell , 60 57 byte

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

Hãy thử trực tuyến!

Dòng đầu tiên là một hàm ẩn danh có hai đối số.

Đây là một triển khai thẳng của thuật toán: zipWithlấy cả hai chuỗi và áp dụng một hàm đã cho cho các cặp ký tự. Nó xử lý cắt ngắn và cũng hoạt động cho các chuỗi trống. fromEnumtoEnumlà các lựa chọn thay thế ordchrđể chuyển đổi giữa các ký tự và các giá trị ASCII của chúng mà không cần nhập dài.

Chỉnh sửa: -3 byte nhờ Bruce Forte.


Bạn có thể lưu 3byte bằng cách rút ra -32và lưu các dấu ngoặc đơn đó, xem tại đây .
ბიმო

5

C ++, 331 291 282 270 268 byte, Phiên bản 2 = 178 176 150 148 byte

Phiên bản gốc :

#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 nhờ Bruce Forte
-39 byte nhờ Zacharý

Phiên bản 2, lấy cảm hứng từ câu trả lời của người khác

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

Nếu phiên bản đầu tiên sử dụng lambda, thì đó là vì tôi muốn thử nghiệm chức năng C ++ 11 std :: async mà tôi mới học trước đây, vì vậy tôi đã giữ nó mà không có lý do ...

Phiên bản dễ đọc hơn:

#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
Chào mừng đến với PPCG!
Martin Ender

Chào mừng đến với trang web! Cảm ơn câu trả lời của bạn, tôi đánh giá cao nó. Tôi không có kinh nghiệm chơi golf với C ++, nhưng ở đây bạn sẽ tìm thấy một số mẹo. Tận hưởng thời gian của bạn ở đây!
ბიმო

Ngoài ra tôi khá chắc chắn rằng bạn chỉ có thể gửi một chức năng, như thế này .
ბიმო

Bạn không thể xóa các khoảng trắng ở đây: #include <string>=> #include<string>#include <algorithm>=> #include<algorithm>?
Zacharý

Ngoài ra, bạn sẽ có thể tạo một macro tương đương stringvà sử dụng nó cho phù hợp.
Zacharý

3

Thuốc nhuộm APL, 36 34 33 25 24 byte

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

Dùng thử trực tuyến (TryAPL)!

Hãy thử trực tuyến (TIO)!

Đầu vào là một danh sách các chuỗi và có khoảng trắng ở cuối.

Đây là cách nó hoạt động:

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

Tôi không có giao diện tryapl.org, vì vậy đây là TIO cho những ai muốn dùng thử.
ბიმო

Ở đó, tôi đặt cả hai trong đó.
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));}

Hãy thử trực tuyến!

-4 byte nhờ @ Zacharý

-1 byte bằng cách di chuyển gia số

Sử dụng lambda và lạm dụng thực tế là các nhân vật về cơ bản là ints.


Bạn có thể sử dụng (l[i]-32)*(n[i]-32)%95+32?
Zacharý

Tại sao có, tôi có thể. Cảm ơn!
jkelm

1
Bạn cần phải đủ điều kiện Consolevà bạn có thể sử dụng currying để lưu một byte. Biên dịch thành một lượt Action<string, Action<string>>thích l=>n=>và gọi như thế("word")("string")
TheLethalCoder

2

Toán học, 114 byte

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


đầu vào

["công khai", "thu phí"]


Có cách nào để thử trực tuyến không?
ბიმო

tất nhiên, hãy truy cập sandbox.open.wolframcloud.com/app/objects dán mã, dán đầu vào ở cuối, nhấn shift + enter
J42161217

"8 ký tự" là gì?
J42161217

Xin lỗi vì sự nhầm lẫn! Thông điệp "Cảm ơn!" sẽ quá ngắn để đăng bài như thế này, nó cần thêm 8 ký tự nữa.
ბიმო

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

2

Xếp chồng lên nhau , 52 byte

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

Hãy thử trực tuyến!

Hàm lấy hai đối số từ ngăn xếp.

Giải trình

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

Hãy xem phần đầu tiên, giả sử hai mục hàng đầu là 'split''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'))

Phần này thực hiện cắt xén.

Sau đó:

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

Sau đó, phần cuối cùng:

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

chức năng ẩn danh; lấy đầu vào là hai chuỗi; đối số thứ ba chỉ để đảm bảo đây là hàm một dòng và lưu một số byte.

Liên kết TIO bên dưới trả về một mảng với các mục được đặt tên với đầu vào đầu tiên.

Hãy thử tất cả các trường hợp thử nghiệm!




2

05AB1E , 16 15 byte

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

Hãy thử trực tuyến!

-1 cho Emigna chỉ ra đẩy 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

là một cái khác.


tiết kiệm một byte. Quá tệ về đầu vào chuỗi trống. Nếu không øsẽ tiết kiệm thêm một vài.
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));}

Giải trình:

Hãy thử nó ở đây.

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

Tôi chắc chắn có rất nhiều việc phải chơi golf nhưng tôi không có thời gian ngay bây giờ.

Hãy thử trực tuyến!

Phiên bản đầy đủ / định dạng:

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

Tôi nghĩ rằng (((c-32)*(t.Substring(0,l)[i]-32))%95)+32)có thể ((c-32)*(t.Substring(0,l)[i]-32)%95+32)(có thể đã làm hỏng các parens ở đó ... nó trông giống như là không thể!)
Zacharý



1

Python 2 , 95 73 byte

  • Cảm ơn @ Zacharý vì 4 byte: đã xóa dấu ngoặc không mong muốn
lambda x,y:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(x,y))

Hãy thử trực tuyến!


3
Trời đất ơi ... học cách sử dụng thứ tự hoạt động! (((ord(x[i])-32)*(ord(y[i])-32))%95)+32=>(ord(x[i])-32)*(ord(y[i])-32)%95+32
Zacharý

1

Charcoal, 30 bytes

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

Try it online! Link is to verbose version of code. I actually wrote the calcualation as (32 - ord(q)) * (32 - ord(h)) because it avoids consecutive numeric literals but I guess I could have just written (ord(q) - ord(" ")) * (ord(h) - ord(" ")) instead.


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

Try it online!

Explanation:

@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
I think you're not correctly truncating the result to the length of the smaller string (see here).
Dada

You're right. Fixed it at a cost of many bytes
Xcali

1

Pip, 19 bytes

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

Takes the strings as command-line arguments. Try it online!

Explanation

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

It's a quotation (lambda), call it with two strings on the stack, leaves the new string on the stack.

As a word:

: 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

Solution:

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

Try it online!

Example:

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

Explanation:

Evaluation is performed right-to-left:

`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); Also, I'm not entirely sure if replacing && with & might also be possible in PHP, reducing it by another byte to 108.
Kevin Cruijssen

0

JavaScript (ES6), 89 bytes

Javascript and the curse of the lengthy function names ...

Using currying and the fact that charCodeAt returns NaN when called with an invalid position. There can be trailing nulls in the 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))))

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.