The Original Number
Python 2, 121 117 115 bytes
def g(s,a=0,f=''):
for c in s:
a+=34**ord(c)%43;r='P!\x83u\x8eI\x92|Z'.find(chr(a))+1
if r:f,a=f+`r`,0
return f
-4 bytes: After all that golfing I forgot to inline a single-use variable. Brain fart.
-2 bytes: Double-spaced indent → single tab indent (thanks to Coty Johnathan Saxman); note that this does not display correctly in the answer.
Ungolfed (compatible with python 3):
nums = [80, 33, 131, 117, 142, 73, 146, 124, 90]
def decode(str):
acc = 0
final = ''
for c in str:
acc += (34**ord(c))%43
if acc in nums:
final += str(1+nums.index(acc))
acc=0
return final
Magic number finder:
#!/usr/bin/env python3
from itertools import count, permutations
def cumul(x):
s = 0
for v in x:
s += v
yield s
all_words = 'ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()
for modulo in range(1, 1000):
for power in range(1, 300):
combinations = []
for word in all_words:
my_combination = []
for perm in permutations(word):
my_combination += cumul(power**(ord(x)) % modulo for x in perm)
combinations.append(my_combination)
past_combinations = set(())
past_intermediates = set(())
collision = False
for combination in combinations:
final = combination[-1]
if final in past_intermediates or any(intermediate in past_combinations for intermediate in combination):
collision = True
break
past_combinations.add(final)
past_intermediates.update(combination)
if not collision:
print("Good params:", power, modulo)
print("Results:", ", ".join(str(x[-1]) for x in combinations))
Explanation:
I had a feeling that I could smash the ASCII bits together and sum them up somehow to determine when I had a full word. Originally I tried messing with 3**ord(letter)
and comparing to expected results, but it resulted in some very large numbers. I though it would be appropriate to brute-force some parameters a little, namely modulus (to ensure the numbers are small) and a multiplier to disperse the numbers differently around the range of the modulus.
I ended up changing the multiplier variable into a variable affecting the power itself because (from trial and error) that somehow managed to give me a slightly shorter golfed answer.
And above you see the results of that brute-forcing and a little manual golfing.
The reason for choosing 3**x
originally is because I knew you could represent every number there. The most repeated digits any number had is two (thrEE, sEvEn, NiNe, etc), so I decided to think of every input as a base-3 number. That way I could (mentally) represent them as something like 10100000000010020000
(three; a 1 in the t
slot, a 1 in the r
slot, a 1 in the h
slot, and a 2 in the e
slot). Each number this way gets a unique representation which can be easily pieced together by iterating the string and summing some numbers, and it ends up independent of the actual order of the letters. Of course, this didn't turn out to be the ideal solution, but the current solution is still written with this idea in mind.
Python 2,131 127 bytes
s=input()
for y in'WXGURFSOIZ':vars()[y]=s.count(y)
while Z<9:s+=[O-U-W,W,R-U,U,F-U,X,S-X,G,I-X-G-F+U][Z]*str(Z+1);Z+=1
print s
Try it online!
Based on a corrected version of the JavaScript Draco18s solution.
PHP, 164 bytes
for($c=count_chars($argn);$i<9;)echo str_pad("",[$c[79]-$c[87]-$u=$c[85],$c[87],$c[72]-$g=$c[71],$u,$f=$c[70]-$u,$x=$c[88],$c[86]-$f,$g,$c[73]-$x-$f-$g][+$i],++$i);
Try it online!
PHP, 179 bytes
based on the previous approach check first the even numbers and then the odd numbers in increasing order
for($z=[$o=($c=count_chars($argn))[87],$f=$c[85],$x=$c[88],$g=$c[71],$c[79]-$o-$f,$c[72]-$g,$v=$c[70]-$f,$c[86]-$v,$c[73]-$x-$v-$g];$i<9;)echo str_repeat(++$i,$z[_405162738[$i]]);
Try it online!
PHP, 201 bytes
for(;$o=ord(WUXGOHFVN[$i]);$i++)for(;$r[$o]<count_chars($argn)[$o];$t[]=$i>3?2*$i-7:2+2*$i,sort($t))for(++$r[$o],$n=0;$q=ord(([TO,ORF,IS,HEIT,EN,TREE,IVE,SEEN,NIE][+$i])[$n++]);)$r[$q]++;echo join($t);
Try it online!