Оригінальний номер


36

Керівні принципи

Сценарій

У Джона важливе число, і він не хоче, щоб його бачили інші.

Він вирішив зашифрувати номер, виконавши наступні кроки:

Його кількість - це завжди не спадаюча послідовність (тобто "1123")

Він перетворив кожну цифру в англійські слова. (тобто "123" -> "ONETWOTHREE")

А потім переставляйте букви навмання. (тобто "ONETWOTHREE" -> "ENOWTOHEETR")

Джон відчував, що його номер у цьому безпечний. Насправді таке шифрування можна легко розшифрувати :(


Завдання

Враховуючи зашифрований рядок s, ваше завдання - розшифрувати його та повернути початкове число.


Правила

  • Це кодовий гольф, тому найкоротша відповідь у байтах виграє
  • Можна припустити, що рядок введення завжди дійсний
  • Вхідний рядок містить лише великі літери
  • Оригінальні номери завжди розташовані у порядку зростання
  • Ви можете повернути номер у рядковому чи цілому форматі
  • Букви будуть змішуватися лише між одним словом, а не між цілим рядком.
  • Цифри будуть лише від 1 до 9 включно ( ONEдо NINE)

Можлива нешифрована рядок

Ось список рядків відразу після їх перетворення в рядки з чисел:

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

Приклади

"NEO" -> 1

"ENOWOT" -> 12

"EONOTWHTERE" -> 123

"SNVEEGHEITNEIN" -> 789

"ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN" -> 123456789

"NOEWOTTOWHEERT" -> 1223


5
У всіх тестових випадках переміщуються лише літери всередині слова, а не літери між словами. Це завжди буде так?
xnor

1
@xnor Так буде завжди. Я відредагував питання.
Amorris

1
тоді вам потрібно змінити це ".... (т. е." ONETWOTHREE "->" TTONWOHREEE ")"
J42161217

2
@ TessellatingHeckler: Не суворо зростаюча послідовність - це коли наступне число може бути таким же, як і попереднє колишнє. 1-1-1-2-2-3 (не суворо зростаючий) на відміну від 1-2-3-4-5 (суворо зростаючий)
koita_pisw_sou

1
Технічно кажучи, це кодування, а не шифрування, оскільки немає ключа.
Патрік Робертс

Відповіді:


5

Желе ,  38  37 байт

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

Монадічне посилання, що містить список символів (рядок) і повертає ціле число.

Спробуйте в Інтернеті!

Використовує дуже відрізняється метод в желе відповідь Pietu1998 в , але має той же лічильник байтів ( я дійсно думав , що це , можливо , вона в кінцевому підсумку , як менше)!

Не покладається на монотонність вихідного числа (так, наприклад, буде вводитися введення даних HTREEWTONOE).

Як?

Спершу зауважте, що самі слова (а отже, будь-які їх анаграми) можуть бути змінені на слова довжиною 4, видаливши будь-які Rs, Gs та Ss та замінивши будь-який Os двома символами (скажімо, "12") та будь-які Xs з трьома символами ( сказати "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

Потім ми можемо зіставити твір порядків цих символів на числа 1 - 9, використовуючи арифметику за модулем, залежно від нашого вибору ("12345"), а потім переглянути їх у перепорядкованому списку цифр. Код фактично вводить символи спочатку, а потім замінює порядки, але це також можливо в 37 байт символами, наприклад, "DIAAE" ( спробуйте ).

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

Ваш відповідь буквально єдина відповідь на цій сторінці , яка повертає правильне значення: NINEONENIENOENNNIENOENNEINEONEINEONNENIENOINNEINENINNEINENIENNIENNNNIENNEININENIENNENINEINENINENNIEINNEINNENNIENIN.
Чарівний восьминіг Урна

+ Бали нескінченності.
Magic Octopus Urn

Спасибі! (що кинуло мене через те, що в блоці коду в коментарі є пробіли нульової ширини, але (коли) він працює )
Джонатан Аллан

Це все-таки неправдивий вхід;).
Magic Octopus Urn

Ох вау, я не знав, що щедрота йде - дякую! Так, це не було частиною запитуваної специфікації, я просто створив метод, який би працював з невпорядкованим введенням.
Джонатан Аллан

10

Python 2, 121 117 115 байт

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 байти: Після цього гольфу я забув ввести змінну для одноразового використання. Мозковий пердеть.
-2 байти: подвійний відступ → відступ на одній вкладці (завдяки Coty Johnathan Saxman); зауважте, що це не відображається правильно у відповіді.

Ungolfed (сумісний з 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

Пошук магічних чисел:

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

Пояснення:

У мене було відчуття, що я можу розбити біти ASCII разом і якось підсумувати їх, щоб визначити, коли я маю повне слово. Спочатку я намагався зіпсуватись 3**ord(letter)і порівняти очікувані результати, але це призвело до дуже великої кількості. Я хоч було б доцільно трохи зафіксувати деякі параметри, а саме модуль (щоб забезпечити малі числа) та множник, щоб по-різному розповсюджувати числа по діапазону модуля.

Я в кінцевому підсумку змінив змінну множника на змінну, що впливає на саму потужність, оскільки (від спроб і помилок) мені якось вдалося дати трохи коротший відповідь на гольф.

А вище ви бачите результати того грубого форсування та трохи ручного гольфу.

Причина вибору 3**xспочатку полягає в тому, що я знав, що ти можеш представляти кожне число. Найбільш повторювані цифри, які мали будь-яке число, - це дві (thrEE, sEvEn, NiNe тощо), тому я вирішив подумати про кожне введення як базове число 3. Таким чином я міг (подумки) зобразити їх як щось подібне 10100000000010020000(три; 1 в tслоті, 1 в rслоті, 1 в hслоті і 2 в eслоті). Кожне число таким чином отримує унікальне подання, яке можна легко скласти разом, повторивши рядок і підсумовуючи деякі цифри, і воно не залежить від фактичного порядку букв. Звичайно, це не виявилося ідеальним рішенням, але поточне рішення все ще написане з цією думкою.


Що таке Py3K? ...
CalculatorFeline

Вибачення, відредаговано (це колишня назва python 3)
Score_Under

1
Це дешево, але ви можете зберегти 2 байти (оскільки це пітон 2), підсунувши свій другий рівень відступу (два пробіли) для однієї вкладки. [ tio.run/##NU7NCoJAGDy7T/… Спробуйте в Інтернеті!]
Coty Johnathan Saxman

Крім того , ви можете бути в змозі зберегти 6 байт з допомогою літерал \x83, \x8eі \x92в рядку.
CalculatorFeline

@CalculatorFeline На жаль , мій перекладач не так: 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. Це працює, якщо я поміщую codingкоментар там, але це набирає 15 зайвих байтів.
Score_Under

6

Python 2 , 131 127 байт

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

Спробуйте в Інтернеті!

На основі виправленої версії рішення JavaScript Draco18s .


Яке цікаве використання vars!
xnor

@xnor було ов, як дізналися мене, що для інших гольфів :)))
mdahmoune

