Il numero originale (II)


18

Questa sfida è essenzialmente identica a questa con una sola differenza: ora è consentito mescolare le lettere in qualsiasi punto della stringa.

Scenario

John ha un numero importante e non vuole che altri lo vedano.

Decise di crittografare il numero, attenendosi alla seguente procedura:

Il suo numero è sempre una sequenza non decrescente (es. "1123")

Ha convertito ogni cifra in parole inglesi. (es. "123" -> "ONETWOTHREE")

E poi, riorganizza le lettere in modo casuale. (es. "ONETWOTHREE" -> "EEWOOHRNTET")

John sentiva che il suo numero era sicuro nel farlo. In effetti, tale crittografia può essere facilmente decifrata :(


Compito

Date le stringhe criptate, il tuo compito è decodificarlo e restituire il numero originale.


Regole

  • Questo è il golf del codice, quindi vince la risposta più breve in byte
  • Si può presumere che la stringa di input sia sempre valida
  • La stringa di input contiene solo lettere maiuscole
  • I numeri originali sono sempre disposti in ordine crescente
  • È possibile restituire il numero in formato stringa o intero
  • Le lettere saranno mescolate solo tra una parola, non tra l'intera stringa. Le lettere possono essere mescolate in qualsiasi punto della stringa.
  • I numeri saranno solo da 1 a 9 inclusi ( ONEa NINE)

Possibile stringa non cifrata

Ecco un elenco delle stringhe subito dopo che sono state convertite in stringhe dai numeri:

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

Esempi

"NEO" -> 1

"NWEOOT" -> 12

"TOEERWNEHOT" -> 123

"IHNEVGENNEISTE" -> 789

"WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" -> 123456789

"EWHEWROETOTTON" -> 1223

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


7
Caso di prova suggerito: qualcosa del tipo "ONEWESTV" -> 27(include un numero che in realtà non appare)
ETHproductions

@ETHproductions Ottima idea! Aggiunto.
Cristian Lupascu,

Perché non c'è lo "ZERO"?
RosLuP,

@RosLuP John odia gli zeri
iniziali

Risposte:


9

Python 2 , 123 byte

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 programma completo che accetta input citati e stampa il numero di John.

Provalo online! o vedere una suite di test

Come?

Lavoriamo con l'esempio "NEONSEXTOWNII" (per produrre 1269, ed essere in qualche modo Leisure Suite Larry -esque!)

Per prima cosa c=map(input().count,"OWHUFXSGIQ")accetta input e conta il numero di ciascuno di OWHUFXSGIQquesti: si tratta di lettere che appaiono in ogni numero in ordine crescente, con 2,4,6 e 8 che hanno le loro "proprie" lettere ( WUXG), più una lettera in più, Qper aggiungere uno zero fino alla fine e rendere uniforme la lunghezza dell'elenco risultante. Per l'esempio:

[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

Le voci per 1, 3, 5, 7 e 9 devono essere modificate per correggere l'abbondanza delle altre lettere. Questo viene eseguito dal ciclo successivo:

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

Si noti che le voci da regolare sono alternative (1,3,5,7,9,1,3,5, ...), quindi possiamo aggiungere due a una variabile indice ad ogni passaggio e modulo di 10 per rimanere in gamma se dobbiamo attraversare più di una volta (cosa che facciamo). Per salvare alcuni byte possiamo incrementare di uno e modulo di 5 e usare il doppio dell'indice.
Poiché le rettifiche per 9 richiedono la maggior parte del lavoro che iniziamo da lì, risiede all'indice 8, quindi iniziamo da i=4. La stringa "71735539994"quindi fornisce gli indici, jdei valori da rimuovere in ogni fase (dove abbiamo assicurato che il nono indice conterrà zero usando "Q"durante la creazione c); c[i*2]-=c[int(j)]esegue ogni singola regolazione e i=-~i%5passa iall'indice successivo (dove si -~itrova -(-1-i)o i+1salvando le parentesi (i+1)%5) mantenendoi*2entro i limiti di c.
Quindi prima sottraggiamo il numero in corrispondenza dell'indice j=7da quello in corrispondenza dell'indice i*2=8, sottraendo il numero di "G" s contato dal numero di "I" s, regolando il conto alla rovescia "NINE" dal (corretto) numero di "EIGHT" s ( che ha anche un "io"). Passiamo quindi a i=0( -~4%5 = (4+1)%5 = 0), facendo riferimento all'indice i*2 = 0che è per "UNO" e sottraggiamo il valore trovato all'indice j=1della voce contando "W" e quindi "DUE", regolando il conteggio di "O" verso il basso. Alla fine del loop abbiamo i conteggi corretti:

[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

quindi non resta che stampare ciò che cora rappresenta ( 1269). iè ora alle 0, quindi lo incrementiamo all'inizio del ciclo e lo usiamo come nostra cifra:

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

I `i`segni di spunta posteriori , sono la scorciatoia di Python2 per la repr(i)quale ottiene una rappresentazione in forma di stringa di un oggetto (il carattere della cifra in questione come stringa) e la moltiplicazione di una stringa per un numero crea una nuova stringa di tante ripetizioni (qui mostriamo solo n=0girare `i`da dire "5"per ""e n=1girando mantenere dire "6"come "6", ma funziona anche per gli interi positivi più grandi, quindi "3"*4diventa "3333"per esempio.)


8

05AB1E , 31 byte

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

Provalo online!

Spiegazione

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

Molto inefficiente per input di grandi dimensioni.


‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']: puoi spiegarci un po ', faccio fatica a capire come può essere generata qualsiasi stringa.
Cyril Gandon,

1
@CyrilGandon: delimita una stringa compressa maiuscola di parole separate da spazio. Zsignifica Z. Tutte le altre coppie di 2 simboli indicano una parola compressa dal dizionario 05AB1E . Quindi, ad esempio, si €µtraduce come ONE.
Emigna,

Bene, come comprimi una stringa contenuta nel dizionario? Qualcosa con il valore unicode della coppia?
Cyril Gandon,

1
@CyrilGandon: prendi il numero di riga della parola nel dict (2420 per ciao ) e sottrai 1. Questo ci dà 2419. I simboli di cui abbiamo bisogno sono i simboli che sono seguiti da 24e 19nei documenti . Nel nostro caso questo è 24=Ÿe 19=™lo HELLOsarebbe anche‘Ÿ™‘
Emigna il

1
C'è anche un compressore scritto da Adnan che puoi usare nella maggior parte dei casi. Il collegamento è un po 'lungo, ma puoi trovarlo nella chat room 05AB1E . Questo è anche un buon posto per chiedere se hai ulteriori domande :)
Emigna,

8

Retina , 112 97 byte

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`.

Provalo online!

-12 byte grazie a @Neil

-3 byte mediante l'uso di classi di caratteri L in trasposizione

Come funziona

Fondamentalmente, questo si basa sul fatto che le lettere sono utilizzate solo in determinati nomi di numeri. Ad esempio SIXè l'unico nome che contiene un X. Questo diventa più complicato dal fatto che alcune parole si sovrappongono in lettere, come entrambe FIVEe SEVENusando V. Questo potrebbe essere corretto identificandosi FIVEcon F(.*)V.


1
@RickHitchcock Risolto. La ricorsione sulla conversione in 8 non funzionava correttamente
fireflame241

1
@RickHitchcock. Risolto il problema della ricorsione per tutti.
fireflame241

Fastidiosamente GHe NOsarebbe adiacente, ad eccezione di qualsiasi sostituzione precedente 8o 1precedente ...
Neil,

Forse }`GH 8avrebbe funzionato per 8- ciò }avrebbe fatto sì che i personaggi fossero riordinati, mettendo così i rimanenti Ge Hinsieme.
Neil,

@Neil Bella idea. Sono stato anche in grado di farlo per NO -> 1, il che era conveniente.
fireflame241,

5

Kotlin 1.1 , 359 352 331 327 325 byte

Presentazione

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}

