El número original (II)

18

Este desafío es esencialmente idéntico a este con solo una diferencia: ahora está permitido mezclar letras en cualquier lugar de la cadena.

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" -> "EEWOOHRNTET")

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 la cadena completa. Las letras se pueden mezclar en cualquier parte de 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

"NWEOOT" -> 12

"TOEERWNEHOT" -> 123

"IHNEVGENNEISTE" -> 789

"WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" -> 123456789

"EWHEWROETOTTON" -> 1223

"ONEWESTV" -> 27 (gracias, ETHproductions!)

Cristian Lupascu
fuente
77
Caso de prueba sugerido: algo como "ONEWESTV" -> 27(incluye un número que en realidad no aparece)
ETHproductions
@ETHproductions ¡Gran idea! Adicional.
Cristian Lupascu
¿Por qué no existe el "CERO"?
RosLuP
@RosLuP John odia los ceros a la izquierda ...
Cristian Lupascu

Respuestas:

9

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

Un programa completo que toma la entrada citada e imprime el número de John.

Pruébalo en línea! o ver un conjunto de pruebas

¿Cómo?

Trabajemos con el ejemplo "NEONSEXTOWNII" (para obtener 1269, y ser algo así como Leisure Suite Larry -esque!)

Primero c=map(input().count,"OWHUFXSGIQ")toma datos y cuenta el número de cada uno de OWHUFXSGIQellos: estas son letras que aparecen en cada número en orden ascendente, con 2,4,6 y 8 con sus letras "propias" ( WUXG), más una letra adicional, Qpara agregar un cero hasta el final y haga que la longitud de la lista resultante sea uniforme. Por el ejemplo:

[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

Las entradas para 1, 3, 5, 7 y 9 deben ajustarse para corregir la abundancia de las otras letras. Esto se realiza mediante el siguiente ciclo:

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

Tenga en cuenta que las entradas para ajustar son alternativas (1,3,5,7,9,1,3,5, ...), por lo que podemos agregar dos a una variable de índice en cada paso y módulo por 10 para permanecer en rango si necesitamos atravesar más de una vez (lo que hacemos). Para guardar algunos bytes, podemos incrementar en uno y módulo en 5 y usar el doble del índice.
Dado que los ajustes para 9 requieren la mayor parte del trabajo, comenzamos allí; reside en el índice 8, así que comenzamos en i=4. La cadena "71735539994"luego proporciona los índices, jde los valores a eliminar en cada etapa (donde nos hemos asegurado de que el noveno índice contendrá cero al usarlo "Q"al crear c); c[i*2]-=c[int(j)]realiza cada ajuste individual y i=-~i%5pasa ial siguiente índice (donde -~iestá -(-1-i)o i+1guarda paréntesis (i+1)%5) manteniendoi*2dentro de los límites de c.
Por lo tanto, primero restamos el número en el índice j=7de ese en el índice i*2=8, restando el número de "G" contadas del número de "I", ajustando la cuenta regresiva "NUEVE" por el número (correcto) de "OCHO" que también tiene un "yo"). Luego nos movemos hacia i=0( -~4%5 = (4+1)%5 = 0), haciendo referencia al índice i*2 = 0que es para "UNO" y restamos el valor encontrado en el índice de j=1la entrada que cuenta "W" y, por lo tanto, "DOS", ajustando la cuenta de "O" s hacia abajo. Al final del ciclo tenemos los conteos corregidos:

