Viết tắt một mảng


26

Mục tiêu:

Đưa ra một chuỗi các chuỗi, tạo các phiên bản rút gọn của mỗi chuỗi.

Đặc điểm kỹ thuật:

Đối với thử thách này, viết tắt là N ký tự đầu tiên của chuỗi. Đối với chuỗi abc: a, ababclà tất cả các chữ viết tắt hợp lệ, trong khi bc, và ackhông.

Đưa ra một chuỗi các chuỗi, chúng tôi muốn tìm tập hợp các từ viết tắt ngắn nhất, ví dụ như đưa ra đầu vào và bất kỳ chữ viết tắt nào, bạn có thể xác định mục nào của đầu vào mà từ viết tắt đang đề cập đến.

Thí dụ:

Đầu vào: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]

Chúng tôi làm việc theo cách của chúng tôi thông qua các chuỗi bắt đầu với chuỗi đầu tiên.

  • Thứ hai chỉ là chuỗi mục với một M, vì vậy viết tắt ngắn nhất có thể là M.

  • Thứ ba bắt đầu với T, nhưng thứ năm cũng vậy. Điều này có nghĩa là chúng tôi thử chuỗi TU. Vì không có chuỗi nào khác bắt đầu với điều đó, chúng tôi sử dụng TU.

  • Thứ tư là W, thứ năm là Th, và thứ sáu là F.

Thêm ví dụ:

Input: "one,two,three,four,five,six,seven"
Output: "o,tw,th,fo,fi,si,se"

Input: "red,orange,yellow,green,blue,purple"
Output: "r,o,y,g,b,p"

Input: "a,ab,abc"
Output: Not valid! No abbreviation for `a` that doesn't apply to the other items.

Ghi chú:

  • Bạn thực hiện đầu vào và đầu ra theo bất kỳ cách hợp lý.

  • Bạn có thể giả định rằng đầu vào sẽ luôn là một chuỗi các chuỗi hợp lệ.

  • Bạn có thể cho rằng sẽ luôn có một giải pháp, không giống như trong trường hợp thử nghiệm cuối cùng.

  • Chuỗi sẽ chỉ bao gồm ASCII có thể in (hoặc các ký tự có thể in trong mã hóa của bạn)

  • Đây là mã golf, vì vậy ít byte nhất giành chiến thắng!


Liên quan: 1 , 2 , 3
Sp3000

5
Bản sao có thể có của Golf Down Tên người dùng
PPCG

2
Tôi không nghĩ đó là bản sao của bất kỳ thứ nào trong số đó (mặc dù chúng đều khá giống nhau). Trên thực tế, tôi nghĩ rằng đây có lẽ là thử thách tốt nhất trong số bốn người; những cái khác đều có các biến thể khiến chúng phức tạp không cần thiết.

2
Là trường hợp quan trọng? Cụ thể, ví dụ ngày trong tuần của bạn sử dụng vốn Ucho thứ ba, nhưng chữ thường hcho thứ năm.
Brian J

1
@Mego Đừng chỉnh sửa bài đăng của tôi trừ khi người điều hành sẽ đánh dấu bài đó không phải là bản sao
Julian Lachniet

Câu trả lời:


10

Võng mạc , 29 byte

