El número original


36

Pautas

Guión

John tiene un número importante y no quiere que otros lo vean.

Decidió encriptar el número, siguiendo los siguientes pasos:

Su número siempre es una secuencia no decreciente (es decir "1123") .

Convirtió cada dígito en palabras en inglés. (es decir "123" -> "ONETWOTHREE")

Y luego, reorganiza las letras al azar. (es decir "ONETWOTHREE" -> "ENOWTOHEETR")

John sintió que su número estaba seguro al hacerlo. De hecho, dicho cifrado se puede descifrar fácilmente :(


Tarea

Dadas las cadenas cifradas, su tarea es descifrarla y devolver el número original.


Reglas

  • Este es el código de golf, por lo que gana la respuesta más corta en bytes
  • Puede suponer que la cadena de entrada siempre es válida
  • La cadena de entrada solo contiene letras mayúsculas
  • Los números originales siempre están ordenados en orden ascendente.
  • Puede devolver el número en formato de cadena o entero
  • Las letras solo se mezclarán entre una palabra, no entre toda la cadena.
  • Los números solo serán del 1 al 9 inclusive ( ONEa NINE)

Posible cadena descifrada

Aquí hay una lista de las cadenas justo después de que se hayan convertido a cadenas de los números:

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

Ejemplos

"NEO" -> 1

"ENOWOT" -> 12

"EONOTWHTERE" -> 123

"SNVEEGHEITNEIN" -> 789

"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" -> 123456789

"NOEWOTTOWHEERT" -> 1223


55
En todos los casos de prueba, solo se mezclan las letras dentro de una palabra, no las letras entre palabras. ¿Será ese siempre el caso?
xnor

1
@xnor Ese siempre será el caso. He editado la pregunta.
Amorris

1
entonces necesita cambiar esto ".... (es decir," ONETWOTHREE "->" TTONWOHREEE ")"
J42161217

2
@ TessellatingHeckler: una secuencia que no aumenta estrictamente es cuando el siguiente número puede ser el mismo que el anterior ex. 1-1-1-2-2-3 (no estrictamente creciente) en lugar de 1-2-3-4-5 (estrictamente creciente)
koita_pisw_sou

1
Técnicamente hablando, esta es una codificación, no un cifrado, ya que no hay clave.
Patrick Roberts

Respuestas:


5

Gelatina ,  38  37 bytes

ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽Gל?9¤Ḍ

Un enlace monádico que toma una lista de caracteres (la cadena) y devuelve un entero.

Pruébalo en línea!

Utiliza un muy diferente método para la respuesta de la jalea Pietu1998 , sin embargo, tiene el mismo número de bytes ( Me pareció que puede que no terminar como menos)!

No se basa en la monotonicidad del número original (por lo que una entrada de HTREEWTONOEfuncionaría, por ejemplo).

¿Cómo?

Primero tenga en cuenta que las palabras mismas (y, por lo tanto, cualquier anagrama de las mismas) se pueden cambiar a las de longitud 4 eliminando cualquier Rs, Gs y Ss y reemplazando cualquier Os con dos caracteres (digamos "12") y cualquier X con tres caracteres ( decir "345").

letters  -> -RGS  -> O:12, X:345
ONE         ONE      12NE
TWO         TWO      TW12
THREE       THEE     THEE
FOUR        FOU      F12U
FIVE        FIVE     FIVE
SIX         IX       I345
SEVEN       EVEN     EVEN
EIGHT       EIHT     EIHT
NINE        NINE     NINE

Luego, podemos mapear el producto de los ordinales de esos caracteres a los números del 1 al 9 utilizando la aritmética del módulo, dependiendo de nuestra elección (el "12345"), luego buscarlos en una lista reordenada de los dígitos. El código se convierte en caracteres primero y luego reemplaza los ordinales, pero también es posible en 37 bytes con caracteres, por ejemplo, "DIAAE" ( pruébelo ).

ḟ“RGS”O“OX‘,“¢©“¢¢¤‘yF×4/%74ị⁽Gל?9¤Ḍ - link: list of characters
 “RGS”                                - literal ['R','G','S']
ḟ                                     - filter discard
      O                               - convert to ordinals
       “OX‘                           - code-page indices list = [79,88]
            “¢©“¢¢¤‘                  - code-page indices lists = [[1,6],[1,1,3]]
           ,                          - pair -> [[79,88],[[1,6],[1,1,3]]]
                    y                 - translate (replace 79s (Os) with [1,6]
                                                       and 88s (Xs) with [1,1,3])
                     F                - flatten into a single list
                       4/             - 4-wise reduce by:
                      ×               -   multiplication (product of each window of four)
                         %74          - modulo 74
                                   ¤  - nilad followed by link(s) as a nilad:
                             ⁽G×      -   base 250 literal = 18768
                                œ?9   -   permutation of [1,2,3,4,5,6,7,8,9] at that
                                      -   index in a lexicographically sorted list of
                                      -   all such permutations -> [1,5,8,2,4,9,7,6,3]
                            ị         - index into
                                    Ḍ - convert from decimal digits to an integer

Su respuesta es, literalmente, la única respuesta en esta página que devuelve un valor correcto para: NINEONENIENOENNNIENOENNEINEONEINEONNENIENOINNEINENINNEINENIENNIENNNNIENNEININENIENNENINEINENINENNIEINNEINNENNIENIN.
Urna mágica de pulpo

+ Puntos infinitos.
Urna mágica de pulpo

¡Gracias! (eso me sorprendió porque hay espacios de ancho cero para el bloque de código en el comentario, pero (¡sí!) funciona )
Jonathan Allan

No es una entrada válida de todos modos;).
Urna mágica del pulpo