Non funziona su TryItOnline a causa del mancato supporto di Kotlin 1.1

Test

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

Logica

Lenzuola per culla

Ho usato il foglio sopra per elaborare il modo più semplice per risolvere ogni lettera

  • Verde = Risolve da solo
  • Blu = Ha bisogno di green da risolvere
  • Arancione = Richiede blues da risolvere
  • Rosso = Richiede arance da risolvere

Le modifiche

  • -7 - Lo spazio bianco cambia di w0lf
  • -21 - Elenco ristretto dell'array
  • -4 - Staffe non necessarie rimosse
  • 0 - Aggiunta logica in
  • -2 - Riutilizzare la stringa vuota grazie a kevin-cruijssen

1
Ho appena notato che sono esattamente legato a te con la mia risposta Java 8 (127 byte), usando un approccio simile. ;) Ma una domanda: non puoi cambiare var s=""e return sper r=""e return rriutilizzando l'ingresso-String, che non è più necessario a quel punto? Non avevo mai programmato prima a Kotlin, quindi potrebbe essere che io parli senza senso qui. ; p
Kevin Cruijssen,


1
Ah sì, quella era ovviamente una possibilità; i parametri sono finaldi default. Mmm, un'altra cosa che potresti essere in grado di giocare a golf: inserisci var s=""la prima cosa nel metodo e sostituiscila val f=r.split("").con val f=r.split(s).. Ancora una volta, non ho idea se funziona. Peccato che TIO non supporti ancora la versione 1.1, altrimenti proverei questi suggerimenti da solo prima di farmi sembrare stupido ..
Kevin Cruijssen,

