O número original


36

Diretrizes

Cenário

John tem um número importante e não quer que outros o vejam.

Ele decidiu criptografar o número, usando as seguintes etapas:

Seu número é sempre uma sequência não decrescente (ie. "1123")

Ele converteu cada dígito em palavras em inglês. (ie. "123" -> "ONETWOTHREE")

E então, reorganize as letras aleatoriamente. (ie. "ONETWOTHREE" -> "ENOWTOHEETR")

John sentiu que seu número estava seguro ao fazê-lo. De fato, essa criptografia pode ser facilmente descriptografada :(


Tarefa

Dadas as seqüências criptografadas s, sua tarefa é descriptografá-la e retornar o número original.


Regras

  • Este é o código golf, então a resposta mais curta em bytes vence
  • Você pode assumir que a sequência de entrada é sempre válida
  • A sequência de entrada contém apenas letras maiúsculas
  • Os números originais são sempre organizados em ordem crescente
  • Você pode retornar o número no formato string ou número inteiro
  • As letras serão embaralhadas apenas entre uma palavra, não entre toda a cadeia.
  • Os números serão apenas de 1 a 9, inclusive ( ONEa NINE)

Possível seqüência sem codificação

Aqui está uma lista das cadeias de caracteres logo após serem convertidas em cadeias de caracteres a partir dos números:

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

Exemplos

"NEO" -> 1

"ENOWOT" -> 12

"EONOTWHTERE" -> 123

"SNVEEGHEITNEIN" -> 789

"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" -> 123456789

"NOEWOTTOWHEERT" -> 1223


5
Em todos os casos de teste, apenas as letras de uma palavra são embaralhadas, não as letras entre as palavras. Será sempre esse o caso?
Xnor

1
@xnor Esse sempre será o caso. Eu editei a pergunta.
Amorris

1
então você precisa mudar isso ".... (isto é. "onetwothree" -> "TTONWOHREEE")"
J42161217

2
@ TessellatingHeckler: Uma sequência que não aumenta estritamente é quando o próximo número pode ser o mesmo que o ex anterior. 1-1-1-2-2-3 (não estritamente crescente) em oposição a 1-2-3-4-5 (estritamente crescente)
koita_pisw_sou

1
Tecnicamente falando, isso é uma codificação, não criptografia, pois não há chave.
Patrick Roberts

Respostas:


5

Geléia ,  38  37 bytes

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

Um link monádico que obtém uma lista de caracteres (a sequência) e retorna um número inteiro.

Experimente online!

Usa um muito diferente do método a resposta geléia de Pietu1998 , ainda tem a mesma contagem de bytes ( Eu realmente pensei que poderia ele se acabar como menos)!

Não depende da monotonicidade do número original (portanto, uma entrada de HTREEWTONOEfuncionaria, por exemplo).

Quão?

Primeiro, observe que as próprias palavras (e, portanto, quaisquer anagramas) podem ser alteradas para as de comprimento 4 removendo Rs, Gs e Ss e substituindo qualquer Os por dois caracteres (digamos "12") e qualquer Xs com três caracteres ( diga "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

Podemos então mapear o produto dos ordinais desses caracteres para os números de 1 a 9 usando o módulo aritmético, dependendo da nossa escolha (o "12345"), e procurá-los em uma lista reordenada dos dígitos. O código realmente converte os caracteres primeiro e depois substitui os ordinais, mas também é possível em 37 bytes por caracteres, por exemplo, "DIAAE" ( tente ).

ḟ“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

A sua resposta é, literalmente, a única resposta sobre esta página que retorna um valor correto para: NINEONENIENOENNNIENOENNEINEONEINEONNENIENOINNEINENINNEINENIENNIENNNNIENNEININENIENNENINEINENINENNIEINNEINNENNIENIN.
Magic Octopus Urn

+ Pontos infinitos.
Magic Octopus Urn

Obrigado! (que me jogou porque há zero de largura espaços para o bloco de código no comentário, mas (ufa) ela não funciona )
Jonathan Allan

De qualquer forma, não é uma entrada válida;).
Magic Octopus Urn

Oh uau, eu não sabia que uma recompensa estava chegando - obrigado! Sim, não fazia parte das especificações solicitadas, apenas criei um método que funcionaria com entradas não ordenadas.
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: Depois de tudo isso, esqueci de incorporar uma variável de uso único. Peido de cérebro.
-2 bytes: recuo em espaço duplo → recuo em uma guia (graças a Coty Johnathan Saxman); observe que isso não aparece corretamente na resposta.

Ungolfed (compatível com 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

Localizador de número mágico:

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

Explicação:

Tive a sensação de poder esmagar os bits ASCII juntos e resumir de alguma forma para determinar quando eu tinha uma palavra completa. Originalmente, tentei mexer 3**ord(letter)e comparar com os resultados esperados, mas resultou em alguns números muito grandes. Eu acho que seria apropriado aplicar um pouco de força bruta a alguns parâmetros, a saber, módulo (para garantir que os números sejam pequenos) e um multiplicador para dispersar os números de maneira diferente em torno do intervalo do módulo.

Acabei mudando a variável multiplicadora para uma variável que afetava o poder em si, porque (por tentativa e erro) que de alguma forma conseguiu me dar uma resposta ligeiramente mais curta.

E acima, você vê os resultados dessa força bruta e um pouco de golfe manual.

A razão para escolher 3**xoriginalmente é porque eu sabia que você poderia representar todos os números lá. Os dígitos mais repetidos que qualquer número teve são dois (thrEE, sEvEn, NiNe, etc), então decidi pensar em cada entrada como um número base-3. Dessa forma, eu poderia (mentalmente) representá-los como algo como 10100000000010020000(três; um 1 no tslot, um 1 no rslot, um 1 no hslot e um 2 no eslot). Cada número dessa maneira obtém uma representação única que pode ser facilmente reunida, iterando a string e somando alguns números, e acaba independente da ordem real das letras. Obviamente, essa não foi a solução ideal, mas a solução atual ainda está escrita com essa ideia em mente.


O que é Py3k ...?
CalculatorFeline

Desculpas, editado (é o antigo nome de python 3)
Score_Under

1
É barato, mas você pode salvar 2 bytes (já que este é python 2) substituindo seu segundo nível de recuo (dois espaços) em uma única guia. [ tio.run/##NU7NCoJAGDy7T/… Experimente on-line!]
Coty Johnathan Saxman

Além disso, você pode ser capaz de salvar 6 bytes utilizando literal \x83, \x8ee, \x92na seqüência.
CalculatorFeline

@CalculatorFeline Infelizmente meu intérprete não gosta disso: 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 se eu colocar o codingcomentário lá em cima, mas isso ganha 15 bytes extras.
12/07

6

Python 2 , 131 127 bytes

s=input()
for y in'WXGURFSOIZ':vars()[y]=s.count(y)
while Z<9:s+=[O-U-W,W,R-U,U,F-U,X,S-X,G,I-X-G-F+U][Z]*str(Z+1);Z+=1
print s

Experimente online!

Com base em uma versão corrigida da solução JavaScript Draco18s .


Que uso interessante vars!
Xnor

@xnor era OVS como me aprendi que para outros campos de golfe :)))
mdahmoune

