Відстань до чотирьох


13

Цей виклик заснований на цьому відео . Рекомендую переглянути його, перш ніж спробувати цей виклик.

Спочатку визначимо функцію. Ця функція ( OEIS ) приймає ціле число n як вхідне та виводить кількість літер в англійському поданні n (без пробілів чи дефісів). Наприклад, у "трьох" є 5 літер, тому 3 карти на 5.

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

Ось графік із силою спрямованістю, що показує орбіти чисел менше 16:

  12 11
    \|      
15 2 6 1 10 14 13
  \ \|/ /  /  /
   7 3-/  8--/
    \|   /
 9 0 5--/
  \ \|
   \-4

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

Формування англійських номерів

Ось коротке пояснення того, як слід скласти англійські слова для цього завдання:

Числа від одного до дев'ятнадцяти:

один, два, три, чотири, п’ять, шість, сім, вісім, дев’ять, десять, одинадцять, дванадцять, тринадцять, чотирнадцять, п’ятнадцять, шістнадцять, сімнадцять, вісімнадцять, дев'ятнадцять

Для чисел, що перевищують дев’ятнадцять, процес такий:

Якщо число має сотень місце, починайте з назви цифри у сотенному місці та "сотня".

напр

100 -> "onehundred"

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

напр

714 -> "sevenhundredfourteen"

В іншому випадку, якщо десяткова цифра не дорівнює нулю, додайте належне подання:

2-> twenty
3-> thirty
4-> forty
5-> fifty
6-> sixty
7-> seventy
8-> eighty
9-> ninety

напр

470 -> "fourhundredseventy"

Нарешті, якщо є цифра, додайте її подання

напр

681 -> "sixhundredeightyone"

Подальші регламенти

  • Для чисел, що перевищують сто, ви повинні залишати "і" під час підрахунку кількості букв. Наприклад, 577 - це "п'ятсот сімдесятдесят", який має 23 літери.

  • Ваша програма повинна приймати всі цілі числа, що перевищують 0 та менше 1000, як введення стандартними методами.

  • Ваша програма повинна вивести кількість етапів, необхідних для стандартних методів виводу.

  • Це кодогольф, тому рішення з найменшими байтами виграє.

Тестові справи

1 -> 3
4 -> 0
7 -> 2
23 -> 5
577 -> 6
600 -> 4 

1
Пов'язане Я думав, що це дуп, але не можу його знайти.
Джеймс

Що сталося з "і"? А точніше, навіщо залишатись і ?!
Джонатан Аллан

@JonathanAllan cuz 'Murica
LegionMammal978

Відповіді:


5

JavaScript (ES6), 106 байт

f=(n,a="03354435543668877998")=>n-4&&1+f(7*(n>99)-(-a[n/100|0]-(a[n%=100]||a[n%10])-"0066555766"[n/10|0]))

Струни, здається, є найкращим способом кодування довжини, незважаючи на числові накладні перетворення.


Ось так, так виглядала моя (майже опублікована) відповідь, лише на 11 байт коротше.
ETHproductions

@ETHproductions Добре, що я переграв 16 байт, перш ніж публікувати його!
Ніл

2

Python, з num2words, 97 113 115 94 93 92 байт

+16 байт (забули переноси , що num2words застосовується , який фактично не змінюють результатів будь-яких з тестових прикладів, хоча 23і 577має дефіс)
+2 байта (забув включити f=хоча рекурсивний)
-20 байт (використання re)
-8 байти завдяки майстру @Wheat (використання ~, замінити n!=4з n-4, і ... одна рядком імпорту> _ <)
-1 байти завдяки @Cyoce (простір з 4 and)

import re,num2words as w
f=lambda n:n-4and-~f(len(re.sub('\W|and','',w.num2words(n))))

Просто підраховує кількість кроків; також працює для величезних і негативних цілих чисел ( \Wзнаходить пробіли, коми і дефіси в результаті num2words):

>>> for test in (1,4,7,23,577,600,-1*2**96,3**96):
...     print('test: {0}  ->  {1}'.format(test, f(test)))
...
test: 1  ->  3
test: 4  ->  0
test: 7  ->  2
test: 23  ->  5
test: 577  ->  6
test: 600  ->  4
test: -79228162514264337593543950336  ->  4
test: 6362685441135942358474828762538534230890216321  ->  5

Ось останній випадок, крок за кроком:

sixquattuordecillionthreehundredsixtytwotredecillionsixhundredeightyfiveduodecillionfourhundredfortyoneundecilliononehundredthirtyfivedecillionninehundredfortytwononillionthreehundredfiftyeightoctillionfourhundredseventyfourseptillioneighthundredtwentyeightsextillionsevenhundredsixtytwoquintillionfivehundredthirtyeightquadrillionfivehundredthirtyfourtrilliontwohundredthirtybillioneighthundredninetymilliontwohundredsixteenthousthreehundredtwentyone
fourhundredfiftyone
nineteen
eight
five

1
Якщо вам не потрібна f=функція лямбда
Ad Hoc Garf Hunter

1
Спробуйте import re,num2words as rзамість двох різних тверджень.
Ad Hoc Garf Hunter

1
n-4те саме, щоn!=4
Ad Hoc Garf Hunter

