독창적이다


93

주어진 문자열 의 비용 을 결정하는 함수 또는 프로그램을 작성하십시오 .

  • 각 문자의 비용은 문자열에서이 지점까지 문자가 발생한 횟수와 같습니다.
  • 문자열 비용은 문자 비용의 합입니다.

의 입력에 abaacab대해 비용은 다음과 같이 계산됩니다.

a b a a c a b
1   2 3   4    occurrence of a
  1         2  occurrence of b
        1      occurrence of c
1+1+2+3+1+4+2 = 14

따라서 문자열 비용 abaacab은 14입니다.

규칙

  • 제출 점수는 위에서 정의한 코드 비용입니다 . 즉, 제출은 자체 소스 코드에서 실행되며 점수가 낮을 수록 좋습니다.
  • 제출물은 인쇄 가능한 ASCII 문자와 제출에 사용 된 모든 문자를 포함하는 문자열에서 작동해야합니다.
  • 문자 즉, 대소 문자를 구분 a하고 A서로 다른 문자입니다.

테스트 케이스

input -> output
"abaacab" -> 14
"Programming Puzzles & Code Golf" -> 47
"" -> 0
"       " -> 28
"abcdefg" -> 7
"aA" -> 2

리더 보드


2
-nPerl 과 같은 프로그램 플래그는 어떻게 점수에 반영됩니까? 표준 perl -e과 편집 사이의 편집 거리가 1이기 때문에 전통적으로 1 바이트로 계산 perl -ne되지만이 문제의 경우 n복제를 계산하기 위해 카운트합니까?
Value Ink

2
@ValueInk 예, 계산 n은 가장 공정한 옵션 이라고 생각합니다 .
Laikoni 2016 년

1
이 문제에 대한 해결책이 있었으면 좋겠다.
Peter1807

10
제출 점수
luizfzs

1
캐릭터의 비용은로 정의됩니다 how often this character has already occurred in the string. 아마도 how many times the character has occurred up to this point첫 사용 비용이 0이 아니라 1이라는 것을 분명히하기 위해 아마도 바뀌었을 것입니다.
undergroundmonorail

답변:


83

MATL , 4 점

&=Rz

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

설명

'ABBA'예를 들어 입력 을 고려하십시오 .

&=   % Implicit input. Matrix of all equality comparisons
     % STACK: [1 0 0 1;
               0 1 1 0;
               0 1 1 0;
               1 0 0 1]
R    % Upper triangular part
     % STACK: [1 0 0 1;
               0 1 1 0;
               0 0 1 0;
               0 0 0 1]
z    % Number of nonzeros. Implicitly display
     % STACK: 6

14
당신은 선형 대수 교수입니까?
Magic Octopus Urn

4
@carusocomputing 실제로 이동 통신 교수. 매트릭스를 사용하는 경향은 Matlab에서 수년간 프로그래밍 한 결과입니다.
Luis Mendo

산뜻한! 그 지역에서 Matlab이 큰가요? 나는 GSM이나 그와 비슷한 것을 본 적이 없다.
Magic Octopus Urn

2
이 훌륭한 솔루션에 대해 귀하를 칭찬하기 위해이 커뮤니티에 가입했습니다!
Wboy

1
@carusocomputing Matlab은 일반적으로 엔지니어링에서 매우 일반적인 도구 / 언어입니다. 선형 대수, 신호 처리 등 수치 계산에 좋습니다. 그리고 해석 된 언어이기 때문에 사용이 매우 쉽습니다.
Luis Mendo

17

파이썬 , 점수 49

lambda S:sum(1+S.count(C)for[C]in	S)/2

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

뒤에 탭이 in있습니다.

점수 분석 :

  • 27 개의 고유 한 문자에 대해 +27
  • 8 개의 이중 문자 : +16 ()Camnou
  • 트리플 캐릭터 1 개당 +6 : S

13
공백 대신 탭을 사용하여 바이트를 저장하십시오.
mbomb007

1
@ mbomb007 방금 같은 아이디어를 가졌습니다 :-)
xnor

