# Indexize a number

Given a string of digits or an integer as input, you will have to indexize it.

This is how you modify the input. We will use 30043376111 as an example:

First, find the sum of the indices of each occurrence of the respective digits:

0: 1 + 2 = 3
1: 8 + 9 + 10 = 27
3: 0 + 4 + 5 = 9
4: 3
6: 7
7: 6


Then, construct a new integer or string where the digits above go in the order of the sums of their indices. In the case that multiple digits yield the same sum, the smaller digit comes before the larger one:

047631


Finally, remove any leading zeroes, and return or print the result:

47631


You must write a program or function which returns or prints the input indexized.

This is , so shortest code in bytes wins!

More test cases can be added if requested.

• For functions, is returning a string okay? How about taking a string as an argument? Mar 28, 2017 at 19:38
• @ConorO'Brien Given a string of digits or an integer Mar 28, 2017 at 19:39
• @AdmBorkBork Well, that answers the input question >_> Mar 28, 2017 at 19:40
• @ConorO'Brien Also, construct a new integer or string, which sounds like returning a string is OK, too. Mar 28, 2017 at 19:41
• May I take input as a list of characters? May I use 1-indexing instead of 0-indexing (if specified in answer)? Nov 1, 2022 at 0:45

# J, 14 bytes

~.".@/:1#.I.@=


Accepts a string, returns a number.

Attempt This Online!

~.".@/:1#.I.@=
I.@=  NB. = makes a boolean table of occurrences, each row is a unique item
@   NB. monadic atop, f@g y => f g y
I.    NB. returns indices of 1s in each boolean list from =
1#.      NB. sums each resulting list
~.              NB. returns unique items from input
".@/:         NB. /: sorts x by y
@           NB. dyadic atop, x f@g y => f x g y
".            NB. eval resulting indexized string


## Haskell, 69 bytes

import Data.List
f x=0+read(nub$sortOn(\d->(sum$elemIndices d x,d))x)


Takes a string, returns a number. Usage example: f "30043376111" -> 47631. Try it online!

Pretty straight forward: sort the digits of the input string first on the sum of their indices and the by the digit itself (-> pairs of (sum ...,d)), remove duplicates and convert to a number to remove leading 0. The 0+ is needed to get the types right.

# Stacked, 59 bytes

:@q uniq[:q\eq q size:>*sum,]map[-1#]sortby[0#]map''#'^0'-


Try it online!

This takes a character string (like $'1231231') as input from the top of the stack, and leaves a string on the stack. ## Explanation :@q uniq[:q\eq q size:>*sum,]map stack: (str) : stack: (str str) @q stack: (str) ; store as q uniq stack: (str') ; de-duplicate [ ]map map the inner over each element : stack: (chr chr) q\eq stack: (chr q') ; q' is where equality occurs q size:> stack: (chr, q', k) ; k is range from 0, size(q') *sum stack: (chr, k') ; k' is sum of indices , stack: ((chr, k'))  Now we are left with pairs of (chr, sum of indices). [-1#]sortby[0#]map''#'^0'- [ ]sortby sort by the inner function - vectorized subtraction of two pairs 1# use the second element as the comparison [0#]map get the first element of each row ''# join by the empty string '^0'- remove all leading zeroes  # 05AB1E, 29 28 bytes -1 thanks to Riley TFN¹SQDg<ÝsÏON‚}){vyD0å_i1è,  Try it online! TFN } # Loop from 0 to 9. ¹SQ # Push 1 if index is same as y. Dg<ÝsÏ # Push index of the number instead of 1. ON‚ # Sum, combine with current y. ){ # Collect, sort 'em. vyD0å_i1è, # Only print the ones with a count above 0.  • Can you substitute TFN for 9Ývy Mar 28, 2017 at 20:05 • @Riley 05AB1E is a weird language... It seems the longer you use it the more you attempt to over-complicate EVERYTHING... Thanks, yes, that does seem to work fine. Mar 28, 2017 at 20:13 # JavaScript (ES6), 98 bytes n=>+[...new Set(n)].sort().sort((a,b)=>(s=d=>[...n].reduce((S,D,i)=>S+i*(d==D),0))(a)-s(b)).join  Takes a string n, then converts it to a Set and then to an Array of distinct digits. Sorts these digits in numerical order, then sorts again according to sums of indices. Concatenates the sorted Array to a String, and finally converts to a Number to remove leading zeros. f= n=>+[...new Set(n)].sort().sort((a,b)=>(s=d=>[...n].reduce((S,D,i)=>S+i*(d==D),0))(a)-s(b)).join console.log(f('30043376111')) • is the repeated sort necessary? Mar 28, 2017 at 20:38 • Yes, "In the case that multiple digits yield the same sum, the smaller digit comes before the larger one". Without the first .sort(), an input of 1332 yields 132 instead of 123. Mar 29, 2017 at 0:24 • Ah, okay, I see Mar 29, 2017 at 1:11 # Jelly, 10 bytes Ġ’S$ÞịDFQḌ


Try it online!

Takes and returns an integer.

### How?

Ġ’S$ÞịDFQḌ - Main link: n e.g. 30043376111 Ġ - group indices of n by value [[2,3],[9,10,11],[1,5,6],[4],[8],[7]] (implicitly treats the number as a decimal list) Þ - sort that by:$       -     last two links as a monad:
’         -         decrement (since Jelly is 1-indexed)
S        -         sum                  [[2,3],[4],[7],[8],[1,5,6],[9,10,11]] (this leaves those indices of lower value to the left as required)
D    - decimal list of n            [3,0,0,4,3,3,7,6,1,1,1]
ị     - index into                   [[0,0],[4],[7],[6],[3,3,3],[1,1,1]]
F   - flatten                      [0,0,4,7,6,3,3,3,1,1,1]
Q  - unique                       [0,4,7,6,3,1]
Ḍ - cast to a decimal number     47631


# k, 7 bytes

.<+/'=$ online repl $30043376111 / convert to string($) "30043376111" =$30043376111 / group(=) - return a mapping (dict) from unique chars to indices
"304761"!(0 4 5
1 2
,3
,6
,7
8 9 10)
+/'=$30043376111 / sum(+/) each(') value in the dict "304761"!9 3 3 6 7 27 <+/'=$30043376111 / grade(<) ascending values - return keys from the dict
"047631"