4

Gelatina , 37 byte

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

Provalo online!

-1 grazie a Jonathan Allan .


Questo timeout per alcuni input più grandi di 7 caratteri (es: NINEFIVE, THREEFIVE). È un bug o il codice è solo inefficiente?
Cristian Lupascu,

@ w0lf quest'ultimo ( Œ!significa "permutazioni")
Erik the Outgolfer

Salvare un byte usando "AA" anziché "!":...“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»...
Jonathan Allan il

@JonathanAllan oh AA è una parola?
Erik the Outgolfer,

È la prima parola nel breve dizionario, sì.
Jonathan Allan,

3

Java 8, 248 234 byte

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

Spiegazione del codice:

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 Grazie a Olivier Grégoire



2

Java 8, 346 345 344 336 327 byte

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

Provalo qui.

Spiegazione generale:

Ho esaminato le occorrenze di ciascun personaggio dell'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
  • Ho contato tutte le occorrenze dei singoli caratteri-partite: G=8; U=4; W=2; X=6.
  • Poi tutte le occorrenze di caratteri a due abbinati, che corrispondono anche uno dei quattro sopra, che posso sottrarre dai loro conti: F=5; H=3.
  • Poi ho fatto di nuovo lo stesso per V=7(sottraendo F=5).
  • Poi lo stesso per tutte e tre le partite-personaggi che sono stati lasciati: O=1; N=9.
    • Ma poiché ci Nsono due ricorrenze in NINE, ho dovuto fare un ulteriore -1per ogni occorrenza di N, quindi l'ho usato I=9invece (sottraendo tre corrispondenze precedenti anziché due).

Spiegazione del codice:

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)

1
Accidenti, avrei pensato che aggiungere a un elenco e poi ordinarlo sarebbe più breve (non lo è). Molto bene!
Olivier Grégoire,

1
Bene, alla fine, ti ho superato , ma non di molto;)
Olivier Grégoire,

2

Perl 5 , 100 byte

Codice 99 byte + 1 byte per -nswitch.

${$_}++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

Provalo online!


1

Python 3 , 225 byte

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

Provalo online!

Semplice: rimuovere prima le cifre identificate da una lettera specifica.


1

Python 3 , 125 byte

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

Provalo online!

Dopo aver letto la sfida collegata mi sono reso conto che si tratta di una variante della soluzione Python di mdahmoune , che è essa stessa basata sulla soluzione ES6 di Draco18s , ma ehi, almeno abbiamo eliminato due byte.

Come quella soluzione, calcoliamo la risposta attraverso una combinazione lineare del numero di occorrenze di determinate lettere. Codifichiamo brevemente le combinazioni lineari scrivendole come parole in cui aggiungere le prime due lettere e sottrarre tutto ciò che segue. A volte è necessario un personaggio per riempire i primi due personaggi; usiamo questo per nascondere la cifra che vogliamo emettere (che non si verificherà mai nell'input, quindi non influenzerà il nostro algoritmo), che estraiamo conmin .


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

Provalo online!


1

Assioma, 351 byte

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)

risultati non commentati

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.