1
@ mbomb007 Hah, 그것은 천재적인 속임수입니다 :-)
ETHproductions

14
단지 탭 대 공간 전쟁이 내부 코드를 golfed 것 @ mbomb007
에릭 Outgolfer

2
양식 피드 (Python 구문에서 공백도 허용됨)를 사용하는 것이 좋지만 더 이상 공백을 넣을 필요는 없습니다.
user2357112 2016 년

8

T-SQL, 775 579! 580

declaRe @ char(876),@x int,@v int=0Select @=q+CHAR(9)from z X:seleCT @x=len(@),@=REPLACE(@,LEFT(@,1),''),@v+=(@x-LEN(@))*(@x-LEN(@)+1)/2IF LEN(@)>0GOTO X prINT @v-1

편집 : 몇 가지 변수를 삭제하고 조금 압축했습니다. @22 개 대신 16 개 기호 까지 , 그 자체로 무려 117 점으로 내 점수가 줄어 듭니다!

좋은 컨테스트, 나는 총 캐릭터 수 이외의 것을 위해 최적화 해야하는 요구 사항을 좋아합니다.

입력 VARCHAR 필드를 통해입니다 Q 기존의 테이블에서 Z , 우리의 IO 규칙 당 . 이 입력 테이블을 포함하는 데이터베이스는 대소 문자 구분 데이터 정렬 로 설정되어야합니다 .

형식화 :

declaRe @ char(876), @x int, @v int=0
Select @=q+CHAR(9)from z
X:
    seleCT @x=len(@)
          ,@=REPLACE(@,LEFT(@,1),'')
          ,@v+=(@x-LEN(@))*(@x-LEN(@)+1)/2
IF LEN(@)>0 GOTO X
prINT @v-1

SQL 키워드는 대소 문자를 구분하지 않으므로 대소 문자를 혼합하여 중복 문자 수를 최소화했습니다 ( aaAAaaaa 보다 더 나은 점수를 생성합니다 ).

메인 루프는 첫 번째 문자의 모든 인스턴스를 제거하기 전후의 길이를 비교합니다. 이 차이 n * (n + 1) / 2가 누적 합계에 추가됩니다.

SQL LEN()함수는 성가신 후행 공백을 무시하므로 제어 문자를 추가하고 끝에 1을 빼야했습니다.

편집 : 내 점수가 2 포인트 (인용 인용 부호가있는 문제)로 잘못 계산되고 1의 케이스를 변경하여 1이 줄어 들었습니다 R. 완전히 다른 전략을 연구하면서이를 자체 답변으로 게시하겠습니다.


3
처음에 나는 당신의 점수는579! ≈ 8.22 x 10^1349
엔지니어 토스트

8

C (GCC) , 점수 :  113  103 100   96  91

팁에 대한 @ugoren, @CalculatorFeline, @gastropner, @ l4m2 및 @ JS1 덕분입니다.

g(char*s){int y[238]={};while(*s)*y-=--y[*s++];*y/=1;}

배열을 0으로 초기화 한 다음 문자열에있는 문자의 ASCII 값을 해당 배열에 대한 인덱스로 사용하여 문자열에있는 각 문자의 인스턴스 수를 추적합니다.

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


3
제안 : 키워드에 사용되지 않는 변수 이름 (예 : z,, x)을 사용하십시오 c.
CalculatorFeline

@CalculatorFeline char포함 c...

3
또한 127 개의 요소 배열 만 있으면 ( \x7f인쇄 할 수 없음) 설명을 추가하십시오.
CalculatorFeline

1
파티에 z;g(char*s){int y[238]={z=0};while(*s)z+=--y[*s++];z/=~0;}
늦었지만

1
g(char*s){int y[238]={};while(*s)*y+=--y[*s++];*y/=~0;}
l4m2

7

자바 스크립트 (ES6), 81 78 점

@Arnauld 덕분에 3 점 절약

s=>s.replace(d=/./g,z=>q+=d[z]=-~d[z],q=0)&&q

