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


18

Це завдання, по суті , ідентична цьому одному тільки з однією відмінністю: він тепер дозволено перетасувати букви в будь-якому місці рядка.

Сценарій

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

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

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

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

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

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


Завдання

Враховуючи зашифрований рядок 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

"NWEOOT" -> 12

"TOEERWNEHOT" -> 123

"IHNEVGENNEISTE" -> 789

"WEETVTRFSVUHNEEFRHIXEOINSNIEGTOONIEE" -> 123456789

"EWHEWROETOTTON" -> 1223

"ONEWESTV" -> 27 (спасибі, ETHproductions!)


7
Пропонований тестовий випадок: щось на кшталт "ONEWESTV" -> 27(включає число, яке насправді не відображається)
ETHproductions

@ETHproductions Чудова ідея! Додано.
Крістіан Лупаску

Чому не існує "ZERO"?
RosLuP

@RosLuP Джон ненавидить провідні нулі ...
Крістіан Лупаску

Відповіді:


9

Python 2 , 123 байт

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

Повна програма з цитованим введенням та друком номера Джона.

Спробуйте в Інтернеті! або побачити тестовий набір

Як?

Давайте попрацюємо з прикладом "NEONSEXTOWNII" (щоб отримати 1269, і бути дещо Leisure Suite Larry -esque!)

Спочатку c=map(input().count,"OWHUFXSGIQ")приймає введення та підраховує кількість кожного OWHUFXSGIQ- це букви, які відображаються в кожному номері у порядку зростання, 2,4,6 та 8 мають свої "власні" літери ( WUXG), а також додаткові літери, Qщоб додати нуль до кінця і зробіть довжину отриманого списку рівним. Для прикладу:

