Знайди Фактор!


74

Створіть найкоротшу програму або функцію, яка знайде факторіал невід'ємного цілого числа.

Факториал, представлений с !, визначається як такий

n!:={1n=0n(n1)!n>0

У звичайній англійській мові факторіал 0 дорівнює 1, а факторіал n, де n більший за 0, у n разів більший за коефіцієнт на один менше n.

Ваш код повинен виконувати введення та виведення, використовуючи стандартні методи.

Вимоги:

  • Не використовує жодних вбудованих бібліотек, які можуть обчислити факторию (це включає будь-яку форму eval)
  • Можна обчислити фактичні дані для чисел до 125
  • Можна обчислити коефіцієнт для числа 0 (дорівнює 1)
  • Проводиться за хвилину до 125

Виграє найкоротше подання, якщо виграє відповідь з найбільшою кількістю голосів на той момент.


10
Скільки з наведених відповідей насправді можна обчислити до 125! без цілого переповнення? Хіба це не було однією з вимог? Чи прийнятні результати як експоненціальні наближення (тобто 125! = 1,888267718 × 10 ^ 209)?
Амі

6
@SHiNKiROU, навіть golfscript може керувати 125! менше, ніж 1/10 секунди, і це та інтерпретована інтерпретована мова!
гніблер

5
@ugoren двозначне рішення іншого питання використовує вбудовану функціональну функцію. Це не дозволено в цій версії виклику.
Майкл Стерн

4
Завершення, що займає менше хвилини, здається, дуже вимогою до обладнання. Яке обладнання комплектується за хвилину ?
сергіол

4
@sergiol Неймовірно, що це не було проблемою протягом останніх 2 років, я підозрюю, що більшість мов можуть це зробити за менше хвилини.
Кевін Браун

Відповіді:


66

Гольфскрипт - 12 символів

{,1\{)*}/}:f

Початок роботи з Гольфскриптом - покроково

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

Тому ми хочемо спробувати наш новий інструмент гольфскрипту . Завжди добре починати з чогось простого, тому ми починаємо з факторства. Ось перша спроба, заснована на простому імперативному псевдокоді:

# pseudocode: f(n){c=1;while(n>1){c*=n;n--};return c}
{:n;1:c;{n 1>}{n c*:c;n 1-:n;}while c}:f

Пробіл дуже рідко використовується в гольфскрипті. Найпростіший трюк позбутися пробілів - це використовувати різні назви змінних. Кожен маркер можна використовувати як змінну (див. Сторінку синтаксису ). Корисні маркери для використання в якості змінних спеціальні символи , такі як |, &, ?- взагалі нічого не використовується в інших місцях в коді. Вони завжди розбираються як символи одного символу. На відміну від цього, для змінних типу nпотрібно буде пробіл, щоб натиснути число до стеку після. Числа по суті є предініціалізованими змінними.