내 원래 점수-81 재귀 솔루션 :

f=([c,...s],d={})=>c?(d[c]=-~d[c])+f(s,d):0



7

레티 나 , 34 점

s(O`.
M&!`^|(?<=(.))\1*
.

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

설명

s(O`.

입력에서 모든 문자를 정렬하여 동일한 문자가 단일 실행으로 그룹화되도록 시작합니다. 는 s(모든 단계에 대한 만일 Singleline 모드 (즉하게 활성화 .일치 줄 바꿈을).

M&!s`^|(?<=(.))\1*

목표는 이 문자의 발생 점수이므로 n 개의 문자를 Tn 문자 ( n 번째 삼각형 숫자) 로 바꾸는 것 입니다. 이를 위해 중복되는 일치 항목을 찾습니다. 특히, 각각의 [1, N은] 우리는 포함하는거야 I-1 경기의 문자를. 겹치는 플래그로 인해 모든 일치 항목을 얻습니다 &. 그것은 우리에게 일치에서 n * (n-1) / 2 = T n-1 = T n -n 문자를 제공합니다. 그러나 일치 단계는 이들을 n에 대한 n 줄 바꿈 인 줄 바꿈 과 결합합니다.성냥. 하나의 문제가 있습니다. 마지막 일치 후에 줄 바꿈이 없으므로 출력의 전체 문자 수가 필요한 것보다 적습니다. 입력의 시작 부분과도 일치시켜이 문제를 해결하여 하나 이상의 다른 일치 항목이있는 경우 하나의 선행 줄 바꿈을 제공합니다.

.

마지막으로 문자열에 몇 개의 문자가 있는지 계산합니다.


6

하스켈, 득점 52 51

f(a:b)=1+sum[1|c<-b,c==a]+f b;f _=0

f와 사이에 탭이 있습니다 _.

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

빈 문자열의 값은 0입니다. 문자열 s의 값입니다. 여기서 a첫 번째 문자이고 b나머지 문자열은 1에 ain을 b더한 횟수 와 b를 사용한 재귀 호출입니다.


5

J , 16 점

1#.,@(*+/\"1)&=

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

설명

1#.,@(*+/\"1)&=
              =  Self-classify: bit matrix of equality between input
                 and its unique elements.
     (      )&   Apply verb in parentheses to it:
       +/\         running sums
          "1       of each row
      *            multiplied with original matrix.
                 This causes the i'th 1 on each row to be replaced by i.
   ,@            Flatten the resulting matrix
1#.              and interpret as a base-1 number, computing its sum.

합계 1#.대신 사용하면 +/@몇 포인트 가 절약되고 모나드 컨텍스트 &대신에 @하나 더 저장하는 데 사용할 수 있습니다 . 반복되는 1비용이 하나 더 들었지만, 그것을 제거 할 수 없었습니다.


"나중에" 1/4
CalculatorFeline

2
@CalculatorFeline 10 시간 후에도 여전히 늦습니다. : P
Zgarb

지금은 세스 퀴 세이 데이로 만들어 보자.
CalculatorFeline

나는 개인적으로 사용 이 형식 , 어쩌면 당신이 그것을 사용하려는 것입니다 코드 섹션의 정확한 바이트 수를 반영하기 위해 TIO의 답변을
코너 오브라이언

5

R , 점수 : 67 83 95 128

Giuseppe의 최고 팁 덕분에 -61

function(x,y=table(utf8ToInt(x)))y%*%{y+1}/2

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

문자열 utf8ToInt은를 사용하여 분할 되고 각 ASCII 값이 계산됩니다 table. 결과는 %*%그 자체 + 1에 대한 행렬 곱셈 을 사용하여 계산 되고 마지막으로 절반입니다.


table대신에 사용 rle; 당신은 제거 할 수 sort(인덱스 당신은 필요가 없습니다뿐만 아니라 [[1]]결과로 strsplit)
주세페

@ 주세페 감사합니다. 나는 심지어 테이블을 생각하지 않았고 곧 통합 될 것입니다.
MickyT

2
난 당신이 대신에 다른 변수 이름을 사용하여 몇 바이트를 저장할 수 있다고 생각 n(이 글은 이후 function두 번)도 변화 (n+1){n+1}
주세페

점수 : 67 . 이것에 약간의 변화가 있으면 점수를 더 줄일 수 있습니다.
주세페

@Giuseppe ... 나는 그것을 다시 읽었어야했다. 으악
MickyT


4

파이스 , 6 점

isaacg 덕분에 1 바이트.

+F/V._

테스트 스위트.

작동 원리

+F/V._
+F/V._QQ  implicit input
  /V      vectorize count: for each element in the first argument,
                           count the number of occurrences of the
                           second argument:
    ._Q       all prefixes of input
       Q      input
+F        fold (reduce) on +, base case 0.

s+0와 동일합니다 +F.
isaacg 2016 년

좋은! 내가 할 수있는 최선은 usaShHGrScQ1 8Z16 세입니다. 설명을 추가 할 수 있습니까?
디지털 외상

1
@DigitalTrauma 설명을 추가했습니다.
Leaky Nun

s/LQ점수는 4이며,이 과제를 해결하는 기능을 사용합니까?
Dave



4

C, 60 바이트, 점수 108 95

g(char*s){int y[256]={},z=0;while(*s)z-=--y[*s++];return z;}

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

일반적으로 사전 및 사후 증가 연산자는 코드 골프에 적합하지만 실제로이 과제를 다치게됩니다!

편집 : 양수를 추가하는 대신 음수를 빼서 전체 점수를 저장했습니다. 세미콜론 for()while()제거하여 교체 했습니다 .



3

C # (.NET Core) , 점수 ∞ (즉, 209)

b=>b.Distinct().Select(z=>{var w=b.Count(p=>p==z);return w*(w+1)/2;}).Sum()

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

점수에는 다음이 포함됩니다.

using System.Linq;

나는 그것이 오랜만 것을 알고,하지만 당신은 변경할 수 return w*(w+1)/2return-~w*w/2(196 득점). 편집 : 당신 은 149 의 점수에 대한 내 Java 8 답변 의 포트를 만들 수 있습니다 : 온라인 사용해보십시오. using System.Linq;b=>{int[]x=new int[256];return\nb.Select(z=>++x[z]).Sum();}
Kevin Cruijssen

1
@KevinCruijssen : 귀하의 솔루션을 111 점으로 b=>{var x=new int[256];return\nb.Sum(z=>++x[z]);}
떨어 뜨 렸습니다

두 번째 공백을 탭으로 변경하면 @raznagul ( * 반년 응답 수신 * ) 109 입니다. ;) 온라인으로 사용해보십시오.
Kevin Cruijssen

1
대화 형 컴파일러가있는 @KevinCruijssen (다른 반년 된 응답 수신) 49, 나는 48 이하로 떨어지지 않을 것이라고 생각합니다. 골프 된 C # 답변이 얻는 방법이 이상할수록 항상 더 읽기 쉽습니다. 온라인으로 사용해보십시오!
누군가

3

젤리 , 5 점

ĠJ€ẎS

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

-2의 Leaky Nun 에게 감사드립니다 (이전 의 답변 )


아아 나는이 질문을 충분히 빨리 알지 못했습니다.
Leaky Nun

@LeakyNun ps 당신은 항상 닌자가 아니에요
아웃 더 페퍼 Erik

정말? 나는 그렇게 생각하지 않습니다.
CalculatorFeline


@LeakyNun 약속대로 ... 그래, 신용이 있습니다 :)
Outgolfer Erik

