Перетворити рядок цифр зі слів у ціле число


19

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

Приклади

  • "four two"-> 42.
  • "zero zero zero one"-> 1.

Припущення

У матеріалах можна припустити, що:

  1. Вхідний рядок складається із знаків, розділених пробілом.
  2. Усі слова є дійсними (у діапазоні "нуль" .. "дев'ять") і малими літерами. Поведінка для порожнього введення не визначена.
  3. Рядок введення завжди представляє непідписане число в межах intта ніколи не є порожнім рядком.

Оцінка балів

Відповіді будуть набрані в байтах, менша кількість байтів буде кращою.


3
Ласкаво просимо на сайт. Є кілька речей, яких ми зазвичай очікуємо від запитань, яких тут не вистачає. Найважливішим був би критерій об'єктивного оцінювання, який повинні мати всі виклики.
Post Rock Garf Hunter

3
Крім цього, це питання є дуже рідким щодо специфікації. Ви повинні точно вказати, що потрібно від подання заяв без двозначності. Одне речення та приклад просто не відповідають нашим стандартам ясності для викликів.
Опублікувати Rock Garf Hunter

3
Крім того, що вже було сказано, у нас є пісочниця, де користувачі можуть викладати свої виклики, перш ніж надсилати їх на основну. Таким чином ви втратите менше інформації під час публікації повідомлень. Якщо ви подивитесь на інші останні публікації на сайті з досить позитивним прийомом, я думаю, ви побачите, що і ваше питання, і рішення не зовсім відповідають тому, що ми робимо тут.
FryAmTheEggman

3
Рискуючи бути педантичним, я хотів би зазначити, що range "zero".."nine"це не вказано повністю.
Непов’язана струна

4
Прикро, вбудований Interpreter@"SemanticNumber"робить саме це в Mathematica - за винятком того, що він не вдається на рядках, починаючи з zero zero .
Грег Мартін

Відповіді:


22

PHP , 74 байти

foreach(explode(' ',$argn)as$w)$n.='793251_8640'[crc32($w)%20%11];echo+$n;

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

Намагався знайти рішення, яке не копіює відповіді. Я отримую поліном на контрольній сумі циклічної надмірності 32-бітної довжини ( crc32 ) для кожного слова, а потім роблю на ньому мод 20 і mod 11, щоб отримати змішані унікальні значення від 0 до 10 (відсутні 6) для кожної цифри. Тоді, використовуючи це унікальне значення, я знаходжу фактичну цифру.

| Word  | CRC32      | %20 | %11 | Equivalent digit |
|-------|------------|-----|-----|------------------|
| zero  | 2883514770 | 10  | 10  | 0                |
| one   | 2053932785 | 5   | 5   | 1                |
| two   | 298486374  | 14  | 3   | 2                |
| three | 1187371253 | 13  | 2   | 3                |
| four  | 2428593789 | 9   | 9   | 4                |
| five  | 1018350795 | 15  | 4   | 5                |
| six   | 1125590779 | 19  | 8   | 6                |
| seven | 2522131820 | 0   | 0   | 7                |
| eight | 1711947398 | 18  | 7   | 8                |
| nine  | 2065529981 | 1   | 1   | 9                |

Ще 74 байти CRC32 альтернатива, використовуючи %493%10: Спробуйте в Інтернеті!

Ще 74 байти CRC32 альтернатива, використовуючи %2326%11: Спробуйте в Інтернеті!


PHP , 74 байти

foreach(explode(' ',$argn)as$w)$n.=strpos(d07bfe386c,md5($w)[21]);echo+$n;

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

Інша альтернатива з однаковою довжиною має 22-й символ у md5слові (єдиний символ, який дає унікальне значення для кожного слова), а потім використовує цей символ для відображення цифри.


Це класна відповідь
Хуан Себастьян Лозано



6

Желе ,  19  17 байт

Ḳµ7ị“*;nÄƲ]³Ṙ»i)Ḍ

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

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

Досить велика частина моєї відповіді Python 2.


Попередній

ḲŒ¿€i@€“©¥q£½¤MÆÑ‘Ḍ

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

Існує цілком можливий коротший шлях, але це шлях, який першим прийшов до тями.


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

1
Ах, я бачу, ви зробили той самий метод, добре.
Джонатан Аллан