Дуже розумний. Зазначте +1 для адаптації моєї відповіді (настільки хибно, як і раніше).
Draco18s

5

PHP , 164 байти

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

Спробуйте в Інтернеті!

PHP , 179 байт

на основі попереднього підходу перевіряють спочатку парні числа, а потім непарні числа у порядку зростання

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

Спробуйте в Інтернеті!

PHP , 201 байт

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

Спробуйте в Інтернеті!


не вдаєтьсяENOOWTWTOWOT
Тит

@Titus тепер виправлено. Я неправильно зрозумів питання
Йорг Гюльсерманн

Так, приклади дещо вводять в оману. Нічого собі, що коштувало! Ви б це зламали ?!
Тит

@Titus Я думаю, що я досяг межі, щоб знайти інший спосіб, як ваш підхід
Jörg Hülsermann

1
$i++<9і $iзамість $i<10і ++$i(-1 байт); _405162738[$i]замість $i%2?$i/2+4:$i/2-1(-4 байти) ( $i/2+~($i%2*-5)також працював би, але це на один байт довше.)
Тіт

5

Javascript (ES6), 288 150 144 байт

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

Довше, ніж два інших, один із інших записів JS, але я подумав, що я кину цікавий підхід, який може працювати для когось іншою мовою.

По суті ми можемо визначити наступне:

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