1
@WheatWizard num2wordsє w, reвсе одно re- зауважте, що і модуль, і функція називаютьсяnum2words
Джонатан Аллан

1
Ок, останній, and 1+можна замінити, and-~щоб зберегти один байт
Ad Hoc Garf Hunter


1

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

Length@FixedPointList[StringLength@StringReplace[IntegerName@#,{" "->"","-"->""}]&,#]-2&

Типова Mathematica: вбудовані функції хороші, довгі назви функцій погані. FixedPointListзастосовує свій перший аргумент (функцію) до другого аргументу кілька разів, поки відповідь не зміниться, перерахувавши всі результати; результати включають оригінал введення та дві копії повторного виводу, отже, -2в кінці. Вбудована програма Mathematica IntegerNameмістить пробіли та дефіси, тому нам потрібно позбутися їх вручну.

Прикро, IntegerNameвихідний текст містить символ "-" (Unicode № 8208), а не звичайні дефіси; тому це подання становить 89 байт, а не 88. (І я не міг передувати коду вище чотирма пробілами, і він повинен прийняти символ Unicode - будь-яку допомогу?), тому що вищевказаний код не буде працювати правильно, якщо вирізати та вставити .)


1

Python 2.7, 344 216 208 байт:

x=`input()`;c=0;y=lambda v:dict(zip(range(0,10),[0]+v));l=[3,3,5,4,4,3,5,5,4];d=y(l);e=y([3,6,6,6,5,5,7,7,6]);f=y([i+7for i in l])
while x!='4':x=`sum([q[int(r)]for q,r in zip([d,e,f],x[::-1])])`;c+=1
print c

Не використовує жодних зовнішніх бібліотек на відміну від інших відповідей Python. Здійснює введення через stdinта виводить на stdout.

Repl.it з усіма тестовими справами!

Пояснення

Спочатку створюється 3 словники, кожен з яких поєднує довжину представлень англійських слів кожного числа до числа, яке воно представляє у закритому інтервалі відповідно [1,9]до знаків, десятків та сотень. Наприклад, перший запис у словнику dбуде , 1:3як 1пишеться oneанглійською мовою і має 3лист.

Потім кожне розрядне місце в якомусь рядковому введенні xприсвоюється відповідному словнику, після чого кожне число у кожному місці узгоджується зі своїм значенням у відповідному словнику. Наприклад, припустимо, вхідний номер був 23. Місце 20в десятках буде сполучено зі словником e, в якому воно зіставлено 6, а 3в тих місцях буде сполучено зі словником d, в якому воно зіставлено 5. Ці зібрані цифри потім додаються разом, щоб представити довжину англійського представлення числа, яке присвоюється xяк рядок, і, x!='4'поки цикл у той час продовжується, збільшується cна1кожен раз представляти кількість кроків, зроблених до цього часу. Отже, 23відповідатиме 11, що, у свою чергу, відповідало б тому, до 6чого звертався б, 3а потім до 5і, нарешті, до 4, в результаті чого 5загальні кроки.

Нарешті, як тільки цикл закінчується, cвиводиться, щоб stdoutпредставити "Відстань до чотирьох", що в цьому випадку було б 5.


1

Java, 556 295 байт

Дякуємо @KevinCruijssen за збереження 261 байта

  void int(n) {int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;while(n>0){if(n/100>0)c+=(s[n/100]+7);else {if(n>0&n<25){c+=s[n];break;}else{c+=s[(n/10)+22];}}n=n%t;t=t/10;}while(c!=4){v++;c=s[c];}System.out.print(v);}


Безголівки:

  void int(n) {

    int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,9,8,6,9,9,11,10,6,6,5,5,7,7,6};
     int c=0,t=(int)Math.pow(10,(int)Math.log10(n)),v=1;
         while(n>0){
            if(n/100>0)
                c+=(s[n/100]+7);
            else {if(n>0&n<25){
                c+=s[n];
            break;
            }
            else{
                c+=s[(n/10)+22];

            }
            }
            n=n%t;
            t=t/10;
        }

        while(c!=4)
        {
            v++;
        c=s[c];
        }
System.out.print(v);
}

Я думаю, у вас є помилка в коді, тому що s++це неможливо на String-масиві ..: S
Kevin Cruijssen

@KevinCruijssen Я оголошую S (лічильник) як INT і STRING теж .... java автоматично вирішує, що це INT.
Numberknot

Що ж, якщо я запускаю ваш код в ideone або Eclipse IDE, він не вдається, тому що у вас є два s.. До речі, ви можете int c(int n){int s[]={0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8,6,9,9,11,10,6,5,5,5,7,6,6},c=0,t=(int)Math.pow(10,(int)Math.log10(n)),x=1;while(n>0)if(n/100>0)c+=s[n/100]+7;else{if(n>0&n<25){c+=s[n];break;}else c+=s[(n/10)+22];}n%=t;t/=10;}for(;c!=4;x++,c=s[c]);return x;}
пограти в

Я в шоці ...... що трапиться з моїм кодом і спасибі @ KevinCruijssen..і я це виправляю ... Ще раз дякую.
Numberknot

Np :) Я думаю, що це може бути якось більше в гольфі, не використовуючи if-else і ввірватися туди (але я залишу це комусь іншому), але ваш початковий код був чудовою базою для вирішення проблеми, тому +1 від мене.
Кевін Круїссен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.