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


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.