Будь-яке виникнення цих букв означає, що ця цифра існує у вихідному номері. Звідси ми можемо вивести решту цифр:

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

У тому числі два складні випадки:

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

І те, 1і 9область Жорсткі порівняно. ОДНЕ, Eв деяких словах з’являється не один раз ( SEVENмає два), як це робиться N( NINE), тому ми застрягли у тому, щоб перевірити, Oщо відбувається у двох інших місцях, на щастя, обидва прості.

Для дев'яти дев'ять важких незалежно від того, як ви їх нарізаєте.

Таким чином, ми закінчуємо цю карту:

[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 здатний здійснювати зворотні посилання siX, eiGht і Five (з 5 зворотними посиланнями foUr) зі змінними призначеннями, економлячи байти. Завдяки Нілу для цього він використовує декілька особливостей JS, з якими я дуже незнайомий (наприклад, зворотні тики для роздягання ('навпіл) і насправді наближається до ідеї, яку я накреслив на папері, перш ніж намагатися її кодувати. (Я залишив 9 як "те, що залишилося", і думав про це як "якщо я бачу, Xя можу видалити його і з, Sі Iз рядка, тоді ...", щоб після чотирьох простих випадків наступними 3 стали простий).

Причина цього запису цікава тим, що він може обробляти будь-який перетасований рядок як вхід. тобто замість того, як окремі слова перетасовуються, ми можемо перемішати цілий рядок. Це те, що я думав, що Джон робив спочатку:

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
Чудово, але є проблема з підрахунком 9 ... Я думаю, що це може бути ixg-f + u
mdahmoune

@mdahmoune Shoot, ти маєш рацію. Я зіпсував це. : <
Draco18s

Збережіть 4 байти за допомогою s.split(t).length-1, 2 байти за допомогою s.repeat(n>0&&n)(чому все-таки n менше нуля? Економить 7 байт). Збережіть купу байтів, оголосивши gв області застосування sтак, що вам не доведеться весь час передавати його, а ще краще - ви можете зробити тег з шаблоном, що заощаджує 55 байт (до 9 виправлення). Зберегти більше байт, зберігаючи повторювані значення в тимчасових, і я голився кілька більше від використання map: s=>[,(l=t=>s.split(t).length-1)`O`-l`W`-l`U`,w=l`W`,l`R`-w,u=l`U`,l`F`-u,x=l`X`,l`S`-x,g=l`G`,l`I`-x-g].map((n,i)=>`${i}`.repeat(n)).join`` .
Ніл

@Neil Я не впевнений, чому N коли-небудь закінчився менше нуля, але це було під час тестування на ТРИ. Я постійно отримував помилку і досліджував, що виявив, що це потрібно, але я все ще не впевнений. У вас шаблонна карта бібліотеки - javascript, яку я навіть не знаю, як читати. : D
Draco18s

@Neil Ах, да, причина для перевірки п> 0: Якщо є в дві , але не ТРЕТЯ. R = 0, W = 1. 0-1 = -1. У мене виникли проблеми з рахунком, що це годину тому, я знав, що це стосується 3-х перевірок, але мав час чорт, який працював над цим (відсутність кави).
Draco18s

4

Математика, 133 байти

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


вхід

"VENESGTHIEENNI"

вихід

789


Не могли б ви зберегти зайвий байт c@#[[i]]замість c[#[[i]]]? Ви можете зберегти інший байт, використовуючи інфіксуючий синтаксис ~на Table.
numbermaniac

4

C #, 218 байт

Коротка версія:

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

Розширена версія:

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

Спробуйте ОНЛАЙН!

Будучи моїм першим записом, я не впевнений у правилах ... Я рахую лише розмір класу, який використовується для декриптування, а не код, який його перевіряє, правда?

Редагувати

І для задоволення - ось що я почав робити, не читаючи повних правил: S - Дивіться це на IdeOne . Він вимикається, навіть коли символи з однієї цифри можуть бути скомпоновані до будь-якого місця в рядку.

Редагувати 2

Скорочено за порадами TheLethalCoder. Спасибі!

Правка 3

А тепер Тит поголив ще кілька байтів. Спасибі!


2
Привіт і ласкаво просимо до PPCG! Вам потрібно лише включити метод, який ви можете видалити public staticз нього. Ви можете конвертувати в анонімний метод, як-от s=>{<do stuff>return"";}. Ви можете використовувати varкілька разів, декларування змінних разом економить байти, тобто int i=1,j;. Створення масиву з рядка та розділення на нього зазвичай коротше (хоча я в цьому випадку не перевіряв), тобто "ONE|TWO".Split('|'). Ви можете використовувати <0замість==-1
TheLethalCoder

Для отримання додаткових порад див поради щодо гольф-коду в C # .
TheLethalCoder

@TheLethalCoder Чудові поради, дякую!
SamWhan

Зовсім не перевірено, але я вважаю, що наступним є еквівалент вашого коду на 221 байт: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

Зі сторони, TIO зазвичай простіше використовувати для своїх TIO!
TheLethalCoder

3

JavaScript (ES6), 142 139 байт

Збережено 3 байти завдяки Нілу .

Наразі не використовує переваги, номери завжди розташовуються у порядку зростання

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


чекати, що?? "axbxc".split`x`.join``. Як це називається? Не можу знайти нічого в Google.
Qwerty

@Qwerty - вони позначені літералами шаблонів , функцією ES6, яку я використовую, щоб зберегти кілька байтів, не потребуючи паронів у випадку splitтаjoin
Крейг Айре

Ви відповіли на це. Я знаю позначені літеральні шаблони, але я не зрозумів, що ви також можете використовувати його на цих функціях. Дякую.
Qwerty

Вони дещо інші, у вас є літеральні шаблони (наприклад x=`foo${5+5}bar`), вони позначені тегами, коли ви викликаєте функцію, використовуючи їх без паролів: foo`foo${5+5}bar`що таке самеfoo(['foo','bar'], 10)
Craig Ayre

1
f(s.slice(y))це завжди рядок, тому ''+перед цим вам не потрібно .
Ніл

2

Желе , 38 байт

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

Спробуйте в Інтернеті!

Пояснення

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.

Виникла проблема з вашим кодом. Спробуйте передати рядок "EIGHTNINE"у неї :)
Amorris

@Amorris встановлено на 0 байт.
PurkkaKoodari

Я думаю, що це не працює для "VENESGTHIEENNI"
J42161217

Я другий @Jenny_mathy
Amorris

@Jenny_mathy Програма дуже неефективна і не вистачає часу та пам'яті на довгі введення (я знаю, це дуже погано). Ви можете замінити 3з , 2.2щоб використовувати менше верхньої межі, що дозволяє легко обчислити 789 , не змінюючи принцип роботи. 2Було б добре, але ледве не вдасться отримати певні входи з великою кількістю шістдесят.
PurkkaKoodari

2

Javascript (ES6), 221 байт

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)

Приклад фрагмента коду:

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

Сітківка , 88 байт

[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

Спробуйте в Інтернеті!

Пояснення

  • По-перше, киньте купу непотрібних символів, не потрібних для виразності
  • Виберіть 1-у частину спереду (це дозволяє нам опустити решту Ос одразу після і очистить кілька Нс, перш ніж ми дістанемося до 5, 7, 9 безладу)
  • 2, 3, 4, 6 і 8 зараз тривіальні
  • 9 є подвійним NN, тому схопіть їх з кінця, перш ніж ми матимемо справу з 5 і 7
  • Замініть 7s справа (щоб ми не зменшували VNV до 75 замість 57)
  • 5s - решта Vs

Якщо ви додасте% (G` до заголовка, ви можете використовувати оригінальний код, і він оцінить кожен рядок введення окремо: TIO
PunPun1000

Дякуємо @ PunPun1000. Я подумав, що має бути спосіб зробити це, але відмовився, не знайшовши його швидко.
Kytheron

1

PowerShell , 182 байти

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

Спробуйте в Інтернеті!

Невикористаний, але не працює код:

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

наприклад, (?<3>[THRE]{5})відповідає класу символівTHRE , тому він може зіставляти їх із порядку, і повинен відповідати будь-якому з цих символів п’ять разів один біля одного, а група захоплення має назву "3", щоб зіставити імена з цифрами.

Рудиментарне стиснення, замінюючи текст, що повторюється, })|(?<на a z.


1

C ++, 296 , 288 байт

Коротка версія:

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

Повна версія:

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

Спробуйте ОНЛАЙН!

Редагувати:
1) 200-> 296 байт, для включення простору імен та визначення N у кількість, як запропонував orlp 2) 296-> 288, для використання макросу, завдяки Zacharý


Потрібно включити визначення Nі using namespace std;в число байтів.
orlp

Я повинен бути більш конкретним, не тільки включити його у свій облік байтів, але й у свою відповідь. Ваша відповідь повинна бути спроможна виконати, зателефонувавши Qвідразу після неї, без будь-яких інших доповнень.
orlp

Я змінив редагування, щоб включити все це. Для визначення N я не був впевнений в собі, але для простору імен я зазвичай не включаю його (трактую його як бібліотечний матеріал). Хоча в нинішньому коді важливо, щоб рядок працював
koita_pisw_sou

1
Чи можете ви визначити макрос для збереження кількох байт? repl.it/JY7k
Zacharý

1

Рубі, 138 114 110 байт

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

Кількість байтів включає 1 байт для -p параметра.

Що?

Це:

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

являє собою регулярний вираз, який за допомогою рядкової інтерполяції оцінює:

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

Якщо ми це призначимо regex, решту коду зрозуміти дещо легко: кожен збіг у вході заміщений номером групи захоплення, вилученою з магічної змінної, $~яка містить дані поточної відповідності:

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

Спробуйте в Інтернеті!


1

Java 8, 198 256 байт

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 байт .. через те, що регулярний вираз попередньої версії не працює належним чином (він також відповідає "EEE"; "EEN" і т. Д.)

Пояснення:

Спробуйте тут.

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
Ерф ... неправильний результат для "ENOOWTEERHTRUOFEVIFXISNEVESTHGIEENIN":(
Олів'є Грегоар

Так, це єдине, що заважало мені поставити +1 цьому! Моє рішення становило 240 байт ... перш ніж ти мене побив.
Олів'є Грегоар

@ OlivierGrégoire Не соромтеся розмістити ваше 240-байтне рішення, тому що я не можу знайти рішення .. Недоліком [ONE]{3}є те, що він також відповідає EENв кінці цього тестового випадку з частинами восьми та дев'яти .. І я сумніваюся, що є регулярний вираз, щоб відповідати всім цим: ENO|EON|NEO|NOE|OEN|ONEбез відповідності також EEE;EEN;EEO;...для всіх чисел, менших за 40 байт .. Можливо, я можу щось зробити, використовуючи substringта зворотну перевірку чисел, але я зараз не маю часу це зрозуміти ..
Kevin Cruijssen

@ OlivierGrégoire Якщо у вас все ще є відповідь на 240 байт, сміливо опублікуйте її. Щойно я знову зіткнувся з цим викликом і виправив свою відповідь, створивши новий регекс на +58 байт ..
Кевін Круїйсен

1
Що ж, схоже, я знайшов ще коротший шлях, коли повторював цей виклик: p
Олів'є Грегоар

1

Java (OpenJDK 8) , 181 байт

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

Спробуйте в Інтернеті!

Я взяв на себе сміливо повторно використовувати шаблон TIO Кевіна Кройссена . Сподіваюся, ви не заперечуєте;)


Ах, ніколи не пам’ятайте про мій попередній коментар .. Ви будуєте регулярний вимір, а не петлю над регулярним виразом. Тим не менш, я був близький зі своєю першою відповіддю, якби тільки я використав це s.substring. Найгірше - це те, що я використовую s.substringв моїй нинішній відповіді, лол .. А ну, +1 від мене. Радий, що майже вихідні ..
Кевін Крейссен

1

05AB1E , 36 31 байт

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

Спробуйте в Інтернеті!


Перегляд його запускався за допомогою налагодження: TIO За допомогою налагодження

‘€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# | 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.

Я просто пропонував вам мати зелену позначку, а не я, і я помітив помилку: FURONESEVreturn FUR1SEV:(
Джонатан Аллан

1

Perl 5 , 102 + 1 (-n) = 103 байти

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

Спробуйте в Інтернеті!


Приємно! Пара трюків , які допомагають: map{...}часто можуть бути замінені map...,, lengthі y///c, як правило , взаємозамінні теж (не завжди менше , коли він не працює на $_хоча!), Замість while, ++$,x s/^$i//коротше, і якщо ви зміните -nдо -pвам можна додати в `$ \` замість дзвінка print! Спробуйте в Інтернеті!
Дом Гастінгс

Крім того, я сподіваюся, що ви не заперечуєте над тим, щоб розмістити будь-яку пораду, якщо ви хочете, я утримаюся. :)
Дом Гастінгс

0

Пітон 3 , 238 236 байт

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*

Спробуйте в Інтернеті!


Рішення грубої сили, не скористався зменшенням цифр.


Завдяки @Mr. Xcoder для збереження 2 байт!


Ви повинні включити def f(s):до свого числа байтів, це не функція
анонімусу

Також ви можете замінити while len(s)>0наwhile len(s)
Містер Xcoder

@ Mr.Xcoder дякую за це роз’яснення
Chase Vogeli

Ви можете перемістити декларацію eв заголовок функції на -1 байт. Крім того, execі розуміння списку може зберегти байти на відступ.
CalculatorFeline

0

PHP, 141 байт

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

старіша версія, 151 байт :

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

прокручуйте цифри від 1 до 9, підраховуючи унікальні символи у слові та віднімаючи не унікальні підрахунки символів, друкуючи цифру на ходу.
Хоча це друк на ходу, підрахунок цифр повинен зберігатися, щоб 9справа працювала.

Запустіть як трубу -nRабо спробуйте в Інтернеті .

Це дозволить заощадити ще 4 байти, щоб зберегти підрахунки цифр $a[$i]замість $a[$i+48]та використовувати ASCII 1та7 (у лапках) замість самих знаків цифр.

зламатися

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

ONEне є єдиним словом з а O, тому йому потрібно відняти підрахунки W(лише в TWO) і U(лише в FOUR) і так далі.
NINEє особливим, тому що немає способу просто відняти, якби я використав букви (що вимагало б I-X-G-F+UабоN-O-S+W+U+X ), тому я використовую замість підрахунків цифр.

PHP, 160 байт

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

передбачає весь верхній регістр; символи можуть бути зашифровані по всьому.
Запустіть як трубу -nRабо спробуйте в Інтернеті .

пояснення

перебирає через цифри слова, рахуючи кількість їх унікальних символів на вході та в процесі зменшення кількості інших символів. "Інші символи" могли означати всі інші символи у слові; але лише враховуючи ті, які пізніше знадобляться, збережені 19 байт.

Перетворення str_repeat циклу в комбінований цикл зберегла 5 байт.

І за допомогою змінних змінних для підрахунку цифр збережено ще 8.

зламатися

$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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.