[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

Записи для 1, 3, 5, 7 та 9 потребують коригування, щоб виправити величину інших літер. Це виконується наступним циклом:

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

Зауважте, що записи для коригування є альтернативними (1,3,5,7,9,1,3,5, ...), тому ми можемо додати дві до змінної індексу на кожному кроці та модуль на 10, щоб залишитися в дальність, якщо нам потрібно пройти більше одного разу (що ми робимо). Щоб зберегти кілька байт, ми можемо збільшити на один, а по модулю - на 5 і використовувати подвійний індекс.
Оскільки коригування для 9 вимагає найбільшої роботи, яку ми починаємо там - вона знаходиться в індексі 8, тому ми починаємо з i=4. Потім рядок "71735539994"дає індекси, jзначень, які слід видалити на кожному етапі (де ми гарантували, що дев'ятий індекс буде містити нуль, використовуючи "Q"при створенні c); c[i*2]-=c[int(j)]виконує кожну індивідуальну настройку і i=-~i%5переходить iдо наступного індексу (де -~iзнаходиться -(-1-i)або i+1збереження дужки (i+1)%5) збереженістьi*2в межах c.
Таким чином, ми спочатку віднімаємо число в індексі j=7від цього в індексі i*2=8, віднімаючи число "G" s, відлічене від числа "I" s, коригуючи відлік "NINE" на (правильне) число "EIGHT" s ( який також має "Я"). Потім переходимо до i=0( -~4%5 = (4+1)%5 = 0), посилаючись на індекс, i*2 = 0який є для "ONE", і віднімаємо значення, знайдене в індексі, j=1підрахунком запису "W" і, отже, "TWO", коригуючи кількість "O" 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

тому залишається лише роздрукувати те, що cзараз являє собою ( 1269). iтепер повернуто на 0, тому ми збільшуємо його на початку циклу і використовуємо його як наш цифр:

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

Задні тики, `i`є скороченням Python2, для repr(i)якого отримується рядкове представлення об'єкта (розрядний символ, про який йде мова, як рядок) і множення рядка на число створює нову рядок, що багато повторюється (тут ми показуємо лише n=0поворот `i`із сказати "5"до ""та n=1повороту зберігання говорять "6"як "6", але це також працює для більших натуральних чисел, так "3"*4стає, "3333"наприклад.)


8

05AB1E , 31 байт

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

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

Пояснення

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

Дуже неефективний для великого введення.


‘Z€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š‘# # push the list ['Z','ONE','TWO','THREE','FOUR','FIVE','SIX','SEVEN','EIGHT','NINE']: Ви можете трохи пояснити, я намагаюся зрозуміти, як можна створити будь-який рядок.
Кирило Гандон

1
@CyrilGandon: розмежовує верхній регістр стислих рядків слова, розділених пробілом. Zзасоби Z. Усі інші 2-символьні пари позначають стиснене слово зі словника 05AB1E . Так, наприклад, €µперекладається як ONE.
Емінья

Добре, як ви стискаєте рядок, що міститься у словнику? Щось із значенням unicode пари?
Кирило Гандон

1
@CyrilGandon: Ви берете номер рядка цього слова в дикті (2420 привіт ) і віднімаєте 1. Це дає нам 2419. Символи нам потрібні ті символи , які слідують 24і 19в документації . У нашому випадку це так, 24=Ÿі 19=™так HELLOби було‘Ÿ™‘
Емінья,

1
Також є компресор, написаний Аднаном, який ви можете використовувати в більшості випадків. Посилання трохи довге, але ви можете знайти його в чаті 05AB1E . Це також гарне місце, щоб запитати, якщо у вас є додаткові питання :)
Emigna

8

Сітківка , 112 97 байт

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

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

-12 байт завдяки @Neil

-3 байти за допомогою класів L символів при переміщенні

Як це працює

В основному, це спирається на те, що букви використовуються лише в певній кількості імен. Наприклад SIX, єдина назва, яка містить X. Це стає складніше від того, що деякі слова перетинаються з літер, наприклад, як обидва, так FIVEі SEVENвживання V. Це можна виправити шляхом ідентифікації FIVEз F(.*)V.


1
Виправлено @ RickHitchcock Рекурсія при перетворенні на 8 не працювала належним чином
fireflame241

1
@RickHitchcock Виправлено рекурсію для всіх них.
fireflame241

Прикро GHі NOбуде суміжним, за винятком будь-якої попередньої 8або 1попередньої заміни ...
Ніл

Можливо, }`GH 8це спрацювало б 8- це }призвело б до того, щоб персонажі були знову відсортовані, таким чином розміщуючи будь-які залишилися Gта Hразом.
Ніл

@Neil Приємна ідея. Я також міг це зробити NO -> 1, що було зручно.
fireflame241

5

Котлін 1,1 , 359 352 331 327 325 байт

Подання

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}

Не працює на TryItOnline через те, що Kotlin 1.1 не підтримується

Тест

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

Логіка

Лист ліжечка

Я використовував аркуш вище, щоб розробити найпростіший спосіб вирішити кожну букву

  • Зелений = Розв’язуй сам
  • Синій = Потрібна зелень для вирішення
  • Апельсин = Потрібно вирішити блюз
  • Червоний = Потрібні апельсини для вирішення

Правки

  • -7 - Зміни білого простору на w0lf
  • -21 - Список скорочень від масиву
  • -4 - Видалено непотрібні дужки
  • 0 - додана логіка в
  • -2 - Повторне використання порожнього рядка завдяки kevin-cruijssen

1
Щойно помітив, що я точно пов'язаний з вами моєю відповіддю Java 8 (127 байт), використовуючи аналогічний підхід. ;) Але одне питання: чи не можете ви змінити var s=""і return sдо, r=""і return rповторно використовувати введення-String, яке вам більше не потрібно в цей момент? Я ніколи раніше не програмував у Котліні, тому могло бути, що я тут говорю дурниці. ; p
Кевін Круїссен


1
Ага так, це, звичайно, була можливість; параметри finalза замовчуванням. Хм, одна річ , яку ви могли б грати в гольф: Помістіть var s=""як перше , що в способі, і замінити val f=r.split("").з val f=r.split(s).. Знову ж таки, поняття не має, якщо це працює. Шкода, що TIO ще не підтримує v1.1, інакше я б сам спробував ці пропозиції, перш ніж зробити себе дурним ..
Kevin Cruijssen

4

Желе , 37 байт

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

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

-1 завдяки Джонатану Аллану .


Це час очікування для деяких входів більше , ніж 7 символів (наприклад: NINEFIVE, THREEFIVE). Це помилка чи код просто неефективний?
Крістіан Лупаску

@ w0lf останнє ( Œ!означає "перестановки")
Ерік Вигнавець

Збережіть байт, використовуючи "AA", а не "!":...“©ȯ¿w¶&ÇhṆỌƘ#Ȯʋ~¢CNẓ_»...
Джонатан Аллан

@JonathanAllan о, це АА слово?
Erik the Outgolfer

Це перше слово в короткому словнику, так.
Джонатан Аллан

3

Java 8, 248 234 байт

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

Пояснення коду:

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 Завдяки Олів'є Грегоаре



2

Java 8, 346 345 344 336 327 байт

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

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

Загальне пояснення:

Я переглянув виникнення кожного символу в алфавіті:

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
  • Я перший підраховані всі входження символів Однополичний матчів: G=8; U=4; W=2; X=6.
  • Тоді все входження двох збіглися символів, які також відповідають одному з чотирьох вище, що я можу вичитати з їх підрахунків: F=5; H=3.
  • Потім я повторив те ж саме для V=7(віднімаючи F=5).
  • Тоді ж для всіх трьох-матчів символів , які були залишені: O=1; N=9.
    • Але оскільки в ньому Nє два випадки NINE, я повинен був зробити додатковий -1для кожного виникнення N, тому я використав I=9замість цього (віднявши три попередні матчі замість двох).

Пояснення коду:

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
Чорт, я б подумав, що додавання до списку та сортування його буде коротшим (це не так). Молодці!
Олів'є Грегоар

1
Ну, врешті-решт, я перевершив тебе , але не набагато;)
Олів'є Грегоар


1

Python 3 , 225 байт

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

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

Прямо вперед: спочатку видаліть цифри, які ідентифікуються певною літерою.


1

Python 3 , 125 байт

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

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

Прочитавши пов'язаний виклик, я зрозумів, що це варіація щодо рішення Python mdahmoune , яке само по собі базується на рішенні ES6 Draco18s , але так, принаймні, ми зіграли два байти.

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



1

Аксіома, 351 байт

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)

unololfed прокоментував результати

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