Muito esperto. Tenha um +1 para adaptar minha resposta (tão defeituosa quanto original).
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);

Experimente online!

PHP , 179 bytes

com base na abordagem anterior, verifique primeiro os números pares e depois os números ímpares em ordem crescente

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

Experimente online!

PHP , 201 bytes

for(;$o=ord(WUXGOHFVN[$i]);$i++)for(;$r[$o]<count_chars($argn)[$o];$t[]=$i>3?2*$i-7:2+2*$i,sort($t))for(++$r[$o],$n=0;$q=ord(([TO,ORF,IS,HEIT,EN,TREE,IVE,SEEN,NIE][+$i])[$n++]);)$r[$q]++;echo join($t);

Experimente online!


falha paraENOOWTWTOWOT
Titus

@Titus agora está corrigido. Eu tenho mal a pergunta
Jörg Hülsermann

Sim, os exemplos são um tanto enganosos. Uau, isso custou! Você dividiria isso ?!
Titus

@Titus Acho que tenho atingir o limite para encontrar uma outra maneira como a sua abordagem
Jörg Hülsermann

1
$i++<9e em $ivez de $i<10e ++$i(-1 byte); _405162738[$i]em vez de $i%2?$i/2+4:$i/2-1(-4 bytes) ( $i/2+~($i%2*-5)iria trabalhar muito, mas isso é um byte mais tempo.)
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)))

Mais do que as outras duas, uma das outras entradas JS, mas pensei em abandonar uma abordagem interessante que poderia funcionar para alguém em outro idioma.

Essencialmente, podemos determinar o seguinte:

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

Qualquer ocorrência dessas letras implica que esse dígito exista no número original. A partir daqui, podemos deduzir o restante dos dígitos:

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

Incluindo os dois casos complicados:

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

