Аксессуары по факту!

10

Этот вызов вдохновлен математикой является фактом. Программирование нет .


Математическая запись факториала или факта - восклицательный знак !. Восклицательный знак также является общим символом для notмногих языков программирования.

Вызов:

Возьмите строку, содержащую цифры и символы: в + !качестве ввода и вывода:

Все перед восклицательным знаком следует оценивать как математическое выражение, так 2+2будет 4.

Все, что после одного восклицательного знака, должно быть добавлено в качестве аксессуаров к тому, что находится перед ним, а значит: 2+2!5должно давать 45, потому что 2+2=4и 5является аксессуаром. 2+2!5+5должен дать 410.

Поскольку !также означает not, что все, что не является аксессуаром после факта, не должно быть добавлено. Итак, 2+2!!5следует дать 4, так как 5это не аксессуар. Теперь not(not(true))==trueтак 2+2!!!5следует дать 45. 2+2!!5!5+5должен дать:, 410потому что 2+2=4затем следует факториал и !5!5+5. Первый 5не факт, но 5+5после другого восклицательного знака, и поэтому факт, еще раз.

Разъяснения:

  • Восклицательные знаки не будут соседствовать с +любой из сторон.
  • Там не будет ведущих +для чисел (это 5не так +5).
  • При желании вы можете включить ведущий ноль, если это результат выражения перед первым !. Оба 4и 04принимаются к выводу:0+0!4

Резюме: оцените каждую сумму (рассматривая !как разделители). Затем отбросьте все числа, которые появляются после четного числа !(считая от начала строки). Тогда удали все !.

Тестовые случаи:

!
   <- Empty string

5
5

12!
12

!87
87

!!5
   <- Empty string

5+5!2+2
104

5+5!!2+2
10

1!2!3!4!5!6!7!8!9
12468

10+10!!2+2!!3+3!4+4
208

2!!3!5
25

2!!3!5!7
25

10!!!!!!!5
105

Это поэтому выигрывает самый короткий код в байтах (на каждом языке)! Пояснения настоятельно рекомендуется!

Стьюи Гриффин
источник
хм ... допустим, у нас есть 2 !! 3! 5 здесь или нет 5 аксессуар 3?
officialaimm
3
@officialaimm Это 25(см. добавленный контрольный пример). Что еще важнее, 2!!3!5!7все равно даст 25, потому что есть четное число !слева от 7(так что вы не просто посчитаете пробег прямо перед номером, но все !слева от него).
Мартин Эндер
Может ли вывод быть Mathematica Row?
ngenisis
Хм ... так что этот вызов на самом деле не имеет ничего общего с факториалами?
DLosc

Ответы:

5

Retina , 35 31 29 байт

Сохранено 4 байта, вдохновленные ETHproductions .

Спасибо Лео за сохранение еще 2 байтов.

