Accessoires après coup!

10

Ce défi est inspiré par les mathématiques est un fait. La programmation ne l'est pas .


La notation mathématique d'un factoriel ou d'un fait est un point d'exclamation !. Le point d'exclamation est également un symbole commun notdans de nombreux langages de programmation.

Défi:

Prenez une chaîne, contenant des chiffres et les caractères: + !comme entrée et sortie les éléments suivants:

Tout ce qui se trouve devant un point d'exclamation devrait être évalué comme une expression mathématique, ce 2+2serait le cas 4.

Tout ce qui se trouve après un seul point d'exclamation doit être ajouté en tant qu'accessoire à tout ce qui se trouve devant, donc: 2+2!5devrait donner 45, car 2+2=4, et 5est un accessoire. 2+2!5+5devrait donner 410.

Puisque !signifie également not, tout ce qui n'est pas un accessoire après coup ne doit pas être ajouté. Donc, 2+2!!5devrait donner 4, car 5n'est pas un accessoire. Maintenant, not(not(true))==trueil 2+2!!!5faut donc donner 45. 2+2!!5!5+5devrait donner:, 410car 2+2=4, puis suivi d'un factoriel et !5!5+5. Le premier 5n'est pas un fait, mais 5+5est après un autre point d'exclamation, et est donc un fait, encore une fois.

Clarifications:

  • Les points d'exclamation ne seront pas adjacents à un +de chaque côté.
  • Il n'y aura pas de leader +pour les chiffres (c'est 5, non +5).
  • Vous pouvez éventuellement inclure un zéro de tête si c'est le résultat de l'expression devant le premier !. Les deux 4et 04sont acceptés en sortie pour entrée:0+0!4

Résumé analytique: évaluer chaque somme (traiter !comme des séparateurs). Ensuite, jetez tous les nombres qui apparaissent après un nombre pair de !(à compter du début de la chaîne). Retirez ensuite tout !.

Cas de 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

C'est du donc le code le plus court en octets (dans chaque langue) gagne! Les explications sont fortement encouragées!

Stewie Griffin
la source
euh ... disons que nous en avons 2 !! 3! 5 voici ou n'est pas 5 un accessoire de 3?
officialaimm
3
@officialaimm C'est 25(voir cas de test ajouté). Plus important 2!!3!5!7encore, donnerait 25, car il y a un nombre pair de !gauche du 7(donc vous ne comptez pas seulement la course juste devant le nombre, mais toute la !gauche).
Martin Ender
La sortie peut-elle être un Mathematica Row?
ngenisis
Euh ... donc ce défi n'a rien à voir avec les factoriels?
DLosc

Réponses:

5

Rétine , 35 31 29 octets

Enregistré 4 octets en s'inspirant des productions ETH .

Merci à Leo d'avoir enregistré encore 2 octets.

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

!\d*!?

Essayez-le en ligne!

Martin Ender
la source
Vous pouvez enregistrer quelques octets dans les dernières lignes comme ceci
Leo
1
@Leo C'est vraiment bien, merci. :)
Martin Ender
5

JavaScript (ES6), 58 56 octets

Enregistré deux octets grâce à 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>

Pourrait être amélioré en quelque sorte ...

ETHproductions
la source
Belle utilisation de l'argument de fonction pour replace.
Neil
@Neil Merci, mais j'ai trouvé un meilleur moyen :-)
ETHproductions
Votre extrait de code me donne la mauvaise réponse 1+1!5. Je pense que vous avez oublié evalun peu avant le !.
Value Ink
@ValueInk Ah sacrément, je ne pense pas qu'il existe un moyen facile de résoudre ce problème.
ETHproductions
2

Gelée , 16 octets

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

Essayez-le en ligne!

Explication

L'observation clé ici est que nous pouvons exécuter les étapes "dans le désordre"; au lieu d'évaluer les sommes puis d'ignorer celles que nous n'aimons pas, nous pouvons ignorer les sommes dans des positions invalides, puis évaluer le reste.

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

L' évaluation d' une somme comme "10+10"évaluera à un certain nombre, par exemple 20, puis de-évaluer à une chaîne, "20". La répétition de ce processus n'a aucun effet supplémentaire (c'est idempotent). Ainsi, nous évaluons efficacement chaque élément de la chaîne, à l' exception de la chaîne nulle, qui reste non évaluée car elle a une longueur nulle.


la source
C'est une excellente astuce pour évaluer conditionnellement chaque élément. Pourriez-vous en quelque sorte prendre le ET logique de chaque élément et sa valeur dévalorisée par l'évaluation? (Je suppose que la chaîne vide est fausse dans Jelly)
ETHproductions
@ETHproductions: la tacitness de Jelly rend peu probable que cela permettrait d'économiser des octets; il préfère éviter d'utiliser la même valeur deux fois si possible, et si vous voulez réutiliser une valeur, vous devez normalement au moins mettre un extra µquelque part (et µne fonctionne pas dans une boucle, ce qui signifie que vous auriez besoin de quelque chose encore plus verbeux). J'ai réussi à le faire fonctionner, ṣ”!µḢW;m2$ȧVṾ$$€mais il n'est pas plus court (et a la pile caractéristique de signes dollar qui a tendance à se produire lorsque vous poussez Jelly au bord de sa capacité à imbriquer des structures de contrôle.)
2

Gelée , 18 octets

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

Essayez-le en ligne!

Comment?

ṣ”!µḊ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
la source
Je ne pense pas que cela fonctionne pour littéral 0+0au milieu de l'entrée (dans un endroit où il n'est pas rejeté); il produit la chaîne nulle, même s'il doit produire un chiffre 0.
Ah, c'est vrai - je vais devoir passer à une solution plus longue :(
Jonathan Allan
Devrait être corrigé (peut-être jouable au golf maintenant).
Jonathan Allan
1

Rubis , 58 56 + 1 = 59 57 octets

Utilise le -pdrapeau. -2 octets de Tutleman .

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

Essayez-le en ligne! (Une ligne de code supplémentaire a été ajoutée pour prendre toutes les lignes d'entrée et imprimer la sortie sur différentes lignes.)

Encre de valeur
la source
Je pense que vous pouvez laisser tomber les parenthèses eval$1, non?
Tutleman
@Tutleman hein. Je ne sais pas quel problème j'ai eu qui m'a fait ajouter les parens (ils n'étaient pas présents lorsque j'ai commencé à écrire le programme), mais il semble que je puisse vraiment les supprimer.
Value Ink
0

Lot, 192 184 octets

@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

Le fait de devoir manipuler les chaînes vides n'est pas pratique.

Neil
la source
0

Pip , 18 octets

Je pense que c'est le plus court possible ... même si je l'ai dit il y a environ trois itérations aussi.

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

Prend l'entrée comme argument de ligne de commande. Essayez-le en ligne!

Explication

                    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
la source
0

R, 95 octets

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

Il y a probablement une marge d'amélioration mais pour le moment c'est le mieux que je puisse trouver.

Robert Hacken
la source