[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

así que todo lo que queda es imprimir lo que cahora representa ( 1269). iahora está de vuelta en 0, así que lo incrementamos al comienzo del ciclo y lo usamos como nuestro dígito:

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

Los ticks posteriores `i`son una abreviatura de Python2 para la repr(i)cual se obtiene una representación de cadena de un objeto (el carácter de dígito en cuestión como una cadena) y la multiplicación de una cadena por un número crea una nueva cadena de tantas repeticiones (aquí solo mostramos el n=0giro `i`desde decir "5"hacia ""y n=1girando manteniendo decir "6"como "6", pero también funciona para enteros positivos más grandes, por lo que se "3"*4convierte "3333"por ejemplo

Jonathan Allan
fuente
8

05AB1E , 31 bytes

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

Pruébalo en línea!

Explicación

[                                   # 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

Muy ineficiente para grandes aportaciones.

Emigna
fuente
‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']: puedes explicar un poco, me cuesta entender cómo se puede generar cualquier cadena.
Cyril Gandon
1
@CyrilGandon: delimita una cadena comprimida en mayúsculas de palabras separadas por espacios. Zsignifica Z. Todos los otros pares de 2 símbolos denotan una palabra comprimida del diccionario 05AB1E . Entonces, por ejemplo, se €µtraduce como ONE.
Emigna
Bien, ¿cómo comprimes una cadena que contiene el diccionario? ¿Algo con el valor unicode del par?
Cyril Gandon
1
@CyrilGandon: Toma el número de línea de la palabra en el dict (2420 para hola ) y resta 1. Esto nos da 2419. Los símbolos que necesitamos son los símbolos seguidos por 24y 19en los documentos . En nuestro caso esto es 24=Ÿy 19=™así HELLOsería‘Ÿ™‘
Emigna
1
También hay un compresor escrito por Adnan que puede usar en la mayoría de los casos. El enlace es un poco largo, pero puede encontrarlo en la sala de chat 05AB1E . Ese también es un buen lugar para preguntar si tiene más preguntas :)
Emigna
8

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
7$1
}`NO
1
NN
9
T`L
O`.

Pruébalo en línea!

-12 bytes gracias a @Neil

-3 bytes mediante el uso de clases de caracteres L en la transposición

Cómo funciona

Básicamente, esto se basa en el hecho de que las letras solo se usan en ciertos nombres de números. Por ejemplo, SIXes el único nombre que contiene un X. Esto se vuelve más complicado con el hecho de que algunas palabras se superponen en letras, como ambas FIVEy el SEVENuso V. Esto podría corregirse identificándose FIVEcon F(.*)V.

fireflame241
fuente
1
@RickHitchcock fijo. La recursividad en la conversión a 8 no funcionaba correctamente
fireflame241
1
@RickHitchcock. Se corrigió la recursividad para todos ellos.
fireflame241
Molesto GHy NOsería adyacente, a excepción de cualquier sustitución anterior 8o 1de una sustitución anterior ...
Neil
Tal vez }`GH 8funcionaría 8, ya }que provocaría que los personajes se ordenaran nuevamente, colocando así los restantes Gy Hjuntos.
Neil
@Neil Buena idea. También pude hacer eso NO -> 1, lo cual fue conveniente.
fireflame241
5

Kotlin 1.1 , 359 352 331 327 325 bytes

Sumisión

fun r(r:String):String{var s=""
val f=r.split(s).groupingBy{it}.eachCount()
val c=Array(10,{0})
c[8]=f["G"]?:0
c[6]=f["X"]?:0
c[4]=f["U"]?:0
c[2]=f["W"]?:0
c[1]=(f["O"]?:0)-c[2]-c[4]
c[3]=(f["R"]?:0)-c[4]
c[7]=(f["S"]?:0)-c[6]
c[5]=(f["V"]?:0)-c[7]
c[9]=((f["N"]?:0)-c[1]-c[7])/2
for(i in 1..9)for(x in 1..c[i])s+=i
return s}

No funciona en TryItOnline debido a que Kotlin 1.1 no es compatible

Prueba

fun r(r:String):String{
val f=r.split("").groupingBy{it}.eachCount()
val c=Array(10,{0})
c[8]=f["G"]?:0
c[6]=f["X"]?:0
c[4]=f["U"]?:0
c[2]=f["W"]?:0
c[1]=(f["O"]?:0)-c[2]-c[4]
c[3]=(f["R"]?:0)-c[4]
c[7]=(f["S"]?:0)-c[6]
c[5]=(f["V"]?:0)-c[7]
c[9]=((f["N"]?:0)-c[1]-c[7])/2
var s=""
for(i in 1..9)for(x in 1..c[i])s+=i
return s}

data class TestData(val input: String, val output: String)

fun main(vararg args:String) {
    val items = listOf(
    TestData("NEO" , "1"),
    TestData("NWEOOT" , "12"),
    TestData("TOEERWNEHOT" , "123"),
    TestData("IHNEVGENNEISTE" , "789"),
    TestData("WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" , "123456789"),
    TestData("EWHEWROETOTTON" , "1223")
    )
    for (item in items) {
        val out = r(item.input)
        if (out != item.output) {
            throw AssertionError("Bad result: $item : $out")
        }
    }
}

Lógica

Hoja de cuna