5

Python 3 , 107 , 91 , 77 , 90 байт

-16 байт від сріотчілізму О'Заїка

+13 байт для видалення провідних нулів

lambda s:int(''.join(map(lambda w:str('zeontwthfofisiseeini'.index(w[:2])//2),s.split())))

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



Хороший! Таким чином, я навіть можу повністю скинути роздільник :)
movatica

1
З оновленнями виклику це більше не діє, оскільки воно включає провідні нулі. :(
Пост Рок Гарф Хантер


1
@movatica Виправлення неправильне. lstripМетод видаляє всі символи в рядку , яка дана як аргумент, так що «вісім два» стає «IGHT два», як «е» отримують роздягли. Також "нуль нульовий нуль" повинен роздрукувати "0", а не видавати помилку.
NemPlayer



3

05AB1E , 18 16 байт

#ε6è}.•ƒ/ÿßÇf•Åβ

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

Пояснення:

#                 # Split the (implicit) input-string on spaces
 ε  }             # Map each string to:
  6è              #  Get the character at 0-based index 6 (with automatic wraparound)
     .•ƒ/ÿßÇf    # Push compressed string "rothuvsein"
              Åβ  # Convert the characters from custom base-"rothuvsein" to an integer
                  # (after which the top of the stack is output implicitly as result)

Дивіться цей 05AB1E наконечник шахти (розділ Як стиснути рядки не частина словника? ) , Щоб зрозуміти , чому .•ƒ/ÿßÇf•це "rothuvsein".



3

05AB1E , 17 16 байт

•D±¾©xWÄ0•I#HèTβ

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

Ідеальний зв’язок з іншою відповіддю 05AB1E , але з використанням зовсім іншого підходу.

•D±¾©xWÄ0•               # compressed integer 960027003010580400
          I#             # split the input on spaces
            H            # convert each word from hex (eg "one" => 6526)
             è           # index (with wrap-around) into the digits of the large integer
              Tβ         # convert from base 10 to integer

3

Сітківка 0,8,2 , 46 45 байт

\w+
¶$&$&$&
%7=T`r\ot\huvs\ein`d`.
\D

^0+\B

Спробуйте в Інтернеті! Посилання включає тестові випадки. Пояснення:

\w+
¶$&$&$&

Поставте кожне слово в окремий рядок і потройте його.

%7=T`r\ot\huvs\ein`d`.

Транслітеруйте 7-й символ кожного рядка, використовуючи рядок @ UnrelatedString.

\D

Видаліть усі нецифрові символи, що залишилися.

^0+\B

Видаліть провідні нулі (але залиште принаймні одну цифру).

Попереднє 46-байтне більш традиційне рішення:

T`z\wuxg`E
on
1
th
3
fi
5
se
7
ni
9
\D

^0+\B

Спробуйте в Інтернеті! Посилання включає тестові випадки. Пояснення:

T`z\wuxg`E

Слова zero, two, four, sixіeight однозначно містять букви zwuxg. Перекладіть їх на парні цифри.

on
1
th
3
fi
5
se
7
ni
9

Для непарних цифр просто порівнюйте перші дві літери кожного слова окремо.

\D

Видаліть усі нецифрові символи, що залишилися.

^0+\B

Видаліть провідні нулі (але залиште принаймні одну цифру).


2

Желе , 20 18 17 байт

Ḳ7ị“*;nÄƲ]³Ṙ»iƲ€Ḍ

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

-2 байти від запуску "rothuvsein" наскрізь струнний компресор user202729 .

-1 байт від викрадення нульової рядки призову Джонатана Аллана та введення її в гранично структуровану програму.

Ḳ                    Split the input on spaces,
              Ʋ€     for each word
             i       find the 1-based index (defaulting to 0)
   “*;nÄƲ]³Ṙ»        in "othuvsein"
 7ị                  of the element at modular index 7,
                Ḍ    and convert from decimal digits to integer.


2

Japt , 13 байт

¸mg6 ì`Ψuv 

Спробуй це

Схоже, що всі інші побили мене до тієї самої ідеї - я міг би врятувати собі клопоту написання сценарію, щоб грубо примусити оптимальну струну для стиснення, тільки щоб знайти це, до індексу 1,000,000(рано було, я не мав свого кофеїну ще!), "ротувсейн" - це єдина можлива струна!

¸mg6 ì`...     :Implicit input of string
¸              :Split on spaces
 m             :Map
  g6           :  Character at index 6 (0-based, with wrapping)
     ì         :Convert from digit array in base
      `...     :  Compressed string "rothuvsein"

Стиснутий рядок містить символи в кодових 206, 168, 117, 118, 160і 136.


1
... ти справді намагався до 1000000? Lcm довжини імен цифр дорівнює 60, тому немає сенсу намагатися перевищувати це (60 еквівалентно 0, 61 до 1 тощо).
Grimmy

1
@Grimy, було рано, кофеїну ще не було! Підключення мільйона до сценарію, який я написав для створення всіх можливостей, було так само просто, як і будь-яке інше число, і врятувало мене робити математику на LCM.
Shaggy


2

T-SQL, 110 байт

SELECT 0+STRING_AGG(CHARINDEX(LEFT(value,2),'_ontwthfofisiseeini')/2,'')
FROM STRING_SPLIT((SELECT*FROM i),' ')

Розрив рядка призначений лише для читабельності.

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

Пояснення:

  1. STRING_SPLIT приймає вхідний рядок і розділяє його на пробіли
  2. CHARINDEXприймає перші 2 символи і повертає (на основі 1) позицію в рядку '_ontwthfofisiseeini'. 'ze'для нуля немає в рядку і повертає 0 для "не знайдено". Підкреслення гарантує, що ми отримуємо лише кратні два.
  3. Розділіть на 2, щоб отримати остаточну цифру
  4. STRING_AGG розбиває цифри назад без роздільника
  5. 0+примушує неявне перетворення в INT і скидає будь-які провідні нулі. 1*також працював би.

2

машинний код x86, 46 байт

Hexdump:

57 53 33 c0 33 ff f6 01 0f 75 15 6a 0a 5b 99 f7
f3 6b ff 0a 03 fa 33 c0 38 01 75 0f 97 5b 5f c3
69 c0 26 2b aa 6e 32 01 c1 e8 02 41 eb d8

Це fastcallфункція - отримує вказівник на рядок у ecxі повертає результат уeax .

Функція хешування множиться на магічне число 1856645926, робить aXOR з вхідним байтом і зміщується вправо на 2 біти.

Збереження та відновлення реєстрів ноклобберів ( ediі ebx) займало 4 байти, але я не знайшов більш ефективного способу втілити це. Зберігання константи 10 дюймівebx було особливо дратує!

Розбирання за допомогою відповідних байтів коду:

57                   push        edi  ; edi = result
53                   push        ebx  ; we use ebx to store the constant 10
33 C0                xor         eax,eax  
33 FF                xor         edi,edi  
    myloop:
F6 01 0F             test        byte ptr [ecx],0Fh  ; check for end of word
75 15                jne         myhash
6A 0A                push        0Ah  
5B                   pop         ebx  
99                   cdq              ; prepare 64-bit dividend in edx:eax
F7 F3                div         eax,ebx  ; find the remainder of division by 10
6B FF 0A             imul        edi,edi,0Ah
03 FA                add         edi,edx  ; update the result
33 C0                xor         eax,eax  ; reset the hash temporary variable
38 01                cmp         byte ptr [ecx],al  ; check for end of input (here al=0)
75 0F                jne         mycontinue
97                   xchg        eax,edi  ; set the return register
5B                   pop         ebx  ; restore registers
5F                   pop         edi  ; restore registers
C3                   ret  
    myhash:
69 C0 26 2B AA 6E    imul        eax,eax,6EAA2B26h  ; hashing...
32 01                xor         al,byte ptr [ecx]  ; hashing...
C1 E8 02             shr         eax,2  ; hashing...
    mycontinue:
41                   inc         ecx  ; next input byte
EB D8                jmp         myloop

Еквівалентний код C:

int doit(const char* s)
{
    int result = 0;
    unsigned temp = 0;
    while (true)
    {
        int c = *s++;
        if ((c & 15) == 0)
        {
            temp %= 10;
            result = result * 10 + temp;
            temp = 0;
            if (c == 0)
                break;
            else
                continue;
        }
        temp *= 1856645926;
        temp ^= c;
        temp >>= 2;
    }
    return result;
}

Як ви знайшли чарівні числа?
Спарклер

Я здійснив пошук за допомогою свого коду С - спробував усі 32-бітні номери та всі зміни. Є лише кілька можливостей - код знайдений лише один у діапазоні до 2000000000.
anatolyg

ви можете використовувати edx замість edi (натисніть edx перед idiv, pop eax після нього, imul з ebx, додайте eax до edx), щоб зберегти один байт.
peter ferrie



1

VBA, 160 байт

Function e(s)
s = Split(s, " ")
For i = LBound(s) To UBound(s)
s(i) = Int((InStr("ontwthfofisiseeini", Left(s(i), 2)) + 1) / 2)
Next
e = Val(Join(s, ""))
End Function

Збігаються перші два символи в рядку, нуль виключено.


(1/3) Чудовий підхід тут, але, схоже, ви не змогли рахувати нові рядки як байти, і що ви можете отримати шлях до числа рахунків, якщо скористаєтесь деякими хитрощами. А саме, немає необхідності в декаліровці значка " " "в", Splitоскільки це значення за замовчуванням, воно Lbound(s)завжди буде нульовим, і ви можете скинути його, (...)+1якщо додати пробіл до початку InStrданих. Крім цього, вам краще використовувати рядок або варіант для обробки даних, що виходять з InStrоператора, як вам не потрібно використовувати (i)або Join(s,""). Ой і Int(a/b)те саме, що a\b.
Тейлор Скотт

(2/3) Використовуючи ці та for eachциклі, ви можете звести свою функцію до 101 байта Function G(x):For Each c In Split(x):G=10*G+InStr(" ontwthfofisiseeini",Left(c,2))\2:Next:End Functionабо 101 байта, оскільки підтекст неявно друкує вихід у вікно налагодження як Sub F(x):For Each c In Split(x):v=10*v+InStr(" ontwthfofisiseeini",Left(c,2))\2:Next:Debug.?v:End Sub. Якщо ви обмежите свою відповідь, ви навіть можете отримати її до 81 байта як функцію негайного вікна Excel VBA як For Each c In Split([A1]):v=10*v+InStr(" ontwthfofisiseeini",Left(c,2))\2:Next:?v.
Тейлор Скотт

(3/3) Настійно рекомендую ознайомитися з нашими порадами щодо гольфу на сторінці VBA, щоб отримати докладнішу інформацію про ці підходи. Ура
Тейлор Скотт

1

Вугілля деревне , 19 байт

I⍘⭆⪪S §ι⁶rothuvsein

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Порт відповіді @ KevinCruijssen 05AB1E. Пояснення:

    S               Input string
   ⪪                Split on spaces
  ⭆                 Map over words and join
       ι            Current word
      §             Cyclically indexed
        ⁶           Literal `6`
 ⍘       rothuvsein Custom base conversion
I                   Cast to string for implicit print

1

PowerShell , 48 байт

+-join($args|%{'rothuvsein'.indexof(($_*3)[6])})

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

rothuvseinЗавдяки Джонатану Аллану використовується той же трюк, що й інші. Очікує вхідних аргументів за допомогою сплайтування, який у TIO проявляється як окремі аргументи командного рядка.


1

Котлін, 83 байти

fun String.d()=split(' ').fold(""){a,b->a+"rothuvsein".indexOf((b+b+b)[6])}.toInt()

+1 байт, якщо ви хочете підтримувати довго toLong()

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



1

Пакет Windows, 169 байт

@setlocal enabledelayedexpansion
@set z=zeontwthfofisiseeini
:a
@set b=%1
@for /l %%c in (0,2,18)do @if "!b:~0,2!"=="!z:~%%c,2!" set/aa=a*10+%%c/2&shift&goto a
@echo %a%


0

Бакон , 83 72 байти

Якщо припустити, що рядок надається у w $, цей код шукає індекс у "zeontwthfofisiseeini", використовуючи регулярний вираз на основі унікальних перших 2 символів кожного слова. Потім індекс ділиться на 2, забезпечуючи правильний результат.

FOR x$ IN w$:r=r*10+REGEX("zeontwthfofisiseeini",LEFT$(x$,2))/2:NEXT:?r
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.