!ms`^(.+?)(?!.+^\1)(?<!^\1.+)

Đầu vào và đầu ra là danh sách các chuỗi được phân tách bằng dòng.

Hãy thử trực tuyến! (Bộ thử nghiệm có phân tách dấu phẩy để thuận tiện.)

Giải trình

Điều này chỉ đơn giản phù hợp với tất cả các tiền tố với một biểu thức chính và in chúng ( !). mslà các công cụ sửa đổi regex thông thường để thực hiện ^bắt đầu dòng .khớp và nguồn cấp dữ liệu khớp.

^(.+?)      # Match the shortest possible prefix of a line and capture
            # it in group 1.
(?!.+^\1)   # Make sure that this prefix does not show up in a line after
            # the current one.
(?<!^\1.+)  # Make sure that this prefix does not show up in a line before
            # the current one.


8

JavaScript (ES6), 81 78 74 70 byte

Đưa đầu vào như một mảng của chuỗi.

a=>a.map(s=>[...s].reduce((y,c)=>a.some(x=>x!=s&!x.indexOf(y))?y+c:y))

Định dạng và nhận xét

a =>                          // given an array of strings 'a'
  a.map(s =>                  // for each string 's' in 'a':
    [...s].reduce((y, c) =>   //   starting with 'y' = first character of 's',
                              //   for each subsequent character 'c' of 's':
      a.some(x =>             //     if we find a string 'x' in 'a' such that:
        x != s &              //       - 'x' is different from 's'
        !x.indexOf(y)         //       - and 'y' appears at the beginning of 'x'
      ) ?                     //     then:
        y + c                 //       append 'c' to 'y'
      :                       //     else:
        y                     //       keep 'y' unchanged
    )                         //   end of reduce(): returns the correct prefix
  )                           // end of map()

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


1
70 cũng vậy, nhưng hoàn toàn khác: codegolf.stackexchange.com/a/113270/32091
Qwertiy 18/03/17

+1 cho reduce.
Neil

6

Thạch , 14 byte

;\w@þ=1Si1⁸ḣð€

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

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

;\w@þ=1Si1⁸ḣð€  Monadic link. Argument: A (string array)

            ð   Collect all links to the left into a chain (arity unknown) and
                begin a dyadic chain.
             €  Map the previous chain over A. The current chain is dyadic and the
                mapped one inherits its arity. Thus, the right will be A for all
                invocations, while the left argument will iterate over A.
                For each string s in A, the following happens.
;\                Cumulative reduce by concatenation; yield all prefixes of s.
  w@þ             Window index swapped table; for each string t in A and each
                  prefix p of s, find the index of the substring t in p.
                  The first index is 1; 0 means not found.
     =1           Compare the indices with 1, returning 1 iff t begins with p.
       S          Sum the Booleans across columns, counting the number of strings
                  in A that begin with a given prefix.
        i1        Find the first index of 1, the shortest prefix that is unique
                  across all strings in A.
          ⁸       Head; truncate s to the computed length.

6

Haskell , 48 byte

[_]#x=""
a#(c:y)=c:[z|d:z<-a,c==d]#y
f=map=<<(#)

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

  • flà hàm chính, lấy danh sách Strings và trả về a String. Định nghĩa của nó là một phím tắt đơn âm cho f a=map (a#) a.
  • a#xnhìn vào chuỗi xvà danh sách avà cố gắng tìm tiền tố ngắn nhất trong số xđó là duy nhất a. Nếu acó một phần tử duy nhất, chỉ cần sử dụng chuỗi trống. Nếu achưa phải là một yếu tố duy nhất, hãy cắt bỏ ký tự đầu tiên x, lọc và cắt các yếu tố abắt đầu với cùng một ký tự, sau đó lặp lại.

4

Toán học, 64 byte

#&@@@StringCases[#,Shortest@x__/;Tr@Boole@StringStartsQ[#,x]<2]&

3

Thạch , 14 12 byte

ḣ€JṙLḶ$ḟ/€Ḣ€

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

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

ḣ€JṙLḶ$ḟ/€Ḣ€  Main link. Argument: A (string array)

  J           Yield the 1-based indices of A, i.e., [1, ..., len(A)].
ḣ€            Head each; for each string s in A, take the first 1, ..., and len(A) 
              characters. This builds the 2D array of prefixes of all strings in A.
    LḶ$       Length-unlength; yield [0, ..., len(A)-1].
   ṙ          Rotate the 2D array 0, ..., and len(A)-1 units to the left.
       ḟ/€    Reduce filterfalse each; for each rotation, remove all prefixes from
              the first set that also occur in later sets.
          Ḣ€  Head each; for each rotation, keep only the shortest unique prefix.

Chỉ cần tự hỏi, tại sao bạn có 2 câu trả lời ở đây? Tôi thích cả hai nhưng tôi chỉ tự hỏi tại sao bạn có hai câu trả lời Jelly ở đây. :)
HyperNeutrino

Nếu tôi có hai cách tiếp cận cạnh tranh tương tự nhưng cách tiếp cận đủ khác nhau, tôi thường đăng chúng trong các câu trả lời riêng biệt.
Dennis

Điểm tốt. Vâng, tôi chỉ đang tự hỏi. :) Đó là một ý kiến ​​hay; Tôi thường không có nhiều hơn một cách tiếp cận: P
HyperNeutrino

2

C ++ 11 (MinGW), 198 byte

#import<list>
#import<iostream>
f(std::list<std::string>l){int i,m;for(auto s:l){for(i=0,m=1;++i<s.length();)for(auto t:l)if(t!=s&&t.substr(0,i)==s.substr(0,i))m=i+1;std::cout<<s.substr(0,m)<<" ";}}

Gọi với:

int main()
{
    f({"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"});
}

Thêm voidđịnh danh trước hàm cũng sẽ làm cho nó biên dịch trên các trình biên dịch khác, do đó thêm 5 byte vào chiều dài.


void f...Đáng lẽ ra , nó không hoạt động nếu không ... + 5 byte, thật không may. Các chức năng, theo như tôi biết, cần các công cụ xác định kiểu trong C ++
Ông Xcoder

Bên cạnh đó, cách tiếp cận nổi bật! Chơi golf trong C / C ++ có thể gây đau đớn
Ông Xcoder

@ Mr.Xcoder Nó cũng biên dịch trên trình biên dịch MinGW mà tôi đang sử dụng. Vì vậy, nó là một phần mở rộng trình biên dịch hoặc hành vi không xác định.
Steadybox 18/03/2017

Tôi nghĩ đó là về phần mở rộng trình biên dịch, trên GCC, nó không hoạt động ...
Ông Xcoder

1
Miễn là có một môi trường mà mã hoạt động, nó hợp lệ
ngầm trong

2

Javascript ES6, 70 ký tự

s=>(s+'#'+s).replace(/(\w+?)(\w*)(?=(\W(?!\1(?!\2))\w+)+$)|#.+/g,"$1")

f=s=>(s+'#'+s).replace(/(\w+?)(\w*)(?=(\W(?!\1(?!\2))\w+)+$)|#.+/g,"$1")

console.log(f("one,two,three,four,five,six,seven")==="o,tw,th,fo,fi,si,se")
console.log(f("red,orange,yellow,green,blue,purple")==="r,o,y,g,b,p")
console.log(f("one,two,three,four,five,six,seven".split`,`)==="o,tw,th,fo,fi,si,se")
console.log(f("red,orange,yellow,green,blue,purple".split`,`)==="r,o,y,g,b,p")


2

PHP, 131 120 119 118 byte

Cảm ơn @ Jörg cho preg_grep.

for(;a&$s=$argv[++$k];$i=+$t=!print"$t
")for(;a&$s[$i]&&1<count(preg_grep("(^".preg_quote($t.=$s[$i++]).")",$argv)););

lấy đầu vào từ các đối số dòng lệnh; in kết quả mỗi dòng một.
Chạy với -nrhoặc thử trực tuyến .

  • có thể thất bại nếu đầu vào chứa bất cứ thứ gì bắt đầu bằng -.
    +15 byte để sửa: thay thế thứ hai $argvbằngarray_slice($argv,1) .
  • đưa ra các cảnh báo trong PHP 7.1; thay thế a&bằng""< (+1 byte) để sửa chữa.
  • -12 byte nếu đầu vào không chứa ký tự đặc biệt regex:
    Chèn &($t.=$c)trước &&và thay thế ". preg_quote($t.=$c)."bằng $t.

phá vỡ

for(;a&$s=$argv[++$k];      # loop $s through arguments
    $i=+$t=!                # 3. reset $i and $t to empty
    print"$t\n")            # 2. print abbreviation
    for(;a&($c=$s[$i++])    # 1. loop $c through characters
        &&1<count(              # 3. if count==1, break loop
            preg_grep("(^"      # 2. find matching arguments
                . preg_quote(
                $t.=$c          # 1. append $c to abbreviation
            ).")",$argv)
        );
    );

phiên bản không phải regex, 131 130 byte

for($a=$argv;a&$s=$a[++$k];$i=+$t=!print"$t
")for($n=1;$n&&a&$c=$s[$i++];)for($n=$m=1,$t.=$c;a&$u=$a[$m++];)$n-=0===strpos($u,$t);

Thay thế cái đầu tiên và cái cuối cùng a&bằng""< (+2 byte) để sửa lỗi cho PHP 7.1.

phá vỡ

for($a=$argv;a&$s=$a[++$k];     # loop through arguments
    $i=+$t=!print"$t\n")            # 2. print abbreviation, reset $i and $t to empty
    for($n=1;$n&&a&$c=$s[$i++];)    # 1. loop through characters while $n<>0
        for($n=$m=1,                    # reset $n and $m to 1
            $t.=$c;                     # append current character to prefix
            a&$u=$a[$m++];              # loop through arguments:
        )$n-=0===strpos($u,$t);         # -$n = number of matching strings -1

lưu ý hoàn toàn không thú vị:
strstr($u,$t)==$u0===strpos($u,$t)có cùng độ dài và cùng kết quả.


Sử dụng một ký tự dòng mới thực sự ( 0x0A) thay vì \n, nó sẽ lưu một byte;).
Hố đen

@Blackhole Cảm ơn; Tôi quên mất điều đó lần này.
Tít

1

PHP, 127 byte

hoạt động không với mảng không hợp lệ

<?foreach($a=$_GET as$k=>$v)for($i=0,$c=2,$s="";$c>1;$r[$k]=$s)$c=count(preg_grep("_^".($s.=$v[$i++])._,$a));echo join(",",$r);

PHP, 132 byte

<?foreach($a=$_GET as$v)for($i=0,$s="";a&$v[$i];)if(count(preg_grep("_^".($s.=$v[$i++])._,$a))==1){$r[]=$s;break;}echo join(",",$r);

Phiên bản trực tuyến

151 Byte hỗ trợ các ký tự đặc biệt

<?foreach($a=$_GET as$v)for($i=0,$s="";a&$v[$i];)if(count(preg_grep("_^".preg_quote($s=substr($v,0,++$i),_)._,$a))==1){$r[]=$s;break;}echo join(",",$r);

PHP, 140 byte

<?foreach($a=$_GET as$k=>$v)for($i=0;a&$v[$i];)if(count(preg_grep("#^".($s=substr($v,0,++$i))."#",$a))==1){$r[]=$s;break;}echo join(",",$r);

Điều này sẽ thất bại nếu đầu vào chứa các ký tự đặc biệt regex. Tôi dữ liệu có 113 byte thay vì 131 nếu không.
Tít

@Titus Trong trường hợp này, tôi có thể thêm preg_quote10 byte nữa
Jörg Hülsermann 18/03/2017

Nó cũng sẽ thất bại nếu đầu vào chứa 0. Nhưng bạn có thể lưu một byte với $i=+$s="".
Tít

và bạn có thể xóa count()-count()nội dung: đầu vào được đảm bảo là hợp lệ (-21 byte). Tôi nghĩ rằng tôi có thể sửa chữa và đánh golf này xuống tới 120 byte. $_GETlà một ý tưởng tốt!
Tít

@Titus Tôi chưa nhận ra rằng chỉ các mảng hợp lệ mới được phép. Vâng, nó sẽ thất bại nếu chuỗi chứa số 0 nhưng điều này đã sinh ra một ý tưởng
Jörg Hülsermann 18/03/17

0

Clojure, 118 byte

#(reduce(partial map(fn[a b](or a b)))(for[i(range 1e2)S[(for[c %](take i c))]](for[s S](if(=((frequencies S)s)1)s))))

Điều này hoạt động trên các tiền tố lên đến chiều dài 1e2nhưng cùng một số byte có thể hỗ trợ tối đa 1e9. ivòng lặp độ dài của tiền tố, Slà chuỗi các chuỗi con có độ dài i. Việc cuối cùng forthay thế các chuỗi con nilxảy ra thường xuyên hơn một lần. Việc giảm giữ giá trị không đầu tiên cho mỗi chuỗi, quá tệor không phải là một hàm nên tôi phải gói nó.

Điều này thực sự trả về danh sách các danh sách các nhân vật như thế nào ((\M) (\T \u) (\W) (\T \h) (\F)), nhưng tôi đoán nó có thể chấp nhận được. Clojure khá dài dòng với các chuỗi, và subssẽ ném StringIndexOutOfBoundsExceptionkhông giốngtake .

Ví dụ đầy đủ:

(def f #(reduce(partial map(fn[a b](or a b)))(for[i(range 1e2)S[(for[c %](take i c))]](for[s S](if(=((frequencies S)s)1)s)))))

(f ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"])
(f (re-seq #"[^,]+" "one,two,three,four,five,six,seven"))
(f (re-seq #"[^,]+" "red,orange,yellow,green,blue,purple"))

0

SQL (PostgreSQL 9.4 hương vị), 219 byte

Bây giờ cho câu trả lời dài nhất :) Tôi không nghĩ rằng điều này thậm chí có thể đánh bại Java. Tôi sẽ cố gắng cạo thêm một vài thứ này. Hy vọng thoát khỏi một trong những truy vấn lồng nhau, nhưng không thích cơ hội của tôi.
Điều này giả định rằng có một bảng chứa các chuỗi được xử lý. Vì đây là SQL nên thứ tự trả về không được đảm bảo giống với thứ tự bảng và trong trường hợp này là không thể. Nếu đây là một vấn đề tôi sẽ xóa.

SELECT R FROM(SELECT*,RANK()OVER(PARTITION BY A ORDER BY C,N)Z FROM(SELECT*,SUM(1)OVER(PARTITION BY R)C FROM(SELECT*FROM A JOIN LATERAL(select left(A,n)R,N FROM generate_series(1,length(A))S(n))L ON 1=1)X)Y)Z WHERE Z=1


Giải thích về Fiddle SQL

  SELECT *
  FROM A 
    JOIN LATERAL(SELECT LEFT(A,n)R,N 
    FROM generate_series(1,length(A))S(n))L ON 1=1

Truy vấn trong cùng sử dụng generate_seriesLATERALnối để tạo các hàng cho chuỗi được chia thành các độ dài tăng dần, do đó, 'một' trở thành 'o', 'on', 'one'. Số lượng nhân vật trong sự trở lại cũng được giữ.

SELECT 
  *,
  SUM(1)OVER(PARTITION BY R)C
FROM ( ... )X

Sau đó, chúng tôi thêm số lượng hồ sơ có kết quả tương tự. Ví dụ: 'f' từ bốn và năm có 2, nhưng 'fo' và 'fi' mỗi cái có một. Câu OVERlệnh trong SQL có thể khá mạnh mẽ. COUNT(*)sẽ là cách thông thường, nhưng SUM(1)cho kết quả tương tự.

SELECT 
  *,
  RANK()OVER(PARTITION BY A ORDER BY C,N)Z
FROM ( ... )Y

Sau đó, chúng tôi xếp hạng kết quả cho mỗi đầu vào dựa trên số lần lặp lại và ký tự ít nhất. ROW_NUMBERsẽ làm việc ở đây là tốt, nhưng là lâu hơn.

SELECT R FROM ( ... )Z WHERE Z=1;

Cuối cùng, chúng tôi chọn số thứ hạng thấp nhất cho mỗi từ.



0

APL (Dyalog) , 27 byte

{⍵↑¨⍨1⍳⍨¨↓+/(↑,⍵)∘.(⊃⍷)⍵}

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

{ một hàm ẩn danh, trong đó đại diện cho đối số ...

∘.( một bảng chức năng trong đó chức năng là

   yếu tố đầu tiên của

   danh sách Boolean "đối số bên trái bắt đầu ở đây trong đối số bên phải?"

) nơi tranh luận đúng

 những tranh luận

( và đối số bên trái là

   một bảng với các hàng bao gồm

  ,/ tiền tố của

  ¨ mỗi

   các đối số

+/ tính tổng (tính có bao nhiêu đối số befin ​​với tiền tố này)

 chia bảng thành danh sách các hàng

⍳⍨¨ trong mỗi cái, tìm vị trí của cái đầu tiên

1 một (tức là tiền tố đầu tiên chỉ đứng đầu một đối số)

↑¨⍨ đối với mỗi vị trí, lấy nhiều ký tự từ phần tử tương ứng của

 tranh luận

} kết thúc chức năng ẩn danh


0

PowerShell, 151 139 byte

$x,$w=@(),$args[0];$w|%{$k=$_;$a='';foreach($l in [char[]]$k){$a+=$l;if($a-notin$x-and!($w|?{$_-ne$k-and$_-like"$a*"})){$x+=$a;break;}}};$x

Quan tâm nếu có một cách tốt hơn để làm điều này. Phải sử dụng foreach(trên a |%) để có thể thực hiện một breakvòng lặp lồng mà không dán nhãn.

Chỉnh sửa: 2 golf từ admBorkBork


1
Tôi đã không đi qua mã trực tiếp, nhưng chắc chắn bạn có thể sử dụng -notinthay vì -not$x.contains($a)!($w...thay vì -not($w...để lưu một số byte, vâng?
admBorkBork

0

APL, 26 byte

{⍵↑¨⍨1+⌈/+/¨∘.(∧\=∧≢)⍨↓↑⍵}

Giải trình:

  • ↓↑⍵: đệm từng chuỗi trong để khớp với độ dài của chuỗi dài nhất
  • ∘.(...)⍨ : cho mỗi cặp chuỗi có thể, tìm tiền tố được chia sẻ:
    • : bất đẳng thức mảng
    • : và
    • =: đẳng thức
    • ∧\: và quét (chỉ giữ các trận đấu hàng đầu)
  • +/¨: tổng hợp từng vectơ trong bảng, đưa ra độ dài của các tiền tố được chia sẻ
  • ⌈/: tìm giá trị tối đa trong mỗi cột
  • 1+: thêm một, đưa ra số lượng ký tự cần thiết để giữ cho mỗi chuỗi duy nhất
  • ⍵↑¨⍨: lấy nhiều ký tự từ mỗi chuỗi

Kiểm tra:

      {⍵↑¨⍨1+⌈/+/¨∘.(∧\=∧≢)⍨↓↑⍵}'Monday' 'Tuesday' 'Wednesday' 'Thursday' 'Friday'
┌─┬──┬─┬──┬─┐
│M│Tu│W│Th│F│
└─┴──┴─┴──┴─┘
      {⍵↑¨⍨1+⌈/+/¨∘.(∧\=∧≢)⍨↓↑⍵}'one' 'two' 'three' 'four' 'five' 'six' 'seven'
┌─┬──┬──┬──┬──┬──┬──┐
│o│tw│th│fo│fi│si│se│
└─┴──┴──┴──┴──┴──┴──┘
      {⍵↑¨⍨1+⌈/+/¨∘.(∧\=∧≢)⍨↓↑⍵}'red' 'orange' 'yellow' 'green' 'blue' 'purple'
┌─┬─┬─┬─┬─┬─┐
│r│o│y│g│b│p│
└─┴─┴─┴─┴─┴─┘

0

Q, 93 byte

{n:1;{$[any e:(,/)1<{(+/)i like x}each i:z#'x;[z+:1;y:?[e;z#'x;i];.z.s[x;y;z]];y]}[x;n#'x;n]}

Giải quyết đệ quy, lấy chuỗi làm đầu vào, lấy n phần tử đầu tiên của mỗi chuỗi với mỗi lần đệ quy. Nếu bất kỳ yếu tố nào trong số đó không phải là duy nhất, nó sẽ thay thế chúng bằng các yếu tố n + 1 đầu tiên.

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.