배열 약자


26

골:

문자열 배열이 주어지면 각 문자열의 약식 버전을 만듭니다.

사양:

이 문제에서 약어는 문자열의 첫 번째 N 문자입니다. 문자열의 경우 abc: a, ab, 및 abc모든 유효한 약어는, 동안 bc, 그리고 ac수 없습니다.

문자열 배열이 주어지면 입력과 약어가 주어지면 약어가 참조하는 입력 항목을 결정할 수있는 가장 짧은 약어 세트를 찾고 싶습니다.

예:

입력: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]

우리는 첫 번째 문자열부터 시작하여 문자열을 통해 작업합니다.

  • 월요일은을 포함하는 항목 문자열 M이므로 가능한 가장 짧은 약어는 M입니다.

  • 화요일은로 시작 T하지만 목요일도 그렇습니다. 이것은 우리가 문자열을 시도한다는 것을 의미합니다 TU. 다른 문자열로 시작하지 않으므로을 사용 TU합니다.

  • 수요일은 W, 목요일은 Th, 금요일은 F입니다.

더 많은 예 :

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.

노트:

  • 합리적인 방법으로 입력 및 출력합니다.

  • 입력이 항상 유효한 문자열 배열이라고 가정 할 수 있습니다.

  • 마지막 테스트 사례와 달리 항상 솔루션이 있다고 가정 할 수 있습니다.

  • 문자열은 인쇄 가능한 ASCII (또는 인코딩의 인쇄 가능한 문자)로만 구성됩니다.

  • 이것은 코드 골프이므로 가장 적은 바이트가 이깁니다!


관련 : 1 , 2 , 3
Sp3000


2
나는 그것들이 그것들의 복제본이라고 생각하지 않습니다 (모두 상당히 비슷하지만). 실제로, 나는 이것이 아마도 네 가지 중에서 가장 어려운 과제라고 생각합니다. 다른 것들은 모두 불필요하게 복잡하게 만드는 변형을 가지고 있습니다.

2
대소 문자가 중요합니까? 특히 요일 예에서는 U화요일에 대문자 를 사용 하지만 h목요일 에는 소문자 를 사용합니다.
Brian J

1
@Mego 중재자가 중복되지 않은 것으로 표시하지 않는 한 내 게시물을 편집하지 마십시오
Julian Lachniet

답변:


10

망막 , 29 바이트

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

입력과 출력은 줄 바꿈으로 구분 된 문자열 목록입니다.

온라인으로 사용해보십시오! 편의상 쉼표로 구분 된 테스트 스위트.

설명

이것은 모든 접두사를 단일 정규식과 일치시키고 인쇄합니다 ( !). m그리고 s일반적인 정규식 수정을 할 수 있습니다 ^매치 라인의 시작과 .일치 줄 바꿈을.

^(.+?)      # 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

자바 스크립트 (ES6), 81 78 74 70 바이트

입력을 문자열 배열로 취합니다.

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

형식화 및 의견

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

테스트 사례


1
70도 있지만 절대적으로 다른 것 : codegolf.stackexchange.com/a/113270/32091
Qwertiy

일에 대한 reduce.
Neil

6

젤리 , 14 바이트

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

온라인으로 사용해보십시오!

작동 원리

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

하스켈 , 48 바이트

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

온라인으로 사용해보십시오!

  • f의 목록을 String가져와 a를 반환하는 주요 함수 String입니다. 정의는에 대한 모나드 단축키입니다 f a=map (a#) a.
  • a#x캐릭터의 외모 x와 목록 a및 시도는 가장 짧은 접두사를 찾기 위해 x그에서 유일하다 a. a단일 요소가있는 경우 빈 문자열을 사용하십시오. a아직 단일 요소가 아닌 경우 의 첫 번째 문자를 잘라 내고 동일한 문자 xa시작 하는 요소를 필터링하고 잘라 내고 재귀하십시오.

4

Mathematica, 64 바이트

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

3

젤리 , 14 12 바이트

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

온라인으로 사용해보십시오!

작동 원리

ḣ€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.

궁금한 점이 있는데 여기에 2 개의 답변이있는 이유는 무엇입니까? 나는 둘 다 좋아하지만 왜 여기에 두 개의 젤리 답변이 있는지 궁금합니다. :)
HyperNeutrino

비슷한 경쟁 접근 방식이 있지만 충분히 다른 접근 방식이있는 경우 대개 별도의 답변으로 게시합니다.
Dennis

