Le numéro d'origine (II)


18

Ce défi est essentiellement identique à celui-ci avec une seule différence: il est désormais autorisé de mélanger les lettres n'importe où dans la chaîne.

Scénario

John a un nombre important, et il ne veut pas que les autres le voient.

Il a décidé de crypter le numéro, en procédant comme suit:

Son nombre est toujours une séquence non décroissante (ie. "1123")

Il a converti chaque chiffre en mots anglais. (c.-à-d. "123" -> "ONETWOTHREE")

Et puis, réorganisez les lettres au hasard. (c.-à-d. "ONETWOTHREE" -> "EEWOOHRNTET")

John estimait que son numéro était sûr de le faire. En fait, un tel chiffrement peut être facilement déchiffré :(


Tâche

Étant donné la chaîne chiffrée, votre tâche consiste à la déchiffrer et à renvoyer le numéro d'origine.


Règles

  • C'est le golf de code, donc la réponse la plus courte en octets gagne
  • Vous pouvez supposer que la chaîne d'entrée est toujours valide
  • La chaîne d'entrée ne contient que des lettres majuscules
  • Les numéros originaux sont toujours classés par ordre croissant
  • Vous pouvez renvoyer le nombre sous forme de chaîne ou d'entier
  • Les lettres ne seront mélangées qu'entre un mot et non entre la chaîne entière. Les lettres peuvent être mélangées n'importe où dans la chaîne.
  • Les nombres ne seront que de 1 à 9 inclus ( ONEà NINE)

Chaîne non brouillée possible

Voici une liste des chaînes juste après leur conversion en chaînes à partir des nombres:

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

Exemples

"NEO" -> 1

"NWEOOT" -> 12

"TOEERWNEHOT" -> 123

"IHNEVGENNEISTE" -> 789

"WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" -> 123456789

"EWHEWROETOTTON" -> 1223

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


7
Cas de test suggéré: quelque chose comme "ONEWESTV" -> 27(inclut un nombre qui n'apparaît pas réellement)
ETHproductions

@ETHproductions Excellente idée! Ajoutée.
Cristian Lupascu

Pourquoi n'y a-t-il pas le "ZERO"?
RosLuP

@RosLuP John déteste les zéros non significatifs ...
Cristian Lupascu

Réponses:


9

Python 2 , 123 octets

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 programme complet prenant les entrées citées et imprimant le numéro de John.

Essayez-le en ligne! ou voir une suite de tests

Comment?

Travaillons avec l'exemple "NEONSEXTOWNII" (pour donner 1269, et soyons un peu Leisure Suite Larry -esque!)

Prend d'abord la c=map(input().count,"OWHUFXSGIQ")saisie et compte le nombre de chacun OWHUFXSGIQ- ce sont des lettres qui apparaissent dans chaque nombre dans l'ordre croissant, 2,4,6 et 8 ayant leurs propres lettres ( WUXG), plus une lettre supplémentaire, Qpour ajouter un zéro à la fin et égaliser la longueur de la liste résultante. Pour l'exemple:

[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

Les entrées pour 1, 3, 5, 7 et 9 doivent être ajustées pour corriger l'abondance des autres lettres. Ceci est effectué par la boucle suivante:

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

Notez que les entrées à ajuster sont des entrées alternatives (1,3,5,7,9,1,3,5, ...), nous pouvons donc ajouter deux à une variable d'index à chaque étape et modulo par 10 pour rester dans plage si nous devons parcourir plusieurs fois (ce que nous faisons). Pour économiser quelques octets, nous pouvons incrémenter d'un et modulo de 5 et utiliser le double de l'index.
Étant donné que les ajustements pour 9 nécessitent le plus de travail, nous commençons là - il réside à l'index 8, donc nous commençons à i=4. La chaîne "71735539994"donne ensuite les index,, jdes valeurs à supprimer à chaque étape (où nous nous sommes assurés que le neuvième index contiendra zéro en utilisant "Q"lors de la création c); c[i*2]-=c[int(j)]effectue chaque ajustement individuel et i=-~i%5passe ià l'index suivant (où -~iest -(-1-i)ou i+1sauvegarde des parenthèses (i+1)%5) en gardanti*2dans les limites de c.
Ainsi, nous soustrayons d'abord le nombre à l'index j=7de celui à l'index i*2=8, en soustrayant le nombre de "G" comptés du nombre de "I", en ajustant le compte "NINE" par le nombre (correct) de "HUIT" ( qui a également un "je"). Nous passons ensuite à i=0( -~4%5 = (4+1)%5 = 0), référençant l'index i*2 = 0qui est pour "UN" et soustrayons la valeur trouvée à l'index en j=1comptant "W" et donc "DEUX", en ajustant le nombre de "O" vers le bas. À la fin de la boucle, nous avons les comptes corrigés:

[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

il ne reste donc qu'à imprimer ce cqui représente maintenant ( 1269). iest maintenant de retour à 0, donc nous l'incrémentons au début de la boucle et l'utilisons comme chiffre:

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

Les tiques arrière `i`,, sont un raccourci Python2 pour repr(i)lequel obtient une représentation sous forme de chaîne d'un objet (le caractère numérique en question sous la forme d'une chaîne) et la multiplication d'une chaîne par un nombre crée une nouvelle chaîne de ce nombre de répétitions (ici, nous ne montrons que le n=0virage `i`de dire "5"vers ""et n=1tournant en gardant dire "6"comme "6", mais cela fonctionne aussi pour les entiers positifs plus grands, "3"*4devient ainsi "3333"par exemple.)


8

05AB1E , 31 octets

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

Essayez-le en ligne!

Explication

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

Très inefficace pour de grandes entrées.


‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']: pouvez-vous expliquer un peu, j'ai du mal à comprendre comment une chaîne peut être générée.
Cyril Gandon

1
@CyrilGandon: délimite une chaîne compressée en majuscules de mots séparés par des espaces. Zsignifie Z. Toutes les autres paires de 2 symboles désignent un mot compressé du dictionnaire 05AB1E . Ainsi, par exemple, se €µtraduit par ONE.
Emigna

Bien, comment compressez-vous une chaîne contenue dans le dictionnaire? Quelque chose avec la valeur unicode de la paire?
Cyril Gandon

1
@CyrilGandon: Vous prenez le numéro de ligne du mot dans le dict (2420 pour bonjour ) et soustrayez 1. Cela nous donne 2419. Les symboles dont nous avons besoin sont les symboles qui sont suivis par 24et 19dans les documents . Dans notre cas, c'est 24=Ÿet 19=™ce HELLOserait le cas‘Ÿ™‘
Emigna

1
Il existe également un compresseur écrit par Adnan que vous pouvez utiliser dans la plupart des cas. Le lien est un peu long, mais vous pouvez le trouver dans la salle de chat 05AB1E . C'est aussi un bon endroit pour demander si vous avez d'autres questions :)
Emigna

8

Rétine , 112 97 octets

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

Essayez-le en ligne!

-12 octets grâce à @Neil

-3 octets par utilisation de classes de caractères L en transposition

Comment ça fonctionne

Fondamentalement, cela repose sur le fait que les lettres ne sont utilisées que dans certains noms de nombres. Par exemple, SIXest le seul nom qui contient un X. Cela devient plus délicat avec le fait que certains mots se chevauchent dans les lettres, comme les deux FIVEet en SEVENutilisant V. Cela pourrait être corrigé en s'identifiant FIVEavec F(.*)V.


1
@RickHitchcock Fixed. La récursivité lors de la conversion en 8 ne fonctionnait pas correctement
fireflame241

1
@RickHitchcock. Correction de la récursivité pour chacun d'eux.
fireflame241

De façon ennuyeuse GHet NOserait adjacente, sauf pour toute substitution précédente 8ou 1d'une substitution antérieure ...
Neil

Peut }`GH 8- être que cela fonctionnerait 8- }cela entraînerait un nouveau tri des caractères, plaçant ainsi tous les éléments restants Get Hensemble.
Neil

@Neil Belle idée. J'ai également pu le faire pour NO -> 1, ce qui était pratique.
fireflame241

5

Kotlin 1.1 , 359 352 331 327 325 octets

Soumission

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}

Ne fonctionne pas sur TryItOnline car Kotlin 1.1 n'est pas pris en charge

Tester

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

Logique

Feuille de crèche

J'ai utilisé la feuille ci-dessus pour trouver le moyen le plus simple de résoudre chaque lettre

  • Vert = Résoudre par lui-même
  • Bleu = Besoin de verts pour résoudre
  • Orange = Besoin de blues à résoudre
  • Rouge = Besoin d'oranges à résoudre

Modifications

  • -7 - Modifications des espaces blancs par w0lf
  • -21 - Shrank listOf to Array
  • -4 - Suppression des supports inutiles
  • 0 - Ajout de logique dans
  • -2 - Réutiliser une chaîne vide grâce à kevin-cruijssen

1
Je viens de remarquer que je suis exactement à égalité avec vous avec ma réponse Java 8 (127 octets), en utilisant une approche similaire. ;) Mais une question: ne pouvez-vous pas changer var s=""et return svers r=""et return ren réutilisant la chaîne d'entrée, dont vous n'avez plus besoin à ce stade? Je n'avais jamais programmé à Kotlin auparavant, il se pourrait donc que je dise des bêtises ici. ; p
Kevin Cruijssen

1
Malheureusement pas> discuter.kotlinlang.org/t/…
jrtapsell

1
Ah oui, c'était bien sûr une possibilité; les paramètres étant finalpar défaut. Hmm, une autre chose que vous pourriez jouer au golf: placez le var s=""comme première chose dans la méthode et remplacez-le val f=r.split("").par val f=r.split(s).. Encore une fois, aucune idée si cela fonctionne. Dommage que TIO ne supporte pas encore la v1.1, sinon j'essaierais ces suggestions moi-même avant de me faire un son stupide ..
Kevin Cruijssen

4

Gelée , 37 octets

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

Essayez-le en ligne!

-1 merci à Jonathan Allan .


Cette fois sur certaines entrées de plus de 7 caractères (ex: NINEFIVE, THREEFIVE). Est-ce un bug ou le code est-il simplement inefficace?
Cristian Lupascu

@ w0lf ce dernier ( Œ!signifie "permutations")
Erik the Outgolfer

Enregistrer un octet en utilisant "AA" plutôt que "!":...“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»...
Jonathan Allan

@JonathanAllan oh est AA un mot?
Erik the Outgolfer

C'est le premier mot du petit dictionnaire, oui.
Jonathan Allan

3

Java 8, 248 234 octets

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

Explication du code:

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 Merci à Olivier Grégoire



2

Java 8, 346 345 344 336 327 octets

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

Essayez-le ici.

Explication générale:

J'ai regardé les occurrences de chaque caractère de l'alphabet:

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
  • Je comptais d' abord toutes les occurrences des caractères d' allumettes: G=8; U=4; W=2; X=6.
  • Ensuite , toutes les occurrences de caractères à deux appariés, qui correspondent aussi à l' un des quatre ci - dessus, que je peux soustraire de leurs comptes: F=5; H=3.
  • Puis j'ai refait la même chose pour V=7(en soustrayant F=5).
  • Puis la même chose pour tous les caractères des trois matchs qui ont été laissés: O=1; N=9.
    • Mais comme il y Na deux occurrences NINE, j'ai dû en faire une supplémentaire -1pour chaque occurrence de N, donc je l'ai utilisé à la I=9place (en soustrayant trois correspondances précédentes au lieu de deux).

Explication du code:

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
Merde, j'aurais pensé que l'ajout à une liste puis le tri serait plus court (ce n'est pas le cas). Bien joué!
Olivier Grégoire

1
Bon, au final, je t'ai surpassé , mais pas beaucoup;)
Olivier Grégoire

2

Perl 5 , 100 octets

Code de 99 octets + 1 octet pour le -ncommutateur.

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

Essayez-le en ligne!


1

Python 3 , 225 octets

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

Essayez-le en ligne!

Simple: supprimez d'abord les chiffres identifiés par une lettre spécifique.


1

Python 3 , 125 octets

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

Essayez-le en ligne!

Après avoir lu le défi lié, j'ai réalisé qu'il s'agissait d' une variation de la solution Python de mdahmoune , elle-même basée sur la solution ES6 de Draco18s , mais bon, au moins nous avons joué deux octets.

Comme cette solution, nous calculons la réponse par une combinaison linéaire du nombre d'occurrences de certaines lettres. Nous codons brièvement les combinaisons linéaires en les écrivant comme des mots où les deux premières lettres doivent être ajoutées et tout ce qui doit ensuite être soustrait. Parfois, un caractère est nécessaire pour remplir les deux premiers caractères; nous l'utilisons pour masquer le chiffre que nous voulons sortir (qui ne se produira jamais dans l'entrée, donc n'affectera pas notre algorithme), que nous extrayons avec min.



1

Axiome, 351 octets

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)

résultats non commentés non commentés

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.