Oh wow, no sabía que vendría una recompensa, ¡gracias! Sí, no era parte de la especificación solicitada, solo hice un método que funcionaría con una entrada desordenada.
Jonathan Allan

10

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: después de todo ese golf, olvidé incluir una variable de un solo uso. Pedo cerebral.
-2 bytes: sangría a doble espacio → sangría de una sola pestaña (gracias a Coty Johnathan Saxman); tenga en cuenta que esto no se muestra correctamente en la respuesta.

Sin golf (compatible con 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

Buscador de números mágicos:

#!/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))

Explicación:

Tenía la sensación de que podía romper los bits ASCII y resumirlos de alguna manera para determinar cuándo tenía una palabra completa. Originalmente intenté jugar 3**ord(letter)y comparar los resultados esperados, pero resultó en algunos números muy grandes. Pensé que sería apropiado forzar un poco algunos parámetros, a saber, el módulo (para garantizar que los números sean pequeños) y un multiplicador para dispersar los números de manera diferente alrededor del rango del módulo.

Terminé cambiando la variable multiplicadora en una variable que afecta la potencia en sí porque (de prueba y error) que de alguna manera logró darme una respuesta ligeramente más corta.

Y arriba puedes ver los resultados de esa fuerza bruta y un poco de golf manual.

La razón para elegir 3**xoriginalmente es porque sabía que podía representar cada número allí. Los dígitos más repetidos que haya tenido cualquier número son dos (tres, sEvEn, NiNe, etc.), así que decidí pensar en cada entrada como un número de base 3. De esa manera podría (mentalmente) representarlos como algo así como 10100000000010020000(tres; un 1 en la tranura, un 1 en la rranura, un 1 en la hranura y un 2 en la eranura). Cada número de esta manera obtiene una representación única que se puede reconstruir fácilmente iterando la cadena y sumando algunos números, y termina independientemente del orden real de las letras. Por supuesto, esto no resultó ser la solución ideal, pero la solución actual todavía está escrita con esta idea en mente.


¿Qué es Py3K? ...
CalculatorFeline

Disculpas, editado (es el antiguo nombre de Python 3)
Score_Under

1
Es barato, pero puede guardar 2 bytes (ya que esto es Python 2) al sustituir su segundo nivel de sangría (dos espacios) para una sola pestaña. [ tio.run/##NU7NCoJAGDy7T/… ¡ Pruébelo en línea!]
Coty Johnathan Saxman

Además, es posible que pueda ahorrar 6 bytes utilizando literal \x83, \x8ey \x92en la cadena.
CalculatorFeline

@CalculatorFeline Desafortunadamente, mi intérprete no le gusta eso: SyntaxError: Non-ASCII character '\xc2' in file <stdin> on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details. Funciona si pongo el codingcomentario allí arriba, pero eso gana 15 bytes adicionales.
Score_Under

6

Python 2 , 131127 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

Pruébalo en línea!

Basado en una versión corregida de la solución JavaScript Draco18s .


¡Qué uso tan interesante vars!
xnor

@xnor fue sobre cómo aprendí eso para otros campos de golf :)))
mdahmoune