좋은 지적. 네, 궁금 했어요 :) 좋은 생각이야; 나는 보통 하나 이상의 접근 방식을 가지고 있지 않다 : P
HyperNeutrino

2

C ++ 11 (MinGW), 198 바이트

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

전화 :

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

void함수 앞에 식별자를 추가하면 다른 컴파일러에서도 컴파일되므로 길이에 5 바이트가 추가됩니다.


그것은해야한다 void f...는 달리 작업을 does't ... + 5 바이트를, 불행히도. 내가 아는 한 함수는 C ++에서 타입 지정자가 필요하다
Mr. Xcoder

그 외에도 뛰어난 접근 방식! C / C ++에서의 골프는 고통 스러울 수 있습니다
Mr. Xcoder

@ Mr.Xcoder 그래도 사용중인 MinGW 컴파일러에서 컴파일합니다. 따라서 컴파일러 확장 또는 정의되지 않은 동작입니다.
Steadybox

나는 그것이 컴파일러 확장에 관한 것이라고 생각합니다. GCC에서는 작동하지 않습니다 ...
Mr. Xcoder

1
코드가 작동하는 환경이있는 한 유효합니다
undergroundmonorail

2

자바 스크립트 ES6, 70 자

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, 131120119118 바이트

@ Jörg에게 감사합니다 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)););

명령 행 인수에서 입력을받습니다. 결과를 한 줄씩 인쇄합니다.
로 실행-nr온라인으로 하거나 사용해보십시오 .

  • 입력에로 시작하는 것이 있으면 실패 할 수 있습니다 -.
    +15 바이트 수정 : 초를 $argv로 바꿉니다 array_slice($argv,1).
  • PHP 7.1에서 경고를 생성합니다. 바꾸다a&""<수정에 (1 바이트).
  • -12 바이트 입력이 더 정규식 특수의 문자가없는 경우 :
    삽입 &($t.=$c)하기 전에 &&및 교체 ". preg_quote($t.=$c)."와 함께$t .

고장

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

비정규 버전, 131130 바이트

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

첫 번째와 마지막을 교체 a&""<PHP 7.1을 수정 을 (+2 바이트)로 바꾸십시오.

고장

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

완전히 메모를 재미 :
strstr($u,$t)==$u0===strpos($u,$t)같은 길이와 같은 결과가 있습니다.


0x0A대신 실제 줄 바꿈 문자 ( )를 사용 \n하면 1 바이트가 절약됩니다.
Blackhole

@ 블랙홀 감사합니다; 이번에는 잊어 버렸습니다.
Titus

1

PHP, 127 바이트

유효하지 않은 배열과 작동하지 않습니다

<?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 바이트

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

온라인 버전

151 바이트는 특수 문자를 지원합니다

<?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 바이트

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

입력에 정규식 특수 문자가 포함되어 있으면 실패합니다. 그렇지 않으면 131 대신 113 바이트가 있습니다.
Titus

@Titus이 경우 preg_quote10 바이트 만 더 만들 수 있습니다
Jörg Hülsermann

입력에가 포함되어 있으면 실패합니다 0. 그러나로 1 바이트를 절약 할 수 있습니다 $i=+$s="".
Titus

그리고 당신은 count()-count()물건을 제거 할 수 있습니다 : 입력이 유효한 것으로 보장됩니다 (-21 바이트). 나는 이것을 120 바이트로 수정하고 골프를 칠 수 있다고 생각합니다. $_GET좋은 생각이었습니다!
Titus

@Titus 나는 유효한 배열 만이 허용된다는 것을 깨닫지 못했다. 예, 문자열에 0이 포함되어 있으면 실패하지만 아이디어가 탄생했습니다.
Jörg Hülsermann

0

클로저, 118 바이트

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

이것은 접두사에서 최대 길이까지 작동 1e2하지만 동일한 바이트 수는 최대까지 지원할 수 있습니다 1e9. i접두사 길이를 반복하고 length의 S하위 문자열 시퀀스입니다 i. 마지막 for은 하위 문자열을nil 두 번 이상 자주 나타나는 . 감소는 각 문자열에 대해 첫 번째가 아닌 0 값을 유지합니다. 너무 나쁘기 or때문에 랩핑해야했습니다.