3

PowerShell, 64 점

$z=@{}
$ARGS|% getE*|%{$u+=($Z.$_+=1)};$U

(점수는 단일 줄 바꿈 개행을 기반으로하며 Windows 표준은 아니지만 PS에서는 작동합니다.)

PS C:\> D:\unique-is-cheap.ps1 (gc D:\unique-is-cheap.ps1 -raw)
64
  • 해시 테이블 @{}
  • 글자를 반복합니다. $args는 매개 변수의 배열입니다.이 경우 입력 문자열은 단일 항목 배열이됩니다. |%항목에 대해 foreach 루프를 수행하고 getE*단축키를 사용 하여 GetEnumerator()문자열 메소드 를 일치시키고 문자열을 문자 스트림으로 변환하기 위해 호출합니다.
  • |%문자를 반복하고 해시 테이블 항목을 늘리고 누적 합계에 추가하십시오. ($x+=1)parens가 있는 양식은 변수를 수정하고 사용할 새 값을 출력합니다.
  • 누계를 출력합니다.

(내가 처음 썼을 때 $c=@{};$t=0;[char[]]"$args"|%{$c[$_]++;$t+=$c[$_]};$t점수는 128 점으로 훨씬 낮아지지 않을 것 같은 느낌이 들었습니다. 64로 반으로 바꾸는 것은 매우 기쁩니다).