Ambos 1e 9área Hard comparativamente. Para ONE, Eaparece mais de uma vez em algumas palavras ( SEVENtem duas) e faz N( NINE), então estamos presos à verificação do Oque ocorre em outros dois lugares, felizmente, ambos são simples.

Para Nove, nove é difícil, não importa como você o corta.

Assim, terminamos com 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 é capaz de referenciar siX, eiGht e Five (com 5 referências anteriores) com as atribuições de variáveis, economizando bytes. Graças a Neil por isso, ele usa vários recursos do JS com os quais eu não estou familiarizado (os back-tiquetaques para retirar ('ao meio, por exemplo) e, na verdade, chega muito mais perto da idéia que eu escrevi no papel antes de tentar codificá-lo (Eu tinha deixado 9 como "o que sobrou", pensando nisso como "se eu vir um X, posso removê-lo e um Se Ida corda, então ..." para que, depois dos quatro casos simples, os próximos três se tornem simples).

A razão dessa entrada ser interessante é porque ela pode manipular qualquer sequência aleatória como entrada. ou seja, em vez de as palavras individuais serem embaralhadas, podemos embaralhar toda a cadeia, que é o que eu pensei que John estava fazendo 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
Grande, mas há um problema com a contagem 9 ... Eu acho que pode ser IXG-f + u
mdahmoune

@mdahmoune Atire, você está certo. Eu estraguei tudo. : <
Draco18s

Salve 4 bytes usando s.split(t).length-1, 2 bytes usando s.repeat(n>0&&n)(por que n é menor que zero afinal? Salva 7 bytes). Salve um monte de bytes declarando gno escopo de sforma que você não precise continuar passando o tempo todo; e melhor ainda, você pode torná-lo um modelo marcado, que economiza 55 bytes no total (antes da correção 9). Economize mais bytes salvando valores repetidos em temporários, e eu raspei mais alguns fora de usar 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`` .
305 Neil

@ Neil Não sei por que N acabou sendo menor que zero, mas foi o teste de TRÊS. Continuei recebendo um erro e investigando descobri que era necessário, mas ainda não tenho certeza. O mapa da biblioteca de modelos que você possui é javascript, que eu nem sei ler. : D
Draco18

@Neil Ah, certo, a razão para a verificação n> 0: Se não é um dois, mas não três. R = 0, W = 1. 0-1 = -1. Eu estava tendo problemas para descobrir isso há uma hora atrás, sabia que estava relacionado ao cheque 3, mas estava tendo um diabo trabalhando nisso (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"

saída

789


Você poderia salvar um byte extra com e c@#[[i]]não c[#[[i]]]? Você pode salvar outro byte usando a sintaxe de infix ~no Table.
numbermaniac

4

C #, 218 bytes

Versão curta:

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

Versão expandida:

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

Experimente ONLINE!

Sendo minha primeira entrada, não tenho certeza sobre as regras ... Estou apenas contando o tamanho da classe usada para descriptografar, não o código que a testa, certo?

Editar

E por diversão - eis o que comecei a fazer, sem ler as regras completas: S - Veja no IdeOne . Ele é criptografado mesmo quando caracteres de um dígito podem ser embaralhados para qualquer lugar da string.

Editar 2

Encurtado de acordo com as dicas de TheLethalCoder. Obrigado!

Editar 3

E agora Titus raspou mais alguns bytes. Obrigado!


2
Olá e bem-vindo ao PPCG! Você só precisa incluir o método, pode removê public static-lo para. Você pode converter para um método anônimo como s=>{<do stuff>return"";}. Você pode usar varalgumas vezes, declarar variáveis ​​juntas economiza bytes, ie int i=1,j;. Criar um array a partir de uma string e dividi-la geralmente é mais curto (embora eu não tenha verificado neste caso), por exemplo "ONE|TWO".Split('|'). Você pode usar em <0vez de==-1
TheLethalCoder 11/17/17


@TheLethalCoder Ótimas dicas, obrigado!
SamWhan

Não testado em tudo, mas eu acredito que o seguinte é o equivalente de seu 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

Em uma nota lateral, geralmente é mais fácil usar o TIO para os seus TIO's!
TheLethalCoder 11/07

3

JavaScript (ES6), 142 139 bytes

Guardado 3 bytes graças a Neil .

Atualmente, não aproveita os números que estão sempre organizados em ordem crescente

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


espere o que?? "axbxc".split`x`.join``. Como isso é chamado? Não consigo encontrar nada no google.
Qwerty

@Qwerty - Eles são etiquetados literais modelo , uma característica ES6 que estou usando para economizar alguns bytes por não precisar parens no caso de splitejoin
Craig Ayre

Você atendeu. Conheço literais de modelo com tags, mas não percebi que você também pode usá-lo nessas funções. Obrigado.
Qwerty

Eles estão um pouco diferente, você tem literais modelo (por exemplo x=`foo${5+5}bar`), eles estão com etiquetas quando você chamar uma função de usá-los sem parênteses: foo`foo${5+5}bar`o que é o mesmo quefoo(['foo','bar'], 10)
Craig Ayre

1
f(s.slice(y))é sempre uma string para que você não precise do ''+antes.
Neil

2

Gelatina , 38 bytes

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

Experimente online!

Explicação

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.

Há um problema com seu código. Tente passar a corda "EIGHTNINE"para ele :)
Amorris

@Amorris corrigido para 0 bytes.
PurkkaKoodari

Eu acho que não funciona para "VENESGTHIEENNI"
J42161217

Eu segundo @Jenny_mathy
Amorris

@ Jenny_mathy O programa é muito ineficiente e fica sem tempo e memória para entradas longas (eu sei, é muito ruim). Você pode substituir o 3com 2.2por usar um limite superior menor, o que permite calcular facilmente o 789 sem alterar o princípio de funcionamento. 2seria bom, mas dificilmente falharia em certas entradas com muitos seis.
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)

Exemplo de trecho de código:

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

Experimente online! Basicamente baseado na resposta do PowerShell do @ 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

Experimente online!

Explicação

  • Primeiro, solte vários caracteres desnecessários, não necessários para a distinção
  • Escolha os 1s na frente (isso nos permite largar o resto do sistema operacional imediatamente depois e limpar alguns Ns antes de chegarmos à bagunça 5, 7, 9)
  • 2, 3, 4, 6 e 8 agora são triviais
  • 9s são um NN duplo, então pegue os que estão no final antes de lidarmos com 5 e 7
  • Substitua 7s da direita (para não reduzirmos o VNV para 75 em vez de 57)
  • 5s são os Vs restantes

Se você adicionar% (G` ao cabeçalho, poderá usar o código original e ele avaliará cada linha da entrada separadamente: TIO
PunPun1000

Obrigado @ PunPun1000. Achei que deveria haver uma maneira de fazer isso, mas desisti depois de não encontrá-lo rapidamente.
Kytheron 18/08/19

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

Experimente online!

Código ungolfed mas não trabalhando:

[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 exemplo, (?<3>[THRE]{5})corresponde à classe de caracteres THRE, para que possa correspondê-los fora de ordem e deve corresponder a qualquer um desses caracteres cinco vezes um ao lado do outro, e o grupo de captura é nomeado '3' para mapear nomes com números.

Compactação rudimentar trocando o texto repetido })|(?<por a z.


1

C ++, 296 , 288 bytes

Versão curta:

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

Versão 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;
}

Experimente ONLINE!

Edit:
1) 200-> 296 bytes, para incluir namespace e definição de N na contagem, conforme sugerido pelo orlp 2) 296-> 288, para usar macro, graças a Zacharý


Você precisa incluir a definição Ne using namespace std;a contagem de bytes.
orlp

Eu deveria ser mais específico, não apenas incluí-lo na sua contagem de bytes, mas também na sua resposta. Sua resposta deve ser capaz de executar apenas ligando Qlogo após, sem outras adições.
orlp

Eu reeditei para incluir tudo. Para a definição de N, eu não tinha certeza, mas para o namespace, geralmente não a incluo (trate-a como material de biblioteca). Embora, no código atual é crucial para a seqüência ao trabalho
koita_pisw_sou

1
Você pode definir uma macro para salvar alguns bytes? repl.it/JY7k
Zacharý

1

Ruby, 138 114 110 bytes

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

A contagem de bytes inclui 1 byte para a -popção.

O que?

Este:

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

é um literal de regex que, através da interpolação de cadeias, avalia como:

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

Se atribuirmos isso a regex, o resto do código será um pouco fácil de entender: Cada correspondência na entrada é substituída pelo número do grupo de captura, extraído da variável mágica $~que contém os dados de correspondência atuais:

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

Experimente 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 .. devido ao regex da versão anterior não estar funcionando corretamente (também correspondia a "EEE"; "EEN"; etc.)

Explicação:

Experimente aqui.

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 ... resultado errado para "ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN":(
Olivier Grégoire

Sim, essa é a única coisa que me impediu de marcar com +1! Minha solução foi 240 bytes ... antes que você me vencesse.
Olivier Grégoire

@ OlivierGrégoire Sinta-se à vontade para postar sua solução de 240 bytes, porque não consigo encontrar uma solução. A desvantagem [ONE]{3}é que ela também corresponde EENno final do caso de teste às partes OITO e Nove. E duvido que exista. um regex para combinar todos estes: ENO|EON|NEO|NOE|OEN|ONEsem também correspondência EEE;EEN;EEO;...para todos os números que é menor do que 40 bytes .. Talvez eu possa fazer algo usando substringe reverter verificando os números, mas eu realmente não tenho tempo para descobrir isso agora ..
Kevin Cruijssen

@ OlivierGrégoire Se você ainda tem sua resposta de 240 bytes, sinta-se à vontade para publicá-la. Apenas me deparei com este desafio novo, e fixa a minha resposta, fazendo um novo regex para +58 bytes ..
Kevin Cruijssen

1
Bem, parece que eu encontrei um caminho ainda mais curto ao refazer este desafio: 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;}

Experimente online!

Tomei a liberdade de reutilizar o modelo de TIO de Kevin Cruyssen . Espero que você não se importe;)


Ah, esqueça o comentário anterior. Você cria a regex, em vez de fazer um loop sobre a regex. Ainda assim, eu estava perto da minha primeira resposta se eu tivesse usado o s.substring. A pior parte é que eu estou usando s.substringna minha resposta atual, lol .. Ah, bem, +1 de mim. Ainda bem que é quase fim de semana ..
Kevin Cruijssen

1

05AB1E , 36 31 bytes

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

Experimente online!


Ver executado com depuração: 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.

Eu estava apenas sugerindo que você tiver o sinal verde em vez de mim e eu notei um erro: FURONESEVretornos 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//)}

Experimente online!


Agradável! Par de truques que ajuda: map{...}muitas vezes pode ser substituído com map...,, lengthe y///cgeralmente são intercambiáveis também (nem sempre menor quando não está trabalhando no $_embora!), Em vez do while, ++$,x s/^$i//é mais curto, e se você mudar -npara -pque você pode acrescentar a `$ \` vez de ligar print! Experimente online!
Dom Hastings

Além disso, espero que você não se importe de eu postar algum conselho, se você preferir que eu me abstenha. :)
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*

Experimente online!


Solução de força bruta, não aproveita a não diminuição dos dígitos.


Graças a @Mr. Xcoder para economizar 2 bytes!


Você tem que incluir def f(s):na sua contagem de bytes, esta não é uma função anonymouos
Mr. Xcoder

Também você pode substituir while len(s)>0porwhile len(s)
Sr. Xcoder 11/07

@ Mr.Xcoder obrigado por esse esclarecimento
Perseguição Vogeli

Você pode mover a declaração de epara o cabeçalho da função para -1 byte. Além disso, as execcompreensões de lista e podem salvar bytes no recuo.
Início>

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

versão mais antiga, 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];

percorre os dígitos de 1 a 9, contando caracteres únicos na palavra e subtraindo as contagens de caracteres não únicos, imprimindo o dígito em movimento.
Embora esteja imprimindo em qualquer lugar, as contagens de dígitos devem ser armazenadas para que o 9caso funcione.

Execute como pipe -nRou experimente online .

Ele economizaria mais 4 bytes para armazenar as contagens de dígitos em $a[$i]vez de $a[$i+48]e usar ASCII 1e 7(entre aspas) em vez dos próprios caracteres de dígito.

demolir

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

ONEnão é a única palavra com um O, portanto, é necessário subtrair as contagens para W(apenas aparecendo em TWO) e U(somente aparecendo em FOUR) e assim por diante.
NINEé especial, porque não há como subtrair apenas se eu usasse as letras (isso exigiria I-X-G-F+Uou N-O-S+W+U+X), então, use as contagens de dígitos.

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

assume todas as entradas em maiúsculas; caracteres podem ser misturados por toda parte.
Execute como pipe -nRou experimente online .

explicação

percorre as palavras dos dígitos, contando as ocorrências de seus caracteres únicos na entrada e no processo, reduzindo a contagem de outros caracteres. "Outros caracteres" pode significar todos os outros caracteres da palavra; mas apenas considerando aqueles que serão necessários posteriormente, salvou 19 bytes.

A transformação do str_repeatloop em um loop combinado economizou 5 bytes.

E o uso de variáveis ​​variáveis ​​para a contagem de dígitos salvou outros 8.

demolir

$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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.