이것은 실제로와 같은 문자 목록을 반환 ((\M) (\T \u) (\W) (\T \h) (\F))하지만 허용되는 것 같습니다. Clojure는 문자열이 매우 장황하며 달리 subs던질 것입니다.StringIndexOutOfBoundsExceptiontake 입니다.

전체 예 :

(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 버전), 219 바이트

가장 긴 대답 :) 나는 이것이 심지어 Java를 이길 수 있다고 생각하지 않습니다. 나는 이것을 조금 더 면도하려고 노력할 것이다. 중첩 된 쿼리 중 하나를 제거하기를 희망하지만 내 기회는 마음에 들지 않습니다.
작업 할 문자열이 포함 된 테이블이 있다고 가정합니다. 이것이 SQL이므로 리턴 순서는 테이블 순서와 같을 수 있으며이 경우에는 가능성이 없습니다. 이것이 문제라면 삭제하겠습니다.

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

SQL 피들
설명

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

가장 안쪽 쿼리는 문자열 길이가 늘어난 행을 만들기 위해 사용 generate_series하고 LATERAL조인하므로 '1'은 'o', 'on', 'one'이됩니다. 반환되는 문자 수도 유지됩니다.

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

그런 다음 동일한 결과를 가진 레코드 수를 추가합니다. 예를 들어 4와 5의 'f'에는 2가 있지만 'fo'와 'fi'에는 각각 1이 있습니다. OVERSQL 의 문장은 매우 강력 할 수 있습니다. COUNT(*)일반적인 방법이지만 SUM(1)동일한 결과를 제공합니다.

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

그런 다음 최소 반복 및 문자를 기준으로 각 입력에 대한 결과 순위를 지정합니다. ROW_NUMBER여기서도 작동하지만 더 길다.

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

마지막으로 각 단어에 대해 가장 낮은 순위 번호를 선택합니다.



0

APL (Dyalog) , 27 바이트

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

온라인으로 사용해보십시오!

{ 익명 함수. 여기서 ⍵는 인수를 나타냅니다.

∘.( 함수가있는 함수 테이블

   의 첫 번째 요소

   부울 목록 "왼쪽 인수는 오른쪽 인수에서 시작합니까?"

) 올바른 주장이있는 곳

 논쟁

( 왼쪽 주장은

   행으로 구성된 테이블

  ,/ 접두사

  ¨ 각각

   논쟁

+/ 합계 (이 접두사로 정의 된 인수 수 계산)

 테이블을 행 목록으로 분할

⍳⍨¨ 각각에서 첫 번째 위치를 찾으십시오.

1 1 개

↑¨⍨ 각 위치에 대해 해당 요소에서 많은 문자를 가져옵니다.

 논쟁 거리

} 익명 함수의 끝


0

PowerShell을 151 139 바이트

$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

더 좋은 방법이 있다면 관심이 있습니다. 용도했다 foreach(이상을 |%을 수행 할 수 있도록)break중첩 된 루프에서 레이블을 지정하지 않고을 했습니다.

편집 : AdmBorkBork에서 2 골프


1
내가 직접 코드를 통해 간 적이 없다, 그러나 확실하게 당신이 사용할 수있는 -notin대신 -not$x.contains($a)하고 !($w...대신 -not($w...네, 몇 바이트를 저장?
AdmBorkBork

0

APL, 26 바이트

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

설명:

  • ↓↑⍵: 가장 긴 줄의 길이와 일치하도록 각 줄 을 채 웁니다.
  • ∘.(... )⍨: 가능한 각 문자열 쌍에 대해 공유 접두사를 찾으십시오.
    • : 배열 불평등
    • : 및
    • =: 항목 별 평등
    • ∧\: 및 스캔 (리딩 경기 만 유지)
  • +/¨: 테이블의 각 벡터를 합하여 공유 접두사의 길이를 제공합니다.
  • ⌈/: 각 열에서 최대 값 찾기
  • 1+: 하나를 추가하여 각 문자열을 고유하게 유지하는 데 필요한 문자 수를 제공하십시오.
  • ⍵↑¨⍨: 각 문자열에서 많은 문자를 가져옵니다.

테스트:

      {⍵↑¨⍨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 바이트

{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]}

재귀 적으로 해결하고, 문자열을 입력으로 사용하고, 모든 재귀마다 각 문자열의 처음 n 개 요소를 가져옵니다. 이러한 요소 중 하나라도 고유하지 않으면 첫 번째 n + 1 요소로 대체됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.