1
증분을 엉망으로
61pts


3

Julia 0.6 , 45 바이트, 점수 : 77

MATL 솔루션에서 영감을 얻은 것 :

f(w)=sum(UpperTriangular([z==j for z=w,j=w]))

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

카운트를 사용하는 덜 예쁜 해결책 :

줄리아 0.6 , 점수 : 82

F(w)=sum(l->[l+1]l/2,count(x->x==i,w)for i=Set(w))

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

점수를 알려주고 팁을 주신 Guiseppe에게 감사합니다. 이 의견은로드에 도움이되었습니다.


1
제출 점수는 코드 비용 이며 135로 생각합니다.
Giuseppe

1
Julia를 잘 모르지만 변수 이름을 바꾸고 괄호 세트를 제거 하여 점수를 110 으로 줄일 수 있다고 생각합니다 . 단일 요소 벡터를 반환하는 것은 허용되는 경우에, 당신은 대체 할 수 (x+1)[x+1]추가 점수를 줄일 수 있습니다.
Giuseppe

두 번째 공백을 탭 또는 줄 바꾸기로 변경하여 점수를 저장할 수 있습니다 : 점수 104 . 그리고 @Giuseppe 사용 [x+1]대신 팁 을 98 점으로(x+1) 낮 춥니 다 .
Kevin Cruijssen

3

자바 10 점 : 149 138 137 134 133 130 103 102 101 100

( 바이트 : 72 73 74 75 64 62 61 ) 바이트는 올라가지 만 점수는 내려갑니다. :디

x->{int j=0,q[]=new int[256];for(var    C:x)j+=++q[C];return
j;}

@Nevay 덕분에 -28 점수 (및 -11 바이트) . @ OlivierGrégoire
덕분에 -1 점수 (-2 바이트) . Java 8을 Java 10으로 변환하여 -1 점수 (및 -1 바이트)

설명:

여기에서 시도하십시오.

x->{                     // Method with character-array parameter and integer return-type
  int j=0,               //  Result-integer, starting at 0
      q[]=new int[256];  //  Integer-array with 256 times 0
  for(var   C:x)         //  Loop over the characters of the input array
    j+=++q[C];           //   Raise the value in the array by 1,
                         //   and then add it to the result-integer
  return                 //  Return 
  j;}                    //         the result

1
~사용 하는 경우 j=0return-j;(133)을 제거 할 수 있습니다 .
Nevay

1
103 :x->{int[]q=new int[256];return\nx.chars().map(v->++q[v]).sum();}
Nevay

1
내가 사용하는 경우, 실제로 103 @Nevay j대신에 u( return포함 u) 대신 공간의 새로운 라인과 탭을 선택합니다. 편집 : Hehe,이 의견을 말했을 때 바로 편집했습니다. :)
Kevin Cruijssen

3

F 번호가 점수 120 118

let j z=Seq.countBy id z|>Seq.sumBy(fun x->List.sum[0..snd x])

Kevin Cruijssen 에게 -2 감사 !

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