Utilicé la hoja anterior para resolver la forma más simple de resolver cada letra

  • Verde = resolver por sí mismo
  • Azul = Necesita verdes para resolver
  • Naranja = Necesita blues para resolver
  • Rojo = Necesita naranjas para resolver

Ediciones

  • -7 - El espacio en blanco cambia por w0lf
  • -21 - Lista de encogimiento de matriz
  • -4 - Se eliminaron los corchetes innecesarios
  • 0 - Se agregó lógica en
  • -2 - Reutilizando una cadena vacía gracias a kevin-cruijssen
jrtapsell
fuente
1
Acabo de notar que estoy exactamente vinculado con usted con mi respuesta Java 8 (127 bytes), usando un enfoque similar. ;) Pero una pregunta: ¿no puede cambiar var s=""y return sa r=""y return rmediante la reutilización de la entrada-String, necesidad que ya no en ese momento? Nunca antes había programado en Kotlin, por lo que podría ser que hable tonterías aquí. ; p
Kevin Cruijssen
1
Lamentablemente no> discuten.kotlinlang.org/t/…
jrtapsell
1
Ah sí, eso era, por supuesto, una posibilidad; Los parámetros son finalpor defecto. Hmm, otra cosa que podrías jugar al golf: coloca el var s=""como la primera cosa en el método y reemplaza val f=r.split("").con val f=r.split(s).. De nuevo, no tengo idea si funciona. Lástima que TIO aún no sea compatible con v1.1, de lo contrario, probaría estas sugerencias yo mismo antes de hacerme
parecer
4

Jalea , 37 bytes

1ðDị“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»ŒuḲ¤ẎŒ!ċð1#

Pruébalo en línea!

-1 gracias a Jonathan Allan .

Erik el Outgolfer
fuente
Este tiempo de espera para algunas entradas de más de 7 caracteres (por ejemplo: NINEFIVE, THREEFIVE). ¿Es un error o el código es simplemente ineficiente?
Cristian Lupascu
@ w0lf el último ( Œ!significa "permutaciones")
Erik the Outgolfer
Guardar un byte usando "AA" en lugar de "!":...“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»...
Jonathan Allan
@ JonathanAllan oh, ¿AA es una palabra?
Erik the Outgolfer
Es la primera palabra en el diccionario corto, sí.
Jonathan Allan
3

Java 8, 248 234 bytes

s->{int x=0,a[]=new int[10];for(String t:"2WO;4UORF;6XSI;8GI;5FI;7S;3R;1O;9I".split(";"))for(;s.indexOf(t.charAt(1))>=0;a[t.charAt(0)-48]++)for(String z:t.split(""))s=s.replaceFirst(z,"");for(s="";x++<9;)for(;a[x]-->0;)s+=x;return s;}

Explicación del código:

s->{
    // Array to count how often which number appears
    int a[]=new int[10];
    // The first character behind the number serves the identification
    // the other characters get removed to identify the other numbers later
    for(String t:"2WO;4UORF;6XSI;8GI;5FI;7S;3R;1O;9I".split(";"))
        // Check if the string contains the id 
        for(;s.indexOf(t.charAt(1))>=0;a[t.charAt(0)-48]++)
            // Remove the relevant charcters
            for(String z:t.split(""))
                s=s.replaceFirst(z,"");
    // Clear the string to write the output
    s="";
    // write the numbers sequential into the output 
    for(int x=0;x++<9;)
        for(;a[x]-->0;)
            s+=x;
    return s;
}

-14 Gracias a Olivier Grégoire

Edwardth
fuente
1
234 bytes
Olivier Grégoire
2

Java 8, 346 345 344 336 327 bytes

s->{int g=c(s+=" ","G"),u=c(s,"U"),w=c(s,"W"),x=c(s,"X"),f=c(s,"F")-u,h=c(s,"H")-g,v=c(s,"V")-f,o=c(s,"O")-u-w,i=c(s,"I")-f-x-g;return d(s=d(s=d(s=d(s=d(s=d(s=d(s=d(s=d("",o,1),w,2),h,3),u,4),f,5),x,6),v,7),g,8),n,9);}int c(String...s){return~-s[0].split(s[1]).length;}String d(String s,int i,int n){for(;i-->0;s+=n);return s;}

Pruébalo aquí

Explicación general:

He visto las ocurrencias de cada personaje en el alfabeto:

