# The Original Number (II)

This challenge is essentially identical to this one with just one difference: it is now allowed to shuffle letters anywhere in the string.

## Scenario

John has an important number, and he doesn't want others to see it.

He decided to encrypt the number, using the following steps:

His number is always a non-decreasing sequence (ie. "1123")

He converted each digit into English words. (ie. "123" -> "ONETWOTHREE")

And then, rearrange the letters randomly. (ie. "ONETWOTHREE" -> "EEWOOHRNTET")

John felt that his number were safe in doing so. In fact, such encryption can be easily decrypted :(

Given the encrypted string s, your task is to decrypt it and return the original number.

## Rules

• This is code golf, so the shortest answer in bytes wins
• You can assume that the input string is always valid
• The input string only contains uppercase letters
• The original numbers are always arranged in ascending order
• You may return the number in string or integer format
• The letters will only be shuffled between one word, not between the whole string. The letters can be shuffled anywhere in the string.
• The numbers will only be from 1 to 9 inclusive (ONE to NINE)

## Possible Unscrambled String

Here is a list of the strings just after they have been converted to strings from the numbers:

1 -> ONE
2 -> TWO
3 -> THREE
4 -> FOUR
5 -> FIVE
6 -> SIX
7 -> SEVEN
8 -> EIGHT
9 -> NINE

## Examples

"NEO" -> 1

"NWEOOT" -> 12

"TOEERWNEHOT" -> 123

"IHNEVGENNEISTE" -> 789

"WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" -> 123456789

"EWHEWROETOTTON" -> 1223

• Suggested test case: something like "ONEWESTV" -> 27 (includes a number that doesn't actually appear) – ETHproductions Aug 28 '17 at 15:52
• @ETHproductions Great idea! Added. – Cristian Lupascu Aug 28 '17 at 16:58
• Why there is not the "ZERO"? – user58988 Aug 29 '17 at 20:33
• @RosLuP John hates leading zeroes... – Cristian Lupascu Aug 29 '17 at 20:42

# Python 2, 123 bytes

c=map(input().count,"OWHUFXSGIQ")
i=4
for j in"71735539994":c[i*2]-=c[int(j)];i=-~i%5
s=""
for n in c:i+=1;s+=i*n
print s

A full program taking quoted input and printing John's number.

Try it online! or see a test-suite

### How?

Let's work with the example "NEONSEXTOWNII" (to yield 1269, and be somewhat Leisure Suite Larry-esque!)

First c=map(input().count,"OWHUFXSGIQ") takes input and counts the number of each of OWHUFXSGIQ - these are letters that appear in each number in ascending order, with 2,4,6, and 8 having their "own" letters (WUXG), plus an extra letter, Q to append a zero to the the end and make the length of the resulting list even. For the example:

[2,1,0,0,0,1,1,0,2,0] <- c
O W H U F X S G I Q  <- is the counts of these letters
1 2 3 4 5 6 7 8 9 0  <- which "relate to" these digits in John's number
2   4   6   8   0  <- these will be correct as the letters are unique to their words

The entries for 1, 3, 5, 7, and 9 need adjusting to correct the abundance of the other letters. This is performed by the next loop:

i=4
for j in"71735539994":c[i*2]-=c[int(j)];i=-~i%5

Note that the entries to adjust are alternate ones (1,3,5,7,9,1,3,5,...), so we can add two to an index variable at each step and modulo by 10 to stay in range if we need to traverse more than once (which we do). To save some bytes we can increment by one and modulo by 5 and use double the index.
Since the adjustments for 9 require the most work we start there - it resides at index 8 so we start at i=4. The string "71735539994" then gives the indexes, j, of the values to remove at each stage (where we have ensured the ninth index will contain zero by using "Q" when creating c); c[i*2]-=c[int(j)] performs each individual adjustment and i=-~i%5 moves i to the next index (where -~i is -(-1-i) or i+1 saving parentheses (i+1)%5) keeping i*2 within the bounds of c.
Thus we first subtract the number at index j=7 from that at index i*2=8, subtracting the number of "G"s counted from the number of "I"s, adjusting the "NINE" count down by the (correct) number of "EIGHT"s (which also has an "I"). We then move onto i=0 (-~4%5 = (4+1)%5 = 0), referencing index i*2 = 0 which is for "ONE" and subtract the value found at index j=1 the entry counting "W" and hence "TWO", adjusting the count of "O"s down. By the end of the loop we have the corrected counts:

[1,1,0,0,0,1,0,0,1,0] <- c   (for 1223333448 it would be: [1,2,4,2,0,0,0,1,0,0])
1 2 3 4 5 6 7 8 9 0

so all that remains is to print out what c now represents (1269). i is now back at 0, so we increment it at the start of the loop and use it as our digit:

s=""
for n in c:i+=1;s+=i*n
print s

The back ticks, i, are Python2 shorthand for repr(i) which gets a string representation of an object (the digit character in question as a string) and multiplying a string by a number creats a new string of that many repeats (here we only show n=0 turning i from say "5" to "" and n=1 turning keeping say "6" as "6", but it also works for larger positive integers, so "3"*4 becomes "3333" for example.)

# 05AB1E, 31 bytes

[{‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#NSèJ{Q#

Try it online!

Explanation

[                                   # start loop
{                                  # sort input
‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#            # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']
N           # push the current iteration counter
S          # split to list of digits
è         # index into the list with each
J{       # join to string and sort
Q#     # if the strings are equal, exit loop
# implicitly print iteration counter

Very inefficient for large input.

• ‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE'] : can you explain a little, I struggle to understand how any string can be generated. – Cyril Gandon Aug 31 '17 at 13:58
• @CyrilGandon: delimits an upper-case compressed string of space separated words. Z means Z. All other 2-symbol pairs denote a compressed word from 05AB1E's dictionary. So for example €µ translates as ONE. – Emigna Aug 31 '17 at 14:01
• Nice, how do you compress a string contains in the dictionary? Something with the unicode value of the pair? – Cyril Gandon Aug 31 '17 at 14:05
• @CyrilGandon: You take the line number of the word in the dict (2420 for hello) and subtract 1. This gives us 2419. The symbols we need are the symbols which are followed by 24 and 19 in the docs. In our case this is 24=Ÿ and 19=™, so HELLOwould be ‘Ÿ™‘ – Emigna Aug 31 '17 at 14:11
• There is also a compressor written by Adnan you can use in most instances. The link is a bit long, but you can find it in the 05AB1E chat room. That is also a good place to ask if have any further questions :) – Emigna Aug 31 '17 at 14:14

# Retina, 112 97 bytes

O.
}GH
8
X
6
H
3
+F(.*)O(.*)U
4$1$2
+O(.*)W
2$1 +F(.*)V 5$1
+N(.*)V

Try it online!

# Python 3, 225 bytes

def f(s):
r=[]
for i,w in zip([2,4,6,8,3,5,7,1,9],["WTO","UFOR","XSI","GEIHT","HTREE","FIVE","VSEEN","ONE","NINE"]):
while s.count(w[0]):
r+=[i]
for l in w:s="".join(s.split(l,1))
return "".join(sorted(map(str,r)))

Try it online!

Straightforward: remove the digits which are identified by a specific letter first.

# Python 3, 125 bytes

lambda s:''.join(min(w)*(2*sum(map(s.count,w[:2]))-sum(map(s.count,w)))for w in"O1WU W2 H3G U4 F5U X6 S7X G8 IUFXG9".split())

Try it online!

After reading the linked challenge I realized this is a variation on mdahmoune's Python solution, which is itself based on Draco18s's ES6 solution, but hey, at least we golfed off two bytes.

Like that solution, we compute the answer through a linear combination of the number of occurrences of certain letters. We encode the linear combinations briefly by writing them as words where the first two letters are to be added and everything afterwards is to be subtracted. Sometimes a character is needed to pad the first two characters; we use this to hide the digit we want to output (which will never occur in the input, so won't affect our algorithm), which we extract with min.

## R, 154

u=utf8ToInt(s)-71
m=sum
b=m(u==16)
d=m(u==14)
f=m(u==17)
a=m(u==8)-b-d
g=m(u==12)-f
cat(rep(1:9,c(a,b,m(u==11)-d,d,m(u==15)-g,f,g,m(!u),(m(u==7)-a-g)/2)))

Try it online!

# Axiom, 351 bytes

s:="GXUWRFVIONETHS";e:EqTable(CHAR,INT):=table();v:=[8,6,4,2,3,5,7,9,1];z:=[k for k in 1..46|prime?(k)];F(x,y)==>for i in 1..#x repeat y;F(z,e.(s.i):=z.i);t:=[1787026,2451,16445,5957,16036207,130169,20372239,495349,20677];h(a)==(r:=1;F(a,r:=r*e.(a.i));j:=[];F(v,while r rem z.i=0 repeat(r:=r quo t.i;j:=cons(v.i,j)));j:=sort j;k:=0;F(j,k:=k*10+j.i);k)

ungolfed commented results

s:="GXUWRFVIONETHS" -- tutte le lettere di ONE..NINE in ordine di importanza
e:EqTable(Character,Integer):=table()
v:=[8,6,4,2,3,5,7,9,1]              -- numeri da controllare in quell'ordine di apparizione di v
z:=[k for k in 1..46|prime?(k)]     -- 14 numeri primi da associare a s
F(x,y)==>for i in 1..#x repeat y
F(z,e.(s.i):=z.i)                   -- riempie la tavola associando numeri primi alle lettere "GXUW..."
t:=[1787026,2451,16445,5957,16036207,130169,20372239,495349,20677]  -- prodotto di numeri primi 1787026 dovrebbe essere HEIGHT
h(a)==
r:=1 ;F(a,r:=r*e.(a.i))        -- calcola il numero associato alla stringa a
j:=[];F(v,while r rem z.i=0 repeat(r:=r quo t.i;j:=cons(v.i,j)));j:=sort j  -- leva il nome dei numeri che man mano trova, aggiunge a j
k:=0 ;F(j,k:=k*10+j.i)         -- costruisce il numero decimale k, da j vettore ordinato
k                              -- ritorna tale numero k
------------------------------------------------------
(8) -> h("IHNEVGENNEISTE")
(8)  789
Type: PositiveInteger