# 05AB1E, 11 bytes

ΣISQā<*O}Ùï


Try it online.

Could be 9 bytes if 1-based indexing is allowed by replacing ā<* with ƶ, in which case 4 would come before the 0 in the example, because 0: 2 + 3 = 5 and 4: 4: try it online.

Explanation:

Σ         # Sort the digits of the (implicit) input by:
I        #  Push the input
S       #  Convert it to a list of digits
Q      #  Check for each if it's equal to the current digit (resulting in 1s/0s)
ā<*   #  Multiply each check by its 0-based index:
ā     #   Push a list in the range [1,length] (without popping)
<    #   Decrease each by 1 to make it the range [0,length)
*   #   Multiply the values at the same indices in the two lists
O  #  Sum the lists together
}Ù        # After the sort-by: uniquify the digits
ï       # Cast it to an integer to remove potential leading 0s
# (after which the result is output implicitly)


# APL (Dyalog Unicode), 77 bytes

{⍎⊃{⍺[⍋⍵]}/{(⊂⊂⍋⊃⍵)⌷¨⍵}↓⍉{⍺(+/⍵-1)}⌸⍵}


Try it online!

# Vyxal, 85 62 bits1, 10.625 7.75 bytes

µ?f=T∑;Uṅ⌊


Try it Online! (link is to bitstring)

-2.875 bytes (2 characters) thanks to @lyxal

#### Explanation

µ?f=T∑;Uṅ⌊  # Implicit input (as a string)
µ     ;     # Sort input string by:
?f         #  List of characters of input
=        #  Equals the current character?
T∑      #  Sum of truthy indices
Uṅ⌊  # Uniquify and convert to integer
# Implicit output


Old:

fDÞzµ∑;İfU₀β  # Implicit input
fD            # Convert to digit list and duplicate
Þz          # Group by indices
µ∑;       # Sort by sum
İfU    # Index in, flatten, uniquify
₀β  # Convert from digit list
# Implicit output


# Thunno 2, 10 bytes

Þ$d=VS;UJN  Port of my Vyxal answer (suggested by @lyxal) #### Explanation Þ$d=VS;UJN  # Implicit input
Þ     ;     # Sort the input string by:
$d= # Vectorised equality with the input string's characters VS # Sum of truthy indices of that list UJN # Uniquify, join, and convert to integer # Implicit output  # PHP, 103 Bytes for(;$i<strlen($a="$argv[1]");)$r[$a[$i]]+=$i++;ksort($r);asort($r);echo ltrim(join(array_keys($r)),0);  # Python 2, 102 92 bytes Thanks to Ben Frankel for saving 10 bytes! a={} for i,j in enumerate(input()):a[j]=a.get(j,0)+i print int(''.join(sorted(a,key=a.get)))  Try it Online! Takes input as a string and outputs an integer. Uses a dictionary to store the sum of indexes, then sorts it by value. Converts to an integer to strip off leading zeroes because int is shorter than .lsplit('0'). • a[j]=a.get(j,0)+i saves 10 bytes. Mar 29, 2017 at 0:54 # Python 3.5, 86 85 bytes Thanks @Ben Frankel for saving a byte: f=lambda s:int(''.join(sorted({*s},key=lambda d:sum(i*(c==d)for i,c in enumerate(s)))))  Old code: lambda s:int(''.join(sorted({*s},key=lambda d:sum(i for i,c in enumerate(s)if c==d))))  Anonymous function taking a string of digits and returning an integer • sum(i*(c==d)for saves 1 byte. Mar 30, 2017 at 1:56 # Pip, 18 bytes +J:$+(a@*_)SKSNUQa