E 13357789
F 45
G 8
H 38
I 5689
N 1799
O 124
R 34
S 67
T 238
U 4
V 57
W 2
X 6
  • La primera vez que conté todas las apariciones de los personajes-Partidos en simples: G=8; U=4; W=2; X=6.
  • A continuación, todas las apariciones de personajes de dos emparejados, que también coinciden con uno de los cuatro anteriormente, que puedo restar de su población en: F=5; H=3.
  • Luego hice lo mismo otra vez para V=7(restando F=5).
  • A continuación, el mismo para todos los partidos tres personajes que quedaron: O=1; N=9.
    • Pero debido a que Ntiene dos ocurrencias NINE, tuve que hacer una adicional -1por cada ocurrencia N, por lo que he usado en su I=9lugar (restando tres coincidencias anteriores en lugar de dos).

Explicación del código:

s->{                    // Method with String as parameter and return-type
  int g=c(s+=" ","G"),  //  Amount of 8s (and append a space to `s` first, for the .split)
      u=c(s,"U"),       //  Amount of 4s
      w=c(s,"W"),       //  Amount of 2s
      x=c(s,"X"),       //  Amount of 6s
      f=c(s,"F")-u,     //  Amount of 5s
      h=c(s,"H")-g,     //  Amount of 3s
      v=c(s,"V")-f,     //  Amount of 7s
      o=c(s,"O")-u-w,   //  Amount of 1s
      i=c(s,"I")-f-x-g; //  Amount of 9s
  return d(             //  Return the result by:
   s=d(
    s=d(
     s=d(
      s=d(
       s=d(
        s=d(
         s=d(
          s=d("",       //   Making the input String `s` empty, since we no longer need it
                 o,1),  //   Append all 1s to `s`
         w,2),          //   Append all 2s to `s`
        h,3),           //   Append all 3s to `s`
       u,4),            //   Append all 4s to `s`
      f,5),             //   Append all 5s to `s`
     x,6),              //   Append all 6s to `s`
    v,7),               //   Append all 7s to `s`
   g,8),                //   Append all 8s to `s`
  i,9);                 //   And then returning `s` + all 9s
}                       // End of method

int c(String...s){  // Separate method with String-varargs parameter and int return-type
                    //  `s[0]` is the input-String
                    //  `s[1]` is the character to check
  return~-s[0].split(s[1]).length;
                    //  Return the amount of times the character occurs in the String
}                   // End of separated method (1)

String d(String s,int i,int n){
               // Separate method with String and two int parameters and String return-type
  for(;i-->0;  //  Loop from the first integer-input down to 0
      s+=n     //   And append the input-String with the second input-integer
  );           //  End of loop
  return s;    //  Return the resulting String
}              // End of separated method (2)
Kevin Cruijssen
fuente
1
Maldición, hubiera pensado que agregar a una lista y luego ordenarla sería más corto (no lo es). ¡Bien hecho!
Olivier Grégoire
1
Bueno, al final, te superé , pero no por mucho;)
Olivier Grégoire
2

Perl 5 , 100 bytes

Código de 99 bytes + 1 byte para el -nconmutador.

${$_}++for/./g;@a=($O-$W-$U,$W,$H-$G,$U,$F-$U,$X,$S-$X,$G,$I-$F+$U-$X-$G);print$_ x$a[$_-1]for 1..9

Pruébalo en línea!

nwellnhof
fuente
1

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

Pruébalo en línea!

Directo: elimina primero los dígitos identificados por una letra específica.

jferard
fuente
1

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

Pruébalo en línea!

Después de leer el desafío vinculado, me di cuenta de que esta es una variación de la solución Python de mdahmoune , que se basa en la solución ES6 de Draco18s , pero bueno, al menos jugamos dos bytes.

Al igual que esa solución, calculamos la respuesta a través de una combinación lineal del número de ocurrencias de ciertas letras. Codificamos brevemente las combinaciones lineales escribiéndolas como palabras en las que se agregarán las dos primeras letras y se restará todo lo siguiente. A veces se necesita un personaje para rellenar los dos primeros caracteres; usamos esto para ocultar el dígito que queremos generar (que nunca ocurrirá en la entrada, por lo que no afectará nuestro algoritmo), con el que extraemos min.

betaveros
fuente
1

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

Pruébalo en línea!

Sven Hohenstein
fuente
1

Axioma, 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)

resultados no comentados

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
RosLuP
fuente