Accessori dopo il fatto!


10

Questa sfida ispirata alla matematica è un fatto. La programmazione no .


La notazione matematica per un fattoriale o un fatto è un punto esclamativo !. Il punto esclamativo è anche un simbolo comune notin molti linguaggi di programmazione.

Sfida:

Prendi una stringa, contenente numeri e caratteri: + !come input e output quanto segue:

Tutto ciò che si trova davanti a un punto esclamativo dovrebbe essere valutato come un'espressione matematica, così 2+2sarebbe 4.

Tutto dopo un singolo punto esclamativo dovrebbe essere aggiunto come accessorio a tutto ciò che si trova di fronte, quindi: 2+2!5dovrebbe dare 45, perché 2+2=4, ed 5è un accessorio. 2+2!5+5dovrebbe dare 410.

Dal momento che !significa anche not, tutto ciò che non è un accessorio dopo il fatto non dovrebbe essere aggiunto. Quindi, 2+2!!5dovrebbe dare 4, dal momento che 5non è un accessorio. Ora, not(not(true))==truecosì 2+2!!!5dovrebbe dare 45. 2+2!!5!5+5dovrebbe dare:, 410perché 2+2=4, quindi seguito da un fattoriale e !5!5+5. Il primo 5non è un dato di fatto, ma 5+5è dopo un altro punto esclamativo, ed è quindi un fatto, ancora una volta.

chiarimenti:

  • I punti esclamativi non saranno adiacenti a un +lato.
  • Non ci saranno +numeri iniziali (è 5, non +5).
  • Opzionalmente puoi includere uno zero iniziale se questo è il risultato dell'espressione davanti al primo !. Entrambi 4e 04sono accettati output per input:0+0!4

Riepilogo esecutivo: valutare ogni somma (trattando !come separatori). Quindi scarta tutti i numeri che compaiono dopo un numero pari di !(contando dall'inizio della stringa). Quindi rimuovere tutto !.

Casi test:

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

Questo è quindi vince il codice più breve in byte (in ogni lingua)! Le spiegazioni sono fortemente incoraggiate!


umm ... diciamo che ne abbiamo 2 !! 3! 5 qui è o non è 5 un accessorio di 3?
officialaimm,

3
@officialaimm È 25(vedi caso di prova aggiunto). Ancora più importante, 2!!3!5!7darei comunque 25, perché c'è un numero pari di !sinistra del 7(quindi non devi solo contare la corsa proprio davanti al numero, ma tutta la sua !sinistra).
Martin Ender,

L'output può essere una Mathematica Row?
ngenesi,

Um ... quindi questa sfida non ha nulla a che fare con i fattoriali?
DLosc,

Risposte:



5

JavaScript (ES6), 58 56 byte

Salvato due byte grazie a Martin Ender .

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>

Potrebbe essere migliorato in qualche modo ...


Buon uso dell'argomento funzione a replace.
Neil,

@Neil Grazie, ma ho trovato un modo migliore :-)
ETHproductions

Il tuo frammento di codice mi sta dando la risposta sbagliata 1+1!5. Penso che ti sia dimenticato evalun po 'prima del !.
Value Ink

@ValueInk Ah dannazione, non credo che ci sia un modo semplice per risolvere il problema.
ETHproductions

2

Gelatina , 16 byte

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

Provalo online!

Spiegazione

L'osservazione chiave qui è che possiamo eseguire i passaggi "fuori servizio"; invece di valutare le somme e quindi ignorare quelle che non ci piacciono, possiamo ignorare le somme in posizioni non valide, quindi valutare il resto.

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

La valutazione di una somma come "10+10"la valuterà in un numero, ad es. 20, Quindi la de-valutazione in una stringa "20". Ripetere tale processo non ha alcun effetto aggiuntivo (è idempotente). Pertanto, valutiamo efficacemente ogni elemento della stringa, tranne la stringa nulla, che non viene valutata perché ha una lunghezza pari a zero.


È un grande trucco per valutare condizionalmente ogni elemento. Potresti in qualche modo prendere l'AND logico di ogni oggetto e il suo valore di valutazione parziale? (Suppongo che la stringa vuota sia falsa in Jelly)
ETHproductions

@ETHproductions: il tacitness di Jelly rende improbabile che ciò salverebbe i byte; preferisce evitare di usare lo stesso valore due volte, se possibile, e se vuoi riutilizzare un valore, di solito devi almeno aggiungere un extra µin qualche posto (e µnon funziona all'interno di un ciclo, il che significa che avresti bisogno di qualcosa ancora più prolisso). Sono riuscito a farlo funzionare come ṣ”!µḢW;m2$ȧVṾ$$€, ma non è più breve (e ha il caratteristico accumulo di simboli del dollaro che tende ad accadere quando spingi Jelly al limite della sua capacità di nidificare le strutture di controllo.)

2

Gelatina , 18 byte

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

Provalo online!

Come?

ṣ”!µḊ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.)

Non penso che questo 0+0funzioni letteralmente nel mezzo dell'input (in un posto in cui non viene scartato); produce la stringa null, anche se dovrebbe produrre una cifra 0.

Ah, vero - dovrò passare a una soluzione più lunga :(
Jonathan Allan,

Dovrebbe essere risolto (possibilmente golfable ora).
Jonathan Allan,


1

Rubino , 58 56 + 1 = 59 57 byte

Usa la -pbandiera. -2 byte da Tutleman .

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

Provalo online! (È stata aggiunta una riga di codice aggiuntiva in modo che prendesse tutte le righe di input e stampasse l'output in righe diverse.)


Penso che puoi lasciare cadere le parentesi eval$1, no?
Tutleman,

@Tutleman eh. Non so quale problema avessi che mi ha fatto aggiungere le parentesi (non erano presenti quando ho iniziato a scrivere il programma), ma sembra che riesca davvero a lasciarle cadere.
Valore inchiostro

0

Lotto, 192 184 byte

@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

Dover gestire le stringhe vuote è scomodo.


0

Pip , 18 byte

Penso che questo sia il più breve ... anche se l'ho detto anche tre iterazioni fa.

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

Accetta input come argomento della riga di comando. Provalo online!

Spiegazione

                    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)

0

R, 95 byte

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

Probabilmente c'è qualche margine di miglioramento, ma al momento è il migliore che mi venga in mente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.