\d+|\+
$*
1+
$.&
1`!

!\d*!?

Попробуйте онлайн!

Мартин Эндер
источник
Вы можете сохранить несколько байтов в последних строках, как это
Лев
1
@ Leo Это действительно здорово, спасибо. :)
Мартин Эндер
5

JavaScript (ES6), 58 56 байт

Сохранено два байта благодаря Мартину Эндеру .

let f =
x=>x.replace(/[^!]+/g,eval).replace(/!(\d*)!?\d*/g,"$1")
<input value="2+2!5+5" oninput="try{O.value=f(value)}catch(e){}"><br>
<input id=O value="410" disabled>

Может быть улучшен как-то ...

ETHproductions
источник
Хорошее использование аргумента функции для replace.
Нил
@Neil Спасибо, но я нашел лучший путь :-)
ETHproductions
Ваш фрагмент кода дает мне неправильный ответ 1+1!5. Я думаю, что вы забыли evalнемного до !.
Value Ink
@ValueInk Ах, черт возьми, я не думаю, что есть какой-то простой способ исправить это.
ETHproductions
2

Желе , 16 байт

ṣ”!µḢW;m2$VṾ$L¡€

Попробуйте онлайн!

объяснение

Ключевое наблюдение здесь заключается в том, что мы можем выполнить шаги «не по порядку»; вместо того, чтобы оценивать суммы, а затем игнорировать те, которые нам не нравятся, мы можем игнорировать суммы в недопустимых позициях, а затем оценивать остальные.

ṣ”!µḢW;m2$VṾ$L¡€
ṣ”!                Split input on '!'
   µ               Set as the new default for missing arguments
    Ḣ              Take the first element, removing it from the default
     W;  $         Cons with
       m2            every odd-numbered element of {the tail of the !-split input}
               €   For each remaining element
          VṾ$      Evaluate and de-evaluate it
             L¡      a number of times equal to its length

Оценивая сумму как, "10+10"вы оцените ее как число, например 20, затем преобразуете ее в строку "20". Повторение этого процесса не имеет никакого дополнительного эффекта (это идемпотент). Таким образом, мы эффективно оцениваем каждый элемент строки, кроме нулевой строки, которая остается неоцененной, поскольку имеет нулевую длину.


источник
Это отличный трюк для условной оценки каждого элемента. Не могли бы вы как-то взять логическое И каждого элемента и его значение eval-deval'd? (Я предполагаю, что пустая строка является ложной в желе)
ETHproductions
@ETHproductions: молчаливость желе делает маловероятным, чтобы это спасло байты; он предпочитает избегать использования одного и того же значения дважды, если это возможно, и если вы хотите повторно использовать значение, обычно вам нужно как минимум добавить дополнительное значение µкуда-то (и µне работает внутри цикла, что означает, что вам нужно что-то еще более многословно). Мне все-таки удалось заставить его работать, ṣ”!µḢW;m2$ȧVṾ$$€но он не короче (и имеет характерную кучу знаков доллара, которые обычно случаются, когда вы толкаете Jelly к краю его способности
2

Желе , 18 байт

ṣ”!µḊm2;@ḢW$LÐfVṾ€

Попробуйте онлайн!

Как?

ṣ”!µḊm2;@ḢW$LÐfVṾ€ - Main link: string
ṣ”!                - split on '!' characters
   µ               - monadic chain separation (call that x)      e.g. ['1+1','0+0','0+0','0+0','','1+0','','','']
    Ḋ              - dequeue x (all but the leftmost entry of x) e.g.       ['0+0','0+0','0+0','','1+0','','','']
     m2            - modulo 2 index into that result             e.g.       ['0+0',      '0+0',   '1+0',   '']
           $       - last two links as a monad
         Ḣ         -     head x (the leftmost entry of x)        e.g.  '1+1'
          W        -     wrap                                    e.g. ['1+1']
       ;@          - concatenate with reversed arguments         e.g. ['1+1','0+0',      '0+0',   '1+0',   '']
             Ðf    - filter keep:
            L      -     length (keep that have non-zero length) e.g. ['1+1','0+0',      '0+0',   '1+0']
               V   - eval as jelly code (vectorises)             e.g. [  2,    0,          0,       1]
                      Yes, addition is just + and decimal numbers are just strings of digits in Jelly believe it or not!
                Ṿ€ - uneval €ach (creates a string from each one)e.g. [ '2',  '0',        '0'     ,'1']
                      without the € it would uneval the list and hence yield commas too)
                   - implicit print (prints the resulting list [of characters and possibly
                      lists of characters] as if it were all one string.)
Джонатан Аллан
источник
Я не думаю, что это работает для литерала 0+0в середине ввода (в месте, где его не отбрасывают); он генерирует пустую строку, хотя должен выдавать цифру 0.
Ах, правда - мне придется перейти к более долгому решению :(
Джонатан Аллан
Должен быть исправлен (возможно, в гольф сейчас).
Джонатан Аллан
1

Рубин , 58 56 + 1 = 59 57 байт

Использует -pфлаг. -2 байта от Тутлемана .

i=0;$_=' '+$_;gsub(/!?([^!]*)/){eval$1if(2>i+=1)||i%2<1}

Попробуйте онлайн! (Была добавлена ​​дополнительная строка кода, чтобы она заняла все строки ввода и напечатала вывод в разных строках.)

Значение чернил
источник
Я думаю, что вы можете отказаться от скобок eval$1, нет?
Tutleman
@ Тутман, да. Я не знаю, какая у меня была проблема, из-за которой я добавил паренсов (их не было, когда я начал писать программу), но, похоже, я действительно могу их отбросить.
Стоимость чернил
0

Пакет, 192 184 байта

@echo off
set/ps=
call:c . "%s:!=" "%"
echo(%s%
exit/b
:c
set s=
if not %2=="" set/as=%2
:l
shift
shift
if "%1"=="" exit/b
if %1=="" goto l
set/at=%1
set s=%s%%t%
goto l

Работать с пустыми строками неудобно.

Нил
источник
0

Пип , 18 байт

Я думаю, что это самое короткое время ... хотя я говорил об этом и три итерации назад.

{VaX++v%2+!v}Ma^'!

Принимает ввод в качестве аргумента командной строки. Попробуйте онлайн!

объяснение

                    a is 1st cmdline arg; global variable v is -1 (implicit)
              a^'!  Split a on !
{           }M      Map this function to the resulting list (note that inside function,
                    a is the function arg):
    ++v              Increment v (so that v tracks the 0-based index of the current
                     element)
       %2            We want to keep the elements where v%2 is 1...
         +!v         ... and also v=0, where v%2 is 0, but adding !v makes it 1
  aX                 String-multiply the argument by the above quantity (turning elements
                     we don't want into empty string)
 V                   Eval it (eval'ing empty string gives nil, but that's okay because
                     nil doesn't output anything)
                    Autoprint the resulting list, concatenated together (implicit)
DLosc
источник
0

R, 95 байт

function(x)for(e in strsplit(gsub('!([^!]*)![^!]*','\\1!',x),'!')[[1]])cat(eval(parse(text=e)))

Вероятно, есть место для улучшения, но на данный момент это лучшее, что я могу придумать.

Роберт Хакен
источник