| Bytes | Lang | Time | Link |
|---|---|---|---|
| 083 | JavaScript Node.js | 250502T063519Z | Steve Be |
| 095 | Juby | 250501T222148Z | Jordan |
| 087 | Swift 6 | 250501T211356Z | macOSist |
| 006 | Japt x | 180120T102552Z | Shaggy |
| 058 | JavaScript | 180122T111919Z | Shaggy |
| 010 | APL Dyalog | 170619T171224Z | user4180 |
| 104 | Factor + grouping.extras math.unicode | 220220T222312Z | chunes |
| 005 | Husk | 220220T144359Z | Dominic |
| 042 | Mathematica | 170619T173825Z | ZaMoC |
| 141 | Excel VBA Immediate Window | 220212T170641Z | Axuary |
| 206 | Excel | 220212T170308Z | Axuary |
| 193 | C++ gcc | 190427T233410Z | movatica |
| 010 | Gaia | 190905T171858Z | Giuseppe |
| 004 | BQN | 220117T090810Z | ovs |
| 006 | Husk | 220117T083156Z | Natte |
| 008 | Pyth | 220117T075537Z | hakr14 |
| 003 | Vyxal d | 220117T064546Z | emanresu |
| 087 | JavaScript | 210926T060615Z | l4m2 |
| 133 | Haskell | 190904T165136Z | Sara J |
| 036 | Zsh | 190904T035912Z | GammaFun |
| 044 | 05AB1E legacy | 190904T075552Z | Kevin Cr |
| 091 | C gcc | 170619T165726Z | Steadybo |
| 034 | Perl 6 | 190427T003809Z | Jo King |
| 133 | JavaScript | 190428T025051Z | Naruyoko |
| 681 | SNOBOL4 CSNOBOL4 | 180123T194733Z | Giuseppe |
| 056 | Reticular | 190103T155923Z | Wisław |
| 118 | F# | 180921T143628Z | Ciaran_M |
| 093 | Kotlin | 180921T190054Z | snail_ |
| 100 | Java 10 | 170914T125039Z | Kevin Cr |
| 067 | SHELL | 180317T032755Z | Ali ISSA |
| 115 | Python 2. Score | 180321T144535Z | AvahW |
| 349 | R | 180317T153203Z | Riccardo |
| 006 | Stax | 180315T081051Z | Weijun Z |
| nan | Rust | 180315T132107Z | dragonit |
| 060 | C | 180317T194746Z | ErikF |
| 038 | Ruby | 180317T142916Z | Asone Tu |
| 009 | Husk | 180316T222917Z | Sophia L |
| 045 | Julia 0.6 | 180314T152017Z | niczky12 |
| 060 | jq | 180316T100631Z | manatwor |
| 033 | ><> | 180315T163430Z | Sok |
| 045 | Perl6/Rakudo | 180315T141609Z | Phil H |
| 044 | PHP | 180315T124343Z | Titus |
| 066 | Standard ML | 180306T222514Z | Laikoni |
| 049 | JavaScript | 170717T114143Z | C5H8NNaO |
| 007 | Jelly | 180123T012541Z | ellie |
| 085 | Python 3 | 170619T170405Z | ovs |
| 015 | K4 | 180120T084921Z | mkst |
| 308 | MSSQL | 180119T192817Z | BradC |
| 580 | TSQL | 170619T195542Z | BradC |
| 036 | Attache | 180119T140251Z | Conor O& |
| 897 | brainfuck | 180119T031213Z | Jo King |
| nan | Japt | 180118T200436Z | Oliver |
| 014 | J | 180118T202850Z | cole |
| 006 | Pyt | 180118T194626Z | mudkip20 |
| 067 | R | 170619T194909Z | MickyT |
| 011 | J | 180118T174857Z | FrownyFr |
| 009 | Jelly | 170918T132327Z | J. Sall& |
| 007 | Pyke | 170915T185941Z | Blue |
| 2435 | Factor | 170718T000655Z | Quelklef |
| 019 | K/Kona | 170717T122001Z | Simon Ma |
| 222 | Common Lisp | 170619T210217Z | Renzo |
| 3577 | FIREBIRD | 170622T172836Z | Filipe S |
| 039 | AWK | 170621T180135Z | Robert B |
| 133 | ><> Fish | 170622T131853Z | Thijs te |
| 018 | CJam | 170622T133212Z | Business |
| 064 | PowerShell | 170622T064548Z | Tessella |
| 153 | Swift 3 | 170622T064226Z | Archmage |
| 031 | Octave | 170619T173139Z | rahnema1 |
| 039 | Octave | 170621T221352Z | Tom Carp |
| 060 | Ruby | 170619T202429Z | Value In |
| 083 | Perl 5 score | 170620T210902Z | user1937 |
| 1110 | F# | 170620T122006Z | Horv |
| 016 | J | 170619T194517Z | Zgarb |
| 023 | J | 170619T181033Z | Leaky Nu |
| 006 | Pyth | 170619T180016Z | Leaky Nu |
| 012 | Actually | 170620T025526Z | user4594 |
| 045 | PHP | 170619T221329Z | Jör |
| 043 | Retina | 170619T173701Z | Neil |
| 049 | Python | 170619T171247Z | xnor |
| 005 | Jelly | 170619T165829Z | Erik the |
| 004 | MATL | 170619T183707Z | Luis Men |
| 128 | QBIC | 170619T195523Z | steenber |
| 034 | Retina | 170619T180125Z | Martin E |
| 209 | C# .NET Core | 170619T191834Z | Charlie |
| 096 | Clojure | 170619T190629Z | NikoNyrh |
| 108 | Python 2 | 170619T173102Z | Daniel |
| 068 | JavaScript Firefox 30+ | 170619T185518Z | ETHprodu |
| 006 | Jelly | 170619T170224Z | Leaky Nu |
| 042 | Haskell | 170619T175127Z | xnor |
| 051 | Haskell | 170619T172312Z | nimi |
| nan | 170619T174348Z | Brad Gil | |
| 015 | APL Dyalog | 170619T173617Z | Adá |
| 083 | Python 2 | 170619T171536Z | mbomb007 |
| 078 | JavaScript ES6 | 170619T170224Z | ETHprodu |
| 006 | 05AB1E | 170619T170546Z | Erik the |
Swift 6, score: 87
var U={X in(X+"").reduce(0){A,C
in A+1+X.count{$0==C}}/2}
The first space (between var and U) is a Unicode non-breaking space (U+00A0); the one between X and in is a normal space; the one between A,C and in is a newline; and the one between in and A+1 is a tab.
JavaScript, 112 95 58 points
A=>A.map(C=>N+=A[C]=-~A[C],N=0)|N
- 7 points saved thanks to ETHProductions
APL (Dyalog), score 27 18 11 10
Reduced score by 7 thanks to @Adám by using a tradfn and using 1⊥ to sum the frequencies
Reduced score by 1 thanks to @rabbitgrowth by using a function instead
1⊥{+/⍳≢⍵}⌸
Factor + grouping.extras math.unicode, score: 104
[ head-clump
[ dup
last '[
_ =
] count
] map
Σ ]
The whitespace is a killer. In order to lessen its impact, I alternate between spaces and newlines. Tabs aren't allowed in TIO's build of Factor or I would have used them too.
Husk, 5 bytes, score 5
ΣṁŀgO
Different and (so far) shorter strategy to Natte's or Sophia Lechner's Husk answers.
O # sort the input
g # and group equal adjacent values;
ṁ # now, for each group
ŀ # make a range 1..length of the group
ṁ # and flatten all the ranges into one list;
Σ # then output the sum
Mathematica, score 42
Total[#^2+#].5&@*CharacterCounts
input
["abcdefg"]
thanks to hftf
thanks to att
Excel VBA Immediate Window, Score 159 141
-18 byte thank to @TaylorRaine
FOR I=1TO[len(b3)]:for J=1to i:Y=Y-(MID([B3],i,1)=mid([B3],j,1)):NEXT:next:?y
The mixed case reduces the score by 30.
Excel, Score: 206
G4 =MID(B3,SEQUENCE(LEN(B3)),1)
C3 =IF(B3<>"",SUM(EXACT(G4#,TRANSPOSE(G4#))/2)+ROWS(G4#)/2,)
C++ (gcc), Score: 209 196 193
98 96 bytes
-3 thanx to l4m2
#include<map>
long F(std::string S,int I=0){for(auto&C:S){++I;for(char&D:S)I+=C==D;}return I/2;}
C++-specific tricks:
#include<map>instead of#include<string>- Returning
longinstead ofintto use more different characters - Using
autoinstead ofcharin one of the loops has the same effect - References (
&) inside range-for save whitespace
Common tricks:
- Evenly use both tabs and blanks
- Upper case variables to be distinct from keyword characters
Gaia, score: 11 10
$uC¦ₔ┅¦_Σ
For some reason, Without the _ is necessary else this spits out garbage answers. But the language is defined by its implementation, so what are ya gonna do._, one of the sublists generated by ┅¦is [1 2] which is converted to 12 by Σ.
$ | split into characters
|
u | get unique
C¦ₔ | implicitly copy original input; get counts of uniques into original
┅¦ | sequence: 1..count
_Σ | flatten and sum
BQN, Score: 4
≠+´⊒
The occurrence count builtin ⊒ calculates the cost of each character decremented by 1. To adjust for that we can either add 1 to each cost or add the length ≠ to the sum. The latter turns out to be a byte shorter.
Husk, Score: 6
ṁoΣ#¹u
Explanation
ṁoΣ#¹u translates to ṁoΣ#⁰u⁰
ṁ u⁰ map following function on unique input and then sum
o composed function
#⁰ count occurrences in input
Σ triangular number
Pyth, 8 bytes, Score: 9
ssSM/LQ{
Explanation
ssSM/LQ{ | Full code
ssSM/LQ{Q | with implicit variables filled
----------+-------------------------------
L {Q | Map over deduplicated input:
/LQ | count in input
SM | Map: to [1...N]
s | Flatten
s | Sum
ss can be replaced with s.n for an identical score with no repeat bytes, at the cost of being one byte longer.
Vyxal d, 3 bytes
Ċɾ⌊
Ċ # Counts of each element within itself
ɾ # Convert each value to 1...n
⌊ # Parse each to integer, zeroes element values
# (d flag) take the deep sum
JavaScript, 87 score
A=([B,...C],Z=0)=>B?C.map(D=>D!=B||Z++)^A(C)-~Z:0
C.map(D=>D!=B||Z++) is either empty, 0, true or something with a ,, making it never show value to ^
Haskell, 150 133 points
(79 75 bytes)
import Data.List
c=foldr(\x-> \y->y+(x*(x+1)`div`2))0.map length.group.sort
- -17 points by removing some parentheses (thanks to @Laikoni)
Zsh, 36 bytes, score 52
for p (${(s..)1})$[j+=++a[#p]]
<<<$j
One tab, one space, one newline. This will fill up the debug log with "command not found". If that must be avoided, 38 bytes, score 55.
05AB1E (legacy), score: 4 (4 bytes)
Ù¢LO
Input as a list of characters.
Try it online or verify all test cases.
Explanation:
Ù # Get all unique characters of the (implicit) input-list
¢ # For each, count the amount of times it occurs in the (implicit) input-list
L # Create a list of each of these counts
# (which implicitly flattens in the legacy version of 05AB1E)
O # Take the sum of all those integers
# (which is output implicitly as result)
C (gcc), score: 113 103 100 96 91
Thanks to @ugoren, @CalculatorFeline, @gastropner, @l4m2, and @JS1 for their tips.
g(char*s){int y[238]={};while(*s)*y-=--y[*s++];*y/=1;}
Initializes an array of zeros, then uses the ASCII values of the characters in the string as indices to that array to keep track of the number of instances of each character in the string.
Perl 6, Score: 34
{sum [\+](^∞)[.comb.Bag{*}]}
Takes advantage of the unicode operator ∞ to save on characters.
Explanation
{ } # Anonymous code block
.comb # Split the input string into characters
.Bag{*} # Get the count of each character
[ ] # And inded each into
(^∞) # The infinite list of integers
[\+] # Triangularly summed (0,0+1,0+1+2...)
sum # And return the sum total
JavaScript, 150 141 133
f=(g,i=[])=>g?(i[j=g.charCodeAt()]=(i[j]|0)+1)+f(g.substr(1),i):0
Ungolfed:
f=(g,i=[])=> //function declaration, a is list of appearance of characters so far.
g? //check if string is empty
(i[j=g.charCodeAt()]= //update appearance list
(i[j]|0)+1)+ //handle undefined, then increment
f(g.substr(1),i) //next character
:0 //base case for the empty string
150->141 - -6 for renaming variables to unique characters (thanks to Ørjan Johansen), and -3 for removing implicit 0 in charCodeAt.
141->133 - -8 for using actual unique variable names(thanks again to Ørjan Johansen).
SNOBOL4 (CSNOBOL4), score: 681
s =iNPUT
Y _table()
d S LEN(1) . x REM . S :F(b)
Y<X> =y<X> + 1 :(D)
b Z _convert(Y,'aRrAy')
N j =J + 1
G _z[j,2] :f(q)
o =o + g * G + g :(N)
q OUtpuT _O / 2
end
looks a bit scary, but SNOBOL matches identifiers case-insensitively, which dropped the score by around 100 points. Note that it requires a single line of input, so I've replaced \n with ; in the input field (which is still valid SNOBOL).
The SNOBOL4 implementation on TIO allows for an additional 16 point golf, as = and _ are both allowable as the assignment operator. How neat!
F#, score 120 118
let j z=Seq.countBy id z|>Seq.sumBy(fun x->List.sum[0..snd x])
-2 thanks to Kevin Cruijssen!
Takes a string as an input. Seq.countBy pairs each distinct character with its count (id is the identity function) so you end up with a collection like 'a' = 4, 'b' = 2 etc.
The Seq.sumBy takes the count for every letter and sums all the numbers from 0 to the count for that letter. So if 'a' = 4 the collection would be 0, 1, 2, 3, 4 which summed together is 10. Then Seq.sumBy sums all those totals.
Java 10, score: 149 138 137 134 133 130 103 102 101 100
(Bytes: 72 73 74 75 64 62 61) Bytes go up, but score goes down. :D
x->{int j=0,q[]=new int[256];for(var C:x)j+=++q[C];return
j;}
-28 score (and -11 bytes) thanks to @Nevay.
-1 score (and -2 bytes) thanks to @OlivierGrégoire.
-1 score (and -1 byte) by converting Java 8 to Java 10.
Explanation:
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
SHELL ( 67 bytes)
Last Solution : ( 68 bytes)
f(){ bc<<<`echo -n "$1"|od -bAn|sed "s/\([^ ]\+\)/s+=++v\1;/g"`s;}
Old solutions :
Old Solution 1 : by creating function f (83 bytes ) :
f(){ bc<<<`echo "$1"|sed "s/./ss+=++&;/g"|sed "s/[A-Z]/\L&_/g"|sed "s/ /bb/g"`ss;}
Old Solution 2 : by creating alias f ( 81 bytes )
alias f='bc<<<`cat -|sed "s/./ss+=++&;/g"|sed "s/[A-Z]/\L&_/g"|sed "s/ /bb/g"`ss'
Explanations :
I used ( sed "s/./ss+=++&;/g" ) to replace any char a by ( ss+=++a; ); where ss is the sum to calculate, then concatenate with ss, and calculate all expression by the command bc :
echo "a" | sed "s/./ss+=++&;/g"
ss+=++a;
for a string in input :
echo "aab" | sed "s/./ss+=++&;/g"
ss+=++a;ss+=++a;ss+=++b;
step by step :
ss+=++a; // a=1 --> ss=1
ss+=++a; // a=2 --> ss=3
ss+=++b; // b=1 --> ss=4
for lowercase only input, the simpler function need only ( 47 bytes ) to define :
f(){ bc<<<`echo "$1"|sed "s/./ss+=++&;/g"`ss;}
to take uppercase in consideration, Without spaces ( 68 bytes) :
f(){ bc<<<`echo "$1"|sed "s/./ss+=++&;/g"|sed "s/[A-Z]/\L&_/g"`ss;}
Complete Solution ( 83 bytes):
f(){ bc<<<`echo "$1"|sed "s/./ss+=++&;/g"|sed "s/[A-Z]/\L&_/g"|sed "s/ /bb/g"`ss;}
fuction tests :
f "abaacab"
14
f "abcdefg"
7
f " "
28
f "Aa"
2
using an alias instead the function, we can reduce code size to ( 68 bytes )
alias f='bc<<<`cat -|sed "s/./ss+=++&;/g"|sed "s/[A-Z]/\L&_/g"|sed "s/ /bb/g"`ss'
alias tests :
echo " " | f
28
echo "Ab" | f
2
Python 2. Score:142 115
def f(a):
x=0
for y in set(a):z=a.count(y);x+=.5*z*-~z
print x
EDIT:-27 thanks to @Kevin Cruijssen
R, 349
Here is my R solution bit of tidy
s=function(x) {c=0
for (i in unique(strsplit(x,"")[[1]])) {
c=c(c,sum(1:sum(charToRaw(x)==charToRaw(i))))}
sum(c)
}
Stax, 8 6
ç╕┌α▒'
Saved 2 points by using runs per comment by @recursive.
Explanation
Uses the unpacked version to explain.
o:GF:T+
o Sort array
:G Run lengths
F For each run length `n`
:T The nth triangular number
+ Add to accumulator
Implicit output
Rust, 265 255 bytes. Score: 1459 1161
fn main(){let mut z=String::new();std::io::stdin().read_line(&mut z);let Z=z.trim_right_matches(|x|x=='\r'||x=='\n');let mut q:Vec<u8>=Z.bytes().collect();q.sort();let(mut k,mut W,mut j)=(0,0u8,0);for Y in&q{if*Y==W{j+=1}else{j=1;W=*Y}k+=j}print!("{}",k)}
Ungolfed
fn main() {
let mut input_string = String::new();
std::io::stdin().read_line(&mut input_string);
let trimmed = input_string
.trim_right_matches(|c| c == '\r' || c == '\n');
let mut chars: Vec<u8> = trimmed.bytes().collect();
chars.sort();
let (mut total_score, mut last_char, mut last_score) = (0, 0u8, 0);
for letter in &chars {
if *letter == last_char {
last_score += 1;
} else {
last_score = 1;
last_char = *letter;
}
total_score += last_score;
}
print!("{}", total_score);
}
Edit: improved answer by renaming variables and altering code
C, 60 bytes, score 108 95
g(char*s){int y[256]={},z=0;while(*s)z-=--y[*s++];return z;}
Usually pre- and post-increment operators are great for code golf, but they really hurt on this challenge!
EDIT: By subtracting negative counts instead of adding positive ones, I saved a whole bunch of score. Replacing for() with while() eliminated a semicolon as well.
Husk, Score 9
½§+L(Σ´×=
Explanation:
This calculates the score as sum_i (n_i^2 + n_i)/2, where i is indexed arbitrarily across unique character types and n_i is the number of characters of type i in the input. But since sum_i n_i is the length of the input, this reduces to (1/2) * (L + sum_i n_i^2)
Code breakdown:
o ½ (§ + L (o Σ (´ (× =))) --With parentheses and two implicit compositions
(× =) --1 or 0 for each equality check between elements of its first and second arguments
(´ (× =)) --argdup, 1 or 0 for each equality check between elements of its only argument
(o Σ (´ (× =)) --# of equalities between pairs (this will give sum_i n_i^2)
L --length
(§ + L (o Σ (´ (× =))) --length + sum_i n_i^2
o ½ (§ + L (o Σ (´ (× =))) --1/2 * (length + sum_i n_i^2)
Julia 0.6, 45 bytes, Score: 77
Inspired by the MATL solution:
f(w)=sum(UpperTriangular([z==j for z=w,j=w]))
A less pretty solution, using counts:
Julia 0.6, score: 82
F(w)=sum(l->[l+1]l/2,count(x->x==i,w)for i=Set(w))
Thanks to Guiseppe for pointing out the scoring and for tips. These comments helped me loads.
jq, score 60
(40 characters code + 3 characters command line option)
[./""|group_by(.)[]|range(length+1)]|add
Sample run:
bash-4.4$ jq -R '[./""|group_by(.)[]|range(length+1)]|add' <<< 'Programming Puzzles & Code Golf'
47
jq, score 63
[./""|group_by(.)[]|range(length+1)]|add+0
In case the result for empty string must be numeric 0. There are a few other solutions that use alternative representation of nothing.
><>, score 33
0vAB;n*<
p>i:0(?^:ag1+:}r-@a
28 bytes, with 2 occurrences each of a and 0, and 3 occurrences of :. AB can be replaced by any two characters which don't appear anywhere else in the code.
Works by storing the current character count in the code grid on row 10. The sum is actually a negative sum to start with, and the -1 from reaching the end of STDIN is multiplied with this to turn it back into a positive number.
Perl6/Rakudo, 45 bytes, score 66
Run with perl -ne:
say [+] bag(.comb).values.map({($_+1)*$_/2});
Uses the essential nature of a Bag (like a set with a count per member).
Step by step:
.say; # abaacab
say .comb; # (a b a a c a b)
say bag(.comb); # Bag(a(4), b(2), c)
say bag(.comb).values; # (2 4 1)
say bag(.comb).values.map({($_+1)*$_/2}); # (3 10 1)
say [+] bag(.comb).values.map({($_+1)*$_/2}); #14
Also note that each character's score can be calculated from its occurrences as (n+1)*n/2.
Edited because I cannot evidently read.
PHP, 44 bytes, score 78:
While($C=ORD($argn[$p++]))$s-=++$$C;EcHo-$s;
Almost Jörg´s solution, but one byte shorter.
PHP, 51 bytes, score 80
ForEach(COUNT_CHARS($argn)As$p)$z-=~$p*$p/2;echo$z;
Run as pipe with -nR or try them online
Standard ML, 66 bytes, score 113
fun$(a::z)=1+length(List.filter(fn y=>y=a)z)+ $z|
$_=0;$o explode;
This code defines an anonymous function which is bound to the implicit result identifier it. Try it online!
Explanation
The ungolfed code looks like this:
fun f (a::z) = 1 + length (List.filter (fn y => y=a) z) + f z
| f _ = 0
val g = f o explode
The function g takes a string as input, converts it to a list of characters with explode, and passes it on to the function f which recurses over the list, with a being the current character and z being the remaining list. For each a the number of occurrences of a in z is computed by filtering z to contain only chars equivalent to a and taking the length of the resulting list. The result is incremented by one to account for the current occurrence of a and added to result of the recursive call of f on z.
JavaScript, 49 bytes, score 88
b={};s=0;for(j in a=prompt())s+=b[a[j]]=-~b[a[j]]
Jelly, score of 7
ċЀQRFS
Explanation:
Q get unique letters
ċЀ count the occurences of each letter in the original string
R [1..n] for n in list of frequencies
F flatten list
S sum
(implicit output)
K4, score 15
Solution:
+/,/{1+!#x}'=
Example:
q)k)+/,/{1+!#x}'="Programming Puzzles & Code Golf"
47
Explanation:
+/,/{1+!#x}'= / the solution
= / group
{ }' / apply lambda to each (')
x / implicit lambda input
# / count length
! / range 0..n
1+ / add one
,/ / flatten list
+/ / sum up
Notes:
In Q this could be written as:
q)sum raze { 1 + til count x } each group "Programming Puzzles & Code Golf"
47
MS-SQL, score 308
I'm using a completely different technique from my other answer, with additional restrictions, so I'm submitting them separately:
SelEcT SUm(k)FROM(SELECT k=couNt(*)*(CoUNT(*)+1)/2froM spt_values,z WHERE type='P'AND number<len(q)GROUP BY sUBstring(q,number+1,1))L
Caveats: this must be run from the master database of a MS-SQL server set to a case-sensitive collation (mine is set to SQL_Latin1_General_CP850_BIN2).
Input is via varchar field q in pre-existing table z, per our IO rules. Formatted:
SelEcT SUm(k)
FROM
(SELECT k=couNt(*)*(CoUNT(*)+1)/2
froM spt_values,z
WHERE type='P'
AND number<len(q)
GROUP BY sUBstring(q,number+1,1)
)L
The trick here is to use a "number table" to join with the input table, which allows me to separate each character into its own row, then group by matching characters, count them up, calculate the score of each, and sum them all together. All the rest is minimizing score by playing with character case, since SQL keywords are not case sensitive.
MS-SQL has a system table in the master database called spt_values with a lot of junk in it, but I restrict it to type='P', I get a nice number table with 0 through 2047.
T-SQL, score 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
EDIT: Dropped a couple of variables, compacted a bit. Down to 16 @ symbols instead of 22, that by itself reduces my score by a whopping 117 points!
Nice contest, I like the requirement to optimize for something besides total character count.
Input is via varchar field q in pre-existing table z, per our IO rules. The database containing this input table must be set to a case-sensitive collation.
Formatted:
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 keywords aren't case sensitive, so I used mixed case to minimize the count of duplicate letters (aaAA generates a better/lower score than aaaa).
The main loop compares the length before and after stripping all instances of the first character out. That difference n*(n+1)/2 is added to a running total.
The SQL LEN() function annoyingly ignores trailing spaces, so I had to append a control character and subtract 1 at the end.
EDIT: Fixed a miscalculation of my own score by 2 points (issue with quoting quotes), reduced by 1 by changing casing of one R. Also working on a completely different strategy, I'll be posting that as its own answer.
Attache, score 36
Sum@Map&:(Count#Last)@Prefixes
Explanation
Sum@Map&:(Count#Last)@Prefixes
This is a composition of 3 functions:
Prefixes- this simply obtains the prefixes of the inputMap&:(Count#Last)- This is a mapped fork. This is equivalent toarr.map { e -> e.count(e.last) }So, for each character, this counts the occurrences of that character so far.Sum- this sums all of these numbers.
brainfuck, score 897
,[<<[[->+>-<<]>>[<]<[<]<[<]<[+<<]>>>>[>]>[->+>+<<]>[-<+>]<<<]<+[->>+<<]>>>[->+<]>[>]>,]<<[<]<
Ends on the cell with the correct value. Assumes a cell size larger than the score of the string, otherwise it'll wrap (got a little suspicious when the interpreter said the score was 188).
Japt, score 12 (+2 for -x) = 14
¬n ó¥ ËÊõÃc
Explanation
¬n ó¥ ËÊõÃc "abaacab"
¬ // Split the input into an array of chars ["a","b","a","a","c","a","b"]
n // Sort ["a","a","a","a","b","b","c"]
ó¥ // Partition matching items [["a","a","a","a"],["b","b"],["c"]]
Ë // map; For each array:
Ê // Get the length x [4,2,1]
õ // Create a range [1...x] [[1,2,3,4],[1,2],[1]]
à // }
c // Flatten [1,2,3,4,1,2,1]
-x // Sum 14
J, score 14
1#.2!1+#/.~
Outgolfed by the other J solution, but figured I'd post this anyways since it uses a slightly different method.
Pyt, 6 bytes
ĐỤ⇹ɔ△Ʃ
Explanation:
Implicit input
Đ Duplicate top of stack
Ụ Get unique characters
⇹ Swap top two items on stack
ɔ Count number of times each unique character occurs in the input
△ Calculates the total score for each character
Ʃ Sum count
Implicit output
R, score: 67 83 95 128
-61 thanks to top tips from Giuseppe
function(x,y=table(utf8ToInt(x)))y%*%{y+1}/2
The string is split using utf8ToInt and each ascii value is counted table. The the result is calculated using doing a matrix multiplication %*% over that at itself + 1 and finally halfed.
Jelly, 10 9 bytes; Score 10 9
ṢŒrzẆṪRẎS
This is the first time I use Jelly, and I didn't want to check other people's answers because I wanted to try it myself. I probably reinvented the wheel a couple times there. Suggestions and feedback are greatly appreciated.
EDIT: -1 byte for removing ɠ and taking the input as an argument.
Explanation:
ṢŒrzẆṪRẎS #Main Link; input abaacab
Ṣ #sorts input; aaaabbc
Œr #run-length encode, or the number of times a character appears; a4b2c1
z #zip; ['abc', [4, 2, 1]]
Ẇ #takes every contiguous sublists
Ṫ #Pops the last element; [4, 2, 1]
R #Takes the range of every element; [[1,2,3,4],[1,2],1]
Ẏ #Collapses every element into a single array; [1,2,3,4,1,2,1]
S #Sum and implicitly print; 14.
(no idea why, but the code doesn't work without Ẇ,
although it gives the exact same output as z)
Pyke, score 7
cemSss
c - count_occurrences(input)
e - values(^)
mS - [range(1,i+1) for i in ^]
ss - sum(sum(i)for i in ^)
Factor, 2435
(o god my score)
"" over [ 2dup swap in? [ drop ] [ suffix ] if ] each { } swap swapd [ dupd 0 swap swapd swap [ over = swap [ [ 1 + ] [ ] if ] dip ] each drop swap [ suffix ] dip ] each drop [ dup 1 + * 2 / ] map sum
(wrong formatting on purpose for multi-line span)
Wow, Factor is hard. Or I'm just bad. Probably a little bit of both.
K/Kona, score 19
+/,/1+!:'(#:)'=
Works as:
= (implicitly take arg as input), group -> make dictionary of characters to their occurring indices
(#:)'= count each of these
1+!:'(#:)'= get a list from 0->n-1 for each of these counts, add one to each
+/,/1+!:'(#:)'= finally, reduce to single list, sum reduce this list
Example:
k)+/,/1+!:'(#:)'="+/,/1+!:'(#:)'="
19
k)+/,/1+!:'(#:)'="abaacab"
14
Legible q equivalent:
(sum/)raze 1+til count each group
Common Lisp, score 286 232 222
(loop with w =(fill(make-list 128)0)as z across(read)sum(incf(elt w(char-code z))))
High-valued score due to the wordy syntax of builtin operators of Common Lisp.
The ungolfed code:
(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
FIREBIRD, score 3577
Version to calculte the score:
SELECT COALESCE(SUM(C),0)FROM(WITH RECURSIVE T AS(SELECT 1 AS I,SUBSTRING(CAST(:V AS BLOB)FROM 1 FOR 1)AS S FROM RDB$DATABASE UNION ALL SELECT I+1,SUBSTRING(CAST(:V AS BLOB)FROM I+1 FOR 1)FROM T WHERE I < CHAR_LENGTH(CAST(:V AS BLOB)))SELECT T.*,(SELECT COUNT(T2.I) FROM T T2 WHERE T2.S=T.S AND T2.I<=T.I)AS C FROM T WHERE CAST(:V AS BLOB) <> '')
Below is the idented version of the code, in case anyone want to now. I'm sorry for any mistakes, first time here actually posting!
SELECT COALESCE(SUM(C), 0)
FROM (
WITH RECURSIVE T AS (
SELECT 1 AS I, SUBSTRING(CAST(:V AS BLOB) FROM 1 FOR 1) AS S
FROM RDB$DATABASE
UNION ALL
SELECT I+1, SUBSTRING(CAST(:V AS BLOB) FROM I+1 FOR 1)
FROM T
WHERE I < CHAR_LENGTH(CAST(:V AS BLOB))
)
SELECT T.*, (SELECT COUNT(T2.I) FROM T T2 WHERE T2.S = T.S AND T2.I <= T.I) AS C
FROM T
WHERE CAST(:V AS BLOB) <> ''
)
Explanation
I start my select in a system table SELECT 1 AS I, SUBSTRING(CAST(:V AS BLOB) FROM 1 FOR 1) AS S FROM RDB$DATABASE, which always has only one row. Using that only one row, I return 1 as a column I, and the character that exists in the input in the I value.
Let's say I've passed 'abaacab' as input:
╔═══╦═══╗ ║ I ║ S ║ ╠═══╬═══╣ ║ 1 ║ a ║ ╚═══╩═══╝
In the UNION ALL part, I start to increment the index from the first select, until it reaches the end of the input. So, in the example I would get this:
╔═══╦═══╗ ║ I ║ S ║ ╠═══╬═══╣ ║ 1 ║ a ║ ║ 2 ║ b ║ ║ 3 ║ a ║ ║ 4 ║ a ║ ║ 5 ║ c ║ ║ 6 ║ a ║ ║ 7 ║ b ║ ╚═══╩═══╝
After that, I also select the count of ocurrences from the value on S, that has already appeared in indexes below the I. So, in a column C I now have the 'cost' of that character, which I only need to SUM after to get the value.
╔═══╦═══╦═══╗ ║ I ║ S ║ C ║ ╠═══╬═══╬═══╣ ║ 1 ║ a ║ 1 ║ ║ 2 ║ b ║ 1 ║ ║ 3 ║ a ║ 2 ║ ║ 4 ║ a ║ 3 ║ ║ 5 ║ c ║ 1 ║ ║ 6 ║ a ║ 4 ║ ║ 7 ║ b ║ 2 ║ ╚═══╩═══╩═══╝
I used BLOB as the type from the input, to not get limited by size.
><> (Fish), score 133
!<01-0&i:2(:?&:?n?;&1+&:}}:3(00@@?.~~:{=&+&{$}8e+0.>.!06}~{
This code reads the input per character, adds a point and loops through all the read characters, adding an extra point for every equal character.
Explanation
!<01-0& // Initialize (put -1 on the stack and 0 in the register)
i:2(:?$:?n?; // Read the next input. If it's -1, print the register and end the program.
&1+& // Add one to the register
:}}: // Duplicate both the input and the check value
3(00@@?.~~ // If the check value is -1, jump the instruction pointer to 0,0 (line 0)
:{=&+& // Compare the input to the check value and add the result to the register
{$}8e+0. // Move the checked value to the bottom of the stack and jump to 22,0 (line 4)
>.!06}~{ // Clean up the stack and jump to 0,6 (line 2)
CJam, score 18
q_,{)W$<}%.e=0+:+
Explanation
q e# Read the input.
_, e# Copy it, get its length.
{ e# Map over the range from 0 .. length-1:
) e# Increment the current number.
W$ e# Push the input.
< e# Get the first <current number> characters of it.
}% e# (end map)
.e= e# Count the occurrences of each character in the corresponding slice.
0+ e# Append a 0 to the result (because you can't reduce and empty list).
:+ e# Reduce by addition (sum).
PowerShell, score 64
$z=@{}
$ARGS|% getE*|%{$u+=($Z.$_+=1)};$U
(Score is based on a single linefeed newline, which isn't Windows standard but does work in PS).
PS C:\> D:\unique-is-cheap.ps1 (gc D:\unique-is-cheap.ps1 -raw)
64
- Hashtable counter
@{} - Iterate through the letters;
$argsis an array of parameters - in this case the input string makes it a single item array;|%does a foreach loop over the items, and uses thegetE*shortcut to match theGetEnumerator()string method and call it to turn the string into a character stream. |%loop over the characters and increment their hashtable entry, add it to a running total. The($x+=1)form with parens both modifies the variable and outputs the new value for use.- Output the running total.
(When I first wrote it, it was $c=@{};$t=0;[char[]]"$args"|%{$c[$_]++;$t+=$c[$_]};$t with a score of 128, and felt like it wouldn't go much lower. Halving it to 64 is quite pleasing).
Swift 3, 153 bytes, score = 637
var u:(String)->Int={var d = Dictionary<Character,Int>()
for c in $0.characters{d[c] = (d[c] ?? 0) + 1}
return d.values.reduce(0,{$0 + $1 * ($1 + 1) / 2})}
Legible version plus explanation
func unique(_ string: String) -> Int {
var dict = Dictionary<Character, Int>()
for char in string.characters { dict[char] = (dict[char] ?? 0) + 1 }
return dict.values.reduce(0, { $0 + $1 * ($1 + 1) / 2 })
}
My solution takes the string, iterates over the characters and tracks each unique character in a dictionary, counting the occurrences per character. Once that's done, it reduces the dictionary's values using the triangle number formula ( n(n+1) / 2 ) and returns the result.
Comments
Swift obviously isn't the best language for golfing, but it was fun to see where I could save bytes despite its rigid syntax. This is my first Swift submission - be gentle!
Octave , score 77 31 bytes
*same as @LuisMendo 's MATL answer.
@(a)nnz(triu(a==a'))
Previous answer:
@(d,g=accumarray(+d',1)-(0:254))sum(g(g>0));
Octave, 39 bytes, Score 69
@(a)sum((b=hist(a,unique(1*a))).^2+b)/2
While there is another Octave answer, this one is entirely my own and a different approach, plus it scores less :).
The approach boils down to first finding the count (b) of each unique character, which is achieved using the histogram function. Then for each element we calculate the sum of 1 to b which is done using the formula (b*(b+1))/2. Then the individual sums are all summed into the final score.
In testing it seems brackets are really costly in the scoring because many are needed. I've optimised down from an initial score of about 88 by rearranging the questions to minimise the number of open/close brackets - hence we now do the /2 on the final total rather than individually, and also I've modified the formula to (b^2+b)/2 as that requires fewer brackets.
Ruby, score 63 60
Uses the -n flag which ends up adding 2 points due to the presence of another n within the code.
-3 points from Alexis Anderson.
i=x=0
gsub(/./){x+=$_[0,i+=1].count$&};p x
Perl 5 score 91 83
Uses the -p flag which adds 2 because of the p in split.
$x=$_;$b+=++$a{$_}for(split//,$x);$_=$b
F#, score:12641110
-154 points, thanks to @Laikoni
let x(y:bool)=System.Convert.ToInt32(y)
let rec p(k:string)q=
let j=k.Length
if(j=1)then(x(k.[0]=q))else p k.[0..(j-2)] q+x(k.[j-1]=q)
let rec d(a:string)=
let z=a.Length
if(z<2)then z else d a.[0..(z-2)]+p a (a.[z-1])
You need to call the d function. In a more readable form:
let x (y:bool)=
System.Convert.ToInt32(y)
let rec e (c:string) b=
let j=c.Length
if(j=1)then
(x(c.[0]=b))
else
e c.[0..(j-2)] b+x (c.[j-1]=b)
let rec d (a:string)=
let h=a.Length
if(h<2)then
h
else
d a.[0..(h-2)]+e a (a.[h-1])
Explanation
It is a recursive algorithm, the base case is, if the length of the string is less than 2 (0 or 1), the score will be the length of the string. This is because, if the length is 0 (empty string), we have no characters, so the score is 0, and if the length is 1, that means, that the string consists of only 1 character, so the score is 1.
Otherwise it trims the last character of the string, and to the score of the truncated string adds the count of the last character in the untruncated string.
The counting algorithm is also recursive. Its base case is, when the length of the string is one, then the count is 1, if the string matches with the character, and 0 otherwise. This can also be done, if we convert the bool to an int, and this results in a lower score.
Otherwise it trims the last character of the string, calculates the count of that string, and if the last character matches the character, we are calculating the count of, adds one to the count. This is again, better, if we convert that boolean to an int.
J, score 16
1#.,@(*+/\"1)&=
Explanation
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.
Using 1#. instead of +/@ for the sum saved a few points, and & could be used instead of @ in a monadic context to save one more.
The repeated 1 costs me one extra point, but I haven't been able to get rid of it.
Pyth, score 6
1 byte thanks to isaacg.
+F/V._
How it works
+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.
Actually, score 12
;╗╔⌠╜cRΣ⌡MΣ
Explanation:
;╗╔⌠╜cRΣ⌡MΣ (implicit input: S)
;╗ save a copy of S in register 0
╔ uniquify S (call it A)
⌠╜cRΣ⌡M for each unique character in A:
╜c count the number of occurrences in S
R range(1, count+1)
Σ sum
Σ sum
Repeating the Σ is two points less than using an alternative formulation with no repeated characters (i`+Y).
PHP, 45 bytes, Score 78
WHILE($x=ORD($argn[$v++]))$y+=$$x-=-1;echo$y;
PHP, 46 bytes, Score 79 Bytes
WHILE(~$xy=$argn[$vz++])$su-=-$$xy+=1;echo$su;
PHP, 56 bytes, Score 92
FOREAch(COUNT_CHARS($argn)as$z)WHILE($z)$y+=$z--;echo$y;
Retina, score 68 45 43
s`(.)(?<=((\1)|.)+)
$#3$*
1
Try it online! Link shows score. Edit: Thanks to @MartinEnder who saved 20 bytes by using overlapping matches instead of lookaheads and a further three bytes by grouping the stages so that the s flag only needs to be applied once. Saved a further two bytes by calculating the triangular number differently, avoiding the need for a sort.
Python, score 49
lambda S:sum(1+S.count(C)for[C]in S)/2
There's a tab after in.
Score breakdown:
- +27 for 27 unique chars
- +16 for 8 double chars:
()Camnou - +6 for 1 tripled char:
S
MATL, score 4
&=Rz
Explanation
Consider input 'ABBA' as an example.
&= % 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
QBIC, score: 128
dim x(126)[_l;||i=asc(_sA,a,1|)┘x(i)=x(i)+1][126|[x(b)|p=p+c}?p
Nice round score of 128.
Explanation
dim x(126) Create an array of 126 elements (one for each ASCII element)
[_l;|| Read cmd line input, loop over its length
i=asc(_sA,a,1|) Read the next char's ascii value
┘ (Syntactic linebreak)
x(i)=x(i)+1 Raise the count of this ASCII char by 1
] NEXT
[126| Loop over the ASCII array again
[x(b)| Read the count and start a loop that runs from 1 to that count
p=p+c Add to running total p the loop counter
} Close both loops
?p PRINT p
Retina, score 34
s(O`.
M&!`^|(?<=(.))\1*
.
Explanation
s(O`.
We start by sorting all the characters in the input so that identical characters are grouped together into a single run. The s( activates singleline mode for all stages (i.e. makes . match linefeeds).
M&!s`^|(?<=(.))\1*
The goal is to turn a run of n characters into Tn characters (the nth triangular number) because that's the score of the occurrences of this character. To do so, we find overlapping matches. In particular, for each i in [1,n], we're going to include i-1 characters in the match. We get all those matches due to the overlapping flag &. That gives us n*(n-1)/2 = Tn-1 = Tn - n characters just from the matches. But the match stage will join these with linefeeds, which are n linefeeds for n matches. There's only one problem. There won't be a linefeed after the last match, so the overall number of characters in the output is one less than we need. We fix this by also matching the beginning of the input, which gives us a single leading linefeed if there is at least one other match.
.
Finally, we just count how many characters there are in the string.
C# (.NET Core), score ∞ (I mean, 209)
b=>b.Distinct().Select(z=>{var w=b.Count(p=>p==z);return w*(w+1)/2;}).Sum()
The score includes the following:
using System.Linq;
Clojure, score 96
#(apply +(for[[k j](frequencies %)](*(inc j)j 0.5)))
Five spaces and pairs of brackets...
Python 2, score 108
lambda S:sum(S.count(Q)*(S.count(Q)+1)/2for Q in set(S))
Still golfing :)
JavaScript (Firefox 30+), score 68
S=>[for(C of(T=0,S))T+=S.split(C).length]&&T/2
This uses array comprehensions which were originally planned for ES7, but were dropped late in the process. Firefox had implemented them anyway.
Haskell, score 52 51
f(a:b)=1+sum[1|c<-b,c==a]+f b;f _=0
There's a tab between f and _.
The value of the empty string is 0. The value of the string s, where a is the first char and b the rest of the string is 1 plus the occurrences of a in b plus a recursive call with b.
Perl 6, score 61 56 53 46 44
(1 X..*.comb.Bag.values).flat.sum
{sum flat 1 X.. .comb.Bag.values}
{sum flat 1 X.. values(.comb.Bag)}
{[+] flat 1 X.. values(.comb.Bag)}
{[+] flat 1 X.. values(bag
.comb)}
APL (Dyalog), score 15
+/1 1⍉+\∘.=⍨⍞
⍞ get text input
∘.=⍨ equality table with self
+\ cumulative sum across
1 1⍉ diagonal (lit. collapse both dimensions into dimension one)
+/ sum
Python 2, score 83
lambda z:sum((2*z.count(x)+1)**2/8for x in set(z))
1/8 (1 + 2 n)^2 -1/8 is the same as n (n+1) / 2. Floor division removes the need to subtract 1/8.
JavaScript (ES6), score 81 78
Saved 3 points thanks to @Arnauld
s=>s.replace(d=/./g,z=>q+=d[z]=-~d[z],q=0)&&q
My original score-81 recursive solution:
f=([c,...s],d={})=>c?(d[c]=-~d[c])+f(s,d):0