Muy inteligente. Tengo un +1 para adaptar mi respuesta (tan defectuosa como era originalmente).
Draco18s

5

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);

Pruébalo en línea!

PHP , 179 bytes

basado en el enfoque anterior, verifique primero los números pares y luego los números impares en orden creciente

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]]);

Pruébalo en línea!

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);

Pruébalo en línea!


falla paraENOOWTWTOWOT
Titus

@Titus ahora está arreglado. No he entendido bien la pregunta
Jörg Hülsermann

Sí, los ejemplos son algo engañosos. ¡Guau, eso costó! ¡¿Podrías romper eso ?!
Titus

@Titus Creo que he llegado al límite para encontrar otra forma de acercamiento
Jörg Hülsermann

1
$i++<9y en $ilugar de $i<10y ++$i(-1 byte); _405162738[$i]en lugar de $i%2?$i/2+4:$i/2-1(-4 bytes) ( $i/2+~($i%2*-5)también funcionaría, pero eso es un byte más).
Titus

5

Javascript (ES6), 288 150 144 bytes

q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``

const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']

testCases.forEach(testCase => console.log(testCase, q(testCase)))

Más largo que los otros dos, una de las otras entradas de JS, pero pensé que abandonaría un enfoque interesante que podría funcionar para alguien en otro idioma.

Esencialmente podemos determinar lo siguiente:

W -> 2
X -> 6
G -> 8
U -> 4

Cualquier aparición de estas letras implica que ese dígito existe en el número original. Desde aquí podemos deducir el resto de los dígitos:

R-U -> 3
F-U -> 5
S-X -> 7

Incluyendo los dos casos complicados:

O-(U+W) -> 1
I-(X+G+(F-U)) -> 9

Ambos 1y 9área dura comparativamente. Para ONE, Eaparece más de una vez en algunas palabras ( SEVENtiene dos) como hace N( NINE), por lo que estamos atascados con la verificación de lo Oque ocurre en otros dos lugares, afortunadamente, ambos son simples.

Para NUEVE, nueve es difícil, no importa cómo lo corte.

Así terminamos con este mapa:

[u=(l=t=>s.split(t).length-1)`U`,  //unused 0; precompute 'U's
 l`O`-l`W`-u,    //1
 l`W`,           //2
 l`R`-w,         //3
 u,              //4
 f=l`F`-u,       //5
 x=l`X`,         //6
 l`S`-x,         //7
 g=l`G`,         //8
 l`I`-x-g-f]     //9