Як завжди, будуть заяви, які ми можемо змінити, не впливаючи на кінцевий результат. У golfscript, все оцінюється як істина , за винятком 0, [], ""та {}(см це ). Тут ми можемо змінити умову виходу з циклу на просто {n}(обв'язуємо додатковий час і закінчуємо, коли n = 0).

Як і для гольфу на будь-якій мові, це допомагає знати доступні функції. На щастя, список є дуже коротким для golfscript. Ми можемо змінити , 1-щоб (врятувати інший персонаж. В даний час код виглядає приблизно так: (ми могли б використовувати тут, 1а не |тут, якби хотіли, що скасує ініціалізацію.)

{:n;1:|;{n}{n|*:|;n(:n;}while|}:f

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

{:n;1{n}{n*n(:n;}while}:f

Ось ще про щось подумати. Ми видаляємо змінну nзі стека в кінці корпусу циклу, але потім натискаємо її відразу після. Насправді, перед тим, як цикл починається, ми також видаляємо його зі стека. Натомість ми повинні залишити його на стеці, і ми зможемо зберегти стан циклу порожнім.

{1\:n{}{n*n(:n}while}:f

Можливо, ми можемо навіть повністю усунути змінну. Для цього нам потрібно буде постійно зберігати змінну в стеку. Це означає, що нам потрібні дві копії змінної на стеку в кінці перевірки умови, щоб ми не втратили її після перевірки. Що означає, що 0після закінчення циклу у нас буде надлишок стека, але це легко виправити.

Це приводить нас до нашого оптимального whileциклу рішення!

{1\{.}{.@*\(}while;}:f

Тепер ми все ще хочемо зробити це коротшим. Очевидною ціллю має стати слово while. Дивлячись на документацію, є дві життєздатні альтернативи - розгортатися і робити . Коли у вас є вибір різних маршрутів, спробуйте зважити переваги обох. Розгортання - це майже цикл часу, тому, як оцінка, ми скоротимо 5 символів whileна 4 /. Що стосується do, ми скорочуємо whileна 3 символи, і отримуємо об'єднати два блоки, що може зберегти ще один або два символи.

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

{1\{}{.@*\(}/;}:f

Чудово! Наше рішення зараз суперкоротке, і ми тут готові, правда? Ні. Це 17 символів, а J - 12 символів. Ніколи не визнайте поразки!


Тепер ви думаєте з ... рекурсією

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

# pseudocode: f(n){return n==0?n*f(n-1):1}
{:n{n.(f*}1if}:f # taking advantage of the tokeniser

Ну це було просто - якби ми раніше спробували рекурсію, ми, можливо, навіть не подивилися на використання whileциклу! І все-таки ми лише на 16 символів.


Масиви

Масиви зазвичай створюються двома способами - з допомогою [і ]символів, або з ,функцією. Якщо виконано з цілим числом у верхній частині стека, ,повертає масив такої довжини з arr [i] = i.

Для ітерації над масивами у нас є три варіанти:

  1. {block}/: штовхати, блокувати, натискати, блокувати, ...
  2. {block}%: [push, block, push, block, ...] (це має деякі нюанси, наприклад, проміжні значення видаляються зі стека перед кожним натиском)
  3. {block}*: push, push, block, push, block, ...

Документація golfscript має приклад використання {+}*для підсумовування вмісту масиву. Це говорить про те, що ми можемо використати {*}*для отримання добутку масиву.

{,{*}*}:f

На жаль, це не все так просто. Усі елементи вимкнено одним ( [0 1 2]замість [1 2 3]). Ми можемо використати {)}%для виправлення цього питання.

{,{)}%{*}*}:f

Ну не зовсім. Це не обробляє нуль правильно. Ми можемо розрахувати (n + 1)! / (N + 1), щоб виправити це, хоча це коштує занадто дорого.

{).,{)}%{*}*\/}:f

Ми також можемо спробувати обробити n = 0 у тому ж відрі, що і n = 1. Це насправді надзвичайно мало, щоб спробувати відпрацювати якнайшвидше.

Не так добре , як сортування, в 7 символів: [1\]$1=. Зауважте, що ця методика сортування має корисні цілі, такі як накладення меж на число (наприклад, `[0 \ 100] $ 1 =)
Ось переможець із лише 3 символами:! +

Якщо ми хочемо, щоб приріст і множення були в одному блоці, нам слід повторити кожен елемент масиву. Оскільки ми не будуємо масив, це означає, що нам слід користуватися {)*}/, що приводить нас до найкоротшого впровадження гольфскрипту факторства! У 12 символів це пов'язано з J!

{,1\{)*}/}:f


Бонусні рішення

Починаючи з прямого ifрішення для doциклу:

{.{1\{.@*\(.}do;}{)}if}:f

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

{1\.!!{{.@*\(.}do}*+}:f
{.!{1\{.@*\(.}do}or+}:f
{.{1\{.@*\(.}do}1if+}:f

Кращою альтернативою є обчислення (n + 1)! / (N + 1), що виключає потребу в ifструктурі.

{).1\{.@*\(.}do;\/}:f

Але найкоротше doрішення тут містить кілька символів, щоб зіставити 0 до 1, а все інше - самому нам, тому нам не потрібно розгалуження. Таку оптимізацію надзвичайно легко пропустити.

{.!+1\{.@*\(.}do;}:f

Для всіх, хто цікавиться, тут запропоновано кілька альтернативних рекурсивних рішень такої ж довжини, як і вище:

{.!{.)f*0}or+}:f
{.{.)f*0}1if+}:f
{.{.(f*}{)}if}:f

* Примітка: я фактично не перевірив багато фрагментів коду в цій публікації, тому сміливо повідомляйте, чи є помилки.


8
Цікаво, що, здається, є помилка у розмітці спойлера, коли ви використовуєте код у спойлері ... Хтось хотів би згадати про це на Meta?
Іво Фліпс

5
Мені цікаво, як golfscript - мова для гольфу - дозволяє багатолітерні назви змінних і "карає" вас за використання 1 літери з необхідним пробілом
Cyoce

44

Хаскелл, 17

f n=product[1..n]

2
Я не знаю Хаскелла ... Але чи розраховуватиме це фактор за 0
Король

11
@Король: так, так і буде. [1..0] ==> []іproduct [] ==> 1
JB

5
Я б заперечував, що це використовує "вбудовану бібліотеку", яку проблема забороняє. Тим не менш, інший метод f 0=1;f n=n*f$n-1також 17 символів.
forevermatt

5
@eternalmatt: та частина обмежень для мене не визначена. І product, скажімо, (*)або (-)"можна обчислити факторіал", і всі вони визначені в прелюдії. Чому одне було б крутим, а не іншим?
JB

2
@YoYoYonnY: Я також рахую 17 символів для меншої (суб'єктивної) читабельності. ІМХО це добре в коментарях.
JB

41

Пітон - 27

Просто просто:

f=lambda x:0**x or x*f(x-1)

22
Хороший трюк: 0**x.
Олександру

Про що math.factorial? Це не вбудований, чи не так?

1
@JackBates вважається вбудованим, оскільки ви не написали код для обчислення факторіалу.
FlipTack

1
Хтось може сказати мені, в чому полягає фокус 0**x?
Павітра

1
@ Pavitra: 0 0 = 1, і це перше, що оцінює, щоб він повертався. Для будь-якого іншого n, 0 n = 0, таким чином, перший операнд або є фальси, таким чином, що другий операнд отримує оцінку.
Mega Man

29

APL (4)

×/∘⍳

Працює як анонімна функція:

    ×/∘⍳ 5
120

Якщо ви хочете дати йому ім'я, 6 символів:

f←×/∘⍳

Я не розмовляю APL, що тут відбувається?
Майкл Стерн

@MichaelStern: робить індексний вектор, тобто ⍳5є 1 2 3 4 5. ×(очевидно) розмножується, /зменшується і є функціональним складом. Отже, ×/∘⍳це функція, яка бере аргумент xі дає добуток чисел [1..x].
marinus

Ах, той самий підхід, що і в рішенні Mathematica @ Іваса Клетта. Дуже хороша.
Майкл Стерн

@NBZ: Цього ще не існувало в 2011 році, коли було написано це питання, ні в 2012 році, коли я писав цю відповідь. Потяги були додані тільки в Dyalog 14.0 , який вийшов в 2014 році
Марина

19

J (12)

Стандартне визначення у J:

f=:*/@:>:@i.

Менше 1сек за 125!

Наприклад:

 f 0
 1
 f 5
 120
  f 125x
 1882677176888926099743767702491600857595403
 6487149242588759823150835315633161359886688
 2932889495923133646405445930057740630161919
 3413805978188834575585470555243263755650071
 31770880000000000000000000000000000000

чому не просто * />: я. ?
Andbdrew

Оскільки ОП просить функцію, і найкраще, що ми можемо зробити в J, - це визначити дієслово.
Ельвакс

2
Немає причини, що це не може бути анонімна функція? Як і ([:*/1+i.)для 10 балів, або навіть 8, оскільки дужки потрібні лише для виклику функції, а не для визначення.
jpjacobs

в останньому, f 125xщо робить x? Це особливий вид числа?
Кіос

@Cyoce, так, це розширене ціле число точності .
Ельвакс

17

Гольфскрипт - 13 символів (SYM)

визначає функцію !

{),()\{*}/}:!             # happy robot version \{*}/ 

чергувати 13 чарові версії

{),()+{*}*}:! 

вся версія програми - 10 символів

~),()+{*}*

тест-вітрини займають менше 1/10 секунди:

вхід:

0!

вихід

1

вхід

125!

вихід

188267717688892609974376770249160085759540364871492425887598231508353156331613598866882932889495923133646405445930057740630161919341380597818883457558547055524326375565007131770880000000000000000000000000000000

1
+1 для символічного вступу в гольф! Я б хотів, щоб я міг подати заявку не раз. :-D
Кріс Єстер-Янг

@ ChrisJester-Young Я зроблю це за тебе.
Кіос

13

Перл 6: 13 символів

$f={[*]1..$_}

[*]те саме product, що і Haskell , і 1..$_це відлік від 1 до $_аргументу.


2
Заборонено більше не використовувати пробіл [*](повідомлення про помилку "Два терміни підряд").
Конрад Боровський

Не потрібно встановлювати змінну, голий блок коду є прийнятною відповіддю, оскільки він неявно утворює функцію. Також це все ще працює для 0?
Філ Х

10

Матлаб, 15

f=@(x)prod(1:x)

Випробування

>> f(0)
ans =
     1
>> f(4)
ans =
    24
>> tic,f(125),toc
ans =
  1.8827e+209
Elapsed time is 0.000380 seconds.

10

Пітон, 28 байт

f=lambda x:x/~x+1or x*f(x-1)

(на основі рішення Олександру)


9

MATL , 2 байти

:p

Пояснили:

:    % generate list 1,2,3,...,i, where i is an implicit input
p    % calculate the product of of all the list entries (works on an empty list too)

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



Я збирався опублікувати саме це :-) Ви можете змінити посилання, щоб включити код та приклад прикладу
Луїс Мендо

Як ви наказуєте, мій пане.
flawr

4
@AndrasDeak, Ні, це виводить усі числа від 1 до i ...
YoYoYonnY

8

Рубін - 21 ч

f=->n{n>1?n*f[n-1]:1}

Тест

irb(main):009:0> f=->n{n>1?n*f[n-1]:1}
=> #<Proc:0x25a6d48@(irb):9 (lambda)>
irb(main):010:0> f[125]
=> 18826771768889260997437677024916008575954036487149242588759823150835315633161
35988668829328894959231336464054459300577406301619193413805978188834575585470555
24326375565007131770880000000000000000000000000000000

8

Ява, 85 символів

BigInteger f(int n){return n<2?BigInteger.ONE:new BigInteger(""+n).multiply(f(n-1));}

1
При цьому пропущено імпорт: import java.math.*;(так, +19 байт).
Олів'є Грегоар

Справедливий пункт. ............
st0le

7

PostScript, 26 символів

/f{1 exch -1 1{mul}for}def

Приклад:

GS> 0 f =
1
GS> 1 f =
1
GS> 8 f =
40320

Сама функція займає лише 21 символ; решта - прив’язати його до змінної. Щоб зберегти байт, його також можна прив'язати до цифри, наприклад:

GS> 0{1 exch -1 1{mul}for}def
GS> 8 0 load exec =
40320

1
Ghostscript не може впоратися з 125 !; нічого, що перевищує 34! виходить як 1.#INF. (Я використовував запас GNU Ghostscript 9.0.7, зібраний для x64 Windows.)
Ross Presser

7

JavaScript, 25

function f(n)!n||n*f(n-1)

CoffeeScript, 19

f=(n)->!n||n*f(n-1)

Повертається trueу випадку n = 0, але JavaScript все одно набере тип «1».


Вам не потрібен returnоператор у функції JavaScript?
Джастін Морган

Оновлення: Святий дим, вам не потрібен return! Але чому б і ні?
Джастін Морган

Це JavaScript 1.8 ( developer.mozilla.org/uk/new_in_javascript_1.8 ). Повне розкриття, воно працює лише на Firefox!
Кейсі Чу

1
Приємно, я не знав про те, щоб не залишати заяву про повернення JavaScript 1.8. Також ви можете гарантувати 1, а не справжній для випадку n = 0 з однаковим кодом довжини: function f(n)n?n*f(--n):1
Briguy37

10
ES6, 17: f=n=>!n||n*f(n-1)Візьміть це, CoffeeScript!
Ри-

6

Рубі - 30 29 символів

def f(n)(1..n).inject 1,:*end

Тест

f(0) -> 1
f(5) -> 120

1
Ви можете поставити endбезпосередньо після :*нового рядка або крапки з комою.
sepp2k

1
Не потрібно передавати номер 1 на дзвінок #inject. (1..10).inject :*# => 3628800
Dogbert

1
@Dogbert, про що f(0)?
Nemo157

@ Nemo157, ах! забув про це.
Догберт

4
Більш короткий використовувати 1.9 синтаксис лямбда: f=->n{(1..n).inject 1,:*}. Телефонуйте за допомогою f[n].
Майкл Коль

6

F #: 26 символів

В F # немає вбудованої функції продукту, але ви можете зробити її зі складкою

let f n=Seq.fold(*)1{1..n}

6

C #, 20 або 39 символів залежно від вашої точки зору

Як традиційний метод примірника (39 символів; протестований тут ):

double f(int x){return 2>x?1:x*f(x-1);}

Як лямбда-вираз (20 символів, але дивіться застереження; перевірено тут ):

f=x=>2>x?1:x*f(x-1);

Ми повинні використовувати, doubleтому що 125! == 1,88 * 10 209 , що набагато вище, ніж ulong.MaxValue.

Відмова від кількості символів версії лямбда:

Якщо ви рекурсуєте в C # лямбда, вам, очевидно, доведеться зберігати лямбда в названій змінній, щоб вона могла викликати себе. Але на відміну від (наприклад) JavaScript, лямбда, що самонасилається, повинна бути оголошена та ініціалізована в попередньому рядку. Ви не можете викликати функцію в тому самому операторі, в якому ви оголошуєте та / або ініціалізуєте змінну.

Іншими словами, це не працює :

Func<int,double> f=x=>2>x?1:x*f(x-1); //Error: Use of unassigned local variable 'f'

Але це робить :

Func<int,double> f=null;            
f=x=>2>x?1:x*f(x-1);  

Немає вагомих причин для цього обмеження, оскільки він fне може бути скасований під час його запуску. Необхідність Func<int,double> f=null;рядка - химерність C #. Чи буде це справедливо ігнорувати його в кількості символів, залежить від читача.

CoffeeScript, 21 19 символів по-справжньому

f=(x)->+!x||x*f x-1

Тестується тут: http://jsfiddle.net/0xjdm971/


6

Брахілог , 7 6 байт

Складаючи діапазон і множуючи його

-1 байт-баки для ов, які мають ідею використовувати функцію max ()

;1⌉⟦₁×

Пояснення

;1          --  If n<1, use n=1 instead (zero case)
  ⟦₁        --      Construct the range [1,n]
    ×       --      return the product of said range

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


Брахілог , 10 9 байт

рекурсія

≤1|-₁↰;?×

Пояснення

            --f(n):
≤1          --  if n ≤ 1: return 1
|           --  else:
 -₁↰        --      f(n-1)
    ;?×     --            *n

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


1
Це працює на 6 байт. Прийняття введення в якості однотонного дозволено за замовчуванням.
ов

@ovs спасибі Але використання ;замість цього ,дозволяє лише звичайний числовий ввід. -1байт все одно
Кроппеб

5

C (39 знаків)

double f(int n){return n<2?1:n*f(n-1);}

3
Приємно. Але можна зберегти деякі символи: double f(n){return!n?1:n*f(n-1);}- 33 символи.
ugoren

2
f(125)переповниться
jkabrg

4

Д: 45 персонажів

T f(T)(T n){return n < 2 ? 1 : n * f(n - 1);}

Більш розбірливо:

T f(T)(T n)
{
    return n < 2 ? 1 : n * f(n - 1);
}

Кулер (хоч і довша версія) - це шаблонований, який робить це все під час компіляції ( 64 символи ):

template F(int n){static if(n<2)enum F=1;else enum F=n*F!(n-1);}

Більш розбірливо:

template F(int n)
{
    static if(n < 2)
        enum F = 1;
    else
        enum F = n * F!(n - 1);
}

Одноіменні шаблони є досить багатослівними, тому ви не можете дуже добре використовувати їх у коді для гольфу. D's вже досить докладний з точки зору характеру розраховувати досить бідний для коду гольф (хоча це на насправді робить дуже добре на зниження загального розміру програми для великих програм). Хоча це моя улюблена мова, тому я вважаю, що, можливо, я б спробував і побачив, наскільки добре я можу це зробити в гольф-коді, навіть якщо подобається GolfScript неминуче змаже його.


3
вийміть пробіл, і ви зможете зменшити його до 36 символів
храповик-фрік

@Cyoce Ви можете пояснити?
YoYoYonnY

Ласкаво просимо на сайт, @ user272735. Зауважте, що ми не редагуємо рішення людей, щоб вдосконалити тут. Натомість ми залишаємо коментарі, які пропонують ці вдосконалення, як це робило вищезгаданий урожай.
Кудлатий

4

PowerShell - 36

Наївно:

filter f{if($_){$_*(--$_|f}else{1}}

Тест:

> 0,5,125|f
1
120
1,88267717688893E+209

4

Скала, 39 символів

def f(x:BigInt)=(BigInt(1)to x).product

Більшість символів забезпечують BigIntвикористання s, тому вимога до значень до 125 виконується.


Дещо коротші варіанти:(x:Int)=>(BigInt(1)to x).product def f(x:Int)=(BigInt(1)to x).product def f(x:BigInt)=(x.to(1,-1)).product def f(x:BigInt)=(-x to-1).product.abs
LRLucena

4

Javascript, ES6 17

f=n=>n?n*f(n-1):1

ES6:

  • Функція стрілки

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

З умовним оператором є щось дивне. Чому є два колони?
Qwertiy

@Qwertiy Ви маєте рацію, це була помилка, дякую.
Afonso Matos

4

PowerShell, 42 байти

(2 символи збережено за допомогою фільтра замість функції )

filter f($x){if(!$x){1}else{$x*(f($x-1))}}

Вихід:

PS C:\> f 0
1
PS C:\> f 5
120
PS C:\> f 1
1
PS C:\> f 125
1.88267717688893E+209

1
Це шлях старо, але ... Можна зберегти більше 1 символу з допомогою реверсування якщо / інше: filter f($x){if($x){$x*(f($x-1))}else{1}}. І його можна зменшити ще до 36 символів, якщо він викликається через конвеєр, оскільки це фільтр (наприклад 125|f):filter f{if($_){$_*($_-1|f)}else{1}}
Ендрю

4

Ракетка (схема) 40 35 29 байт

Обчислює 0! бути 1, а обчислює 125! за 0 секунд за таймером. Регулярний рекурсивний підхід

(define(f n)(if(= n 0)1(* n(f(- n 1)))))

Нова версія, щоб перемогти звичайний ліс: множує всі елементи списку (те саме, що і рішення Haskell)

(λ(n)(apply *(build-list n add1)))

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

(λ(n)(foldl * n(range 1 n)))

4

Морнінгтон Півмісяць , 1827 р. 1698 ч

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

Take Northern Line to Bank
Take Central Line to Holborn
Take Piccadilly Line to Heathrow Terminals 1, 2, 3
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Parsons Green
Take District Line to Bank
Take District Line to Parsons Green
Take District Line to Acton Town
Take District Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Acton Town
Take District Line to Acton Town
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Parsons Green
Take District Line to Notting Hill Gate
Take Circle Line to Notting Hill Gate
Take Circle Line to Bank
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Bank
Take District Line to Upney
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Upney
Take District Line to Bank
Take Circle Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

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

Кожен, хто подорожував Лондоном, зрозуміє це миттєво, тому я впевнений, що мені не потрібно давати повних пояснень.

Більшість робіт на початку - це обробка справи 0. Після ініціалізації продукту на 1 я можу використовувати це для обчислення max (input, 1), щоб отримати новий вхід, скориставшись тим, що 0! = 1! Тоді може початися головна петля.

(EDIT: Цілу купу поїздок було врятовано, знявши 1 з "Heathrow Terminals 1, 2, 3", а не генеруючи його, розділивши 7 (Сестри) самостійно. Я також використовую більш дешевий метод для генерування -1 у наступний крок.)

Зниження в Морнінгтоні Півмісяця (хоча і менш дороге, ніж сама трубка). Щоб зробити ефективнішими речі, я генерую -1, беручи NOT на розбір 0 і зберігаю його в Hammersmith для більшої частини циклу.


Я вклав у це якусь значну роботу, але оскільки це моя перша спроба гри в гольф у Морнінгтоні Півмісяця (насправді моя перша спроба будь-якою мовою), я сподіваюся, що тут і там я пропустив кілька оптимізацій. Якщо ви зацікавлені в програмуванні на цій мові самостійно (а чому б вам цього не було?), Esoteric IDE - з його режимом налагодження та вікном перегляду - обов'язковий!


3

Befunge - 2х20 = 40 символів

0\:#v_# 1#<\$v *\<
    >:1-:#^_$>\:#^_$

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

Наприклад, для обчислення факторіалу 125

555**   0\:#v_# 1#<\$v *\<
            >:1-:#^_$>\:#^_$    .@

Тестування 0

0   0\:#v_# 1#<\$v *\<
        >:1-:#^_$>\:#^_$    .@

Я знаю, що це досить старе, але я думаю, що це дещо коротше і швидше: &:!#@_>:# 1# -# :# _$>\# :#* _$.@(де & слід замінити на введення). Це 32 символи / байти
FliiFe

3

J - 6 символів

*/>:i.

Чи враховується це? Я знаю, він дуже схожий на попередній J-приклад, але він трохи коротший :)

Я початківець з J, але поки це дуже весело!


3

В (23 символи)

Це зловживає "функцією" GCC, яка робить останнє призначення вважається поверненням, якщо повернення не вказано.

f(a){a=a>0?f(a-1)*a:1;}

У відповідному С 28 символів

f(a){return a>0?f(a-1)*a:1;}

+1 для "функції" GCC. Я думаю, що GCC навіть дозволяє повернути значення блоку (пам'ятаю, робити щось подібне)0 == ({printf("Hello, world!"); 0;});
YoYoYonnY

3

Кона ( 11 6)

*/1.+!

K працює справа наліво (здебільшого), тому ми перераховуємо x(робимо список / масив чисел від 0до x-1), додаємо 1до нього (список діапазонів 0до x), а потім множимо всі числа разом. Якщо б не було вимоги до обчислення 125!, я міг би зберегти ще 1 байт, видаливши .поруч з 1. У будь-якому випадку 125! обчислюється за кілька мілісекунд:

  */1.+!125.
1.882677e+209

Вам цього не потрібно багато. K має curry, тому вся відповідь стає */1.+!: 6 байт.
kirbyfan64sos

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