Takes the number as a command-line argument. Try it online!

### Explanation

                    a is 1st cmdline arg (implicit)
UQa  Get unique digits in a
SN     Sort (numerically)
SK       Then sort with this key function:
a@*_           Find all indices of argument in a
$+( ) and sum them J: Join the resulting list back into a string (: is used to lower the precedence of J) + Convert to number (eliminates leading 0) Print (implicit)  # Scala, 123 104 bytes (_:String).zipWithIndex.groupBy(_._1).toSeq.sortBy(c=>c._2.map(_._2).sum->c._1).map(_._1).mkString.toInt  Example (using Scala REPL): scala> (_:String).zipWithIndex.groupBy(_._1).toSeq.sortBy(c=>c._2.map(_._2).sum->c._1).map(_._1).mkString.toInt res0: String => Int = <function1> scala> res0("30043376111") res1: Int = 47631  Pretty straightforward, using tuple as sorting predicate for secondary sort. # Pyth, 9 bytes sosxNcQ1{  Try it online Takes a string of digits as input. sosxNcQ1{ sosxNcQ1{Q Implicit variable introduction {Q Unique digits o Order by cQ1 Chop input into list of individual characters. xN Find all indexes of the digit in question in the list. s Sum s Convert string to integer.  # Ruby, 96 bytes I'm sure this can be golfed more. ->a{(0..9).map{|n|[(0...a.size).select{a[_1]==n}.sum,n]}.select{_1[0]>0}.sort.map{_2}.join.to_i}  Attempt This Online! # Japt v2.0a0 -N, 10 bytes ñ ñ@ðX xÃâ  Try it Input as a string Explanation: ñ ñ@ðX xÃâ ñ # Sort the digits by value ñ@ Ã # Stable-sort the digits by this function: ðX # Find all indices where it appears in the input x # Sum them â # Remove repeated characters -N # Convert the string to number (removes leading 0)  • 10 bytes, with the -N flag. Nov 1, 2022 at 0:16 • @Shaggy Good find, I looked into -N but it didn't work on arrays of digits so I didn't find a way to use it. Nov 1, 2022 at 15:18 • Actually, do we need the first sort here? Dec 23, 2022 at 0:05 # K (ngn/k), 16 7 bytes .<+/'=:  Try it online! Down 9 bytes thanks to ovs for the sum tip! A pretty literal implementation of the challenge. Takes a string and output an integer. Explanations: .<+/'=: Main function. Takes implicit input with : = Group, creates a dictionary with characters as the keys and their occurances position as the values ' In each of the key's values... +/ Sum < Sort by ascending order . Evaluate  • Applying +/' to a dictionary implicitly applies +/ to each key and returns an updated dictionary. – ovs Nov 12, 2022 at 8:52 ## C#, 245 bytes using System.Linq;s=>{var a=new int[10];for(int i=0,l=0;i<10;i++){a[i]=-1;while((l=s.IndexOf(i+"",l+1))!=-1)a[i]+=l;}return string.Concat(a.Select((c,i)=>new{c,i}).OrderBy(o=>o.c).ThenBy(o=>o.i).Where(o=>o.c>-1).Select(o=>o.i)).TrimStart('0');};  Not happy with how long it ended up being and it can probably be shorter but this is what I ended up with. # Perl 6, 65 61 52 bytes {+[~] {}.push(.comb.map:{$_=>$++}).sort({.value.sum,.key})».key}  Try it {+[~] {}.push(.comb.antipairs).sort({.value.sum,.key})».key}  Try it {+[~] .comb.antipairs.Bag.sort({.value,.key})».key}  Try it ## Expanded { # bare block lambda with implicit parameter ｢$_｣

+    # turn the following into a Numeric
[~]  # reduce the following using &infix:<~> (join)

.comb              # list of digits from ｢\$_｣ (implicit method call)
.antipairs         # get a list of ｢value => index｣ pairs from above list
.Bag               # combine them together (does the sum)
.sort(
{ .value, .key } # sort it by the sum of indexes, then by the digit
)».key             # get the list of digits from that
}


# Scala, 131 bytes

Golfed version. Try it online!

def f(x:String)=scala.collection.immutable.SortedSet(x:_*)(Ordering.by((d:Char)=>(x.indices.filter(x(_)==d).sum,d))).mkString.toInt


Ungolfed version. Try it online!

import scala.collection.immutable.SortedSet

object Main {
def main(args: Array[String]): Unit = {
println(f("30043376111"))
}

def f(x: String): Int = {
val sortedUnique = SortedSet(x: _*)(Ordering.by((d: Char) => (x.indices.filter(x(_) == d).sum, d)))
sortedUnique.mkString.toInt
}
}
`