string입력으로 취합니다 . Seq.countBy각각의 구별되는 문자를 개수와 짝짓기id 므로 (identity 함수입니다) 'a' = 4, 'b' = 2등 의 컬렉션으로 끝납니다 .

Seq.sumBy문자는 모든 문자의 수를 취하고 해당 문자의 수에 대한 모든 숫자를 합산합니다 0. 따라서 'a' = 4컬렉션이 0, 1, 2, 3, 4합산 되면 입니다 10. 그런 다음 Seq.sumBy모든 합계를 합산하십시오.


2
당신은 변경하여 2 점수를 낮출 수 let qlet j이 있기 때문에, q이미 모두 사용된다 Seq.
Kevin Cruijssen


2

망막 , 점수 68 45 43

s`(.)(?<=((\1)|.)+)
$#3$*
1

온라인으로 사용해보십시오! 링크는 점수를 보여줍니다. 편집 : @MartinEnder 덕분에 lookaheads 대신 겹치는 일치를 사용하여 20 바이트를 저장하고 스테이지를 그룹화하여 3 바이트를 더 추가하여 s플래그를 한 번만 적용하면됩니다. 정렬 할 필요없이 삼각 수를 다르게 계산하여 2 바이트를 더 절약했습니다.



2

펄 5 스코어 91 83

-p분할 된 p 때문에 2를 더하는 플래그를 사용합니다 .

$x=$_;$b+=++$a{$_}for(split//,$x);$_=$b

PPCG에 오신 것을 환영합니다!
Laikoni 2016 년

1
답변을 기본으로 사용하고 팁 페이지에서 몇 가지 기술을 적용하여 점수를 31로 낮추었습니다. 온라인으로 사용해보십시오! . $` is automatically 인쇄 ed after each call so we can use that to store the score and 의 모든 문자의 목록을 반환 g` /./ $_보다 저렴, split//.
Dom Hastings

나는 이것이 오래된 도전이라는 것을 알고 있지만, 당신은 더 많은 점수를 삭감 할 수 있습니다 : 온라인으로보십시오!
Xcali

2

옥타브 , 39 바이트, 점수 69

@(a)sum((b=hist(a,unique(1*a))).^2+b)/2

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

다른 옥타브 답변이 있지만이 답변은 전적으로 내 자신의 접근법이며 다른 접근법이며 점수가 적습니다. :).

이 접근 방식은 히스토그램 함수를 사용하여 각 고유 문자의 개수 (b)를 먼저 찾는 것으로 요약됩니다. 그런 다음 각 요소에 대해 공식을 사용하여 1에서 b의 합을 계산합니다 (b*(b+1))/2. 그런 다음 개별 합계가 모두 최종 점수에 합산됩니다.

테스트에서 많은 부분이 필요하기 때문에 대괄호가 실제로 점수를 매기는 데 비용이 많이 드는 것 같습니다. 나는 열기 / 닫기 괄호의 수를 최소화하기 위해 질문을 재정렬하여 초기 점수 약 88에서 최적화했습니다. 따라서 이제 개별적이 아닌 최종 총계에 / 2를 수행하고 수식을 다음과 같이 수정했습니다. (b^2+b)/2적은 괄호가 필요합니다.


1
불행히도 이것은 빈 문자열에서 실패한 것으로 보입니다.error: hist: subscript indices must be either positive integers less than 2^31 or logicals
Laikoni

2

커먼 리스프, 득점 (286) 232 (222)

(loop with w =(fill(make-list 128)0)as z across(read)sum(incf(elt w(char-code z))))

Common Lisp의 내장 연산자의 단어 구문으로 인한 높은 점수입니다.

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

ungolfed 코드 :

(loop with w = (fill (make-list 128) 0)  ; create a list to count characters
   as z across (read)                   ; for each character of input
   sum (incf (elt w (char-code z))))     ; increase count in list and sum

2

매스 매 티카, 54 점

Total[#(#+1)/2&@Counts@Characters@#]&

입력

[ "abcdefg"]

hftf 덕분에


Total[#(#+1)/2&@Counts@Characters@#]&54.
hftf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.