9 es capaz de hacer referencia a siX, eiGht y Five (con 5 referencias hacia atrás) con las asignaciones variables, ahorrando bytes. Gracias a Neil por esto, utiliza varias características de JS con las que no estoy muy familiarizado ( ('por ejemplo, los ticks de fondo para la eliminación ) y en realidad se acerca mucho más a la idea que había escrito en papel antes de intentar codificarlo. (Dejé 9 como "lo que sobra", pensando en ello como "si veo Xque puedo eliminarlo y an Sy Ide la cadena, entonces ..." para que después de los cuatro casos simples los siguientes 3 se conviertan simple).

La razón por la que esta entrada es interesante es porque puede manejar cualquier cadena aleatoria como entrada. es decir, en lugar de barajar las palabras individuales, podemos barajar la cadena completa, que es lo que pensé que John estaba haciendo originalmente:

q=s=>[u=(l=t=>s.split(t).length-1)`U`,l`O`-l`W`-u,l`W`,l`R`-w,u,f=l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g-f].map((n,i)=>`${i}`.repeat(i&&n)).join``

const testCases = ['XENSENINEVSI']

testCases.forEach(testCase => console.log(testCase, q(testCase)))


1
Genial, pero hay un problema al contar 9 ... Creo que puede ser ixg-f + u
mdahmoune

@mdahmoune Shoot, tienes razón. Lo estropeé. : <
Draco18s

Ahorre 4 bytes usando s.split(t).length-12 bytes usando s.repeat(n>0&&n)(¿por qué es n menor que cero de todos modos? Ahorra 7 bytes). Ahorre un montón de bytes declarando gel alcance de smodo que no tenga que seguir pasándolo todo el tiempo, y mejor aún, puede convertirlo en una plantilla etiquetada, lo que ahorra 55 bytes en total (antes de 9 correcciones). Ahorre más bytes guardando valores repetidos en temporarios, y eliminé algunos más usando map:s=>[,(l=t=>s.split(t).length-1)`O`-l`W`-l`U`,w=l`W`,l`R`-w,u=l`U`,l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g].map((n,i)=>`${i}`.repeat(n)).join`` .
Neil

@Neil No estoy seguro de por qué N alguna vez terminó en menos de cero, pero lo hizo al probar TRES. Seguí recibiendo un error e investigando descubrí que era necesario, pero todavía no estoy seguro. El mapa de la biblioteca con plantilla que tienes allí es JavaScript que ni siquiera sé leer. : D
Draco18s

@Neil Ah, bien, el motivo de la comprobación n> 0: Si no es un dos, pero hay tres. R = 0, W = 1. 0-1 = -1. Estaba teniendo problemas para resolverlo hace una hora, sabía que estaba relacionado con el cheque 3, pero estaba pasando un mal rato resolviéndolo (falta de café).
Draco18s

4

Mathematica, 133 bytes

(s={};c=Characters;j=c@#;Table[If[FreeQ[j~Count~#&/@c[#[[i]]]&@ToUpperCase@IntegerName@Range@9,0],s~AppendTo~i],{i,9}];FromDigits@s)&


entrada

"VENESGTHIEENNI"

salida

789


¿Podría guardar un byte extra con en c@#[[i]]lugar de c[#[[i]]]? Es posible que pueda guardar otro byte utilizando la sintaxis infija ~en Table.
numbermaniac

4

C #, 218 bytes

Version corta:

string q(string s){var n="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');for(inti=0,j;;i++)for(j=0;n[i].IndexOf(s[j])>=0;){if(++j==n[i].Length){var r=++i+"";for(;j<s.Length;r+=++i)j+=n[i].Length;return r;}}}

Versión ampliada:

string q(string s)
{
    var n = "ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".Split(',');
    for (int i = 0, j; ; i++)
        for (j = 0; n[i].IndexOf(s[j]) >= 0;)
        {
            if (++j == n[i].Length)
            {
                var r = ++i + "";
                for (; j < s.Length; r += ++i)
                    j += n[i].Length;
                return r;
            }
        }
}

Prueba en línea!

Siendo mi primera entrada, no estoy seguro acerca de las reglas ... Solo estoy contando el tamaño de la clase utilizada para descifrar, no el código que lo prueba, ¿verdad?

Editar

Y por diversión, esto es lo que comencé a hacer, no leer las reglas completas: S - Véalo en IdeOne . Se descifra incluso cuando los caracteres de un dígito se pueden codificar en cualquier lugar de la cadena.

Editar 2

Acortado según los consejos de TheLethalCoder. ¡Gracias!

Editar 3

Y ahora Titus se afeitó unos pocos bytes más. ¡Gracias!


2
Hola y bienvenidos a PPCG! Solo necesita incluir el método, puede eliminarlo public static. Puede convertir a un método anónimo como s=>{<do stuff>return"";}. Puede usar varalgunas veces, declarar variables juntas ahorra bytes, es decir int i=1,j;. Crear una matriz a partir de una cadena y dividirla generalmente es más corta (aunque no lo he verificado en este caso), es decir "ONE|TWO".Split('|'). Puede usar en <0lugar de==-1
TheLethalCoder


@TheLethalCoder Grandes consejos, gracias!
SamWhan

No se ha probado en absoluto, pero creo que lo siguiente es el equivalente de su código para 221 bytes:s=>{var n="ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE".Split('|');for(int i=0,j;++i<= 9;)for(j=0;n[i-1].IndexOf(s[j])<0;){if(++j==n[i-1].Length){var r=i+"";while(j<s.Length){j+=n[i].Length;r+=++i;}return r;}}return "";}
TheLethalCoder

En una nota al margen, ¡generalmente es más fácil usar TIO para sus TIO!
TheLethalCoder

3

JavaScript (ES6), 142 139 Bytes

Guardado 3 Bytes gracias a Neil .

Actualmente no aprovecha los números, siempre están ordenados en orden ascendente

f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''

f=s=>s?'ENO|OTW|EEHRT|FORU|EFIV|ISX|EENSV|EGHIT|EINN'.split`|`.findIndex(w=>[...s.slice(0,y=w.length)].sort().join``==w)+1+f(s.slice(y)):''

const testCases = ['NEO', 'ENOWOT', 'EONOTWHTERE', 'SNVEEGHEITNEIN', 'ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN']

testCases.forEach(testCase => console.log(testCase, f(testCase)))


¿¿esperar lo?? "axbxc".split`x`.join``. ¿Cómo se llama esto? Parece que no puedo encontrar nada en Google.
Qwerty

@Qwerty: son etiquetas literales de plantilla , una función ES6 que estoy usando para guardar algunos bytes al no necesitar parens en el caso de splityjoin
Craig Ayre

Lo respondiste Conozco los literales de plantilla etiquetados, pero no me he dado cuenta de que también puedes usarlo en estas funciones. Gracias.
Qwerty

Están un poco diferente, que tienen literales plantilla (por ejemplo x=`foo${5+5}bar`), que están etiquetados cuando se llama a una función de usarlos sin parens: foo`foo${5+5}bar`lo que es lo mismo quefoo(['foo','bar'], 10)
Craig Ayre

1
f(s.slice(y))siempre es una cadena, por lo que no necesita el ''+anterior.
Neil

2

Jalea , 38 bytes

Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu
L3*Ç€iṢ

Pruébalo en línea!

Explicación

L3*Ç€iṢ    Main link. Argument: s (string)
L            Get length of s.
 3*          Raise 3 to that power. This will always be greater than n.
   ǀ        Get the name of each of the numbers using the helper link.
     iṢ      Find the position of the sorted input.

Dị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»Ḳ¤FṢŒu    Helper link. Argument: n (number)
D                                   Get digits of n.
  “©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»            The string "one two (...) eight nine AA".
                        Ḳ           Split that string at spaces.
 ị                                  Get name of each digit in the list.
                          F         Flatten to a single string.
                           Ṣ        Sort the characters.
                            Œu      Make uppercase.

Hay un problema con su código. Intenta pasarle la cuerda "EIGHTNINE":)
Amorris

@Amorris arreglado para 0 bytes.
PurkkaKoodari

Creo que no funciona para "VENESGTHIEENNI"
J42161217

Yo segundo @Jenny_mathy
Amorris

@Jenny_mathy El programa es muy ineficiente y se queda sin tiempo y memoria para entradas largas (lo sé, es realmente malo). Puede reemplazarlo 3con 2.2para usar un límite superior más pequeño, que le permite calcular fácilmente 789 sin cambiar el principio de funcionamiento. 2sería bueno, pero apenas fallaría para ciertas entradas con muchos seises.
PurkkaKoodari

2

Javascript (ES6), 221 bytes

s=>(m=btoa`8Ñ>Mc¾LtDáNQ!Q>HþHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)

Fragmento de código de ejemplo:

f=

s=>(m=btoa`8Ñ>Mc¾LtDáNQ…!Q>H…þHA7átþ4Ò`.split`+`.map(s=>RegExp(s.replace(/(.)\1*/g,c=>`(?=(.*${c[0]}){${c.length}})`))),t=0,r=0,[...s].map(c=>(t+=c,d=1,n=0,m.map((r,i)=>t.match(r)&&(d--,n=i)),d||(r=r*10+n+1,t=0))),r)

console.log(f("NEO"))
console.log(f("ENOWOT"))
console.log(f("EONOTWHTERE"))
console.log(f("SNVEEGHEITNEIN"))
console.log(f("ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN"))


2

Retina , 160 bytes

([ONE]{3})*([TWO]{3})*([THRE]{5})*([FOUR]{4})*([FIVE]{4})*([SIX]{3})*([SEVN]{5})*([EIGHT]{5})*([NIE]{4})*
$#1$*1$#2$*2$#3$*3$#4$*4$#5$*5$#6$*6$#7$*7$#8$*8$#9$*9

Pruébalo en línea! Basada en la respuesta de PowerShell de @TessellatingHeckler.


2

Retina , 88 bytes

[EFIST]

^(ON|NO)*
$#1$*1
O

W
2
HR|RH
3
UR|RU
4
X
6
GH|HG
8
(NN)*$
$#1$*9
r`NV|VN
7
V
5

Pruébalo en línea!

Explicación

  • Primero, suelte un montón de caracteres innecesarios que no son necesarios para la distinción
  • Elija los 1 del frente (esto nos permite soltar el resto de los Os inmediatamente después y aclara algunos N antes de llegar al lío 5, 7, 9)
  • 2, 3, 4, 6 y 8 ahora son triviales
  • Los 9 son un doble NN, así que tómalos del final antes de lidiar con 5 y 7
  • Reemplazar 7s desde la derecha (para no reducir VNV a 75 en lugar de 57)
  • 5s son las Vs restantes

Si agrega% (G` al encabezado, puede usar el código original y evaluará cada línea de la entrada por separado: TIO
PunPun1000

Gracias @ PunPun1000. Pensé que debía haber una manera de hacerlo, pero me di por vencido después de no encontrarlo rápidamente.
Kytheron

1

PowerShell , 182 bytes

[regex]::Replace("$args",'(?<1>[ONE]{3z2>[TWO]{3z3>[THRE]{5z4>[FOUR]{4z5>[FIVE]{4z6>[SIX]{3z7>[SVEN]{5z8>[EIGHT]{5z9>[NIE]{4})'.replace('z','})|(?<'),{$args.groups.captures[1].name})

Pruébalo en línea!

Sin codificar pero no funciona el código:

[System.Text.RegularExpressions.Regex]::Replace("$args",

    '(?<1>[ONE]{3})       
    |(?<2>[TWO]{3})
    |(?<3>[THRE]{5})
    |(?<4>[FOUR]{4})
    |(?<5>[FIVE]{4})
    |(?<6>[SIX]{3})
    |(?<7>[SVEN]{5})
    |(?<8>[EIGHT]{5})
    |(?<9>[NIE]{4})'

    ,{$args.groups.captures[1].name}
)

por ejemplo, (?<3>[THRE]{5})coincide con la clase de caracteres THRE, por lo que puede coincidir con ellos fuera de orden, y tiene que coincidir con cualquiera de estos caracteres cinco veces uno al lado del otro, y el grupo de captura se llama '3' para asignar nombres con números.

Compresión rudimentaria intercambiando el texto repetido })|(?<por a z.


1

C ++, 296 , 288 bytes

Version corta:

#define T string
using namespace std;T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};T Q(T S){T R="";for(int i=0;i<9;i++){do{if(S.find(N[i])!=T::npos){S.erase(S.find(N[i]),N[i].size());R+=to_string(i+1);}}while(next_permutation(N[i].begin(),N[i].end()));}return R;}

Versión completa:

#define T string
using namespace std;

T N[]={"ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE"};

T Q(T S)
{
    T R="";
    for(int i=0;i<9;i++)                             //for all possible                             
                                                     //codewords (ONE,TWO...NINE)   
    {
        do
        {   
            if(S.find(N[i])!=T::npos)                //if found in encrypted word
            {
                S.erase(S.find(N[i]),N[i].size());  //erase it from the word
                R+=to_string(i+1);                  //save integer to the result string
            }
                                                    //check next permuation of codeword  

        } while(next_permutation(N[i].begin(),N[i].end())); 
    }                                                   

    return R;
}

Prueba en línea!

Edit:
1) 200->296 bytes, for including namespace and definition of N in the count, as suggested by orlp 2) 296->288, for using macro, thanks to Zacharý


You need to include the definition of N and using namespace std; into your byte count.
orlp

I should be more specific, not just include it in your byte count but also into your answer. Your answer must be able to run just by calling Q right after it without any other additions.
orlp

I re-edited to include it all. For the definition of N i was not sure myself, but for the namespace, I usually dont include it (treat it as library stuff). Though, in the current code it is crucial for the string to work
koita_pisw_sou

1
Can you define a macro to save a few bytes? repl.it/JY7k
Zacharý

1

Ruby, 138 114 110 bytes

gsub(/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/){(1..9).find{|i|$~[i]}}

Byte count includes 1 byte for the -p option.

What?

This:

/#{"3ONE3TWO5THRE4FOUR4FIVE3SIX5SEVN5EIGHT4NIE".gsub(/(.)(\D+)/,'([\2]{\1})|')}/

is a regex literal which, through string interpolation, evaluates to:

/([ONE]{3})|([TWO]{3})|([THRE]{5})|([FOUR]{4})|([FIVE]{4})|([SIX]{3})|([SEVN]{5})|([EIGHT]{5})|([NIE]{4})|/

If we assign that to regex, the rest of the code is somewhat easy to grasp: Each match in the input is substituted with the number of the capturing group, extracted from the magical variable $~ which contains the current match data:

gsub(regex){(1..9).find{|i|$~[i]}}

Try it online!


1

Java 8, 198 256 bytes

s->{String r="",x=r;for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){for(char c:n.toCharArray())x+="(?=.*"+c+")";x+="["+n+"]{"+n.length()+"}x";}for(int i=0,q;i<9;)for(q=(s+" ").split(x.split("x")[i++]).length-1;q-->0;)r+=i;return r;}

+58 bytes.. due to regex of the previous version not working properly (it was also matching "EEE";"EEN";etc.)

Explanation:

Try it here.

s->{                     // Method with String as parameter and return-type
  String r="",           //  Result-String
         x=r;            //  Regex-String
  for(String n:"ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE".split(" ")){
                         //  Loop (1) from "ONE" through "NINE":
    for(char c:n.toCharArray())
                         //   Inner loop (2) over the characters of this String
      x+="(?=.*"+c+")";  //    Append regex-group `(?=\w*c)` where `c` is the capital character
                         //   End of inner loop (2) (implicit / single-line body)
    x+="["+n+"]{"+n.length()+"}x";
                         //   Append regex part `[s]{n}` where `s` is the String, and `n` is the length
  }                      //  End of loop (1)
  // The regex now looks like this, which we can split on "x":
  // (?=.*O)(?=.*N)(?=.*E)[ONE]{3}x(?=.*T)(?=.*W)(?=.*O)[TWO]{3}x(?=.*T)(?=.*H)(?=.*R)(?=.*E)(?=.*E)[THREE]{5}x(?=.*F)(?=.*O)(?=.*U)(?=.*R)[FOUR]{4}x(?=.*F)(?=.*I)(?=.*V)(?=.*E)[FIVE]{4}x(?=.*S)(?=.*I)(?=.*X)[SIX]{3}x(?=.*S)(?=.*E)(?=.*V)(?=.*E)(?=.*N)[SEVEN]{5}x(?=.*E)(?=.*I)(?=.*G)(?=.*H)(?=.*T)[EIGHT]{5}x(?=.*N)(?=.*I)(?=.*N)(?=.*E)[NINE]{4}x
  for(int i=0,q;i<9;)    //  Loop (3) from 0 through 9 (exclusive)
    for(q=(s+" ").split(x.split("x")[i++]).length-1;
                         //   Split the input on the current regex-part,
                         //   and save the length - 1 in `q`
        q-->0;           //   Inner loop (4) over `q`
      r+=i               //    And append the result-String with the current index (+1)
    );                   //   End of inner loop (4)
                         //  End of loop (3) (implicit / single-line body)
  return r;              //  Return the result-String
}                        // End of method

1
Erf... wrong result for "ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" :(
Olivier Grégoire

Yeah, that's the only thing that prevented me to +1 this! My solution was 240 bytes... before you beat me to it.
Olivier Grégoire

@OlivierGrégoire Feel free to post your 240 byte solution, because I'm unable to find a solution.. The disadvantage about [ONE]{3} is that it also matches EEN at the end of that test case with parts of EIGHT and NINE.. And I doubt there is a regex to match all these: ENO|EON|NEO|NOE|OEN|ONE without also matching EEE;EEN;EEO;... for all numbers that is shorter than 40 bytes.. Maybe I can do something using substring and reverse checking the numbers, but I don't really have the time to figure it out now..
Kevin Cruijssen

@OlivierGrégoire If you still have your 240 byte answer, feel free to post it. Just came across this challenge again, and fixed my answer by making a new regex for +58 bytes..
Kevin Cruijssen

1
Well, looks like I found an even shorter way while redoing this challenge :p
Olivier Grégoire

1

Java (OpenJDK 8), 181 bytes

s->{String x="",r;for(int i=0,l;i<9;)for(r="ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE".split(",")[i++],l=r.length();s.matches("["+r+"]{"+l+"}.*");s=s.substring(l))x+=i;return x;}

Try it online!

I took the liberty to reuse Kevin Cruyssen's TIO template. Hope you don't mind ;)


Ah, nevermind my previous comment.. You build the regex, instead of loop over the regex. Still, I was close with my first answer if only I had used the s.substring. The worst part is, is that I am using s.substring in my current answer, lol.. Ah well, +1 from me. Glad it's almost weekend..
Kevin Cruijssen

1

05AB1E, 36 31 bytes

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘#vyœN>UvyX:

Try it online!


View it ran with debug: TIO With Debug

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# | Push ['ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE']
vyœ                   | For each list of permutations of that word...
   N>U                | Push index + 1 into register X.          
      vyX:            | Replace each permutation with X.

I was just suggesting you had the green mark rather than me and I noticed a bug: FURONESEV returns FUR1SEV :(
Jonathan Allan

1

Perl 5, 102 + 1 (-n) = 103 bytes

for$i(map{"[$_]{".length.'}'}ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN,EIGHT,NINE){$,++;print$,while(s/^$i//)}

Try it online!


Nice! Couple of tricks that help: map{...} can often be replaced with map...,, length and y///c are usually interchangeable too (not always smaller when not working on $_ though!), instead of the while, ++$,x s/^$i// is shorter, and if you change -n to -p you can append to ` $\ ` instead of calling print! Try it online!
Dom Hastings

Also, I hope you don't mind me posting any advice, if you'd prefer I'll refrain. :)
Dom Hastings

0

Python 3, 238 236 bytes

def f(s):
 e=''
 while len(s):
  for i in range(9):
   for r in[''.join(p)for p in permutations('ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE'.split()[i])]: 
    if s[:len(r)]==r:e+=str(i+1);s=s[len(r):]
 return e
from itertools import*

Try it online!


Brute-force solution, doesn't take advantage non-decreasingness of digits.


Thanks to @Mr. Xcoder for saving 2 bytes!


You have to include def f(s): in your byte count, this is not an anonymouos function
Mr. Xcoder

Also you can replace while len(s)>0 with while len(s)
Mr. Xcoder

@Mr.Xcoder thanks for that clarification
Chase Vogeli

You can move the declaration of e into the function header for -1 byte. Also, exec and list comprehensions might save bytes on indentation.
CalculatorFeline

0

PHP, 141 bytes

for($a=count_chars($argn);$c=ord($s[++$p]?:$s=[OWU,W,HG,U,FU,X,SX,G,N17.$p=0][$i-print str_repeat($i++,$x)]);)$x=$a[$i+48]+=($p?-1:1)*$a[$c];

older version, 151 bytes:

for($a=count_chars($argn,1);$s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];print str_repeat($i,$a[$i+48]))for($p=0;$c=ord($s[$p]);)$a[$i+48]+=($p++?-1:1)*$a[$c];

loops through the digits from 1 to 9, counting unique characters in the word and subtracting non-unique characters´ counts, printing the digit on the go.
Although it is printing on the go, the digit counts must be stored for the 9 case to work.

Run as pipe with -nR or try it online.

It would save 4 more bytes to store the digit counts in $a[$i] instead of $a[$i+48] and use ASCII 1 and 7 (in quotes) instead of the digit characters themselves.

breakdown

for(
    $a=count_chars($argn,1);                # count character occurences in input
    $s=[OWU,W,HG,U,FU,X,SX,G,N17][+$i++];   # loop through digit names
    print str_repeat($i,$a[$i+48])              # print digit repeatedly
)
    for($p=0;$c=ord($s[$p]);)                   # loop through name
        $a[$i+48]+=                                 # add to digit count
        ($p++?-1:1)*                                # (add first, subtract other)
        $a[$c];                                     # character occurences

ONE is not the only word with an O, so it needs to subtract the counts for W (only appearing in TWO) and U (only appearing in FOUR) and so on.
NINE is special, because there is no way to just subtract if I used the letters (that would require I-X-G-F+U or N-O-S+W+U+X), so I use the digit counts instead.

PHP, 160 bytes

$a=count_chars($argn);foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)for(${$s[$p=1]}+=$n=$a[ord($s)];$c=ord($s[++$p]);)$a[$c]-=$n;while($$i--?print$i:$i++<9);

assumes all upper case input; characters may be scrambled all over.
Run as pipe with -nR or try it online.

explanation

loops through the digit words, counting their unique characters´ occurences in the input and in the process reducing the count of other characters. "Other characters" could mean all other characters in the word; but only considering those that will be needed later saved 19 bytes.

Transforming the str_repeat loop to a combined loop saved 5 bytes.

And using variable variables for the digit count saved another 8.

breakdown

$a=count_chars($argn);                              # count character occurences in input
foreach([W2O,U4FOR,X6SI,G8I,F5I,O1,R3,S7,I9]as$s)   # loop through digit names
    for(${$s[$p=1]}+=                                   # 2. add to digits count
        $n=$a[ord($s)];                                 # 1. get count of unique character
        $c=ord($s[++$p]);)                              # 3. loop through other characters
        $a[$c]-=$n;                                         # reduce character count
while(
    $$i--?print$i                                       # print digit repeatedly
    :$i++<9);                                       # loop through digits
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.