Akcesoria po fakcie!

10

To wyzwanie inspirowane matematyką jest faktem. Programowanie nie jest .


Notacja matematyczna dla silni lub faktu jest wykrzyknikiem !. Wykrzyknik jest również częstym symbolem notw wielu językach programowania.

Wyzwanie:

Weź ciąg zawierający cyfry i znaki: + !jako dane wejściowe i wyjściowe wykonaj następujące czynności:

Wszystko przed wykrzyknikiem powinno być ocenione jako wyrażenie matematyczne, tak też 2+2byłoby 4.

Wszystko po jednym wykrzykniku powinno być dołączone jako akcesoria do wszystkiego, co jest przed nim, więc: 2+2!5powinno dać 45, ponieważ 2+2=4i 5jest akcesorium. 2+2!5+5powinien dać 410.

Ponieważ !oznacza to również not, że nic, co po fakcie nie jest akcesorium, nie powinno być dołączane. Tak więc 2+2!!5powinienem dać 4, ponieważ 5nie jest akcesorium. Teraz not(not(true))==true, więc 2+2!!!5powinien dać 45. 2+2!!5!5+5powinien dać:, 410ponieważ 2+2=4następnie następuje silnia i !5!5+5. Pierwszy 5nie jest faktem, ale 5+5jest po kolejnym wykrzykniku i dlatego jest faktem po raz kolejny.

Wyjaśnienia:

  • Wykrzykniki nie będą przylegać do znaku +po obu stronach.
  • +Liczby nie będą prowadzić (to 5nie jest +5).
  • Opcjonalnie możesz dołączyć wiodące zero, jeśli jest to wynik wyrażenia przed pierwszym !. Zarówno 4i 04są przyjmowane wyjście do wejścia:0+0!4

Streszczenie: oceń każdą sumę (traktując !jako separatory). Następnie odrzuć wszystkie liczby, które pojawiają się po parzystej liczbie !(licząc od początku ciągu). Następnie usuń wszystko !.

Przypadki testowe:

!
   <- 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

To jest więc wygrywa najkrótszy kod w bajtach (w każdym języku)! Wyjaśnienia są bardzo zalecane!

Stewie Griffin
źródło
umm ... powiedzmy, że mamy 2 !! 3! 5 tutaj jest, czy nie 5, akcesorium 3?
officialaimm
3
@officialaimm It's 25(patrz dodany przypadek testowy). Co ważniejsze 2!!3!5!7, nadal by dawał 25, ponieważ jest parzysta liczba po !lewej stronie 7(więc nie liczysz tylko biegu tuż przed liczbą, ale całą !pozostałą część).
Martin Ender
Czy wynikiem może być Mathematica Row?
ngenisis
Um ... więc to wyzwanie nie ma nic wspólnego z silnią?
DLosc

Odpowiedzi:

5

Retina , 35 31 29 bajtów

Zaoszczędź 4 bajty, czerpiąc inspirację z produkcji ETH .

Dzięki Leo za uratowanie kolejnych 2 bajtów.

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

!\d*!?

Wypróbuj online!

Martin Ender
źródło
Możesz zapisać niektóre bajty w ostatnich wierszach takich jak ten
Leo
1
@Leo To naprawdę miłe, dziękuję. :)
Martin Ender
5

JavaScript (ES6), 58 56 bajtów

Zaoszczędzono dwa bajty dzięki Martinowi Enderowi .

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>

Może być jakoś ulepszony ...

ETHprodukcje
źródło
Ładne użycie argumentu funkcji do replace.
Neil
@Neil Dzięki, ale znalazłem lepszy sposób :-)
ETHproductions
Twój fragment kodu daje mi złą odpowiedź 1+1!5. Myślę, evalże trochę zapomniałeś przed !.
Wartość tuszu
@ValueInk Ach, cholera, nie sądzę, że istnieje prosty sposób, aby to naprawić.
ETHprodukcje
2

Galaretka , 16 bajtów

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

Wypróbuj online!

Wyjaśnienie

Kluczową obserwacją jest to, że możemy wykonać kroki „poza kolejnością”; zamiast szacować sumy, a następnie ignorować te, które nam się nie podobają, możemy zignorować sumy w nieprawidłowych pozycjach, a następnie ocenić resztę.

ṣ”!µḢ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

Ocenianie suma jak "10+10"ocenią go do numeru, na przykład 20, a następnie de-ocenić go na ciąg, "20". Powtarzanie tego procesu nie ma dodatkowego efektu (jest idempotentny). Dlatego skutecznie oceniamy każdy element łańcucha, z wyjątkiem łańcucha zerowego, który pozostaje nieoceniony, ponieważ ma zerową długość.


źródło
To świetna sztuczka, aby warunkowo ocenić każdy przedmiot. Czy mógłbyś w jakiś sposób wziąć logiczne ORAZ każdego przedmiotu i jego wartość eval-deval'd? (Zakładam, że pusty sznurek jest falsy w galaretce)
ETHproductions
@ETHproductions: Milczenie galaretki sprawia, że ​​jest mało prawdopodobne, aby to oszczędzało bajty; woli unikać dwukrotnego użycia tej samej wartości, jeśli to możliwe, a jeśli chcesz ponownie użyć wartości, zwykle musisz przynajmniej µgdzieś wstawić dodatkową wartość (i µnie działa wewnątrz pętli, co oznacza, że ​​potrzebujesz czegoś jeszcze bardziej gadatliwy). Udało mi się sprawić, że to działa, ṣ”!µḢW;m2$ȧVṾ$$€ale nie jest wcale krótsze (i ma charakterystyczny stos znaków dolara, który zdarza się, gdy
2

Galaretka , 18 bajtów

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

Wypróbuj online!

W jaki sposób?

ṣ”!µḊ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.)
Jonathan Allan
źródło
Nie sądzę, żeby to działało dosłownie 0+0w środku danych wejściowych (w miejscu, gdzie nie jest odrzucane); generuje ciąg zerowy, mimo że powinien dać cyfrę 0.
Ach, prawda - będę musiał przejść do dłuższego rozwiązania :(
Jonathan Allan
Powinien zostać naprawiony (prawdopodobnie teraz do gry w golfa).
Jonathan Allan
1

Rubinowy , 58 56 + 1 = 59 57 bajtów

Używa -pflagi. -2 bajty od Tutlemana .

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

Wypróbuj online! (Dodano dodatkowy wiersz kodu, aby zabrał wszystkie wiersze wejściowe i wydrukował dane wyjściowe w różnych wierszach.)

Wartość tuszu
źródło
Myślę, że możesz upuścić nawiasy eval$1, nie?
Tutleman
@Tutleman huh. Nie wiem, jaki miałem problem, który zmusił mnie do dodania parenów (nie były one obecne, kiedy zacząłem pisać program), ale wygląda na to, że naprawdę mogę je upuścić.
Wartość tuszu
0

Partia, 192 184 bajty

@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

Posługiwanie się pustymi łańcuchami jest niewygodne.

Neil
źródło
0

Pip , 18 bajtów

Wydaje mi się, że jest to najkrótszy możliwy czas ... chociaż powiedziałem to również około trzech iteracji temu.

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

Pobiera dane wejściowe jako argument wiersza polecenia. Wypróbuj online!

Wyjaśnienie

                    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
źródło
0

R, 95 bajtów

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

Prawdopodobnie jest miejsce na poprawę, ale w tej chwili jest to najlepsze, co mogę wymyślić.

Robert Hacken
źródło